1. 程式人生 > >關於Android應用程式退至後臺,再次啟動資料丟失的問題

關於Android應用程式退至後臺,再次啟動資料丟失的問題

問題描述:
最近專案中出現了個Bug,開啟應用程式按home鍵退出前臺,啟動其他的應用,經過一段時間再次啟動自己的應用程式,發現介面中出現了資料丟失問題,導致程式出現一系列問題。
發現即使用Static 修飾的變數,也竟然被GC回收了,很納悶這個問題。這問題在我除錯的手機上沒有發生過,但是測試人員描述,應用程式開啟後,退出前臺,一晚上過一段時間再次啟動就出現這問題了。

分析:
分析測試描述,發現應用是在退出前臺,再次進入前臺出現的問題。考慮到這點想起了做畢業論文時候看過的一段話:
*在Android系統中,為了使系統能夠正確決定記憶體不足時終止那個程序從而回收記憶體,Android會依據程序中當前活躍元件的重要程度來儘可能高的估量一個程序的級別,根據級別把程序裝入“Importance Hierarchy(重要性分級)“中, “Importance Hierarchy”中的程序是按重要程度排序的。*


1.前臺程序(Foreground)
前臺程序是與用於進行互動的程序,在程式執行中僅有少量的程序處於前臺,不同的元件會通過不同的方式將程序移植前臺,當記憶體無法供給前臺程序同時執行時候,部分前臺程序才被殺死,用於維持使用者介面響應。*
2.可見程序(Visible)
可見程序不在前臺顯示,但使用者可以看到他的Activity,當一個Activity被呼叫onPause()方法時,它的程序就處於可見狀態。可見程序一般不允許被終止,當前系統記憶體不足阻塞前臺程序時,會終止可見程序釋放記憶體供前臺程序使用。
3.服務程序(Service)
服務程序是使用者不可以直接看到程序,雖然使用者不能看到該程序的執行,但該程序做著使用者關心的問題,例如,在後臺播放音樂。系統會一直維護該程序執行,除非系統記憶體不足時,無法維護前臺程序和可見程序,系統將殺死該類程序。

4.後臺程序(Background)
後臺程序有一個使用者看不到的Activity,該Activity的onStop()方法被系統呼叫,Activity處於停止狀態,對使用者的體驗沒有影響,系統可以在任何時刻殺死該類程序回收其記憶體供前臺程序、可見程序、服務程序使用。系統中通常存在較多該程序儲存在LRU中,當記憶體不足時系統回收LRU中使用者最早使用的後臺程序。
5.空程序(Empty)
該程序的設立是為了提高程式執行速度,元件再次執行時虛擬機器不需要重新為元件分配記憶體。系統經常會殺死這種程序會殺死這種程序中優先順序較低的程序以保持程序快取和系統核心快取之間的平衡。

現在很清楚,按home鍵,應用程式程序製為後臺程序,呼叫Onstop() 方法,當系統記憶體不足的時候,GC會回收該程序中變數(即便變數的引用沒有斷開),從而導致資料丟失,但是Activity沒有被 finish調,再次進入前天程序,就會出現資料丟失的現象。
這裡寫圖片描述

問題解決:
Activity 提供儲存 資料的方法:
onSaveInstanceState(Bundle outState) 和onRestoreInstanceState(Bundle savedInstanceState)
onSaveInstanceState 呼叫情況:
1.按下或長按home鍵
2.橫豎螢幕切換
3.該Activity 啟動其他Activity
4.按下電源鍵
onRestoreInstanceState 呼叫情況:
當Activity退出前臺,確實被系統銷燬,會呼叫該方法,使用者儲存資料。
在 onCreate(Bundle savedInstanceState) 方法中可以進行資料的回覆。

savedInstanceState 可以儲存序列換的list
outState.putParcelableArrayList(“childList”, childList);
如何進行 Parcelable 參考