美文网首页
Activity 和 Fragment 状态保存与恢复细节

Activity 和 Fragment 状态保存与恢复细节

作者: Rreply | 来源:发表于2018-10-10 00:40 被阅读13次

Activity状态恢复与保存的时候发生了什么?

我们都知道Activity状态保存的时候是通过onSaveInstancestate方法,那这个方法具体做了什么呢?

  • 手动保存成员变量数据
  • 自动收集View Hierarchy(视图层次)中每一个View的状态。
    save.gif

那恢复状态时调用的onRestoreInstanceState方法又做了什么呢?

  • 手动将保存的成员变量数据重新赋值
  • 自动把收集的View数据恢复到每一个View中。
    restore.gif

看到这里,大家也许会有一个疑问,为什么成员变量需要手动恢复,而View中的数据可以自动恢复呢。
原因就是这些View中实现了保存和恢复数据的方法,系统的控件TextView、checkBox等全部都实现了这两个方法。实现了这两个方法的第三方控件也是可以自动恢复保存的。

@Override
public Parcelable onSaveInstanceState() {
    Bundle bundle = new Bundle();
    // Save current View's state here
    return bundle;
}
@Override
public void onRestoreInstanceState(Parcelable state) {
    super.onRestoreInstanceState(state);
    // Restore View's state here
}

View恢复数据的时候时根据其Android:id指定的id来恢复的,因此没有定义Android:id的View是不能够自动恢复的。

Fragment状态恢复与保存的时候发生了什么?

Fragment状态恢复与保存的过程和Activity是类似的,先给出动图示意。

save.gif
与Activity不同的是,Fragment没有onRestoreInstanceState方法。我们要恢复数据,需要从onActivityCreated方法中恢复。
public class TestFragment extends Fragment {
    // These variable are destroyed along with Activity
    private int VarA;
    private String VarB;
    ...
    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putInt("VarA", VarA);
        outState.putString("VarB", VarB);
    }
    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        VarA = savedInstanceState.getInt("VarA");
        VarB = savedInstanceState.getString("VarB");
    }
}

还有一个重要的不同之处是与Fragment回退栈有关系的。


Fragment生命周期.png

从图中可以看到,Fragment可以通过两种途径来从前台退出。

  • 使用导航栏中的回退键或者Fragment直接被removedreplaced
  • Fragment先被添加到回退栈中,然后再被removedreplaced

第一种情况,该Fragment实例被销毁。
第二种情况,该Fragment的实例依然存在,但是其View被销毁。从图中可以看出在执行onDestroyView方法之后,如果该Fragment从回退栈中又放到前台的话,其onCreateView方法会被调用,重建视图而不是重建Fragment实例。
所以在第二种情况下,Fragment中的成员变量是自动保存下来的,因为本来其就没有被销毁啊

Fragment与View的正确使用

从上文得知,如果View中有保存和恢复数据的方法的话,在其设置了Android:id的情况下,是能够自动恢复的。所以我们在使用View的时候,应该在View的内部实现保存恢复功能,而不应该是在Fragment中实现该功能。因为这样有利于Fragment与View的状态分开处理,也有利于代码的整洁。
所幸Android提供的控件都是实现了保存和恢复数据的方法的。而对于那些没有实现的第三方控件我们应该实现它的子类,手动实现这两个方法。

参考:[译]Android Activity 和 Fragment 状态保存与恢复的最佳实践

相关文章

网友评论

      本文标题:Activity 和 Fragment 状态保存与恢复细节

      本文链接:https://www.haomeiwen.com/subject/dujuaftx.html