Android中Activity執行restart過程中涉及到的四種資料儲存恢復的方法
我們知道,當Configuration Change發生的時候(比如橫豎屏切換等),會導致Activity重啟,即先destroy,然後會restart,一般情況下restart的時間比較短,為了保證一致的使用者體驗,我們應該在Activity重啟前將一些資料儲存下來,然後在restart的時候重新根據這些資料更新UI。當然你可能想將這些資料寫到物理檔案或資料庫中,但是這樣有缺點,因為IO操作時耗時操作,會影響restart的過程,甚至導致ANR程式無響應,本文將介紹幾種將資料快取在記憶體中以便restart時進行恢復的方法。
onSaveInstanceState
Activity具有onSaveInstanceState回撥方法,如果onSaveInstanceState方法被呼叫了,那麼該回撥方法一定是在onStop之前被呼叫的,但是不能保證是在onPause之前還是之後被呼叫。一般在此處將UI持久化的一些資訊存入到Bundle中,然後在Activity重新建立執行onCreate(Bundle)或onRestoreInstanceState(Bundle)的時候再根據Bundle恢復。Activity.onSaveInstanceState的預設實現是遍歷層級結構中的所有含有id屬性的View,然後依次呼叫View.onSaveInstanceState()方法。onSaveInstanceState是android.view.View的方法,所以所有繼承自View的widget都有該方法。View.onSaveInstanceState()會儲存View自身的一些資訊,比如儲存當前選擇的哪個item等。
由於Activity.onSaveInstanceState方法只會遍歷Activity中含有id屬性的View對其UI資訊進行儲存,所以我們我們在編碼時最好給View都新增id屬性,這樣可以使其在上述方法執行的時候呼叫View的onSaveInstanceState方法,從而儲存該View的UI資訊。
如果要重寫onSaveInstanceState方法,首先要呼叫super.onSaveInstanceState(bundle)。重寫的時候不應該在此處儲存持久化的資料(比如要向SQLite資料中寫入持久資料),應該在該方法中只儲存一些與UI相關的瞬時變數,比如有時候某些成員變數也儲存著一些和UI相關的資訊,這時候就可以在onSaveInstanceState中儲存下來。
Bundle不是為儲存大量資料(比如bitmap)而設計的,並且Bundle中的資料必須經過序列化與反序列化, 因此在onSaveInstanceState不應該儲存大量資料。
onSaveInstanceState是在Activity將要被killed並且預測過段時間會重新create這樣條件下才會被呼叫。也就是說onSaveInstanceState之所以被呼叫是為了Activity在銷燬後進行重新生成進行restore的,如果Android Framework認為不滿足需要進行onSaveInstanceState的條件,那麼就不會呼叫該方法,具體來說:
如果使用者顯式地通過back鍵退出了程式,那麼不會呼叫onSaveInstanceState方法。
如果開始開啟了Activity A,然後開啟了Activity B,對A進行了部分遮罩,這時候會觸發A的onPause方法,但是Framework可能會避免呼叫A的onSaveInstanceState方法(如果在B的生命週期內A沒有被kill掉)。
利用Fragment儲存大量資料
由於onSaveInstanceState不適合儲存大量的資料,所以如果在Activity銷燬重建恢復資料的時候就不能使用該onSaveInstanceState毀掉函式存取大量資料了。
由於configuration change導致Activity銷燬的時候,Activity中標記為保留的Fragment不會銷燬,所以可以利用該特性實現存取資料,具體方法如下:
擴充套件Fragment類,並定義好相應欄位存取資料,對外暴露出設定資料和獲取資料的方法,比如setData和getData
在Fragment的onCreate方法中呼叫方法setRetainInstance(true),標記該Fragment為保留的
將該Fragment加入到Activity中
在Activity的onDestroy方法中將activity的中需要儲存的資料呼叫Fragment中上述定義的setData方法,將其儲存在Fragment中
在Activity銷燬重新生成執行onCreate的時候,重新從Fragmet中呼叫getData獲取之前儲存的資料
最後需要注意記憶體洩露的發生
考慮使用Loader快取資料
Android中可以用Loader和LoaderManager非同步獲取資料,且Loader機制有個很好的特性:可以在Activity執行restart的過程中繼續持有資料,也就是說,如果Loader一開始就已經載入了資料,那麼在Activity進行了restart之後,Activity會從Loader中立即獲取到之前快取的資料,而無需再次用LoaderManager載入資料,這樣就能實現restart之後資料恢復的功能。
如果對Loader機制不瞭解,可以參見以下兩篇博文:
Android中Loader及LoaderManager的使用(附原始碼下載)
深入原始碼解析Android中Loader、AsyncTaskLoader、CursorLoader、LoaderManager
使用靜態變數儲存資料
我們知道Java中如果一個類的成員變數是static的,那麼該static成員變數的生命週期就與該類的生命週期相同,具體來說:當Java虛擬機器載入該類的時候,就會給該類的static成員變數分配記憶體空間;當Java虛擬機器解除安裝該類的時候,該類的static成員變數的記憶體才會被回收。Android也具有該特性,假設我們的Activity中有一個static的成員變數,在Activity進行restart的過程中,Java虛擬機器沒有解除安裝掉該Activity,因為在後面的restart的過程中會用到,所以在restart過程中,該Activity的static的成員變數的記憶體沒有被回收,這樣我們就可以在restart之前往該Activity的static成員變數中寫入值,在restart之後從Activity的static成員變數中讀取值,這樣就跨restart過程持有了資料。使用該特性也要注意,在非restart導致的destroy的時候,我們需要將Activity的static成員變數賦值為null,防止記憶體洩露。
希望本文對大家有所幫助!
相關文章
- 儲存過程中巢狀儲存過程的變數執行方式儲存過程巢狀變數
- 儲存崩潰資料恢復過程;資料恢復案例資料恢復
- 【伺服器資料恢復】NetApp儲存中lun被誤刪除的資料恢復過程伺服器資料恢復APP
- 在儲存過程中建立表的兩種方法儲存過程
- Activity資料儲存與恢復淺析
- vsan儲存資料恢復過程—虛擬機器故障恢復過程資料恢復虛擬機
- 【伺服器資料恢復】多次異常斷電後儲存執行中突然崩潰的資料恢復伺服器資料恢復
- 淺談資料庫中的儲存過程資料庫儲存過程
- 恢復被覆蓋的儲存過程 oracle儲存過程Oracle
- 儲存過程誤刪除的恢復儲存過程
- 用flashback恢復儲存過程儲存過程
- Sqlserver中的儲存過程SQLServer儲存過程
- mssql 儲存過程呼叫另一個儲存過程中的結果的方法分享SQL儲存過程
- Android中的資料儲存Android
- Android中Activity的四種啟動方式Android
- V3700系列儲存資料恢復成功過程資料恢復
- 【伺服器資料恢復】華為OceanStor T系列儲存中卷的資料恢復案例伺服器資料恢復
- 【伺服器資料恢復】Storwize儲存Mdisk中硬碟離線的資料恢復案例伺服器資料恢復硬碟
- Android Activity 重建之狀態儲存與恢復Android
- 【伺服器資料恢復】OceanStor儲存中NAS卷資料丟失的資料恢復案例伺服器資料恢復
- 用flashback恢復儲存過程(ZT)儲存過程
- 在儲存過程A中呼叫儲存過程B的結果儲存過程
- 【儲存資料恢復】某品牌EqualLogic系列儲存介紹和資料恢復方法資料恢復
- EMC儲存重灌系統丟失分割槽的資料恢復過程資料恢復
- 儲存過程中檢視sql執行計劃的方法儲存過程SQL
- Oracle中執行儲存過程call和exec區別Oracle儲存過程
- 【儲存資料恢復】HP EVA儲存誤刪除VDISK的資料恢復案例資料恢復
- 【儲存資料恢復】EqualLogic PS系列儲存磁碟故障的資料恢復案例資料恢復
- 【儲存資料恢復】NetApp儲存誤刪除的資料恢復案例資料恢復APP
- 【儲存資料恢復】NetApp儲存誤刪資料夾的資料恢復案例資料恢復APP
- Android中的Activity四種啟動模式(launchMode)Android模式
- 【儲存資料恢復】esx vmfs的互斥導致儲存資料丟失的資料恢復案例資料恢復
- 資料庫恢復中需要大量儲存空間的原因HQ資料庫
- MySQL儲存過程中捕獲異常的方法MySql儲存過程
- 恢復MySQL資料庫建立儲存過程是遇到錯誤MySql資料庫儲存過程
- EMC UNITY 400儲存卷刪除資料恢復操作過程Unity資料恢復
- Android中的資料儲存之檔案儲存Android
- [MSSQL]sql 儲存過程定時執行方法SQL儲存過程