Services, AsyncTasks and the CalledFromWrongThreadException
I have a very strange issue in an application I'm writing. It may be as simple that I am misunderstanding something about Services, AsyncTasks and when I have access to the UI thread again.
The application consists of a main activity through which you navigate to multiple other activities. The app has two Services, one that sits in the background and periodically polls while the application is in foreground, and another that runs "AACPlayer" to stream a live radio stream.
One of the activities, the one that has the UI controls for the radio, starts the service for the radio. To do this an AsyncTask is fired to grab and parse the PLS file, and finally start the Service with the proper URL of the stream. The service is started that also i开发者_如何学JAVAnitiates the AACPlayer. Once the stream has started playing, a broadcast is issued that says the stream has started playing. The broadcast receiver in the activity that holds the radio controls handles the intent and updates the UI.
This works great except for one race condition where through a seemingly random combination of leaving the app or backing out of the radio screen, before the Service has broadcasted its intent to update the UI, all other activities now seem to run outside of the UI thread. Every other activity fired up during this condition receives an exception that it's in an illegal state and can not modify do anything UI related as we're not running on the UI thread. The usual culprit exception message is: W/System.err( 3818): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
Has anyone else encountered that suddenly the entire application no longer is running on its usual UI Thread, and all other activities report this exception? I don't think I have any code that's doing anything illegal that would trigger this error. No UI related things inside AsyncTasks. The callback that's triggered by the broadcast receiver (receiving from the radio Service) does touch UI, but I can't think of a different way to do this?
The problem is not fixed even when the application force quits itself, but gets remedied when the application is either force quit or has its data cleared from the Android Settings.
EDIT - As requested here's some code that outlines the service being started and the activity that starts the service / controls the UI: https://gist.github.com/1080797
Any thoughts would be appreciated. Thanks.
Try moving the initialization of your PlayerServiceUpdateReceiver to onCreate(). I don't think you need to reinitialize it on every onResume(), you just need to re-register it. Do you know what I mean?
I think what is happening is that you're getting callbacks to receivers that you've overwritten with new instances.
Or I might be completely wrong and it's the correct way to do it. Correct me if I'm wrong.
精彩评论