簡體   English   中英

什么時候調用onSaveInstanceState()和onRestoreInstanceState()?

[英]When exactly are onSaveInstanceState() and onRestoreInstanceState() called?

下圖(來自官方文檔 )描述了Android活動的眾所周知的生命周期

在此輸入圖像描述

另一方面,當系統銷毀活動時(例如因為需要回收內存),活動的狀態有時會通過onSaveInstanceState()onRestoreInstanceState()方法自動保存和恢復 ,如圖所示通過下圖(也來自官方文檔 ):

在此輸入圖像描述

我知道當活動即將被銷毀時, 並不總是調用 onSaveInstanceState() 例如,如果由於用戶按下“后退”按鈕而導致銷毀,則不會保留活動狀態。 但在情況下,當狀態保存和恢復,以及onSaveInstanceState() / onRestoreInstanceState()被調用, 什么時候被他們叫什么名字

例如,根據上面的圖, onRestoreInstanceState()可能在onStart()之前,或在onStart()但在onResume()之前或onResume()之后被調用。 類似地, onSaveInstanceState()存在幾種可能性。 那他們什么時候打電話呢?

理想情況下,我希望看到一個組合圖,顯示活動生命周期狀態和保存/恢復方法 (如果存在)。

根據文件

void onRestoreInstanceState(Bundle savedInstanceState)

onStart()onPostCreate(Bundle)之間onStart()此方法。

void onSaveInstanceState(Bundle outState)

如果調用此方法,則此方法將在onStop()之后針對以Build.VERSION_CODES.P開頭的平台的應用程序發生。 對於針對早期平台版本的應用程序,此方法將在onStop()之前發生,並且無法保證它是在onPause()之前還是之后發生。

根據doc1doc2

的onSaveInstanceState

在Honeycomb之前,活動在被暫停之后才被認為是可計費的,這意味着在onPause()之前立即調用了onSaveInstanceState()。 然而,從Honeycomb開始,活動被認為只有在它們被停止后才可以運行,這意味着onSaveInstanceState()現在將在onStop()之前調用,而不是在onPause()之前調用。

onRestoreInstanceState

當從先前保存的狀態重新初始化活動時,在onStart()和onPostCreate(Bundle)之間調用此方法

除了已發布的答案之外,Android P中還引入了一個微妙的變化,即:

void onSaveInstanceState(Bundle outState)

如果被調用,對於以P開頭的平台的應用程序,此方法將在onStop() 之后發生。 對於針對早期平台版本的應用程序,此方法將在onStop()之前發生,並且無法保證它是在onPause()之前還是之后發生。

資料來源: docs

至於為什么要引入這種變化,這里是答案:

...因此,應用程序可以安全地在onStop()執行片段事務,並且以后可以保存持久狀態。

資料來源: docs

這是onSaveInstanceState(Bundle)的額外信息

來自docs

不要將此方法與活動生命周期回調混淆,例如onPause(),當活動被放置在后台或者去往破壞的路徑時,或者在銷毀之前調用的onStop()時,它會被調用。 調用onPause()和onStop()時的一個示例,而不是此方法是當用戶從活動B導航回活動A時:不需要在B上調用onSaveInstanceState(Bundle),因為該特定實例永遠不會被恢復,所以系統避免調用它。 調用onPause()而不是onSaveInstanceState(Bundle)的示例是在活動A前面啟動活動B時:如果在B的生命周期內沒有殺死活動A,系統可能會避免調用活動A上的onSaveInstanceState(Bundle) A的用戶界面狀態將保持不變。

所以這是...的默認實現

默認實現通過在具有id的層次結構中的每個視圖上調用onSaveInstanceState()並保存當前聚焦視圖的id(所有這些都由以下內容恢復)來為您處理大多數UI每實例狀態。 onRestoreInstanceState(Bundle)的默認實現)。 如果重寫此方法以保存每個單獨視圖未捕獲的其他信息,則可能需要調用默認實現,否則請准備好自己保存每個視圖的所有狀態。

String activityState;
@Override 
public void onCreate(Bundle savedInstanceState) {
// call the super class onCreate to complete the creation of activity like 
// the view hierarchy 
super.onCreate(savedInstanceState);

// recovering the instance state 
if (savedInstanceState != null) {
     activityState = savedInstanceState.getString(STATE_KEY);
 } 

   setContentView(R.layout.main_activity);
   mTextView = (TextView) findViewById(R.id.text_view);
} 

//僅當先前使用// onSaveInstanceState()保存了已保存的實例時,才會調用此回調。 我們在onCreate()中恢復一些狀態,同時我們可以選擇在這里恢復//其他狀態,可能在onStart()完成后可用。 // savedInstanceState Bundle與onCreate()中使用的相同。

@Override 
public void onRestoreInstanceState(Bundle savedInstanceState) {
 mTextView.setText(savedInstanceState.getString(STATE_KEY));
  } 


// invoked when the activity may be temporarily destroyed, save the instance 
//state here 
//this method will be called before onstop

@Override 
 public void onSaveInstanceState(Bundle outState) {
    outState.putString(STATE_KEY, activityState);

    // call superclass to save any view hierarchy 
    super.onSaveInstanceState(outState);
} 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM