在安卓开发中,由于旋转设备会造成配置改变进而导致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. 自定义窗口 mfc

    typedef struct _WNDCLASS { UINT style; //制定窗口的类型 WNDPROC lpfnWndProc; int cbClsExtra; //额外的数值 int cb ...

  2. JQuery 获取验证码倒计时

    HTML代码: <button id="btn">点击获取验证码</button> Jquery:代码: $(document).ready(functio ...

  3. php读取memcache二进制数据

    memcache作为一个数据中间层,经常用来做数据交换. 比如在某个系统内部我们规定如下的用户状态的信息,每个用户只需要存续52个字节. Key state#ID 如”state#10888” Val ...

  4. pyenv简介——Debian/Ubuntu中管理多版本Python

    pyenv简介——Debian/Ubuntu中管理多版本Python MAY 21ST, 2016 12:00 AM | COMMENTS pyenv是管理Python版本的工具,它支持在多个Pyth ...

  5. Python操作excel(xlrd和xlwt)

    Python操作excel表格有很多支持的库,例如:xlrd.xlwt.openpyxl.win32com,下面介绍使用xlrd.xlwt和xlutils模块这三个库不需要其他的支持,在任何操作系统上 ...

  6. iPhone开发:Objective C 代码规范-iOS总结版

    一,关于空行 A:.h中的空行 1,文件说明与头文件包涵(#import)之间空1行 2,头文件包涵(#import)之间,如果需要分类区别,各类别之间空1行 3,头文件包涵(#import)与@cl ...

  7. Android修改XML文件

    最近在项目中需要使用XML记录数据,网上这方面的文章较少,记录一下 使用DOM方式 /** * 追加内容到XML文档 * @param instructions * @throws ParserCon ...

  8. C51的编程规范

    现在单片机的程序设计,C51已经得到广泛的推广和应用,算是单片机的主流设计程序,甚至可以说作为单片机开发人员必须要掌握的一门语言了.作为一门工具,最终的目的就是实现功能.在满足这个前提条件下,我们希望 ...

  9. 颠覆你的时空观-----理解傅立叶transform

    在知乎上看到的,非常不错,最起码知道为什么了: 傅立叶变换,拉普拉斯变换,z变换这三种方法的本质主要就是将信号从时域转换成频域,因为频域更好展开分析 = =. 频域只是另一种看到信号的角度(世界观). ...

  10. 解密随机数生成器(二)——从java源码看线性同余算法

    Random Java中的Random类生成的是伪随机数,使用的是48-bit的种子,然后调用一个linear congruential formula线性同余方程(Donald Knuth的编程艺术 ...