Android-为何以及如何保存Fragment实例
在安卓开发中,由于旋转设备会造成配置改变进而导致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实例的更多相关文章
- Android为TV端助力 fragment 的用法以及与activity的交互和保存数据的方法,包括屏幕切换(转载)!
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/37992017 1.管理Fragment回退栈 类似与Android系统为Acti ...
- Android开发之漫漫长途 Fragment番外篇——TabLayout+ViewPager+Fragment
该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列.该系列引用了<Android开发艺术探索>以及<深入理解And ...
- Android面试收集录4 Fragment详解
1.什么是Fragment? 你可以简单的理解为,Fragment是显示在Activity中的Activity. 它可以显示在Activity中,然后它也可以显示出一些内容. 因为它拥有自己的生命周期 ...
- Fragment-如何监听fragment中的回退事件与怎样保存fragment状态
一.如何监听Fragment中的回退事件 1.问题阐述 在Activity中监听回退事件是件非常容易的事,因为直接重写onBackPressed()函数就好了,但当大家想要监听Fragment中的回退 ...
- Android解惑 - 为什么要用Fragment.setArguments(Bundle bundle)来传递参数(转)
Fragment在Android3.0开始提供,并且在兼容包中也提供了Fragment特性的支持.Fragment的推出让我们编写和管理用户界面更快捷更方便了. 但当我们实例化自定义Fragmen ...
- 【Android 应用程序开发】 Fragment 详细说明
笔者 : 汉书亮 转载请著名出处 : http://blog.csdn.net/shulianghan/article/details/38064191 本博客代码地址 : -- 单一 Fragmen ...
- Android 两步搞定Fragment的返回键
Fragment可以说是在Android开发必需要使用到技术,项目中的界面基本上都是使用Fragment来实现,而Activity只是作为Fragment的载体,但有些特殊情况下Fragment也不得 ...
- android activity状态的保存
今天接到一个电面,途中面试官问到一个问题,如果一个activity在后台的时候,因为内存不足可能被杀死,在这之前如果想保存其中的状态数据,比如说客户填的一些信息之类的,该在哪个方法中进行. onSav ...
- Android应用底部导航栏(选项卡)实例
现在很多android的应用都采用底部导航栏的功能,这样可以使得用户在使用过程中随意切换不同的页面,现在我采用TabHost组件来自定义一个底部的导航栏的功能. 我们先看下该demo实例的框架图: 其 ...
随机推荐
- 视图必须派生自 WebViewPage 或 WebViewPage错误解决方法
1,在每个视图上面添加 @inherits System.Web.Mvc.WebViewPage 2,将views中的web.config COPY到新的视图模版文件夹下,就可以了
- DotNET知识点总结五(笔记整合)
1.委托:通常指的是 多播委托 通常的说,委托就是一个存放方法指针的容器,是一个安全的函数指针,供程序员安全调用.委托的本质就是一个类,继承于MulticastDelegate——>Delega ...
- C++ primer学习方法
C++ primer学习: 第一次可以跳着看.关键是要尽快用起来,在使用中熟练,而不是在细节中迷失. 以C++ Primer第五版为例,第一遍读的时候: Part1也就是前七章,除了6.6,6 ...
- Android 部分属性学习
android:imeOptions属性 谈一下个人的理解,设置软件盘中下一个/完成按钮的显示,如果需要监听软件盘中该按钮的事件,则需要实现 setOnEditorActionListener 其实, ...
- ActionBar兼容性的实现方式的要点
1.对于APILevel <11 的版本兼容ActionBar <1> Activity 继承ActionBarActivity <2> 获取ActionBar的方法:g ...
- linux下编译eXosip、osip,以及UAC和UAS的例子
从网站上看到了这样的一篇博文 :Windows下编译eXosip.osip,以及UAC和UAS的例子 (链接:http://www.cnblogs.com/dyllove98/archive/2013 ...
- Razor 在JS中嵌入后台变量
HTML 中定义全局变量 @{ int CurrentUserId =ViewBag.CurrentUserId; } JS中取值方式var CurrentUserId = parseInt(@Htm ...
- HDU_2052——画矩形
Problem Description Give you the width and height of the rectangle,darw it. Input Input contains a ...
- Java中快速排序的实现
快速排序是对冒泡排序的一种改进.它的基本思想是:通过一躺排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要 小,然后再按次方法对这两部分数据分别进行快速排序,整个排 ...
- jQuery的基本语法
index.html代码 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> ...