java和javascript配合,让Java和Javascript更加亲密
在移动App开发中,为了快速迭代,通常都会使⽤Native+Web的模式开发。具体来说就是使⽤Java提供接⼝,使⽤WebView控件嵌套Web页⾯来实现UI和交互。
在Android中,Java可以很⽅便的提供接⼝给WebView中的Js进⾏调⽤,只要以下⼀⾏代码就能搞定:
mWebView.addJavascriptInterface(new JavascriptInterface(), "custom_name");
这样,JavascriptInterface的所有声明为public的⽅法,都能被mWebView中的Js通过以下⽅式调⽤:
window.();//xxx为JavascriptInterface的公有⽅法
⽽Java需要调⽤Js时,则是通过WebView实例的loadUrl⽅法调⽤:
mWebView.loadUrl("javascript:xxx(yyy)");
这其实跟你在浏览器的地址栏敲下“javascript:alert(1)”的原理是⼀样的。
⼀切看起来都是那么的美好,只是……
当Java需要传递⼤量字符串给Js时,URL就⼒不从⼼了。另外,从URL执⾏的Js,在页⾯没加载完成时,是有可能导致页⾯出现undefined错误(因为要执⾏的那个⽅法可能还没有声明呢),会引发各种奇形怪状的错误。
那要怎么办呢?
再回看上⾯Js调⽤Java接⼝的地⽅,可以发现,Js是可以直接调⽤Java⽅法并取得Java给的返回值的(必须是可序列化的数据)。那么,为何不试试把Java需要执⾏的Js⽅法,保存起来,让Js来读取、执⾏、并把结果写回?
步骤如下:
Java把Js调⽤(命令)和回调缓存,如保存到ArrayList;
Js定时轮询Java提供的getCommandList接⼝;
Js读取到要执⾏命令,执⾏它,并把结果通过setResult写回给Java;
Java把对应命令的回调取出并执⾏。
如此即完成了Java调⽤Js的流程。
为了⽅便使⽤,简单的封装了下,名为AndroidJavascriptBridge,可移步到Github查看源码和⽰例(MainActivity.java和test.js )。
使⽤⽅法
Android端调⽤, 加⼊com.imatlas.jsb 和 com.imatlas.util包, 按如下步骤调⽤
//1. 创建JavascriptBridge实例
final JavascriptBridge jsb = new JavascriptBridge(webView);
//2. 调⽤Javascript⽅法
Bundle params = new Bundle();
params.putString("asdfasdf", "123123");
@Override
public void onComplate(JSONObject response, String cmd, Bundle params) {
Log.i("js response",String());
}
});
//3. 提供Java⽅法给Javascript调⽤
//添加个 messagebox ⽅法给js
jsb.addJavaMethod("messagebox", new JavascriptBridge.Function() {
@Override
public Object execute(JSONObject params) {
Toast.makeText(getApplicationContext(), String(), Toast.LENGTH_LONG) .show();
return "{\"ret\":123}";
}
});
Javascript端的调⽤, 须先引⼊web/js/jsb.js, 之后按如下⽅式调⽤
//1. 调⽤Java⽅法
js方法
alert('调⽤messagebox回来啦\n' + JSON.stringify(response));
});
//2. 提供Javascript⽅法给Java调⽤
jsb.addJavascriptMethod('alert', function(params){
alert( '------\n' + JSON.stringify(params) + '\n========\n');
return {'text': 'alert ok'};
});
IOS的话就要反过来了,要改成由Objective-C来轮询Js,来实现Js对Native的调⽤。
嗯,等改天有时间了,就把IOS也封装进来,⽤起来就简单多了。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。