IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    [原]android4.1 JELLY_BEAN:All WebView methods must be called on the same thread[问题已解决]

    changemyself发表于 2014-11-07 08:33:40
    love 0

    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)));
    		}
    	}
    	
     
    }
    

    上面代码其实在android4.4以下版本也不会出什么问题,以前我也这么写过,但是 Android 4.1,API 17,也就是JELLY_BEAN 开始,android就针对webview中执行js代码和原生代码之间交互做了一些改动,具体改动什么我也没有去研究,只是把依照异常信息给出解决方法而已;

    上述代码,只要把js调用的方法 call()和 showContacts()都放在同一个handler.post线程执行就没有问题了。


    此外,只有被JavascriptInterface 注解标识的公有方法可以被JS代码访问,大家一定记住这一点

    @JavascriptInterface
    		public void showContacts() {

    如果在android4.1以上版本,你提供给js调用的方法,没有标示注解,这个方法是无法被webview里的javascript访问到的,很多人也问到这个问题了。


    看看最终执行效果:



    assets目录下的index.html代码:

    
    
    
    
    Insert title here
    
    
    
    	
    姓名 存款 电话



    源代码下载:(有人需要我就上传)



    • 欢迎加入CSDN技术群:221057495 交流



沪ICP备19023445号-2号
友情链接