webview与javascript交互回调与异步

传送门:

webview与javascript基本交互方法请看这里:android-webview与javascript交互

webview与javascript异步回调实现方案:android-webview与javascript交互

*
*

1.在javascript中回调java代码内容

在java方法重直接返回值就行

@JavascriptInterface public String getUserName() { try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } return "pengwei08"; }

在javascript中可以直接使用

hello world

注意

在javascript这样写是同步的,直到window.jsBridge.getUserName()返回值js才会直接执行下去,在java代码重getUserName中线程休眠了5s,在javascript中window.jsBridge.getUserName()也需要等待5s才会继续往下执行。



2.在javascript中异步回调java代码内容

@JavascriptInterface public void asyncGetUserName(final String func) { new AsyncTask() { @Override protected String doInBackground(Object... params) { return "pengwei08++"; } @Override protected void onPostExecute(String aVoid) { super.onPostExecute(aVoid); // 回调传过来的function String js = "var callback = " + func + "; callback('" + aVoid + "')"; webView.loadUrl("javascript:(function(){" + js + "})()"); } }.execute(); }

在javascript重调用方法,并传入function(){}进行回调

hello world

js报错如下

Uncaught TypeError: undefined is not a function

原因很简单,在js中asyncGetUserName()参数是function,属于javascript对象,而在java代码中,asyncGetUserName()参数是字符串(换成Object也不行,js对象和java不能转化),

所以执行javascript回调函数失败。

是不是这样就不能回调了?

虽然我们不能直接传递function()对象,但是传递字符串还是可以的,但是要求执行固定的回调函数

@JavascriptInterface public void asyncGetUserName(final String func) { new AsyncTask() { @Override protected String doInBackground(Object... params) { return "pengwei08++"; } @Override protected void onPostExecute(String aVoid) { super.onPostExecute(aVoid); // 回调已经存在的a()方法 webView.loadUrl("javascript:a('"+aVoid+"')()"); } }.execute(); }

hello world

这样唯一的不好就是回调函数和参数都必须固定吧。

*
*

3.在java中回调javascript的值

@JavascriptInterface public void showImage(String imageUrl){ // 在这里可以执行加载图片的功能 Toast.makeText(MainActivity.this, imageUrl, Toast.LENGTH_LONG).show(); }

在javascript中执行showImage并传递参数就可以了

window.jsBridge.showImage("http://**.png");

要传递多个参数的话那就加多个参数就好了