2015-10-17 109 views
0

我正在追蹤一個在極少數情況下會導致應用程序在後臺處理一段時間後通過最近的應用程序列表重新激活時發生崩潰的錯誤。發生這種情況時,調用堆棧信息指示該活動尚未正確恢復其實例狀態。用於保存/恢復狀態的必要代碼爲 - 狀態保存在onSaveInstanceState中並在onCreate(在此情況下不是onRestoreInstanceState)中恢復。Android殺死進程時未調用saveInstanceState

我知道Android正在做什麼:它會在某個時候殺死應用進程以節省內存,並在重新激活應用時重新啓動它。但看起來Android在調用進程之前有時不會調用onSaveInstanceState,導致將一個null Bundle傳遞給onCreate。這是致命的,因爲從應用程序的角度來看,它從未停止過,但現在它的狀態已經消失。

任何想法如何發生?

另一個令人費解的細節是,雖然通過任務管理器殺死應用程序的過程不能(很容易地)再現崩潰,但在設備的開發人員選項中將後臺進程的數量設置爲「無」是一貫可重複的。 (我知道整個過程實際上在兩種情況下都被殺死了,因爲當應用程序重新啓動時,我可以看到它在等待調試器附加,當過程仍然存在時不會發生)。

在不允許後臺進程的情況下,按主頁按鈕並通過最近的應用程序列表重新激活應用程序足以重現崩潰。記錄清楚地表明onSaveInstanceState未被調用,並且null包被傳遞給onCreate

根據文檔,onSaveInstanceState總是在系統殺死進程之前調用。任何想法爲什麼它不會在這種情況下呢?

回答

0

你想保存什麼類型的數據?最好在onPause()中提交任何長期數據,因爲有些情況下onSaveInstanceState()可能不會被調用。我還建議理智檢查數據,所以如果你從Bundle得到任何東西,它將得到妥善處理。從Activity文檔:

「...因此,您應該使用onPause()方法將任何持久性數據(例如用戶編輯)寫入存儲。另外,方法onSaveInstanceState(Bundle)被調用在將活動置於這種後臺狀態之前,允許您將活動中的任何動態實例狀態保存到給定的Bundle中,以便稍後在onCreate(Bundle)中接收,如果活動需要重新創建。請參閱流程生命週期請注意,將持久數據保存在onPause()而不是onSaveInstanceState(Bundle)中是很重要的,因爲後者不是生命週期回調的一部分,所以在其文檔中所描述的每種情況下都不會被調用。「