2

我正在开发一个库,该库以某种方式CalledFromWrongThread在三星 Galaxy S1(api v7 - android 2.1)上出现异常崩溃。代码是这样的:

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 线程是否搞砸了?

4

1 回答 1

2

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

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

Activitys 有一个内置函数runOnUiThread(Runnable),它会保护可运行对象中的代码不会在错误的线程上运行。基本上,你的问题很常见,android 有一个内置的解决方案。 runOnUiThread只会在需要时增加开销,换句话说,如果您的线程是 UI 线程,它将RunnableHandler运行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

于 2013-08-26T13:59:06.127 回答