译:Activity和Fragment状态保存和恢复

Activity状态的保存和恢复

  Activity被killed或者配置发生变化前会调用onSaveInstanceState (Bundle)来保存Activity状态以便在onCreate(Bundle)onRestoreInstanceState(Bundle)中恢复。正常的生命周期中onSaveInstanceState (Bundle)onRestoreInstanceState(Bundle)是不会被调用。

  onSaveInstanceState (Bundle)是在onStop()前调用,但是无法保证和onPause()的调用顺序。onRestoreInstanceState(Bundle)的调用发生在onStart()onPostCreate(Bundle)中间。

  onSaveInstanceState (Bundle)的默认实现是通过调用Activity布局中的每个设置了android:id属性的View的onSaveInstanceState (Bundle)来保存每个View的状态。然后在onRestoreInstanceState(Bundle)中根据对应的id恢复View的状态。

  所以,View状态要能够保存和恢复,需要满足两点:

  1. onSaveInstanceState (Bundle)onRestoreInstanceState(Bundle)中保存和恢复状态。
  2. 设置了android:id以便根据id恢复View状态。

  TextView不仅需要设置android:id还需要设置android:freezesText="true"才能保存状态。查看TextView的onSaveInstanceState (Bundle)方法,当变量mFreezesTexttrue时才会保存TextView的状态。

  Activity状态的保存和恢复过程如下:

  所以,对于Activity的成员变量需要我们自己手动保存和恢复。

   private int countCanRestored = 0;

   @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putInt("countCanRestored", countCanRestored);
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        countCanRestored = savedInstanceState.getInt("countCanRestored", 0);
        ...
    }
复制代码

Fragment状态的保存和恢复

  当系统资源不足导致Fragment被销毁或者配置发生变化时,Fragment状态的保持和恢复跟Activity类似。

  Activity状态的保存和恢复过程如下:

  不过需要注意的是Fragment有 onSaveInstanceState(Bundle)方法却没有 onRestoreInstanceState(Bundle)方法。对应地,Fragment是在 onCreate(Bundle), onCreateView(LayoutInflater, ViewGroup, Bundle), onActivityCreated(Bundle)方法中恢复View状态和成员变量。需要注意的是Bundle可能为空,使用前需要判断一下。

  下面考虑两种比较特殊的情况:

  1. setRetainInstance(true);   当配置发生变化时,Fragment不会随着Activity的消毁而消毁,Fragment的实例还是存在的,只是onDestroyView()方法被调用,View被销毁了。Fragment的成员变量和View状态都会被系统自动保存和恢复。onSaveInstanceState(Bundle)onActivityCreated(Bundle)onCreateView(LayoutInflater, ViewGroup, Bundle)方法会被调用。onCreate(Bundle)不会被调用。
  2. Fragment从Activity的back stack中恢复。Fragment的实例并没有被销毁,只是onDestroyView方法被调用,View被销毁了。Fragment的成员变量和View状态都会被系统自动保存和恢复。onSaveInstanceStateonCreate(Bundle)没有被调用。onActivityCreated(Bundle)onCreateView(LayoutInflater, ViewGroup, Bundle)方法会被调用。

所以保持和恢复Activity和Fragment状态的正确姿势是:

  1. 确保需要保存和恢复状态的View重写了onSaveInstanceState (Bundle)onRestoreInstanceState(Bundle)这个两个方法。有的View还需要手动开启这项功能,比如TextView需要设置android:freezesText="true"。当我们使用第三方自定义View时需要确保是否已经实现了这两个方法。如果没有,可以继承这个View,重写这个两个方法。我们自己自定义View的时候也要记得实现这两个方法。
  2. 给需要保存和恢复状态的View设置android:id
  3. 保存和恢复Activity和Fragment的实例变量。

Reference:inthecheesefactory.com/blog/fragme…

你可能感兴趣的:(译:Activity和Fragment状态保存和恢复)