JSBrige系列直通車爆安,由淺入深理解JS-Native的通信過(guò)程:
JSbridge系列解析(一):JS-Native調(diào)用方法
JSbridge系列解析(二):lzyzsd/JsBridge使用方法
JSbridge系列解析(三):lzyzsd/JsBridge源碼解析
JSbridge系列解析(四):Web端發(fā)消息給Native代碼流程具體分析
關(guān)于JSBridge的開(kāi)源庫(kù)暇韧,業(yè)界使用最多的是:https://github.com/lzyzsd/JsBridge。 使用方法如下:
一、添加編譯依賴
在應(yīng)用的build.gradle文件中添加如下代碼:
repositories {
// ...
maven { url "https://jitpack.io" }
}
dependencies {
compile 'com.github.lzyzsd:jsbridge:1.0.4'
}
二徽鼎、JS -> Native方法
可注冊(cè)Java Handler方法冀膝,供JS調(diào)用
//Java注冊(cè)方法示例,函數(shù)名submitFromWeb【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");
}
});
//JS調(diào)用注冊(cè)方法submitFromWeb【JS代碼】
WebViewJavascriptBridge.callHandler(
'submitFromWeb'
, {'param': str1}
, function(responseData) {
document.getElementById("show").innerHTML = "send get responseData from java, data = " + responseData
}
);
三甚负、Native -> JS方法
可注冊(cè)JS Handler方法柬焕,供java調(diào)用。注意callHandler方法需要在主線程中調(diào)用
//JS注冊(cè)方法示例梭域,方法名functionInJs【JS代碼】
WebViewJavascriptBridge.registerHandler("functionInJs", function(data, responseCallback) {
document.getElementById("show").innerHTML = ("data from Java: = " + data);
var responseData = "Javascript Says Right back aka!";
responseCallback(responseData);
});
//Java調(diào)用注冊(cè)的方法functionInJs【Java代碼】
webView.callHandler("functionInJs", new Gson().toJson(user), new CallBackFunction() {
@Override
public void onCallBack(String data) {
}
});
四斑举、JS初始化注意事項(xiàng)
JSBridge在運(yùn)行中為window對(duì)象注入了WebViewJavascriptBridge對(duì)象,在使用前需要判斷對(duì)象是否存在病涨。如果WebViewJavascriptBridge對(duì)象不存在富玷,則可以監(jiān)聽(tīng)WebViewJavascriptBridgeReady 事件,代碼示例如下:
if (window.WebViewJavascriptBridge) {
//do your work here
} else {
document.addEventListener(
'WebViewJavascriptBridgeReady'
, function() {
//do your work here
},
false
);
}
五既穆、JS與JAVA調(diào)用默認(rèn)Handler
JSBridge提供了默認(rèn)方法供JS和JAVA相互調(diào)用赎懦,避免注冊(cè)的步驟。
JAVA注冊(cè)默認(rèn)hander幻工,在不使用assigned handlerName情況下励两,供js發(fā)送消息給java
//java代碼。lib中提供DefaultHandler來(lái)處理接收到的js消息
webView.setDefaultHandler(new DefaultHandler());
//js代碼
window.WebViewJavascriptBridge.send(
data
, function(responseData) {
document.getElementById("show").innerHTML = "repsonseData from java, data = " + responseData
}
);
JS調(diào)用初始化方法囊颅,設(shè)置默認(rèn)handler当悔,在不使用assigned handlerName情況下傅瞻,供java發(fā)送消息給js
//JS代碼
bridge.init(function(message, responseCallback) {
console.log('JS got a message', message);
var data = {
'Javascript Responds': 'Wee!'
};
console.log('JS responding with', data);
responseCallback(data);
});
//Java代碼,console將輸出'JS got a message hello' and 'JS responding with'
webView.send("hello");
init方法在WebviewJavascriptBridge.js中實(shí)現(xiàn)盲憎,對(duì)應(yīng)方法如下嗅骄。該方法中初始化了WebViewJavascriptBridge._messageHandler,即默認(rèn)的handler焙畔,該變量在下一章節(jié)將源碼實(shí)現(xiàn)時(shí)出現(xiàn)在_dispatchMessageFromNative中掸读。
//set default messageHandler
function init(messageHandler) {
if (WebViewJavascriptBridge._messageHandler) {
throw new Error('WebViewJavascriptBridge.init called twice');
}
WebViewJavascriptBridge._messageHandler = messageHandler;
var receivedMessages = receiveMessageQueue;
receiveMessageQueue = null;
for (var i = 0; i < receivedMessages.length; i++) {
_dispatchMessageFromNative(receivedMessages[i]);
}
}