2013-05-08 96 views
4

在Android中,在UI-Thread中不執行數據庫操作(或者至少是複雜的操作)通常是一種好的做法。我有一個複雜形式的活動,我希望確保所有數據都在活動進入後臺時保存(例如,用戶按下主頁按鈕或打電話進來)。在activity的onPause()方法中,我可以啓動一個將數據存儲在數據庫中的AsyncTask,但我永遠無法確定該任務是否成功完成,因爲在任務完成之前,android可以終止進程,因爲活動和整個應用程序都處於後臺。如何確保android在殺死進程之前保存數據

我可以在onPause方法中保存數據同步,但可以運行到ANR。
我知道在活動被殺後,Android會恢復視圖,但只有在視圖ID是唯一的情況下,此功能纔有效。我有很多以編程方式添加的視圖,我無法確保Id的唯一性,並且使用saveInstanceState功能幾乎是不可能的,因爲我必須保存非常複雜的模型。

有沒有可能確保數據在android之前殺死一個進程而不在UI線程中執行?

回答

3

我創建了一個應用程序,曾經有過類似的數據一致性問題。我在那裏做的是將數據對象存儲到我爲此創建的服務中。雖然這會讓你的Activity的啓動/停止/初始化變得更加困難(一旦活動再次啓動,你將不得不等待服務完成它以前啓動的保存操作),但這是我唯一可以使用的「Android」方式想想解決這個問題。

+1

根據Android API文檔不太可能,但也有可能服務將被殺死。好吧,我可以嘗試重新啓動服務,但爲了確保數據將被保存,我可以運行到一個無限循環(我承認這是非常不可能的,但不是不可能的)。目前唯一的方法來存儲數據,並確保它保存在任何情況下是在UI線程是一個非常糟糕的應用程序設計 – dan 2013-05-08 11:08:12

+0

我完全同意你觀察有關Android決定殺死最糟糕的情況即使它正在託管服務也是如此。這是可能的,但在同一時間(如你所說)極不可能。在UI線程上存儲數據實際上並不能確保被保存,因爲在幾秒鐘之後,用戶可能會看到一條ANR消息。當他決定殺死你的應用程序時,它會立即下降,甚至沒有完成你的保存操作。 – baske 2013-05-08 11:20:53

+2

順便說一下,這些故事呢:用戶決定關閉手機,而您的服務正在存儲數據。你會採取喚醒鎖來防止這種情況發生嗎?即使所有這些東西都在原地:如果電池完全死亡,你會做什麼?我給出了這些觀察結果,說明一點:你想成爲多少人?您應該始終分析完成「足夠」和「太多」以防止數據丟失之間的權衡。您處理的數據有多關鍵?國際海事組織委派一個AsyncTask仍然很危險,但委託給一個服務是相當安全的。 – baske 2013-05-08 11:26:06

0

如果您擔心繫統會在完成後終止您的後臺進程,那麼您可以考慮使用該服務。這可能是過度殺手,但肯定會按預期工作=)只要谷歌「Android服務教程」,如果你不確定如何使用它們。

-服務不會被殺死,除非你想讓他們!

0

事實上,如果您在onPause()中運行AsyncTask,Android可以在不等待工作線程完成的情況下終止應用程序的進程。但是如果有一個正在運行的Service,它不會殺死進程。所以這裏一個很好的解決方案是使用IntentService來實現數據庫同步邏輯。

+0

Android在30分鐘後殺死每個「服務」並重新啓動它。至少,這是我注意到的。如果「Service」正在使用內存中的緩存數據來與外部源同步,那麼您的解決方案是否仍然有效? – DroidBender 2013-05-08 11:00:35

+0

@MartijnVanMierloo,IntentService對於運行時間超過30分鐘的任務來說不是一個好的解決方案。 – Egor 2013-05-08 11:14:31

+0

@Egor,實際上如果你問我這是Android每30分鐘殺死一次服務的總漏洞。此外,它甚至與服務文檔相沖突。在我看來,IntentService與任何需要運行任意時間(包括30分鐘以上)的任務相比,與任何其他服務(您會選擇其他機制)完全相同。現在我知道你可以以「前景」優先級開始一個服務,但是對我來說更像實施安慰劑而不是概念差異。 – baske 2013-05-08 11:31:39

0

我在這裏面臨同樣的問題,何時保存數據:用戶完成表單或活動暫停時。我們還必須考慮屏幕旋轉或其他可能導致數據丟失的事件。

以下是我對Android developer site發現:

對於內容提供商的數據,我們建議活動「 正在編輯」用戶模式使用。也就是說,用戶做出的任何編輯實際上都是 ,而不需要額外的確認步驟。 支持這個模型通常是以下兩個 規則的一個簡單的問題:

  • 當創建一個新文檔時,它會立即創建後備數據庫條目或文件 。例如,如果用戶選擇編寫 新電子郵件,則只要它們在 開始輸入數據時就立即創建該電子郵件的新條目,以便在 之後指向此電子郵件的任何其他活動郵件現在將出現在草稿列表中。
  • 當一個活動的onPause()方法被調用時,它應該提交給後臺 內容提供者或文件所做的任何更改。這確保 這些更改將被任何其他活動看到,即將運行的 。你可能會想你的活動的生命週期中更加積極提交您的數據 在關鍵時刻: 之前,例如啓動一個新的活動,整理你的自己的活動之前,當輸入字段之間的 用戶開關等

這種模式旨在 防止當用戶活動之間的導航數據丟失,並且 允許系統已暫停後的任何時候安全地殺死一個活動(因爲需要的系統資源 別的地方)。注意 這意味着用戶從您的活動中按下BACK不是 的意思是「取消」 - 這意味着將活動的當前 內容保存起來。必須通過某種其他機制(例如明確的「還原」或「撤消」選項)來提供取消活動中的編輯 。