2012-05-19 35 views
2

我正在使用執行操作並需要將操作結果傳回給啓動操作結果的活動的Intent服務。將服務中的數據發送到活動和屏幕旋轉

我已經搜查了幾十個類似的帖子,但據我所知,我發現所有的解決方案都有問題。他們不能很好地處理屏幕旋轉。假設某個活動啓動了Intent Service,該服務需要10秒才能執行該操作,並且在這10秒內,屏幕會旋轉。活動被破壞,並創建一個新的。

  1. 使用接收者:它創建一個內存泄漏,因爲接收者綁定到必須銷燬的活動,所以活動永遠不會被破壞。
  2. 使用廣播:您必須註冊一個偵聽器,並在活動被破壞之前取消註冊偵聽器。如果廣播消息在監聽器未註冊之後到達,並且新活動的監聽器被註冊之前,則不會收到該消息。
  3. 使用消息:與接收者相同。
  4. 使用共享首選項/數據庫與偵聽器:與廣播相同。

我想出的解決方案是讓服務將結果保存在一個首選項文件中,並定期檢查(每200毫秒)對首選項文件進行更改。因此,當屏幕旋轉時,活動停止檢查,並在重新創建時重新開始。如果結果是在兩者之間傳遞的,它仍會到達(重新創建的)活動。但是,它好像消耗了CPU並從SD卡執行不必要的讀取。

另一種解決方案是讓服務將結果保存在首選文件/數據庫中,並將全局變量設置爲保存該結果的時間。該活動具有傾聽者的偏好文件/數據庫。在註冊偵聽器之前,它會檢查全局變量以查看在屏幕旋轉期間是否放置了結果(全局變量< currentTimeMillies()),如果爲true,則獲取結果,如果不是,則註冊偵聽器。由於結果可能放在支票和註冊之間,因此必須在活動持有鎖的服務塊內完成,服務必須獲取該鎖來放置結果。這也可以,但它太複雜了。

有沒有一個更簡單,更優雅的方式做到這一點,倖存的屏幕旋轉?

回答

1

看一看我回答這個問題:

How to handle IPC between a service and an activity (and its subactivity)?

也許會給你一個想法。

EDIT(以下添加建議):

另一種方法是使用你在活動創建一個接收器。在屏幕旋轉時,操作系統將調用onRetainNonConfigurationInstance(),您可以在其中返回Receiver實例,並將其切換到新的Activity(請參閱getLastNonConfigurationInstance())。注意:這些方法在4.0中已被棄用,您可以使用Fragment和setRetainInstance()來實現類似的行爲。

+0

我喜歡你重定向到的答案。我採用了我寫的第二個解決方案,使用首選項並且根本沒有全局變量。問題是,首選項不能保存所有類型的數據(Bundles,Parcelables,BigDecimals等),迫使我做一個不斷的從字符串轉換到字符串。你的解決方案似乎更加優雅,沒有使用SD卡,沒有嚴重的內存消耗(一見鍾情),所有的整潔和乾淨。我還爲IntentService通信實現了一個基類。順便說一句,我想與Android 1.6(API級別4)的兼容性,所以我儘量不使用片段,甚至沒有使用ACL。 – cdriver

+0

很高興能爲您解決問題提供幫助和快樂! –