美文网首页
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