Android:来自WebView的shouldOverrideUrlLoading的CalledFromWrongThreadException

时间:2013-08-25 22:42:40

标签: android multithreading sdk webview

我正在开发一个库,以某种方式在三星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是否正在搞乱搞乱?

1 个答案:

答案 0 :(得分:1)

现在我还没有对此进行过测试,但我会尽我所能回答。也就是说,我的直觉告诉我你只是间歇性地看到错误,因为来自WebView(浏览器)的web请求发生了不同程度的异步性,并且可能利用线程池来实现这一点。基本上,有时它会并行请求资源,有时则不会。更糟糕的是,您可能只在单个设备上看到此错误,因为OEM根据他们的偏好和意见(特别是三星)优化操作系统级代码(如WebView内部)。无论哪种方式,真正的问题是你在一个绝对不能保证“UI友好”的地方做“UI相关”的事情......也就是说,你正在获得子系统回调的任何地方。

您的问题的解决方案比解释简单得多:只使用您的context(我假设是Activity)..

Activity有一个名为runOnUiThread(Runnable)的内置函数,可以防止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