1. 常見的通訊方案
在這裡我們討論的是Android平臺,js與native通訊主要包括Java調Js,Js調Java; Java調Js主要是通過webView.loadUrl(url)
來實現,Js調Java包括兩種;一種是Android原生支援的addJavascriptInterface(),另一種就是JsBridge.
2. jsBridge
這裡我們主要討論的是jsBridge,jsBridge不同的開源專案實現的方式還是有些細微的差別的
3. safe-java-js-webview-bridge
這個方案存在很早了,但是作者已經很久都沒有維護了,還是有不少缺陷的,我更新了工程的配置,重新做了下處理。 使用的時候只需要依賴
compile 'com.github.xingstarx:safe-java-js-webview-bridge:master-SNAPSHOT'
複製程式碼
這個的實現思路如下:
- 生成需要嵌入到html裡面js程式碼
- js呼叫Java方法的時候會回撥WebChromeClient的onJsPrompt方法,這個時候會把關鍵的引數資訊傳遞回來,對這些引數進行解析並執行,也就是執行jsCallJava.call(webView, jsonStr),在這個過程中,就通過反射的機制,執行了我們的java方法
貼一下格式化後的這段js程式碼:
javascript: (function(b) {
console.log("HostApp initialization begin");
var a = {
queue: [],
callback: function() {
var d = Array.prototype.slice.call(arguments, 0);
var c = d.shift();
var e = d.shift();
this.queue[c].apply(this, d);
if (!e) {
delete this.queue[c]
}
}
};
a.alert = a.changeVariables = a.retJavaObject = a.selectImage = a.toast = function() {
var f = Array.prototype.slice.call(arguments, 0);
if (f.length < 1) {
throw "HostApp call error, message:miss method name"
}
var e = [];
for (var h = 1; h < f.length; h++) {
var c = f[h];
var j = typeof c;
e[e.length] = j;
if (j == "function") {
var d = a.queue.length;
a.queue[d] = c;
f[h] = d
}
}
var g = JSON.parse(prompt(JSON.stringify({
method: f.shift(),
types: e,
args: f
})));
if (g.code != 200) {
throw "HostApp call error, code:" + g.code + ", message:" + g.result
}
return g.result
};
Object.getOwnPropertyNames(a).forEach(function(d) {
var c = a[d];
if (typeof c === "function" && d !== "callback") {
a[d] = function() {
return c.apply(a, [d].concat(Array.prototype.slice.call(arguments, 0)))
}
}
});
b.HostApp = a;
console.log("HostApp initialization end")
})(window);
複製程式碼
js學的不是很好,這段程式碼沒看懂,好菜啊?
4. 存在的缺陷,以及完善,對koltin的支援
github上面這個專案的issue不少,作者也沒有在跟進了,問題比較多 另外專案用上了如今比較火的kotlin語言,那麼實現的HostApp這個kotlin類無法正常工作,是由於koltin的語言特性造成,kotlin實現的類預設都是public final method()形式的
if (method.getModifiers() != (Modifier.PUBLIC | Modifier.STATIC) || (sign = genJavaMethodSign(method)) == null) {
continue;
}
複製程式碼
JsCallJava的構造方法裡面有這麼一段判斷邏輯,規定了HostApp裡面的類方法得是public static method()
,而不能是其他的,所以對判斷邏輯做了一點修改
//針對kotlin語言做相容處理,kotlin實現的HostApp,是`pubic static final method()`,而java語言實現的HostApp是`public static method()`,仔細理解下面的位運算
if ((method.getModifiers() | Modifier.FINAL) != (Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL) || (sign = genJavaMethodSign(method)) == null) {
continue;
}
複製程式碼
5. 其他的jsBridge方案
在github上找到了其他的jsBridge,還需要調研下在總結 JsBridge 有一段時間沒有維護了 JsBridge 比較新