美文网首页
Fragment采坑记录

Fragment采坑记录

作者: 人丑茶凉 | 来源:发表于2019-03-27 18:34 被阅读0次
  • 1、 bug现象:当手机上的app运行的数量 超过手机清理的上限,即内存不足时,应用进入后台再次打开时嵌套的Fragment页面显示空白; 问题分析:内存不足时,宿主Activity会被异常关闭,当再次打开时,Activity重新创建,但嵌套的Fragment填充发生了错乱。

解决问题:复现bug,会发现除嵌套的Fragment外,其他的Fragment显示和点击事件均正常,也就是说问题可以锁定在嵌套的Fragment的宿主Fragment。 问题范围锁定后,查阅资料,发现与FragmentManager(Fragment管理类)有关。回看代码, 问题在对象FragmentTransaction,发现宿主Activity和宿主Fragment获取对象FragmentTransaction的方式均为 getSupportFragmentManager().beginTransaction(),而宿主Fragment需要使用getChildFragmentManager().beginTransaction(), 替换代码,重新运行,问题解决; 总结:Activity中获取对象FragmentTransaction,统一使用getSupportFragmentManager().beginTransaction(); Fragment中获取对象FragmentTransaction,统一使用getChildFragmentManager().beginTransaction()。

补充(语言有些书面难懂,不求甚解者可忽略):关于getChildFragmentManager() 和 getSupportFragmentManager() getChildFragmentManager()是fragment中的方法, 返回的是管理当前fragment内部子fragments的manager. getSupportFragmentManager()在activity和fragment中都有. 在activity中, 方法用getSupportFragmentManager(), 返回的是管理activity中fragments的manager. 在fragment中, 还叫getSupportFragmentManager(), 返回的是把自己加进来的那个manager. 也即, 如果fragment在activity中, fragment.getFragmentManager()得到的是activity中管理fragments的那个manager. 如果fragment是嵌套在另一个fragment中, fragment.getFragmentManager()得到的是它的parent的getChildFragmentManager(). 总结就是: getFragmentManager()是本级别管理者, getChildFragmentManager()是下一级别管理者. 这实际上是一个树形管理结构.

  • 2、 bug现象:当手机上的app运行的数量 超过手机清理的上限,即内存不足时,应用进入后台再次打开时点击或者滑动Fragment应用闪退。

问题分析:内存不足时,宿主Activity会被异常关闭,当再次打开时,Activity重新创建, 但与Viewpager结合使用的Fragment生命周期异常,viewpager的适配器继承自FragmentPagerAdapter,页面虽然被恢复, 但Fragment内的数据均被回收,所以Fragment会出现空指针。

解决问题:经不断探索目前有两种解决方案。

第一种,在Fragment集合放入适配器之前, 利用getSupportFragmentManager().getFragments(),获取到新的List<Fragment>, 然后遍历并删除这个集合内的所有的Fragment对象, 删除Fragment对象的代码:

getSupportFragmentManager().beginTransaction().remove(saveFragmentList.get(i)).commit()。
            List<Fragment> saveFragmentList = getSupportFragmentManager().getFragments();
            for (int i = 0; i < saveFragmentList.size(); i++) {
                getSupportFragmentManager().beginTransaction().remove(saveFragmentList.get(i)).commit();
            }
            list1Fragment = new List1Fragment();
            list2Fragment = new List2Fragment();
            list3Fragment = new List3Fragment();
            list4Fragment = new List4Fragment();
            fragmentList.clear();
            fragmentList.add(list1Fragment);
            fragmentList.add(list2Fragment);
            fragmentList.add(list3Fragment);
            fragmentList.add(list4Fragment);

第二种,解释起来比较麻烦,代码比较直观,直接上代码。

List<Fragment> saveFragmentList = getSupportFragmentManager().getFragments();
            if (saveFragmentList != null && saveFragmentList.size() > 0) {
                list1Fragment = (List1Fragment) saveFragmentList.get(0);
                list2Fragment = (List2Fragment) saveFragmentList.get(1);
                list3Fragment = (List3Fragment) saveFragmentList.get(2);
                list4Fragment = (List4Fragment) saveFragmentList.get(3);
            } else {
                list1Fragment = new List1Fragment();
                list2Fragment = new List2Fragment();
                list3Fragment = new List3Fragment();
                list4Fragment = new List4Fragment();
            }
            fragmentList.clear();
            fragmentList.add(list1Fragment);
            fragmentList.add(list2Fragment);
            fragmentList.add(list3Fragment);
            fragmentList.add(list4Fragment);

个人比较倾向于第二种。这两种方法的区别是,第一种会重新绘制所有相关的Fragment, 而第二种会保存Activity异常销毁前的Fragment的展示状态。

相关文章

  • Fragment采坑记录

    1、 bug现象:当手机上的app运行的数量 超过手机清理的上限,即内存不足时,应用进入后台再次打开时嵌套的Fra...

  • 采坑记录

    一、访问页面报502错误 常见问题: 最大可能是应用启动报错,没有启动起来 应用虽然起来了,但是由于遇到运行时er...

  • element 复选框点击一个全部选中bug

    因为有坑记录下先给出代码在细说 别的我就不说了,采坑记录下。

  • arraylist采坑记录

    而最近,看到一个以前的同学写的一段代码就是在循环过程中删除元素,我很是纳闷啊。然后后来决定给他改掉。然后引发了另外...

  • iOS采坑记录

    采坑记录 iOS 通过 Webview点击下载链接问题 Webview点击下载链接,需要通过文件名下载文件,需要通...

  • RecyclerView采坑记录

    今天使用RecyclerView过程中遇到了坑,RecyclerView的条目中既有checkbox,又有edit...

  • swagger采坑记录

    一、swagger-ui.html正常显示但doc.html空白 注意:我的doc.html不是404,说明在后端...

  • Flutter采坑记录

    在 Flutter 开发中遇到的一些 BUG,避免遗忘,记录一下,如果正在看文章的你也遇到了,那激动的心,颤抖的手...

  • TextSnake采坑记录

    一、提示错误: RuntimeError: Cannot re-initialize CUDA in forked...

  • Vue 采坑记录

    1、

    网友评论

      本文标题:Fragment采坑记录

      本文链接:https://www.haomeiwen.com/subject/ypstbqtx.html