返回

Android 11源码分析:onSaveInstanceState和onRestoreInstanceState的调用时机剖析

Android

引言
作为一名安卓开发者,您可能对 onSaveInstanceState 和 onRestoreInstanceState 并不陌生。这两个方法在 Activity 的生命周期中发挥着重要的作用,它们负责在 Activity 因屏幕旋转、系统内存不足等原因被销毁时保存 Activity 的状态,并在重建时恢复状态。在本文中,我们将深入分析 onSaveInstanceState 和 onRestoreInstanceState 的调用时机,帮助您深入理解这些方法的行为以及如何正确地使用它们。

源码分析

为了准确了解 onSaveInstanceState 和 onRestoreInstanceState 的行为,我们直接对 Android 11. SDK 30 的源代码进行分析。

1. onSaveInstanceState 的调用时机

我们首先分析 onSaveInstanceState 方法的调用时机。在 Activity 的生命周期中,onSaveInstanceState 可能在以下几种情况下被调用:

  1. 当系统内存不足时,Activity 可能被系统杀死。此时,系统会调用 onSaveInstanceState 方法来保存 Activity 的状态,以便在重建时可以恢复。
  2. 当用户按下后退键或按下了 home键,Activity 可能被销毁。此时,系统同样会调用 onSaveInstanceState 方法来保存 Activity 的状态,以便在重建时可以恢复。
  3. 当 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 方法可能在以下几种情况下被调用:

  1. 当系统内存不足时,Activity 可能被系统杀死。在重建时,系统会调用 onRestoreInstanceState 方法来恢复 Activity 的状态。
  2. 当用户按下后退键或按下了 home键,Activity 可能被销毁。在重建时,系统会调用 onRestoreInstanceState 方法来恢复 Activity 的状态。
  3. 当 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 的状态能够正确保存和恢复,您需要注意以下几点:

  1. 在 onSaveInstanceState 方法中,只保存需要持久化的数据。避免保存过多的数据,以免导致性能问题。
  2. 在 onRestoreInstanceState 方法中,只恢复需要持久化的数据。避免恢复过多的数据,以免导致性能问题。
  3. 使用 non-configuration changes 来指定哪些数据需要在 Activity 因屏幕旋转或重建时被保存。
  4. 使用 Bundle 来保存和恢复 Activity 的状态。Bundle 是一个键值对存储,可以存储各种类型的数据。

总结

本文通过对 Android 11. SDK 30 源码的分析,详细介绍了 onSaveInstanceState 和 onRestoreInstanceState 的调用时机。希望通过本文的介绍,您能对这两个方法的行为有更深入的了解,并在开发中正确地使用它们,以确保 Activity 的状态能够正确保存和恢复。