Android: Set WebViewManager methods/fields as protected instead of private

Summary:
**Motivation**

See discussion in #10946. The motivation is to make `ReactWebViewManager` more extensible.

Re-using logic from the ReactWebViewManager when implementing your own custom WebView is a pain since so much of the logic is set as `private`.

This PR makes for easier extension/overriding of behavior, and less duplication of code, since most of the methods/fields are set as `protected` instead.

I've also made some "create" methods for the `WebView` and `WebViewBridge` so they can more easily be overridden.

**Test plan**
The test plan is the same as the other PR (#10946). I've made an simple test app which extends `RCTWebViewManager`: https://github.com/cbrevik/overrideWebview

See [CustomWebViewManager.java](https://github.com/cbrevik/overrideWebview/blob/master/android/app/src/main/java/com/overridewebview/CustomWebViewManager.java) for a simple implementation.

CC shergin (https://github.com/facebook/react-native/pull/10946#issuecomment-304763562)
Closes https://github.com/facebook/react-native/pull/14261

Differential Revision: D5413922

Pulled By: shergin

fbshipit-source-id: d2f6d478f2a147e2e7b5e05c195a8b28a0a3d576
This commit is contained in:
Christian Brevik 2017-07-12 20:33:12 -07:00 committed by Facebook Github Bot
parent aafccdf622
commit e2c87b59be
1 changed files with 26 additions and 18 deletions

View File

@ -87,11 +87,11 @@ public class ReactWebViewManager extends SimpleViewManager<WebView> {
protected static final String REACT_CLASS = "RCTWebView";
private static final String HTML_ENCODING = "UTF-8";
private static final String HTML_MIME_TYPE = "text/html; charset=utf-8";
private static final String BRIDGE_NAME = "__REACT_WEB_VIEW_BRIDGE";
protected static final String HTML_ENCODING = "UTF-8";
protected static final String HTML_MIME_TYPE = "text/html; charset=utf-8";
protected static final String BRIDGE_NAME = "__REACT_WEB_VIEW_BRIDGE";
private static final String HTTP_METHOD_POST = "POST";
protected static final String HTTP_METHOD_POST = "POST";
public static final int COMMAND_GO_BACK = 1;
public static final int COMMAND_GO_FORWARD = 2;
@ -102,14 +102,14 @@ public class ReactWebViewManager extends SimpleViewManager<WebView> {
// Use `webView.loadUrl("about:blank")` to reliably reset the view
// state and release page resources (including any running JavaScript).
private static final String BLANK_URL = "about:blank";
protected static final String BLANK_URL = "about:blank";
private WebViewConfig mWebViewConfig;
private @Nullable WebView.PictureListener mPictureListener;
protected WebViewConfig mWebViewConfig;
protected @Nullable WebView.PictureListener mPictureListener;
protected static class ReactWebViewClient extends WebViewClient {
private boolean mLastLoadFailed = false;
protected boolean mLastLoadFailed = false;
@Override
public void onPageFinished(WebView webView, String url) {
@ -185,7 +185,7 @@ public class ReactWebViewManager extends SimpleViewManager<WebView> {
createWebViewEvent(webView, url)));
}
private void emitFinishEvent(WebView webView, String url) {
protected void emitFinishEvent(WebView webView, String url) {
dispatchEvent(
webView,
new TopLoadingFinishEvent(
@ -193,7 +193,7 @@ public class ReactWebViewManager extends SimpleViewManager<WebView> {
createWebViewEvent(webView, url)));
}
private WritableMap createWebViewEvent(WebView webView, String url) {
protected WritableMap createWebViewEvent(WebView webView, String url) {
WritableMap event = Arguments.createMap();
event.putDouble("target", webView.getId());
// Don't use webView.getUrl() here, the URL isn't updated to the new value yet in callbacks
@ -212,10 +212,10 @@ public class ReactWebViewManager extends SimpleViewManager<WebView> {
* to call {@link WebView#destroy} on activty destroy event and also to clear the client
*/
protected static class ReactWebView extends WebView implements LifecycleEventListener {
private @Nullable String injectedJS;
private boolean messagingEnabled = false;
protected @Nullable String injectedJS;
protected boolean messagingEnabled = false;
private class ReactWebViewBridge {
protected class ReactWebViewBridge {
ReactWebView mContext;
ReactWebViewBridge(ReactWebView c) {
@ -258,6 +258,10 @@ public class ReactWebViewManager extends SimpleViewManager<WebView> {
injectedJS = js;
}
protected ReactWebViewBridge createReactWebViewBridge(ReactWebView webView) {
return new ReactWebViewBridge(webView);
}
public void setMessagingEnabled(boolean enabled) {
if (messagingEnabled == enabled) {
return;
@ -265,7 +269,7 @@ public class ReactWebViewManager extends SimpleViewManager<WebView> {
messagingEnabled = enabled;
if (enabled) {
addJavascriptInterface(new ReactWebViewBridge(this), BRIDGE_NAME);
addJavascriptInterface(createReactWebViewBridge(this), BRIDGE_NAME);
linkBridge();
} else {
removeJavascriptInterface(BRIDGE_NAME);
@ -308,7 +312,7 @@ public class ReactWebViewManager extends SimpleViewManager<WebView> {
dispatchEvent(this, new TopMessageEvent(this.getId(), message));
}
private void cleanupCallbacksAndDestroy() {
protected void cleanupCallbacksAndDestroy() {
setWebViewClient(null);
destroy();
}
@ -330,9 +334,13 @@ public class ReactWebViewManager extends SimpleViewManager<WebView> {
return REACT_CLASS;
}
protected ReactWebView createReactWebViewInstance(ThemedReactContext reactContext) {
return new ReactWebView(reactContext);
}
@Override
protected WebView createViewInstance(ThemedReactContext reactContext) {
ReactWebView webView = new ReactWebView(reactContext);
ReactWebView webView = createReactWebViewInstance(reactContext);
webView.setWebChromeClient(new WebChromeClient() {
@Override
public boolean onConsoleMessage(ConsoleMessage message) {
@ -568,7 +576,7 @@ public class ReactWebViewManager extends SimpleViewManager<WebView> {
((ReactWebView) webView).cleanupCallbacksAndDestroy();
}
private WebView.PictureListener getPictureListener() {
protected WebView.PictureListener getPictureListener() {
if (mPictureListener == null) {
mPictureListener = new WebView.PictureListener() {
@Override
@ -585,7 +593,7 @@ public class ReactWebViewManager extends SimpleViewManager<WebView> {
return mPictureListener;
}
private static void dispatchEvent(WebView webView, Event event) {
protected static void dispatchEvent(WebView webView, Event event) {
ReactContext reactContext = (ReactContext) webView.getContext();
EventDispatcher eventDispatcher =
reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher();