我正在开发一个库,该库以某种方式在 Samsung Galaxy S1(api v7 - android 2.1)上发生 CalledFromWrongThread
异常崩溃。代码是这样的:
class MyWebViewClient extends WebViewClient {
@Override
public void shouldOverrideUrlLoading(WebView view, String url) {
someListener.addToUiView();
}
}
当然,还有实际抛出错误的方法(实现监听器回调):
View v;
public void addToUiView(){
v.addView(new TextView(context)); //<-- this line is throwing the error on rare occasions
}
我跳过了中间的一些代码,但我没有在其他地方做任何奇怪的事情。另请注意:这种崩溃似乎只发生了非常小部分的时间。 (不一定是结论性的,因为并非每个人都报告他们的数据)。
还有人遇到过这个吗? WebCore 线程是否把事情弄乱了?
最佳答案
现在我还没有真正测试过这个,但我将尽我所知回答。也就是说,我的直觉告诉我,您只会间歇性地看到错误,因为来自 WebView
(浏览器)的 Web 请求会发生不同程度的异步性,并且可能会利用线程池来完成此操作。基本上,有时它会并行请求资源,有时则不会。更糟糕的是,您可能只会在单个设备上看到此错误,因为 OEM 根据他们的偏好和意见(尤其是三星)优化操作系统级别代码(如 WebView
内部)。无论哪种方式,真正的问题是您正在一个绝对不能保证“UI 友好”的地方做一些“UI 相关”的事情......也就是说,在您获得子系统回调的任何地方。
问题的解决方案比解释简单得多:只需使用您的上下文
(我假设是一个Activity
)..
Activity
有一个名为 runOnUiThread(Runnable)
的内置函数这将防止可运行对象内的代码在错误的线程上运行。基本上,你的问题确实很常见,android 有一个内置的解决方案。 runOnUiThread
只会在需要时增加开销,换句话说,如果您的线程是 UI 线程,它只会运行 Runnable
,如果不是,它会使用正确的 Handler
(与 UI 线程关联的处理程序)来运行 Runnable
。
它应该是这样的:
View v;
public void addToUiView() {
final Activity activity = (Activity) context;
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
v.addView(new TextView(activity));
}
});
}
我将其编码在 SO 窗口内,因此我对任何严重错误表示歉意,希望有所帮助,如果您需要更多信息或这不能解决您的问题,请告诉我 -ck
关于Android:来自 WebView 的 shouldOverrideUrlLoading 的 CalledFromWrongThreadException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18434470/