Android中 一些维持状态的经验

转自 https://bluzwong.github.io

在 Activity 中的情况

1. 使用 retained Fragment

大牛鸿洋在博文中提及一种方法 如果是大量数据,使用Fragment保持需要恢复的对象, 用法大概是

用于维持状态的 Fragment

    public class ByFragment extends Fragment {

        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            // 设置 维持实例
            setRetainInstance(true);
        }

        // 需要维持状态的数据
        int count = 0;
    }

需要维持状态的 Activity:

 public class ByFragmentActivity extends Activity {

        SwipeRefreshLayout refreshLayout;
        TextView textView;
        ByFragment fragment;
        int count = 0;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_state);

            refreshLayout = (SwipeRefreshLayout) findViewById(R.id.refresh);
            textView = (TextView) findViewById(R.id.tv);

            // 获取 activity 的 FragmentManager 中用于维持状态数据的 Fragment
            fragment = (ByFragment) getFragmentManager().findFragmentByTag("ByFragment");
            if (fragment == null) {
                fragment = new ByFragment();
                getFragmentManager().beginTransaction().add(fragment, "ByFragment").commit();
            } else {
                count = fragment.count;
            }
            refreshTv();

            refreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
                @Override
                public void onRefresh() {
                    refreshLayout.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            count++;
                            fragment.count = count;
                            refreshTv();
                            refreshLayout.setRefreshing(false);
                        }
                    }, 1000);
                }
            });
        }

        @Override
        protected void onSaveInstanceState(Bundle outState) {
            super.onSaveInstanceState(outState);
            fragment.count = count;
        }

    }

打开 开发者选项 中的 不保留活动 以方便测试

这里写图片描述

进入到 Activity 中,count 是需要维持状态的数据

这里写图片描述

旋转屏幕

这里写图片描述

数据成功维持。

按 Home 键,置于后台,然后再返回 Activity

这里写图片描述

数据消失了。

2.使用 savedInstanceState: Bundle

这种方式比较基础,用法就不再多述

    public class ByBundleActivity extends Activity {

        SwipeRefreshLayout refreshLayout;
        TextView textView;
        int count = 0;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_state);

            refreshLayout = (SwipeRefreshLayout) findViewById(R.id.refresh);
            textView = (TextView) findViewById(R.id.tv);

            if (savedInstanceState != null) {
                count = savedInstanceState.getInt("KEY_COUNT", 0);
            }
            refreshTv();

            refreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
                @Override
                public void onRefresh() {
                    refreshLayout.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            count++;
                            refreshTv();
                            refreshLayout.setRefreshing(false);
                        }
                    }, 1000);
                }
            });
        }

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

    }

进入 Activity 获取数据。

旋转屏幕,数据还在。

按 Home,再回来,数据还在。

3.小结

第一种方式使用 retained Fragment,当配置发生变化时(屏幕旋转就是情况之一),其实例在内存中没有被销毁。优点是能够在 Fragment 中完整维持数据,并且不需要实现任何一种序列化的方式。缺点呢,也很明显,当长时间在后台时,难免 Activity 和 其 Fragment 会被系统所回收(开启不保留活动模拟),所以维持的数据也当然没有了。

第二种方式使用 Bundle。优点是就算被系统回收了,保存的状态也能在下一次启动时 onCreate(Bundle savedInstanceState) Bundle 中获取。缺点是,这些数据都要进行序列化、反序列化,一些复杂对象可能会出现问题,特别是如网络请求等较长时间的任务,是比较难保存的。

综上,数据尽量使用第二种 Bundle 来维持。长时间执行的任务,通过第一种 retained Fragment 来维持,旋转屏幕时,长时间的任务也没有被销毁,破费!

本文Demo

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值