Table of Contents
与WebView交互(JsBridge框架)
一、未封装的JS-Native调用
二、使用JSBridge
三、在JSBridge上进一步封装(优化)
四、部分调用的结果
五、可能容易踩的坑
安卓提供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 消息
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");
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方式等)