首先先看下傳統的js與native交互的方式代碼:
1. js 調用 native 方法
wb.addJavascriptInterface(new Object(){
@JavascriptInterface
public void pushWebView(final String title, final String url) {
runOnUiThread(new Runnable() {
@Override
public void run() {
javaInvodeJsResult.setText("js返回信息: "+title+"url:"+url);
Toast.makeText(MainActivity.this,"js調用native了",Toast.LENGTH_SHORT).show();
}
});
}
},"jsInvodeJava");
第一個參數 : new Object () 創建了一個對象 ,第二個參數 : 我認為可以是對象的別名,就相當于這樣的代碼:
Object jsInvodeJava = new Object();
這樣 js 通過 這個 jsInvodeJava 對象 就可以調用 這個 pushWebView 這個方法了。
但是要特別注意:js 調用別名 和 方法名稱 ,參數必須完全一致,否則就會失敗,需要雙方約定好。
然后 js這邊的代碼就可以是這樣的:
javascript:jsInvodeJava.pushWebView("js","http://www.baidu.com");
2.native 調用 js 方法
native 調用js 代碼就 更簡單啦 ,直接可以在loadUrl里寫:
webview.loadUrl("javascript:alert('hello js')");
調用方法時,就這么寫:
webview.loadUrl("javascript:shareCallBack()");
瞬間感覺真是無敵了....就好像調用自己本身的方法一樣
在業務量不大的情況下,可以采用這種方式進行通信,但是隨著業務量變大的時候,交互特別頻繁的時候,這種交互方式所表現出現的弊端也就出來了。
弊端1:
java 和 js 兩者有非常大的依賴性,雙方的對象名稱和方法名,參數名 一樣都不能錯,一旦一方有修改,另一方就要修改,雙方高度依賴對方,可謂是高內聚的表現,耦合性特別高。需要做的就是:要實現雙方知道對方越少越好。
弊端2:
就是當js 要跟客戶端發消息時,需要判斷是android 還是 ios ,從而針對不同系統,發出方式不一樣,就要多做判斷,諸如下面代碼:
function (){
if(android){
<!--給android發消息-->
}else if(ios){
<!--給ios發消息-->
}
}
加入再有別的系統,需要再繼續判斷,無疑增加了代碼量,繁瑣。
js調用Android 接口是運行在一個叫jsBridge中,是一個子線程中的,而Android 調用js是運行在主線程中的,如果回調js方法,<<就需要一個線程切換>>,如上,當js通過代碼調用pushWebView方法時,
window.jsInvodeJava.pushWebView("title","http://www.baidu.com");
回調回來的接口是在子線程中的,如果我們要做一個頁面顯示需要運行在主線程中,就需要使用runOnUiThread方法,或者使用Handler然后處理結果。
如果可以,native 和 js 之間雙方互相暴露給對方一個接口就好,雙方建立一個通道,然后互相通信,就像socket通道一樣,并在此基礎上,建議一個協議,雙方都按照這個協議互相發消息,大家按照固定的規則發送和處理response,耦合性就會大大降低。