Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 392|回复: 0

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

[复制链接]
  • TA的每日心情
    奋斗
    2024-4-6 11:05
  • 签到天数: 748 天

    [LV.9]以坛为家II

    2034

    主题

    2092

    帖子

    70万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    705612
    发表于 2021-4-22 10:59:52 | 显示全部楼层 |阅读模式

    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代码:

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
    <script type="text/javascript">
    	function show(jsondata) {
    		var jsonobjs = eval(jsondata); 							// 生成json数组
    		var table = document.getElementById("personTable");
    		for ( var y = 0; y < jsonobjs.length; y++) { 			// 遍历json数组
    			var tr = table.insertRow(table.rows.length); 		// 每一个对象创建1个TR
    			var td1 = tr.insertCell(0);							// 创建3个TD	
    			var td2 = tr.insertCell(1);
    			var td3 = tr.insertCell(2);
    			td1.innerHTML = jsonobjs[y].name; 					// 设置TD的内容为json对象的name属性
    			td2.innerHTML = jsonobjs[y].amount;
    			td3.innerHTML = "<a href='javascript:contact.call(\"" + jsonobjs[y].phone + "\")'>" + jsonobjs[y].phone + "</a>"; // 点击超链接时运行Java方法
    		}
    	}
    </script>
    </head>
    <body onLoad="javascript:contact.showContacts()">
    	<table width="100%" id="personTable">
    		<tr>
    			<td width="30%">姓名</td>
    			<td width="30%" align="center">存款</td>
    			<td align="center">电话</td>
    		</tr>
    	</table>
    </body>
    </html>
    



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



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

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-5-3 20:18 , Processed in 0.068875 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表