Android 11源码分析:onSaveInstanceState和onRestoreInstanceState的调用时机剖析
2023-10-04 05:53:57
引言
作为一名安卓开发者,您可能对 onSaveInstanceState 和 onRestoreInstanceState 并不陌生。这两个方法在 Activity 的生命周期中发挥着重要的作用,它们负责在 Activity 因屏幕旋转、系统内存不足等原因被销毁时保存 Activity 的状态,并在重建时恢复状态。在本文中,我们将深入分析 onSaveInstanceState 和 onRestoreInstanceState 的调用时机,帮助您深入理解这些方法的行为以及如何正确地使用它们。
源码分析
为了准确了解 onSaveInstanceState 和 onRestoreInstanceState 的行为,我们直接对 Android 11. SDK 30 的源代码进行分析。
1. onSaveInstanceState 的调用时机
我们首先分析 onSaveInstanceState 方法的调用时机。在 Activity 的生命周期中,onSaveInstanceState 可能在以下几种情况下被调用:
- 当系统内存不足时,Activity 可能被系统杀死。此时,系统会调用 onSaveInstanceState 方法来保存 Activity 的状态,以便在重建时可以恢复。
- 当用户按下后退键或按下了 home键,Activity 可能被销毁。此时,系统同样会调用 onSaveInstanceState 方法来保存 Activity 的状态,以便在重建时可以恢复。
- 当 Activity 因屏幕方向改变而被销毁时,系统也会调用 onSaveInstanceState 方法来保存 Activity 的状态,以便在重建时可以恢复。
从源码中,我们发现onSaveInstanceState 在Activity.java文件,第2239行有如下定义:
@Override
public void onSaveInstanceState(Bundle outState) {
if (!isFinishing()) {
if (mManagedDialog != null) {
mManagedDialog.onSaveInstanceState();
}
super.onSaveInstanceState(outState);
if (mDestroyed) {
// Okay to ignore this request, the activity is now finished.
return;
}
saveManagedDialogs(outState);
mCalled = true;
if (mRetainNonConfigurationInstance) {
callLocalOnSaveInstanceState(outState);
}
}
}
而 Activity.callLocalOnSaveInstanceState()又进一步调用了Activity.onRetainNonConfigurationInstance(),其中Activity.onRetainNonConfigurationInstance()对Activity的成员变量进行了保存,并将数据存储至Bundle中。
2. onRestoreInstanceState 的调用时机
onRestoreInstanceState 方法与 onSaveInstanceState 方法成对出现,当 Activity 重建时,系统会调用 onRestoreInstanceState 方法来恢复 Activity 的状态。具体来说,onRestoreInstanceState 方法可能在以下几种情况下被调用:
- 当系统内存不足时,Activity 可能被系统杀死。在重建时,系统会调用 onRestoreInstanceState 方法来恢复 Activity 的状态。
- 当用户按下后退键或按下了 home键,Activity 可能被销毁。在重建时,系统会调用 onRestoreInstanceState 方法来恢复 Activity 的状态。
- 当 Activity 因屏幕方向改变而被销毁时,系统也会调用 onRestoreInstanceState 方法来恢复 Activity 的状态。
在Activity.java文件,第2322行,onRestoreInstanceState方法如下定义:
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
if (mCalled) {
super.onRestoreInstanceState(savedInstanceState);
restoreManagedDialogs(savedInstanceState);
} else {
mCalled = true;
if (mRetainNonConfigurationInstance) {
restoreAllState(savedInstanceState);
} else {
super.onRestoreInstanceState(savedInstanceState);
restoreManagedDialogs(savedInstanceState);
}
}
// This needs to happen here as super can change the content, and
// we don't know where it's saving the instance state to.
mCalled = false;
}
可以看出,onRestoreInstanceState()方法主要做的事情是读取Bundle中保存的数据,并对Activity成员变量进行初始化。
最佳实践
为了确保 Activity 的状态能够正确保存和恢复,您需要注意以下几点:
- 在 onSaveInstanceState 方法中,只保存需要持久化的数据。避免保存过多的数据,以免导致性能问题。
- 在 onRestoreInstanceState 方法中,只恢复需要持久化的数据。避免恢复过多的数据,以免导致性能问题。
- 使用 non-configuration changes 来指定哪些数据需要在 Activity 因屏幕旋转或重建时被保存。
- 使用 Bundle 来保存和恢复 Activity 的状态。Bundle 是一个键值对存储,可以存储各种类型的数据。
总结
本文通过对 Android 11. SDK 30 源码的分析,详细介绍了 onSaveInstanceState 和 onRestoreInstanceState 的调用时机。希望通过本文的介绍,您能对这两个方法的行为有更深入的了解,并在开发中正确地使用它们,以确保 Activity 的状态能够正确保存和恢复。