繁体   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