android - 服务、AsyncTasks 和 CalledFromWrongThreadException

标签 android

我在编写的应用程序中遇到一个非常奇怪的问题。这可能很简单,我对服务、AsyncTasks 以及何时可以再次访问 UI 线程有一些误解。

该应用程序包含一个主要 Activity ,您可以通过该 Activity 导航到多个其他 Activity 。该应用程序有两个服务,一个位于后台并在应用程序处于前台时定期轮询,另一个运行“AACPlayer”以流式传输实时广播流。

其中一个 Activity (具有 radio 的 UI 控件的 Activity )启动 radio 服务。为此,将触发 AsyncTask 以获取和解析 PLS 文件,并最终使用正确的流 URL 启动服务。该服务已启动,同时也启动了 AACPlayer。一旦流开始播放,就会发出一个广播,表示流已经开始播放。 Activity 中包含 radio 控件的广播接收器处理 Intent 并更新 UI。

这很好用,除了一个竞争条件,在服务广播其更新 UI 的 Intent 之前,通过看似随机的离开应用程序或退出 radio 屏幕的组合,所有其他 Activity 现在似乎在用户界面线程。在这种情况下启动的所有其他 Activity 都会收到一个异常,表明它处于非法状态并且无法修改任何与 UI 相关的操作,因为我们没有在 UI 线程上运行。通常的罪魁祸首异常消息是:W/System.err(3818): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

有没有其他人遇到过突然整个应用程序不再在其通常的 UI 线程上运行,并且所有其他 Activity 都报告此异常?我不认为我有任何代码在做任何会触发此错误的非法行为。 AsyncTasks 中没有 UI 相关的东西。由广播接收器(从 radio 服务接收)触发的回调确实触及 UI,但我想不出其他方法来做到这一点?

即使应用程序强制退出,问题也没有解决,但当应用程序强制退出或从 Android 设置中清除其数据时,问题得到补救。

编辑 - 根据要求,这里有一些代码概述了正在启动的服务以及启动服务/控制 UI 的 Activity :https://gist.github.com/1080797

如有任何想法,我们将不胜感激。谢谢。

最佳答案

尝试将 PlayerServiceUpdateReceiver 的初始化移动到 onCreate()。我不认为你需要在每个 onResume() 上重新初始化它,你只需要重新注册它。你懂我的意思吗?

我认为正在发生的事情是您收到了对已用新实例覆盖的接收器的回调。

或者我可能完全错了,这是正确的方法。如果我错了,请纠正我。

关于android - 服务、AsyncTasks 和 CalledFromWrongThreadException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6682862/

相关文章:

android - 在 Android 中删除绘画标志

android - 替换 com.google.android.gms :play-services with google-play-services. jar

android - startActivity 总是在原始 Activity 上调用 onDestroy

android - 后台服务可以在 Android 和 iOS 上运行多长时间

java - 在 libgdx 中绘制透明的 ShapeRenderer

android - PendingIntent 取消打开的 Activity

android - 如何返回webview的缓存页面?

android - 无法从 Firebase 上的存储引用中获取 URI

android - 如何停止在Android上的通话记录中记录电话

java - Android,Json解析错误