Fragment销毁时replace和add两个方法的区别
2015-12-03 20:52
423 查看
这个首先从一个bug说起,如图:
![](http://www.ithtw.com/wp-content/uploads/2015/03/2015032611145532.gif)
![](http://www.ithtw.com/wp-content/uploads/2015/03/2015032611145564.png)
![](http://www.ithtw.com/wp-content/uploads/2015/03/2015032611150084.png)
我们都知道fragment切换有两种方式:
1. replace方式
2. add-hide-show方式
而上面按钮中出现bug的就是采用第二种方式。然后我们来分析下用add,hide,show为什么出现这种bug,我把每个操作都打印出了以下日志:
![](http://www.ithtw.com/wp-content/uploads/2015/03/2015032611150350.png)
复现bug的操作是:
1.首先打开,默认选中的是第一个tab,如上面的一张图片正常那样。
2.切换到tab2,并把tab1 hide掉;
3.再切回到tab1,并不会触发tab1对应fragment的任何生命周期;
4.然后home键进入后台,我在activity的onPause()中手动对IndexFragment赋空,模拟长时间后台,系统销毁了该引用。
5.再次启动,其实tab1 的fragment实例在内存中还在,只是他的引用被销毁了。
6.再切到tab2,这里其实是先把tab1的hide,在show tab2,但是tab1 的fragment引用为空,所以无法hide,就出现了tab2叠在tab1上的花屏情况。
7.再切到tab1,tab1就会重复创建对象。
同样的操作,我们使用replace的方式
![](http://www.ithtw.com/wp-content/uploads/2015/03/2015032611150428.png)
使用replace方式,虽然这种方式会避免上述的bug,但也是重复创建了对象。因为replace方式,对应的FrameLayout只有一 层,而add方式,这个FrameLayout其实有2层。但是这种方式的缺点是:每次replace会把生命周期全部执行一遍,如果在这些生命周期函数 里拉取数据的话,就会不断重复的加载刷新数据。
那么最合适的处理方式是这样的:
1.在add的时候,加上一个tab参数
transaction.add(R.id.content, IndexFragment,”Tab1″);
2.然后当IndexFragment引用被回收置空的话,先通过
IndexFragment=FragmentManager.findFragmentByTag(“Tab1″);
找到对应的引用,然后继续上面的hide,show;
![](http://www.ithtw.com/wp-content/uploads/2015/03/2015032611145532.gif)
![](http://www.ithtw.com/wp-content/uploads/2015/03/2015032611145564.png)
![](http://www.ithtw.com/wp-content/uploads/2015/03/2015032611150084.png)
我们都知道fragment切换有两种方式:
1. replace方式
transaction.replace(R.id.content, IndexFragment);
2. add-hide-show方式
transaction.add(R.id.content, IndexFragment); transaction.hide(otherfragment); transaction.show(thisfragment);
而上面按钮中出现bug的就是采用第二种方式。然后我们来分析下用add,hide,show为什么出现这种bug,我把每个操作都打印出了以下日志:
![](http://www.ithtw.com/wp-content/uploads/2015/03/2015032611150350.png)
复现bug的操作是:
1.首先打开,默认选中的是第一个tab,如上面的一张图片正常那样。
2.切换到tab2,并把tab1 hide掉;
3.再切回到tab1,并不会触发tab1对应fragment的任何生命周期;
4.然后home键进入后台,我在activity的onPause()中手动对IndexFragment赋空,模拟长时间后台,系统销毁了该引用。
IndexFragment=null;
5.再次启动,其实tab1 的fragment实例在内存中还在,只是他的引用被销毁了。
6.再切到tab2,这里其实是先把tab1的hide,在show tab2,但是tab1 的fragment引用为空,所以无法hide,就出现了tab2叠在tab1上的花屏情况。
7.再切到tab1,tab1就会重复创建对象。
同样的操作,我们使用replace的方式
![](http://www.ithtw.com/wp-content/uploads/2015/03/2015032611150428.png)
使用replace方式,虽然这种方式会避免上述的bug,但也是重复创建了对象。因为replace方式,对应的FrameLayout只有一 层,而add方式,这个FrameLayout其实有2层。但是这种方式的缺点是:每次replace会把生命周期全部执行一遍,如果在这些生命周期函数 里拉取数据的话,就会不断重复的加载刷新数据。
那么最合适的处理方式是这样的:
1.在add的时候,加上一个tab参数
transaction.add(R.id.content, IndexFragment,”Tab1″);
2.然后当IndexFragment引用被回收置空的话,先通过
IndexFragment=FragmentManager.findFragmentByTag(“Tab1″);
找到对应的引用,然后继续上面的hide,show;
相关文章推荐
- HDU 1698 Just a Hook(线段树的区间更新《标记》)
- glibc 中的 __attribute__ 关键字
- android有关图片的操作(一)
- Hadoop是如何工作的
- JVM知识学习与巩固
- hdu 5568 sequence2(dp + 大数)
- 使用Fragment实现底部菜单栏
- eclipse 导入tomcat7源码
- Android 修改当前显示时间
- leetcode -- Add Binary -- 简单要了解
- hdu 5567 sequence1(水)
- dataTables-使用详细说明整理,还有各种参数、回调方法
- 数据挖掘十大算法
- class(类)和struct(结构)的区别
- MyEclipse2014安装插件的几种方式(适用于Eclipse或MyEclipse其他版本)
- (三)、Express 路由、静态文件、
- crontab
- Android SDK Manager 无法更新下载怎么办?
- Android shape的使用笔记
- hdu 5409 CRB and Graph(强连通)