我遇到了与此问题相同的错误的崩溃报告:WebView methods on same thread error
建议创建一个Runnable()。
我不明白为什么这才能解决问题。该错误在同一个Thread"上显示" Webview方法,但答案建议在UI-Thread(主线程)上创建该方法。但是不是UI-Thread唯一的线程吗?有人可以详细解释整个过程(考虑到我在构造函数中的每个活动中创建一个新的Webview)?
我实现Javascript函数/方法的代码如下所示:
public class JS_Bind {
private static final String TAG = "JS_Bind";
private Context context;
private AdvancedWebView mWebView;
public JS_Bind(Context c, AdvancedWebView mWebView) {
context = c;
this.mWebView = mWebView;
}
@JavascriptInterface
public void openActivity(String activityName) {
try {
Class activityClass = Class.forName(PACKAGE_NAME + "." + activityName);
context.startActivity(new Intent(MainActivity.this, activityClass));
} catch (ClassNotFoundException e) {
Toast.makeText(context, "Invalid activity name: " + activityName, Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
@JavascriptInterface
public void makeToast(String toast) {
Toast mToast = Toast.makeText(context, toast, Toast.LENGTH_SHORT);
mToast.setGravity(Gravity.CENTER, 0, 0);
mToast.show();
}
@JavascriptInterface
public void external(String url) {
mTracker.send(new HitBuilders.EventBuilder().setCategory("Action").setAction("External Link: " + url).build());
Uri uri = Uri.parse(url);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
}
@JavascriptInterface
public String showToken() {
return gcmToken;
}
@JavascriptInterface
public int showUid() {
SharedPreferences pref = getSharedPreferences("Pref", Activity.MODE_PRIVATE);
int uid = pref.getInt("uid", 0);
return uid;
}
@JavascriptInterface
public void buyPremium() {
bp.purchase(MainActivity.this, PRODUCT_ID);
}
}
我是否必须将每个函数更改为此代码(first answer in the question I refered to):
@JavascriptInterface
mWebView.post(new Runnable() {
@Override
public void makeToast() {
// ...
}
});
?
顺便说一句,这就是我在构造函数活动onCreate
方法中创建webview的方法:
mWebView = (AdvancedWebView) findViewById(R.id.webView);
mWebView.setListener(this, this);
mWebView.addJavascriptInterface(new JS_Bind(this, mWebView), "Android");
mWebView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
if (!DetectConnection.checkInternetConnection(this)) {
mWebView.loadUrl("file:///android_asset/offline.html");
}
else {
mWebView.loadUrl("http://example.com/tw3/index.php?s=home");
}
答案 0 :(得分:1)
但是UI-Thread不是唯一的线程吗?
没有。 WebView
有自己的线程池。可以有many other threads in an Android application。
我是否必须将每个功能更改为此代码
不一定。
首先,我不知道您是如何从上面显示的A WebView method was called on thread 'JavaBridge'. All WebView methods must be called on the same thread.
方法中获得该错误(@JavascriptInterface
)的。该错误是在WebView
本身上调用方法时,您没有这样做。
如果符合以下条件,您将需要使用runOnUiThread()
(或等效技术)
您的@JavascriptInterface
方法是指WebView
本身,或
您的@JavascriptInterface
尝试在主应用程序线程上执行必须执行的其他操作(这将产生不同的错误消息,因为它不会专门与WebView
绑定)
可能需要在主应用程序线程上调用startActivity()
调用 - 我忘了是否可以在后台线程上调用它。与您的Toast
工作类似 - 虽然我认为可以在后台线程上完成,但我不确定。自从我尝试从后台线程中完成其中任何一项工作以来已经很久了。
此外,如果您控制WebView
中显示的每个字节,请仅使用您的代码。将startActivity()
暴露给任意Web内容具有重大的安全隐患。