android-APP長期運行於後台,重啟後如何避免異常
問題的詳細描述是這樣的:
android中,當我們按home鍵(一般指手機的物理按鈕的中間那個鍵)回到手機案頭,此時app並沒有退出,而是一直運行與後台中,此時如果我們點擊app表徵圖,還是會進入剛剛的介面之中。但是這存在一個問題,就是如果記憶體緊張或者當我們回到案頭,點擊了別的應用造成記憶體緊張,此時再通過點擊表徵圖進入app,此時會出現異常。這樣造成的使用者感覺非常不好!
其實,歸納起來,並不僅僅這種情況下造成資料丟失,造成資料丟失的情況有如下幾種:
(1)、當使用者按下HOME鍵時。
這是顯而易見的,系統不知道你按下HOME後要運行多少其他的程式,自然也不知道activity A是否會被銷毀,因此系統會調用onSaveInstanceState(),讓使用者有機會儲存某些非永久性的資料。
(2)、長按HOME鍵,選擇運行其他的程式時。
(3)、按下電源按鍵(關閉螢幕顯示)時。
(4)、從activity A中啟動一個新的activity時。(這種情況應該是,當我們在activity A時,此時通知欄有其他的通知,我們點擊通知啟動activity B,此時我們進入別的應用)
(5)、螢幕方向切換時,例如從豎屏切換到橫屏時。
值得幸運的是,android對此提供了非常好的解決辦法!
Activity的 onSaveInstanceState() 和 onRestoreInstanceState()並不是生命週期方法,它們不同於 onCreate()、onPause()等生命週期方法,它們並不一定會被觸發。當應用遇到意外情況(如:記憶體不足、使用者直接按Home鍵)由系統銷毀一個Activity時,onSaveInstanceState() 會被調用。但是當使用者主動去銷毀一個Activity時,例如在應用中按返回鍵,onSaveInstanceState()就不會被調用。因為在這種情況下,使用者的行為決定了不需要儲存Activity的狀態。通常onSaveInstanceState()只適合用於儲存一些臨時性的狀態,而onPause()適合用於資料的持久化儲存。
在activity被殺掉之前調用儲存每個執行個體的狀態,以保證該狀態可以在onCreate(Bundle)或者onRestoreInstanceState(Bundle) (傳入的Bundle參數是由onSaveInstanceState封裝好的)中恢複。這個方法在一個activity被殺死前調用,當該activity在將來某個時刻回來時可以恢複其先前狀態。
@Override protected void onSaveInstanceState(Bundle outState) { System.out.println(BaseActivity.onSaveInstanceState()); outState.putString(loginname, Application.LOGINNAME); outState.putInt(classId, Application.classId); outState.putSerializable(classinfos, (ArrayList)Application.getInstance().getClassInfos()); super.onSaveInstanceState(outState); } @SuppressWarnings(unchecked) @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { System.out.println(BaseActivity.onRestoreInstanceState()); super.onRestoreInstanceState(savedInstanceState); if (savedInstanceState != null) { Application.LOGINNAME = savedInstanceState.getString(loginname); Application.classId = savedInstanceState.getInt(classId); Application.getInstance().setClassInfos( (List)savedInstanceState.getSerializable(classinfos)); } }
執行個體代碼如上,通過重寫上面兩個方法儲存一些需要當前介面或者整個應用需要使用的資料,緩衝起來,等到重新啟動時,這些資料依然存在,這樣重啟之後不會造成app異常退出!
需要提醒的是,我們開發一個app的時候,activity是非常多的,一個介面中需要的資料很多,並且不知道使用者會在哪個activity中按下Home鍵退回到了手機案頭,這樣該如何處理呢?
此時的解決辦法是,使用一個基本BaseActivity,在BaseActivity重寫onSaveInstanceState和onRestoreInstanceState兩個方法,然後每個介面Activity繼承基類BaseActivity,這樣不必每個activity重寫這兩個方法,同時,不管在哪個activity中按下home鍵,都會把資料儲存起來,重啟之後資料不至於丟失!
———————————— 分隔字元—————————————-
另外,還有一個地方需要說明,有些app可能想每次點擊應用表徵圖的時候,都能夠進入主介面,不管此時app處於什麼狀態,不管app此時是否運行與後台,這時可以使用activity的配置
啟動的activity中配置android:launchMode=”singleTask”即可。這樣配置,保證每次點擊應用表徵圖,都進入主介面內,不管此時app是否運行與後台之中。