注:本文翻譯自Google官方的Android Developers Training文檔,譯者技術一般,由于喜愛安卓而產生了翻譯的念頭,純屬個人興趣愛好。
原文鏈接: http://developer.android.com/training/basics/activity-lifecycle/recreating.html
在應用被正常使用的情況下,會有一些場景發生并使得你的activity被銷毀,比如:當用戶按下了返回鍵,或者你的activity調用了
finish()
方法將自己銷毀。當你的
activity
處于停止態且已經很久沒有被使用的情況下,系統也會將它銷毀。還有一種情況是處于前臺的
activity
需要更多的資源,此時系統必須將一部分后臺進程停止來釋放出一些內存空間。
當你的activity因為用戶按下了返回鍵或者自己調用了finish()將自己銷毀時,該 Activity 的實例將不再存在,因為導致其被銷毀的行為暗示了這個activity已經不再需要了。然后如果是由于系統資源緊張而被迫將Activity銷毀(非正常的應用行為),那么雖然 Activity 的實例已經不再了,當用戶回到這個 Activity 時,系統仍然會記得它其實是存在的。此時,系統會利用該 Activity 被銷毀時所保存的描述其狀態的數據集,來創建一個新的 Activity 實例。這些系統用來恢復之前狀態的數據被稱作為“ 實例狀態(instance state) ”,它實質上是一個存儲于一個 Bundle 對象的鍵值對數據集合。
Caution:
每次用戶旋轉了屏幕后,你的activity都會被銷毀和重新創建。這樣做的原因是因為屏幕的旋轉會導致屏幕參數的變化(長和寬互換),此時你的activity可能需要加載一些可選的資源(比如針對于橫屏或豎屏下的布局)
默認的,系統使用 Bundle 實例狀態 來保存你的activity布局中每個 View 對象的信息(比如在 EditText 對象中輸入的文字)。所以,如果你的activity實例被銷毀和重新創建,布局的狀態會恢復到之前的狀態,且你不需要為此編寫代碼。然而,你的activity可能會有更多你希望存儲的狀態信息,比如一些用來追蹤用戶進度的成員變量。
Note:
為了讓Android系統恢復activity中的view狀態, 每個View必須有一個獨有的ID ,這個ID由屬性字段“
android:id
”提供。
為了存儲更多關于activity狀態的數據,你必須覆寫 onSaveInstanceState() 回調函數。當用戶離開你的activity時系統會調用該方法,并且傳遞給他一個 Bundle 對象,存儲數據以防activity被意外地銷毀了。之后如果系統必須重新創建這個activity實例,它會把相同的 Bundle 對象傳遞給 onRestoreInstanceState() 方法和 onCreate() 方法。
圖1. 當系統要停止你的activity時,它會調用 onSaveInstanceState() 方法(1),所以你可以指定你先要存儲的額外數據,當activity被重新創建時會用到它們。 如果activity被銷毀了同時這個activity實例需要重新創建,系統會將(1)中定義的數據傳遞給 onCreate() 方法(2),以及 onRestoreInstanceState() 方法(3)
?
一). 保存你的Activity狀態
當你的activity將要停止,系統會調用 onSaveInstanceState() 方法這樣你的activity會通過鍵值對的形式將狀態信息保存起來。這個方法的默認實現會保存activity的 view狀態,比如一個 EditText 控件內的文本信息或者 ListView 當前滑動到的位置信息。
為了為你的activity保存額外的狀態信息,你必須實現 onSaveInstanceState() 方法,并且將鍵值對添加到 Bundle 對象中。例如:
static final String STATE_SCORE = "playerScore" ; static final String STATE_LEVEL = "playerLevel" ; ... @Override public void onSaveInstanceState(Bundle savedInstanceState) { // Save the user's current game state savedInstanceState.putInt(STATE_SCORE, mCurrentScore); savedInstanceState.putInt(STATE_LEVEL, mCurrentLevel); // Always call the superclass so it can save the view hierarchy state super .onSaveInstanceState(savedInstanceState); }
Caution:
必須調用父類的 onSaveInstanceState() ,這樣默認的實現會保存View的狀態
?
二). 恢復你的Activity狀態
當你的Activity在之前被銷毀后需要被重新創建時,你可以通過系統傳遞給Activity的 Bundle 對象來恢復之前的狀態。 onRestoreInstanceState() 方法和 onCreate() 方法都會接受到相同的 Bundle 對象,其中包含了實例的狀態信息。
因為不管是系統在創建一個新的實例還是重新創建一個舊的, onCreate() 都會被系統調用,所以在你嘗試讀取 Bundle 之前,必須檢查它是否是null。如果是null,那么系統會創建一個新的activity實例,而不是進行恢復。
下面就是你將如何在 onCreate() 中恢復狀態的例子:
@Override protected void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); // Always call the superclass first // Check whether we're recreating a previously destroyed instance if (savedInstanceState != null ) { // Restore value of members from saved state mCurrentScore = savedInstanceState.getInt(STATE_SCORE); mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL); } else { // Probably initialize members with default values for a new instance } ... }
除了在 onCreate() 恢復狀態,你還可以選擇實現 onRestoreInstanceState() ,這個方法在系統調用了 onStart() 方法之后被調用。僅當有可以用來恢復的以保存數據存在是,系統才會調用 onRestoreInstanceState() ,所以你不需要判斷 Bundle 是否是null:
public void onRestoreInstanceState(Bundle savedInstanceState) { // Always call the superclass so it can restore the view hierarchy super .onRestoreInstanceState(savedInstanceState); // Restore state members from saved instance mCurrentScore = savedInstanceState.getInt(STATE_SCORE); mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL); }
Caution:
必須調用父類的 onRestoreInstanceState() ,這樣默認的實現會恢復View的狀態
如果想要學習關于在運行時由于重啟事件導致activity被重新創建(如旋轉了屏幕),可以閱讀: Handling Runtime Changes
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
