2011-09-19 60 views
8

我正在處理我的第一個Android應用程序。它有一個隨着用戶更新而持久保存到數據庫的模型。onSaveInstanceState/onPause - 等到狀態完全保存後才允許進程被終止

當調用onSaveInsanceState時,我想保存一個可用於從數據庫加載用戶正在處理的文檔的標識。但是這隻能在文檔完全打開數據庫時纔會發生。在某些情況下,持續複雜的文檔可能需要幾秒鐘的時間(我希望一旦我完成所有的詳細註銷,速度會加快,並且在實際使用中,複雜的文檔將由用戶分階段構建,其中每一個將被保存到數據庫中,因此複雜文檔不一定要全部保存)。

現在,線程在Android上的#1規則是「不要屏蔽UI線程」,所以當然數據庫交互發生在一個單獨的線程上。但是我對Android生命週期的理解是,在很多情況下onSaveInstanceState被調用,因爲Android系統想要終止進程。這表明我不能讓這個方法返回,直到數據庫線程完成保存文檔爲止(事實上,使用我目前的設計,實際上我並不知道文檔的ID號是什麼,直到它被保存到數據庫中,所以我甚至不能把它放在保存好的狀態中)。

在這些情況下阻止UI線程等待持久任務是否合適?當調用onSaveInstanceState是因爲進程被終止時,該應用程序在前臺不再可見,所以沒有界面變得無法響應。

但是,當Activity實例被配置更新拋棄時,也會調用onSaveInstanceState,這會在屏幕方向更改時發生。這是非常不幸的,當側向旋轉屏幕無法做任何事情幾秒鐘。在這種情況下,進程(因此內存空間)仍然存在,所以如果我可以只在Bundle中存儲引用而不是其ID,那麼我並不嚴格需要確保文檔到達數據庫。但我不知道有什麼方法可以說明這兩種情況之間的區別。

對於這些情況是否有一個公認的做法?我應該阻止線程安全嗎?我可以使用普通的Java線程原語來阻止和等待嗎?有什麼我可以做的阻止線程,但確保堅持任務將完成之前Android關閉的過程?

所有這些也適用於,因爲onSaveInstanceState不一定會被調用。

回答

0

你應該試試AsyncTask,它會阻止你的用戶界面,但不會顯示空白屏幕,將加載必要的XML元素,然後將異步任務調用異步任務保存您的文檔在數據庫中。

請點擊此鏈接:AyncTask Exmaple

+0

我認爲'AsyncTask'的重點是它*不會阻塞UI線程?難道不是使用它來做長期作業的重點嗎? – Ben

+0

如果您在配置更改時遇到問題,請不要擔心,只需在此活動標記中的mainfest文件中記下configChanges,以便在方向更改時從不調用onSaveInstanceState()。它不會強制重新啓動 –

+0

這很方便(但有其自身的問題),但與問題完全無關,這是如何確保在應用程序被終止時實際保存的持久數據(如果保存是由背景完成的)線。 – Ben

2

你不必做永久保存在onSaveInstanceState,就可以非常簡單,只是保存實例狀態在Bundle,以便實例可以迅速恢復onRestoreInstanceState

文檔指出您應該在中寫入關鍵的持久數據(例如用戶編輯)到存儲中,但它也聲明它應該很快,以便下一個活動可以開始做任何它想做的事情。

我認爲我的建議是保存文檔文本和任何在onSaveInstanceState中的包,並將其恢復到onRestoreInstanceState。使用快速保存「備份副本」(臨時文件可能?),然後可以在onResume中將其恢復(如果尚未保存到數據庫中)。然後使用onStop(在活動已在後臺時調用它)實際將數據保存到數據庫。

請注意,在調用之後(以前從未這麼做,除非系統只剩下非常少的資源...),否則活動可能會中斷,這就是爲什麼在嘗試將其提交到數據庫之前保存快速備份的原因。

編輯 - 額外的基於評論

要確保在做保存過程完成之前保存應用程序可以被系統殺死後臺線程,我認爲它的罰款,以阻止和等待爲了在從返回之前完成保存線程,但我建議使用android:configChanges="orientation"來防止在方向更改時重新啓動活動(和調用)。

+0

我實際上一旦寫入數據庫就將所有數據提交給數據庫。我不會在'onSaveInstanceState'中執行。麻煩的是,當調用'onSaveInstanceState'時,最後觸發的保存操作*可能仍在進行中。我需要知道如何等待告訴Android系統「現在可以殺了我」,直到持久數據實際上是安全的。如果系統的資源如此之低以至於無論如何都會隨意殺死我的進程,那麼可以丟失未經過編輯的編輯,但我不希望在正常操作條件下通過數據庫操作中途中止進程。 – Ben

+0

在這種情況下,您可以按照mak_just4anything的建議,通過在清單文件中使用android:configChanges =「orientation」來跳過'onSaveInstanceState'。只要確保保存在'onPause' /'onStop'中完成。更多信息在這裏:http://developer.android.com/guide/topics/resources/runtime-changes.html#HandlingTheChange – Zharf

+0

我顯然沒有讓我的問題理解。可以說我的'onPause'調用了'tellBackgroundThreadToSaveStateToDb'。好。完成。現在,當Android想要殺死我的進程時,如何確保後臺線程不處理該請求? – Ben