11-06 18:29:15.582: W/WebView(27807): java.lang.Throwable: A WebView method was called on thread 'JavaBridge'. All WebView methods must be called on the same thread. (Expected Looper Looper (main, tid 1) {425f48a8} called on Looper (JavaBridge, tid 92104) {426508d0}, FYI main Looper is Looper (main, tid 1) {425f48a8})
今天群里的一个朋友进来问到此问题,我提示他:异常信息提示很明确,所有的webview的方法比调用必须在一个线程,2个方法调用tid明显不同嘛。
我们先看他写得代码:
package com.webview; import android.annotation.SuppressLint; import android.app.Activity; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.webkit.JavascriptInterface; import android.webkit.WebView; public class MainActivity extends Activity { private Handler handler= new Handler(); private WebView webView; @SuppressLint("NewApi") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); webView = (WebView) findViewById(R.id.webView); // 根据ID找到WebView webView.getSettings().setJavaScriptEnabled(true); // 允许JS webView.loadUrl("file:///android_asset/index.html"); // 加载页面 webView.addJavascriptInterface(new Contact(), "contact"); // 创建Contact对象, 传给WebView, 作为JS对象 } class Contact { @JavascriptInterface public void showContacts() { /* handler.post(new Runnable(){ @Override public void run(){ String json = "[{name:\"王小二\", amount:\"12345\", phone:\"18600012345\"}, {name:\"黎明\", amount:\"54321\", phone:\"18600054321\"}]"; webView.loadUrl("javascript:show('" + json + "')"); // 调用JS方法// 把js数据,传递给html页面 } });*/ String json = "[{name:\"王小二\", amount:\"12345\", phone:\"18600012345\"}, {name:\"黎明\", amount:\"54321\", phone:\"18600054321\"}]"; webView.loadUrl("javascript:show('" + json + "')"); // 调用JS方法// 把js数据,传递给html页面 } @JavascriptInterface public void call(final String phone) { /* handler.post(new Runnable() { @Override public void run(){ startActivity(new Intent(Intent.ACTION_CALL, Uri.parse("tel://" + phone))); } });*/ startActivity(new Intent(Intent.ACTION_CALL, Uri.parse("tel://" + phone))); } } }
上述代码,只要把js调用的方法 call()和 showContacts()都放在同一个handler.post线程执行就没有问题了。
此外,只有被JavascriptInterface 注解标识的公有方法可以被JS代码访问,大家一定记住这一点
@JavascriptInterface public void showContacts() {
如果在android4.1以上版本,你提供给js调用的方法,没有标示注解,这个方法是无法被webview里的javascript访问到的,很多人也问到这个问题了。
看看最终执行效果:
assets目录下的index.html代码:
Insert title here
姓名 | 存款 | 电话 |
源代码下载:(有人需要我就上传)