Services,AsyncTasks和CalledFromWrongThreadException

时间:2011-07-13 17:13:33

标签: android

我正在编写的应用程序中有一个非常奇怪的问题。可能很简单,我误解了有关Services,AsyncTasks的内容,以及当我再次访问UI线程时。

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

其中一项活动,即具有无线电UI控制的活动,启动无线电服务。为此,将触发AsyncTask以获取和解析PLS文件,最后使用该流的正确URL启动服务。该服务已启动,同时启动AACPlayer。流开始播放后,将发出一个广播,表示该流已开始播放。保存无线电控件的活动中的广播接收器处理意图并更新UI。

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

是否有其他人突然遇到整个应用程序不再在其通常的UI线程上运行,而所有其他活动都报告此异常?我认为我没有任何代码可以做任何非法的代码来触发此错误。 AsyncTasks中没有UI相关的东西。由广播接收器触发的回叫(从无线电服务接收)确实触摸了用户界面,但是我想不出有不同的方法来做到这一点?

即使应用程序强制退出问题,问题也不会得到解决,但是当应用程序强行退出或从Android设置中清除其数据时,问题就会得到解决。

编辑 - 根据要求,此处列出了一些代码,其中概述了正在启动的服务以及启动服务/控制用户界面的活动:https://gist.github.com/1080797

任何想法都将不胜感激。感谢。

1 个答案:

答案 0 :(得分:1)

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

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

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