1. An overview of the

When we use H5 combined with Native development, and use H5 to develop some functions, it will definitely involve the problem of mutual call between Android and Js. Usually, there are two implementation methods.

The first is solved using the native addJavascriptInterface()

The second uses a third-party framework, WebViewJavascriptBridge, which is what I’m going to share today

Why use WebViewJavascriptBridge

For those who have developed Android for a period of time, Google webView has a security loophole before Android 4.4. Websites can get the important information of the client through JS injection, and even easily call the local code for rogue behavior. Google later found this loophole, and added defensive measures. If javascript calls native code, the developer must declare JavascriptInterface in the code,

Before 4.0, we need to make the webView load JS with the following code:

mWebView.addJavascriptInterface(new JsToJava(), "myjsfunction");  
Copy the code

4.4 After the call need to add @javascriptInterface annotation in the call method, if the code does not have this declaration, then it will not be able to make JS effective, that is to say, this can avoid malicious web pages using JS to steal and attack android clients.

But even so, we often need to do some judgment and restrictions, or perhaps also do some filtering and user friendly hints in js to record the native code, so JavascriptInterface will not meet our needs. So someone wrote the WebViewJavascriptBridge framework.

3. Start using it

Step 1.Android Studio guide package
repositories {
    // ...
    maven { url "https://jitpack.io" }
}

dependencies {
    compile 'com. Making. Lzyzsd: jsbridge: 1.0.4'
}
Copy the code
Step 2. Add in the layout file
<com.github.lzyzsd.jsbridge.BridgeWebView
    android:id="@+id/wv_web_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />
Copy the code
Step 3. Add interactive methods to the code

H5 Adjust the Android method

/ / the android client code
mWebView.registerHandler("test".new BridgeHandler() {
            @Override
            public void handler(String data, CallBackFunction function) {
           function.onCallBack("Specify that Handler receives the data from the Web and sends it back to you.");
}

/ / H5 server-side code
function test() {
           // Call the local Java method
           // The first argument is the name of the function to call Java, the second argument is the data to be passed, and the third argument is the method to execute the callback, and the responseData is the data returned by the Java layer
           var data='Send message to Java code to specify receive';
           window.WebViewJavascriptBridge.callHandler(
               'test'
               ,data
               , function(responseData) {
                   bridgeLog('Return data from Java:'+ responseData); }); }Copy the code

or

/ / the android client code
mWebView.setDefaultHandler(new BridgeHandler() {
            @Override
            public void handler(String data, CallBackFunction function) {
                function.onCallBack("Specify that Handler receives the data from the Web and sends it back to you."); }});/ / H5 server-side code
function test() {
           // Send a message to the Java code
           var data = 'Send message to Java code global receive';

           window.WebViewJavascriptBridge.send(
               data
               , function(responseData) {
                  bridgeLog('Return data from Java:'+responseData); }); }Copy the code

One of the above two ways is to specify the specific protocol good method, a global call

Android tuning H5

/ / the android client code
mWebView.send("Send data to the Web default receiver".new CallBackFunction(){
                    @Override
                    public void onCallBack(String data) {
                        Log.e(TAG, "Data sent back from the Web:"+ data); }});/ / H5 server-side code
// Register the callback function and call the initialization function on the first connection
connectWebViewJavascriptBridge(function(bridge) {
           bridge.init(function(message, responseCallback) {
               bridgeLog('Default to receive data from Java:' + message);
               var responseData = 'Default receives data from Java and sends it back to you';
               responseCallback(responseData);
           });

          
       })
Copy the code

or

/ / the android client code
mWebView.callHandler("test"."Send data to web specified receive".new CallBackFunction(){
                    @Override
                    public void onCallBack(String data) {
                        Log.e(TAG, "Data sent back from the Web:"+ data); }});/ / H5 server-side code
   connectWebViewJavascriptBridge(function(bridge) {
          bridge.registerHandler("test", function(data, responseCallback) {
               bridgeLog('Specify to receive data received from Java:' + data);
               var responseData = 'Specify receive received data from Java, return data to you';
               responseCallback(responseData);
           });
       })
Copy the code

The other way is to specify the specific method and so far we can’t interact with each other, so we need to configure setWebViewClient

mWebView.setWebViewClient(new BridgeWebViewClient(mWebView));
Copy the code

If you do not configure the test click will not respond at all. If you want to customize the WebViewClient, you must implement the corresponding constructor, and the overridden method must call the superclass method, as follows:

Private class MyWebViewClient extends BridgeWebViewClient {private class MyWebViewClient extends BridgeWebViewClient {public MyWebViewClient(BridgeWebView webView) { super(webView); } @Override public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) { super.onReceivedError(view, request, error); View.loadurl ("about:blank"); }Copy the code

At this point, the configuration is complete, and H5 and Android can call each other

Framework to link

GitHub