与WebView交互(JsBridge框架)

Table of Contents

与WebView交互(JsBridge框架)

一、未封装的JS-Native调用

二、使用JSBridge

三、在JSBridge上进一步封装(优化)

四、部分调用的结果

五、可能容易踩的坑


 

与WebView交互(JsBridge框架)

一、未封装的JS-Native调用

安卓提供Webview用来加载html页面,以安卓4.4系统为分水岭,之前的webview内核采用webkit;4.4及之后改为chromium内核。

JS -> Native

常用的JS调用Java代码的方法,主要包括以下三种:

1)通过WebView的addJavascriptInterface进行对象映射

2)通过 WebViewClient 的shouldOverrideUrlLoading方法回调拦截 url

3) 通过 WebChromeClient 的onJsAlert、onJsConfirm、onJsPrompt方法回调拦截JS对话框alert、confirm、prompt 消息

 

二、使用JSBridge

WebViewJavascriptBridge是移动UIView和Html交互通信的桥梁,用作者的话来说就是实现java(ios为oc)和js的互相调用的桥梁。替代了WebView的自带的JavascriptInterface的接口,使得开发者更方便的让js和native灵活交互,使我们的开发更加灵活和安全。

2.1 引入JSBridge

在应用的build.gradle文件中添加如下代码:

repositories {
    // ...
    maven { url "https://jitpack.io" }
}

dependencies {
    compile 'com.github.lzyzsd:jsbridge:1.0.4'
}

2.2 JSBridge的代码实现

2.2.1 JS->Native(特有方法)

JS

//call native method
window.WebViewJavascriptBridge.callHandler(
    'submitFromWeb'
    , {'param': '中文测试'}
    , function(responseData) {
        document.getElementById("show").innerHTML = "send get responseData from java, data = " + responseData
    }
);

Java

webView.registerHandler("submitFromWeb", new BridgeHandler() {

   @Override
   public void handler(String data, CallBackFunction function) {
      Log.i(TAG, "handler = submitFromWeb, data from web = " + data);
              function.onCallBack("submitFromWeb exe, response data 中文 from Java");
   }
});

2.2.2 Native->JS(特有方法)

JS

  bridge.registerHandler("functionInJs", function(data, responseCallback) {
        document.getElementById("show").innerHTML = ("data from Java: = " + data);
        if (responseCallback) {
            var responseData = "Javascript Says Right back aka!";
            responseCallback(responseData);
        }
    });
})

Java

webView.callHandler("functionInJs", new Gson().toJson(user), new CallBackFunction() {
    @Override
    public void onCallBack(String data) {

    }
});

2.2.3 JS->Native(不指定方法名)

Java

webView.setDefaultHandler(new DefaultHandler());

JS

window.WebViewJavascriptBridge.send(
    data
    , function(responseData) {
        document.getElementById("show").innerHTML = "repsonseData from java, data = " + responseData
    }
);

2.2.4 Native->JS(不指定方法名)

JS

bridge.init(function(message, responseCallback) {
    console.log('JS got a message', message);
    var data = {
        'Javascript Responds': '测试中文!'
    };

    if (responseCallback) {
        console.log('JS responding with', data);
        responseCallback(data);
    }
});

Java

webView.send("hello");

三、在JSBridge上进一步封装(优化)

3.1 为了使webview能有后退功能,对返回键建进行了拦截

mWebView.setOnKeyListener(new OnKeyListener() {
    @Override
    public boolean onKey(View view, int i, KeyEvent keyEvent) {
        if (keyEvent.getAction() == KeyEvent.ACTION_DOWN) {
            if ((i == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack()) {
                mWebView.goBack();
                return true;
            }
        }
        return false;
    }
});

如果防止webview代码产生内存泄漏,请及时在activity销毁时,清空webview

if (mWebView != null) {
    //避免内存泄漏
    mWebView.removeAllViews();
    mWebView.destroy();
}

3.2 还可以对WebViewClient和WebChromeClient进行封装

比如加入错误页的指定

比如进行进度的显示与隐藏等

 

四、部分调用的结果

Native->JS

JS->Native

五、可能容易踩的坑

Native->JS(不指定方法名)的方式有可能看不到打印的Log中的message,但其实是有的(有可能是AS的问题),调试时可以通过其他方式来看获取的数据是否正确(比如用alert方式等)

 

 

 

 

 

 

 

 

你可能感兴趣的:(Android与web混合开发)