什么时候调用 onSaveInstanceState()和 onRestoreInstanceState() ?

下图(来自 官方文件)描述了一个众所周知的 Android 活动的 生命周期:

enter image description here

另一方面,当活动被系统破坏时(例如,因为需要回收内存) ,活动的状态有时会通过方法 onSaveInstanceState()onRestoreInstanceState()自动地 保存和修复,如下图(也来自 官方文件)所示:

enter image description here

当一个活动即将被破坏时,我知道 onSaveInstanceState()并不总是叫我。例如,如果由于用户按下了“后退”按钮而被销毁,则不保留活动状态。但在这种情况下,当状态 保存和恢复,和 onSaveInstanceState()/onRestoreInstanceState()被调用,具体是什么时候

例如,根据上面的数字,onRestoreInstanceState()可以在 onStart()之前调用,或者在 onStart()之后但在 onResume()之前调用,或者在 onResume()之后调用。类似地,onSaveInstanceState()也存在几种可能性。具体是什么时候?

理想情况下,我希望看到的是一个 显示活动生命周期状态和保存/恢复方法的组合图,如果存在的话。

73895 次浏览

根据 documentation:

Void onRestoreInstanceState (Bundle savedInstanceState)

此方法在 onStart()onPostCreate(Bundle)之间调用。

Void onSaveInstanceState (Bundle outState)

如果调用此方法,此方法将出现在以 Build.VERION _ CODES 开始的针对平台的应用程序的 onStop ()之后。对于针对早期平台版本的应用程序,此方法将发生在 onStop ()之前,并且不能保证它是发生在 onPuse ()之前还是之后。

As per doc1 and 文件2

OnSaveInstanceState

在蜂巢之前,活动只有在它们 暂停了,这意味着 OnSaveInstanceState ()在 onPuse ()之前立即被调用。 然而,从 Honeycomb 开始,Activity 被认为是 只有在它们被阻止之后才能被杀死,这意味着 现在将在 onStop ()之前调用 onSaveInstanceState () ,而不是 立即停止()。

OnRestoreInstanceState

时,在 onStart ()和 onPostCreate (Bundle)之间调用此方法 正在从以前保存的状态重新初始化活动

这是 OnSaveInstanceState (Bundle)的额外信息

from docs

不要将此方法与活动生命周期回调混淆,例如 onPause(), which is always called when an activity is being placed in 背景或在其销毁的路上,或 onStop () ,这是 在销毁之前调用。 onPuse ()和 onStop ()的一个例子 而不是当用户从 活动 B 到活动 A: 没有必要打电话 在 B 上保存 onSaveInstanceState (Bundle) ,因为该特定实例将 永远不会还原,因此系统避免调用它 调用 onPuse () ,而不调用 onSaveInstanceState (Bundle) 活动 B 在活动 A 前面启动: 系统可避免 在活动 A 上调用 SaveInstanceState (Bundle) ,如果它没有被杀死的话 自 A 的用户界面的状态以来,在 B 的生存期内 会完好无损。

所以这是默认实现。

默认实现负责每个实例的大部分 UI 控件中的每个视图调用 onSaveInstanceState ()来为您设置 对象的 id,并通过保存当前 焦点视图(所有这些视图都由默认实现还原 如果将此方法重写为 保存每个单独视图未捕获的其他信息,则 将可能希望调用默认实现, 否则,准备自己保存每个视图的所有状态。

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);
}

//只有在以前保存了实例时才调用此回调 saved using //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);
}

除了已经发布的答案,Android P 还引入了一个微妙的变化,那就是:

void onSaveInstanceState(Bundle outState)

如果调用此方法,则对于以 P开始的针对平台的应用程序,将出现 之后onStop()。对于针对早期平台版本的应用程序,这种方法将在 onStop()之前出现,并且不能保证它将在 onPause()之前还是之后出现。

资料来源: 医生

至于为什么要引入这种变化,答案如下:

... 因此应用程序可以安全地在 onStop()中执行片段事务,并能够在以后保存持久状态。

资料来源: docs