2011-10-06 76 views
3

我試圖創建一個包含遠程服務內容觀察員的申請,但一直得到錯誤:服務,觀察和活套

「不能內螺紋已不叫尺蠖準備創建處理程序」

我對Android Developers網站以及許多Google搜索進行了大量閱讀,但我仍然不完全瞭解該問題。到目前爲止,我從中獲得的是Content Observer需要一個線程來運行(對於Handler)。加入後:

Looper.myLooper().prepare();
mObserver = new Observer(new Handler());

彎針呼叫立即創建一個新的內容之前觀察員正確地使應用程序的工作。不過,我想更好地理解爲什麼這是 - 我在網上找到的東西,幫助我理解爲什麼到目前爲止。另外,添加Looper代碼行是否正確和有效?有沒有我需要做的清理工作,以防止後來的內存泄漏?

說明越簡單越好。仍然在Android開發的第一個月,並取得良好的進展 - StackOverflow一直是一個巨大的幫助!謝謝。

UPDATE
玩耍和做更多的閱讀中,我想以後有關於如何使這項工作,以及如何把它清理乾淨,但仍然缺少一個小部分較好的把握。

從我收集的內容中我可以調用Looper.prepare()作爲靜態方法。然後,我可以使用新的Handler()創建我的內容觀察器。當我想停止這個Content Observer時,我可以用mLooper = Looper.myLooper.getThread()獲得對象的線程,然後我可以運行一個mLooper.quit()。但是,我必須什麼時候以及爲什麼要撥打mLooper.loop()?

UPDATE 2
好的,所以在這裏,我正在處理的問題。該應用程序是內部的,有點複雜的解釋,但這裏是我的最佳鏡頭:

我們有一個遠程服務運行,接收和發送網絡數據。我們的信息類型是在數據中定義的,所以我們可以將它們引導到手機上正確的數據庫。有一個Jar界面文件供其他APK導入以連接到正在運行的服務。當收到他們感興趣的新消息時,這些APK可以註冊接收廣播。要做到這一點,一個內容觀察者註冊到APK使用的內容,因此當新數據添加到數據庫時,內容觀察者將發出廣播以提醒正確的APK。然後,APK可以處理它,但它希望。

因此,如果將null用作新內容觀察器的參數,還是使用新的Handler()爲該觀察者創建線程會更好。

我已經嘗試創建一個線程,但到目前爲止它不工作,我認爲它是因爲我還沒有啓動Looper.loop(這會凍結我的服務)。任何建議將不勝感激!提前致謝。

回答

3

當您在一個線程中啓動Looper時,其他線程將獲得向其發送消息的能力,並且它將接收並處理它們。這個方案在Android中被廣泛使用:looper在UI線程上被初始化,並且其他線程被分配來執行一些簡單的操作。這些「工作者」線程可以通過發佈消息Handler將他們的努力結果發送到UI線程。

而且,是的,您需要撥打Looper.loop()才能讓事情順利進行。否則你的處理程序永遠不會收到任何事件而且似乎您必須調用Looper.quit()才能阻止它並避免資源泄漏。

這裏是有趣的部分。根據ContentObserver's source code來判斷,它並不完全需要Handler。如果您通過null,它將在運行它的同一個線程上執行onChange()

P.S.我的開發機器關閉了,所以我無法驗證我的聲明。也許當前版本的ContentObserver確實需要Handler工作。實驗將顯示。

+0

把null放在我的代碼中使它工作!我認爲它是因爲我從來沒有說過Looper.loop()讓一切都開始。我會在更新我的問題時解釋更多。這有效......但我寧願讓onChange由於流量而在自己的線程中運行。 – jjNford

+0

讓我換一個更新#2。您有一個數據庫作爲存儲消息的中心,然後由不同的客戶端在不同的APK中接收消息,並且ContentObserver執行調度,是否正確? – Ash

+0

正確。實際上有幾個數據庫,但傳入的消息將攜帶它所屬的DB的ID。我希望它能夠儘可能有效地運行,而不需要日誌,並且儘可能多地使用線程就是最好的選擇。有任何想法嗎? – jjNford