在安卓开发中,由于旋转设备会造成配置改变进而导致Activity实例被摧毁(当然也包括Activity托管的Fragment)。Activity或Fragment实例被摧毁自然也就让Model被摧毁,数据也就没有了。这是我们不想看到的。因此有了重写Activity或者Fragment的onSavedInstanceState(Bundle)方法来保存Model。

  通过上述的这种方法的确可以解决一部分数据被摧毁的问题,但是有些数据我们需要一直保持,而非摧毁->重建。比如听音乐听得好好的,我旋转设备,程序员通过onSavedInstanceState(Bundle)方法把音乐保存了,然后onCreate(Bundle)再来将刚刚摧毁的音乐放出来,这可以么?当然不行,你说你吃着火锅唱着歌,就旋转个屏幕,音乐突然就没了,然后嘿又好了,你不骂这个app开发者傻逼我都看不下去!因此有了一个新需求,在设备旋转等配置改变的情况下我们要让model一直在,而不是摧毁->重建。这个想想好像无从下手,其实不难。我们可以跳出保存Model的思路,而是直接让存放Model的Fragment就不会死,那不就行了。

  讲完了为何,再来说如何保存Fragment实例。

  我们只需要重写Fragment.onCreate()方法,加上setRetainInstance(true)就行了

  

  知其然须知其所以然,我们应该对系统是如何保存了fragment实例的工作原理也要了解。

  如果不写setRetainInstance(true)这句话会发生什么呢?

  如上图所示,由于旋转完屏幕,设置被改变,FragmentManager会首先销毁队列中fragment的视图,为什么要销毁它们的原因也很简单,新的配置可能对应新的资源,当有更适合的新资源匹配时,需要更换成新视图。然后FragmentManager会依次检查fragment实例的retainInstance值,如果为false立即销毁fragment实例。然后众所周知,会有一个新的Activity创建一个新的FragmentManager来创建新的Fragment实例及其视图。

  但是如果fragment实例的retainInstance值为true,就不会被销毁。当新的Activity创建新的FragmentManager时,会找到这个被保存的fragment实例,并重新创建它的视图。

这个"不会死"的fragment,在activity被摧毁时处于被保留状态,此时没有任何activity托管它(因为托管它的activity被摧毁了)。

再来看看fragment的生命周期,加深理解。

从上面大段的讲述,我们可以总结出fragment需要有如下两个条件才能进入被托管状态。

1.它的retainInstance值为true

2.托管它的activity正在被摧毁

等到activity重建,fragment被纳入麾下,被保留状态也就结束了。

再来比较一下onSaveInstance方法和保留fragment实例方法

先看图:

  由图可得出,在进程关闭时(通常可能发生在用户暂时离开当前应用以及系统需要回收内存从而销毁了activity以及被保留的fragment实例时),fragment依然会被摧毁。

因此在需要将数据保存时间和activity记录一样长时,并且无需连贯保持(至少表面看不出来是断掉的)的情况时,最好采用onSaveInstance方法。

  太阳照常升起,人生寂寞如雪。

Android-为何以及如何保存Fragment实例的更多相关文章

  1. Android为TV端助力 fragment 的用法以及与activity的交互和保存数据的方法,包括屏幕切换(转载)!

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/37992017 1.管理Fragment回退栈 类似与Android系统为Acti ...

  2. Android开发之漫漫长途 Fragment番外篇——TabLayout+ViewPager+Fragment

    该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列.该系列引用了<Android开发艺术探索>以及<深入理解And ...

  3. Android面试收集录4 Fragment详解

    1.什么是Fragment? 你可以简单的理解为,Fragment是显示在Activity中的Activity. 它可以显示在Activity中,然后它也可以显示出一些内容. 因为它拥有自己的生命周期 ...

  4. Fragment-如何监听fragment中的回退事件与怎样保存fragment状态

    一.如何监听Fragment中的回退事件 1.问题阐述 在Activity中监听回退事件是件非常容易的事,因为直接重写onBackPressed()函数就好了,但当大家想要监听Fragment中的回退 ...

  5. Android解惑 - 为什么要用Fragment.setArguments(Bundle bundle)来传递参数(转)

    Fragment在Android3.0开始提供,并且在兼容包中也提供了Fragment特性的支持.Fragment的推出让我们编写和管理用户界面更快捷更方便了.   但当我们实例化自定义Fragmen ...

  6. 【Android 应用程序开发】 Fragment 详细说明

    笔者 : 汉书亮 转载请著名出处 : http://blog.csdn.net/shulianghan/article/details/38064191 本博客代码地址 : -- 单一 Fragmen ...

  7. Android 两步搞定Fragment的返回键

    Fragment可以说是在Android开发必需要使用到技术,项目中的界面基本上都是使用Fragment来实现,而Activity只是作为Fragment的载体,但有些特殊情况下Fragment也不得 ...

  8. android activity状态的保存

    今天接到一个电面,途中面试官问到一个问题,如果一个activity在后台的时候,因为内存不足可能被杀死,在这之前如果想保存其中的状态数据,比如说客户填的一些信息之类的,该在哪个方法中进行. onSav ...

  9. Android应用底部导航栏(选项卡)实例

    现在很多android的应用都采用底部导航栏的功能,这样可以使得用户在使用过程中随意切换不同的页面,现在我采用TabHost组件来自定义一个底部的导航栏的功能. 我们先看下该demo实例的框架图: 其 ...

随机推荐

  1. 监听<input/>标签行为的方法总结

    一.内容改变 1.<input onchange="javascript:function()"/>方法 onchange可以替换为下面几种:oninput,onpro ...

  2. query等待ajax执行完毕再继续执行下面代码的操作

    Jquery等待ajax执行完毕再继续执行下面代码的效果,具体代码如下,其实就是将 jquery ajax 函数的 async 参数设置为 false 即可,该参数默认为 true: $(docume ...

  3. 关于Cococs中的CCActionEase

    尊重作者劳动,转载时请标明文章出处.作者:Bugs Bunny地址:http://www.cnblogs.com/cocos2d-x/archive/2012/03/13/2393898.html 本 ...

  4. 文件磁盘读写类CArchive类

    CArchive类的成员 数据成员 m_pDocument 指向被串行化的CDocument对象 构造函数 Carchive 创建一个Carhcive对象 Abort在不异常的情况下,关闭归档文件 C ...

  5. php处理字符串格式的计算公式

    有时候我们对每一种产品都有一个提成公式,而这个计算提成的公式是以字符串格式存在表中的 当我们用这个计算公式时,他并不像我们写的:$a=2+3*5;这样简单的能计算出结果,而它是个字符串 所以,我们就必 ...

  6. mysql 日期比较

    情景是:距离当前到期时间多少天 可以考虑当前系统时间加上某个天数后,与数据库的字段作比较 1.已知的时间>=CURDATE()+10 2.在数据的查询中,考虑到sql语句的优化问题,应减少通配符 ...

  7. 最新Android 出现Please ensure that adb is correctly located at问题的解决方法

    最近经常遇到下面的问题 遇到问题描述: 运行android程序控制台输出: [2013-07-23 17:28:06 - ] The connection to adb is down, and a  ...

  8. HDOJ 1418 抱歉(欧拉公式)

    Problem Description 非常抱歉,本来兴冲冲地搞一场练习赛,由于我准备不足,出现很多数据的错误,现在这里换一个简单的题目: 前几天在网上查找ACM资料的时候,看到一个中学的奥数题目,就 ...

  9. Android中几种常用的话框

    1.普通对话框: Builder alert=new AlertDialog.Builder(MainActivity.this); alert.setTitle("提示"); a ...

  10. HDU_2041——走楼梯,递推

    Problem Description 有一楼梯共M级,刚开始时你在第一级,若每次只能跨上一级或二级,要走上第M级,共有多少种走法?   Input 输入数据首先包含一个整数N,表示测试实例的个数,然 ...