github地址
https://github.com/lzyzsd/JsBridge
常規接入方式
repositories {
// ...
maven { url "https://jitpack.io" }
}
dependencies {
implementation 'com.github.lzyzsd:jsbridge:1.0.4'
}
// java註冊接口 給js調用
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 調用java註冊的接口
WebViewJavascriptBridge.callHandler(
'submitFromWeb'
, {'param': str1}
, function(responseData) {
document.getElementById("show").innerHTML = "send get responseData from java, data = " + responseData
}
);
//也可以用 defaultHandler
// java中 註冊default
webView.setDefaultHandler(new DefaultHandler());
//js中 通過defaultHandler
window.WebViewJavascriptBridge.send(
data
, function(responseData) {
document.getElementById("show").innerHTML = "repsonseData from java, data = " + responseData
}
);
//js注入一個方法 供java調用
WebViewJavascriptBridge.registerHandler("functionInJs", function(data, responseCallback) {
document.getElementById("show").innerHTML = ("data from Java: = " + data);
var responseData = "Javascript Says Right back aka!";
responseCallback(responseData);
});
// java調用 js注入的方法
webView.callHandler("functionInJs", new Gson().toJson(user), new CallBackFunction() {
@Override
public void onCallBack(String data) {
}
});
//js註冊一個默認方法,來接受java層的信息
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層傳遞信息
webView.send("hello");
注意:
jsbridge 庫會註冊一個WebViewJavascriptBridge 對象到window ,在js中 使用WebViewJavascriptBridge對象前
必須判斷WebViewJavascriptBridge 是否存在,如果不存在,需要重新監聽ready事件
if(window.WebViewJavascriptBridge){
//do your work here
}else {
document.addEventListener(
'WebViewJavascriptBridgeReady'
,function(){
//do your work here
},
false
);
}
遇到的坑
1. jsbridge調用無效
原因:
給webview設置了 webviewClient ,jsbridge需要使用webviewClient對於url進行轉發
解決方案:
使用 BridgeWebviewClient 進行拓展
webView.setWebViewClient(new BridgeWebViewClient(webView));
2. jsbridge java層面回調無效
mWebView.registerHandler("callMethod", (data, function) -> {
function.onCallBack("this is callback message"); //這裏無效 h5收不到
});
分析原因:
realeas 1.0.4 構建的不是最新的代碼
解決方案:
fork jsbridge分支 打最新包解決問題 (發現當前最新commit 構建失敗,使用2018年10月29日 commit aca02b46 進行構建成功) ,使用ok
3. 使用jsbridge 無故調用兩次
使用最新的 aca02b46 構建的包,出現 h5調用 java註冊方法後,當路由發生變化時,會無端調用之前調用過的方法,或者調用兩次。重新切換到老的構建版本 1.0.4 並未發現此類情況
查看2018年1月前後 發信啊一個 lost message 修復bug 引入 bizMessagingIframe ,但與之前的messagingIframe 並無區別
修改 _fetchQueue 方法總 bizMessagingIframe 爲 messagingIframe ,相當於使用該commit之前的代碼 ,重新構建允許
bug修復,路由切換 調用正常
解決方案
function _fetchQueue() {
var messageQueueString = JSON.stringify(sendMessageQueue);
sendMessageQueue = [];
//android can't read directly the return data, so we can reload iframe src to communicate with java
if (messageQueueString !== '[]') {
// bizMessagingIframe.src = CUSTOM_PROTOCOL_SCHEME + '://return/_fetchQueue/' + encodeURIComponent(messageQueueString);
messagingIframe.src = CUSTOM_PROTOCOL_SCHEME + '://return/_fetchQueue/' + encodeURIComponent(messageQueueString);
}
}
個人fork後的 release
implementation 'com.github.caixingcun:JsBridge:2.1.3'