android4.1 JELLY_BEAN:All WebView methods must be called on the same thread[問題已解決]


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 交流


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM