关于Fragment处于后台被回收后,点击重启,Fragment页面无法做任何操作

关于Fragment处于后台被回收后,点击重启,Fragment页面无法做任何操作

开发过程中,出现过这样一个bug,在fragment跳转到系统权限设置页面,对权限进行开关后,返回app,app白屏重新启动,fragment页面仿佛被锁死,无法进行任何操作。

项目ui架构

MainActivity

  • HomeFragment
  • ListFragment
  • AlarmFragment
  • MineFragment

操作逻辑

HomeFragment使用某个功能需要请求权限,当用户点击拒接不勾选不再提示后,当下次点击该功能时弹框提示用户跳转系统权限设置页面进行操作。(或者其它导致MainActivity处于后台被系统杀死回收的操作)

问题发现

当跳转到系统权限设置页面进行权限开关返回时,两种现象:

  1. App重启,重启一切正常;
  2. App不重启,白屏重新加载当前页面,加载完毕此HomeFragment无法操作。百分百复现。
问题排查

怀疑是Fragment生命周期出现问题,对MainActivity设置Log打印输出。以下是App不重启时日志输出总结:

  • 打印生命周期,MainActivity重新走了onCreate()方法,参数savedInstanceState不为null。(推断App已经被系统杀死回收)
  • 打印FragmentManagergetFragments()方法,输出两个HomeFragment。(问题关键点)
  • 打印FragmentTransactiongetBackStackEntryCount(),输出0。
  • 打印FragmentManagerfindFragmentByTag(String tag)方法,输出全为null
结论

阅读FragmentManager、FragmentStore、FragmentTransaction、BackStackRecord等系统源码,结合Activity、Fragment生命周期,Android系统回收机制等,可以得知当Activity被系统回收时,系统会将当前页面的数据保存在savedInstanceState,重新恢复时,系统会对这些对象进行恢复,但由于我们未重写数据保存和恢复的方法,所以系统恢复时并不是百分百完全复原,有些数据找不到,所以出现了add了相同的HomeFragment,而show的时候导致应该被回收的HomeFragment重叠在新add的HomeFragment上。

解决方法

最简单的方法,在MainActivity的onCreate方法中判断savedInstanceState是否为null,如果不为null,判断FragmentManager的getFragments()是否为空,不为空则将之前未销毁的fragment一个个销毁掉。

FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
List<Fragment> list = fragmentManager.getFragments();
if(savedInstanceState != null && list.size() != 0){
    for(Fragment fragment: list){
        fragmentTransaction.remove(fragment);
        fragmentTransaction.commitAllowingStateLoss();
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值