我遇到了一个奇怪的问题。我的代码有一个广播接收器,它在它的 onReceive() 中执行此操作:
view.post(new Runnable() {
@Override
public void run() {
view.refreshUI();
}});
我对这段代码出现 android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views 的原因感到困惑。
我已经将 Runnable
中的 refreshUI()
调用发布到 view
上。那么它如何不在 UI 线程上运行呢?
另一个奇怪的观察是,在我看到这个崩溃的情况下,广播发送服务甚至没有发送广播。我知道这一点是因为发送方和接收方的 logcat 中都记录了语句。但其中一个在坠机前就已经存在。
为了提供一些背景知识,上面的代码是在 Android 框架内编写的,用于键盘锁(或锁屏)。我正在研究为我们的硬件/主板定制的 Android 4.3 源代码。
以上代码自过去 1.5 年以来一直存在。尽管此处没有任何更改,但在过去几个月中只出现过两次该问题。
我已经回答过 Running on UIThread and posting to view, still get CalledFromWrongThreadException 和其他类似的问题,但它们主要是处理 AsyncTasks
。在我的案例中,我没有任何 AsyncTask
。
有什么想法吗?
最佳答案
当您想从非 UI 线程更新 UI 时,您必须使用 runOnUiThread()。例如,如果您想从后台线程更新您的用户界面。您也可以使用 Handler 来做同样的事情。
你应该使用这个:
runOnUiThread(new Runnable() {
@Override
public void run() {
view.refreshUI();
}
});
关于Android:即使将 Runnable 发布到 View ,也会获取 CalledFromWrongThreadException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33914969/