赞
踩
Android WebViewJSBridge分析
这种方法采用js注入的方式来实现webView与h5的交互
相关文件的UML图
image
Native相关操作
Activity中new WebViewJavascriptBridge()对象 bridge
在WebView加载成功之后 onPageFinish()方法中加载本地js代码
在WebView对象上addJavascriptInterface(Object object, String name),This method can be used to allow JavaScript to control the host application. 在本地js文件中可以通过该name来,调用Native方法,调用的方法必须由@JavascriptInterface 注解
mWebView.addJavascriptInterface(this, "_WebViewJavascriptBridge");
本地js代码实现的功能
在当前window上添加WebViewJavascriptBridge对象
在当前document对象上添加一个event, 将该WebViewJavascriptBridge添加到event中,通过document分发这个event
在html加载的js文件中,监听该event。收到该event消息之后,获取event中WebViewJavascriptBridge对象,进行初始化, 给WebViewJavascriptBridge._messageHandler赋值。
现在H5页面获取WebViewJavascriptBridge对象,可以进行交互啦!
H5发送消息到Native
bridge就是H5页面获取的WebViewJavascriptBridge对象
bridge.callHandler("handler1","gift for handler1",function(responseData){
console.log("got handler1 response:"+responseData);
});
Native处理H5发来的消息
native本地的js代码
function callHandler(handlerName, data, responseCallback) {
_doSend({ handlerName:handlerName, data:data }, responseCallback)
}
function _doSend(message, responseCallback) {
if (responseCallback) {
var callbackId = 'cb_'+(uniqueId++)+'_'+new Date().getTime();
responseCallbacks[callbackId] = responseCallback;
message['callbackId'] = callbackId;
}
console.log("sending:"+JSON.stringify(message));
//调用Native方法
_WebViewJavascriptBridge._handleMessageFromJs(JSON.stringify(message.data)||null,message.responseId||null,
message.responseData||null,message.callbackId||null,message.handlerName||null);
}
native代码处理消息
_handleMessageFromJs方法负责找到注册该hanlderName的WVJBHandler,把h5发来的信息回调回Activity,Activity做相应的处理。
@JavascriptInterface
public void _handleMessageFromJs(final String data, String responseId,
String responseData, String callbackId, String handlerName){
if (null!=responseId) {
WVJBResponseCallback responseCallback = _responseCallbacks.get(responseId);
responseCallback.callback(responseData);
_responseCallbacks.remove(responseId);
} else {
WVJBResponseCallback responseCallback = null;
if (null!=callbackId) {
responseCallback=new CallbackJs(callbackId);
}
final WVJBHandler handler;
if (null!=handlerName) {
handler = _messageHandlers.get(handlerName);
if (null==handler) {
Log.e("test","WVJB Warning: No handler for "+handlerName);
return ;
}
} else {
handler = _messageHandler;
}
try {
final WVJBResponseCallback finalResponseCallback = responseCallback;
mContext.runOnUiThread(new Runnable(){
@Override
public void run() {
//回调给Activity处理
handler.handle(data, finalResponseCallback);
}
});
}catch (Exception exception) {
Log.e("test","WebViewJavascriptBridge: WARNING: java handler threw. "+exception.getMessage());
}
}
}
Native发送消息到H5
Activity中WebViewJavascriptBridge对象bridge,这个对象和window.WebViewJavascriptBridge不是同一个。
bridge.callHandler("gotoMarker","1");
WebViewJavascriptBridge.java
public void callHandler(String handlerName, String data) {
callHandler(handlerName, data,null);
}
public void callHandler(String handlerName, String data, WVJBResponseCallback responseCallback){
_sendData(data, responseCallback,handlerName);
}
private void _sendData(String data, WVJBResponseCallback responseCallback, String handlerName){
Map message=new HashMap();
message.put("data",data);
if (null!=responseCallback) {
String callbackId = "java_cb_"+ (++_uniqueId);
_responseCallbacks.put(callbackId,responseCallback);
message.put("callbackId",callbackId);
}
if (null!=handlerName) {
message.put("handlerName", handlerName);
}
_dispatchMessage(message);
}
private void _dispatchMessage(Map message){
String messageJSON = new JSONObject(message).toString();
//调用WebViewJavascriptBridge.js的方法
final String javascriptCommand=String.format("javascript:WebViewJavascriptBridge._handleMessageFromJava('%s');",doubleEscapeString(messageJSON));
mContext.runOnUiThread(new Runnable(){
@Override
public void run() {
mWebView.loadUrl(javascriptCommand);
}
});
}
H5处理Native发来的消息
Native的js代码处理,找到H5代码注册的那个Handler回调方法,回调回去,即可处理消息。
WebViewJavascriptBridge.js
function _dispatchMessageFromJava(messageJSON) {
var message = JSON.parse(messageJSON);
var messageHandler;
if (message.responseId) {
var responseCallback = responseCallbacks[message.responseId];
if (!responseCallback) { return; }
responseCallback(message.responseData);
delete responseCallbacks[message.responseId]
} else {
var responseCallback;
if (message.callbackId) {
var callbackResponseId = message.callbackId;
responseCallback = function(responseData) {
_doSend({ responseId:callbackResponseId, responseData:responseData })
}
}
var handler = WebViewJavascriptBridge._messageHandler;
if (message.handlerName) {
handler = messageHandlers[message.handlerName]
}
try {
handler(message.data, responseCallback)
} catch(exception) {
if (typeof console != 'undefined') {
console.log("WebViewJavascriptBridge: WARNING: javascript handler threw."+ exception)
}
}
}
}
html中方法
bridge.registerHandler("showAlert", function(data) { console.log("alert:"+data); });
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。