从Fragment被销毁看replace和add的区别

首先从一个bug说起

我们都知道fragment切换有两种方式:

1. replace方式

Java

transaction.replace(R.id.content, IndexFragment);

2. add-hide-show方式

Java

transaction.add(R.id.content, IndexFragment);
transaction.hide(otherfragment);
transaction.show(thisfragment);

而上面按钮中出现bug的就是采用第二种方式。然后我们来分析下用add,hide,show为什么出现这种bug,我把每个操作都打印出了以下日志:

复现bug的操作是:

1.首先打开,默认选中的是第一个tab,如上面的一张图片正常那样。

2.切换到tab2,并把tab1 hide掉;

3.再切回到tab1,并不会触发tab1对应fragment的任何生命周期;

4.然后home键进入后台,我在activity的onPause()中手动对IndexFragment赋空,模拟长时间后台,系统销毁了该引用。

Java

IndexFragment=null;

5.再次启动,其实tab1 的fragment实例在内存中还在,只是他的引用被销毁了。

6.再切到tab2,这里其实是先把tab1的hide,在show tab2,但是tab1 的fragment引用为空,所以无法hide,就出现了tab2叠在tab1上的花屏情况。

7.再切到tab1,tab1就会重复创建对象。

同样的操作,我们使用replace的方式

使用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;

附:TabView demo地址 https://github.com/JayFang1993/android-demos/tree/master/TabHost

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值