2011-07-13 57 views
1

我正在寫一個應用程序中有一個很奇怪的問題。這可能很簡單,我誤解了有關服務,AsyncTasks以及何時再次訪問UI線程的內容。服務,AsyncTasks和CalledFromWrongThreadException

該應用程序由一個主要活動組成,通過它您可以導航到多個其他活動。該應用程序有兩個服務,一個位於後臺,在應用程序處於前臺時定期輪詢,另一個運行「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相關的東西。由廣播接收器(從無線電服務接收)觸發的回調確實觸及UI,但我想不出用不同的方式來做到這一點?

即使應用程序強制自行退出,該問題仍未修復,但在應用程序強制退出或從Android設置清除其數據時得到補救。

編輯 - 由於這裏要求的一些代碼,列出正在啓動的服務和啓動服務活動/控制UI:https://gist.github.com/1080797

任何想法,將不勝感激。謝謝。

+0

請添加一些代碼... – Marmoy

+0

創建一個服務文件和該服務的「主管」活動的要點。 https://gist.github.com/1080797 – jlindenbaum

回答

1

嘗試將您的PlayerServiceUpdateReceiver的初始化移動到onCreate()。我不認爲你需要在每個onResume()重新初始化它,你只需要重新註冊它。你懂我的意思嗎?

我認爲正在發生的事情是您正在接收器的回調函數被新實例覆蓋。

或者我可能是完全錯誤的,這是正確的做法。如我錯了請糾正我。

+0

初始化現在在onCreate,註冊仍然在onResume - 是你的意思? https://gist.github.com/1080797/c473eb5084f53fc22c3a8b25cd136dede9958e0a – jlindenbaum

+0

是的,這是否有所作爲? – Marmoy

+0

只是被放到要測試的設備上。很難說它是否修復了它,或者我們無法重現它。 ;) 你有沒有看到有什麼你會做不同/更好? – jlindenbaum

相關問題