首先先看下传统的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,耦合性就会大大降低。