在安卓开发中,由于旋转设备会造成配置改变进而导致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. css设置时父元素随子元素margin值移动

    父元素的盒子包含一个子元素盒子,给子元素盒子一个垂直外边距margin-top,父元素盒子也会往下走margin-top的值,而子元素和父元素的边距则没有发生变化. HTML,CSS: <div ...

  2. 网址测速JS

    /*.route_nav li a:hover{background: #3c7f84 url(title.png) no-repeat;border-color:#84a3a5;}*/ .route ...

  3. java eclipse 连接数据库全过程

    1.需要下载一个jar包.地址 http://pan.baidu.com/s/1i50LRId 2.代码如下: import java.sql.*; public class Mytest { pub ...

  4. Intent携带额外的数据的方法

    1.putExtras(Bundle data):向Intent中放入需要“携带”的数据.2.putXxx(String key,Xxx data):向Bundle放入Int.Long等各种类型的数据 ...

  5. Ubuntu下Qt-4.7.1的静态编译

    最近在学习Qt的静态编译,相比较来说windows的Qt静态编译比较容易,相反对于linux编译网上的文章实践下来都有这样那样的错误,这里简要小结一下自己的编译成果. 一.实验环境 1.Ubuntu  ...

  6. Linux read语法及浅析

    read命令 -n(不换行) -p(提示语句) -n(字符个数) -t(等待时间) -s(不回显) 1.基本读取read命令接收标准输入(键盘)的输入,或其他文件描述符的输入(后面在说).得到输入后, ...

  7. HDOJ 1326 Box of Bricks(简单题)

    Problem Description Little Bob likes playing with his box of bricks. He puts the bricks one upon ano ...

  8. LeeCode-String to Integer (atoi)

    Implement atoi to convert a string to an integer. Hint: Carefully consider all possible input cases. ...

  9. Contest - 2014 SWJTU ACM 手速测试赛(2014.10.31)

    题目列表: 2146 Problem A [手速]阔绰的Dim 2147 Problem B [手速]颓废的Dim 2148 Problem C [手速]我的滑板鞋 2149 Problem D [手 ...

  10. [Qt] qtcreator 中打开console

    (1) qtcreator-->左侧Projects-->Run-->中间的checkbox (Run in terminal)打上勾 (2) 在项目的.pro文件中加上 " ...