Fragment嵌套使用存在的一些BUG以及解决方法

Case 1:当使用Fragment去嵌套另外一些子Fragment的时候,我们需要去管理子Fragment,这时候需要调用ChildFragmentManager去管理这些子Fragment,由此可能产生的Exception主要是:

java.lang.IllegalStateException: No activity

首先我们来分析一下Exception出现的原因:

通过DEBUG发现,当第一次从一个Activity启动Fragment,然后再去启动子Fragment的时候,存在指向Activity的变量,但当退出这些Fragment之后回到Activity,然后再进入Fragment的时候,这个变量变成null,这就很容易明了为什么抛出的异常是No activity

这个Exception是由什么原因造成的呢?如果想知道造成异常的原因,那就必须去看Fragment的相关代码,发现Fragment在detached之后都会被reset掉,但是它并没有对ChildFragmentManager做reset,所以会造成ChildFragmentManager的状态错误。

找到异常出现的原因后就可以很容易的去解决问题了,我们需要在Fragment被detached的时候去重置ChildFragmentManager,即:

@Override
  public void onDetach() {
    super.onDetach();
    try {
      Field childFragmentManager = Fragment.class
          .getDeclaredField("mChildFragmentManager");
      childFragmentManager.setAccessible(true);
      childFragmentManager.set(this, null);

    } catch (NoSuchFieldException e) {
      throw new RuntimeException(e);
    } catch (IllegalAccessException e) {
      throw new RuntimeException(e);
    }
  }

Case 2:当我们从一个Activity启动了一个Fragment,然后在这个Fragment中又去实例化了一些子Fragment,在子Fragment中去有返回的启动了另外一个Activity,即通过startActivityForResult方式去启动,这时候造成的现象会是,子Fragment接收不到OnActivityResult,如果在子Fragment中是以getActivity.startActivityForResult方式启动,那么只有Activity会接收到OnActivityResult,如果是以getParentFragment.startActivityForResult方式启动,那么只有父Fragment能接收(此时Activity也能接收),但无论如何子Fragment接收不到OnActivityResult。

这是一个非常奇怪的现象,按理说,应该是让子Fragment接收到OnActivityResult才对,究竟是什么造成的呢?这是由于某位写代码的员工抱怨没发奖金,稍稍偷懒了,少写了一部分代码,没有考虑到Fragment再去嵌套Fragment的情况。

我们来看看FragmentActivity中的代码:

protected void onActivityResult(int requestCode, int resultCode, Intent data)
  {
    this.mFragments.noteStateNotSaved();
    int index = requestCode >> 16;
    if (index != 0) {
      index--;
      if ((this.mFragments.mActive == null) || (index < 0) || (index >= this.mFragments.mActive.size())) {
        Log.w("FragmentActivity", "Activity result fragment index out of range: 0x" + Integer.toHexString(requestCode));

        return;
      }
      Fragment frag = (Fragment)this.mFragments.mActive.get(index);
      if (frag == null) {
        Log.w("FragmentActivity", "Activity result no fragment exists for index: 0x" + Integer.toHexString(requestCode));
      }
      else {
        frag.onActivityResult(requestCode & 0xFFFF, resultCode, data);
      }
      return;
    }

    super.onActivityResult(requestCode, resultCode, data);
  }

很显然,设计者把Fragment的下标+1左移16位来标记这个request是不是Fragment的,拿到result再解码出下标,直接取对应的Fragment,这样并没有去考虑对Fragment嵌套Fragment做一个Map映射,所以出现了这种BUG。

但是如果我们需要在OnActivityResult的时候处理一些事情的话,我们可以通过在子Fragment中以getParentFragment.startActivityForResult的方式来启动,然后在父Fragment中去接收数据,我们需要在子Fragment中提供一个方法,如:getResultData(Object obj),通过父Fragment中的子Fragment实例去调用这个方法,把相应的数据传过去,然后去更新子Fragment。

时间: 2024-08-29 14:05:32

Fragment嵌套使用存在的一些BUG以及解决方法的相关文章

浅谈Android Fragment嵌套使用存在的一些BUG以及解决方法

自从Android3.0引入了Fragment之后,使用Activity去嵌套一些Fragment的做法也变得更加流行,这确实是Fragment带来的一些优点,比如说:Fragment可以使你能够将activity分离成多个可重用的组件,每个都有它自己的生命周期和UI,更重要的是Fragment解决了Activity间的切换不流畅,实现了一种轻量及的切换,但是在官方提供的android.support.v4包中,Fragment还是或多或少的存在一些BUG,今天就与大家分享一下这些BUG和解决方

写出几种IE6 BUG的解决方法

1.双边距BUG float引起的  使用display:inline 2.3像素问题 使用多个float和注释引起的 使用dislpay:inline -3px 3.超链接hover 点击后失效  使用正确的书写顺序 link visited hover active 4.Ie z-index问题 给父级添加position:relative 5.Png 透明 使用js代码 改 6.Min-height 最小高度 !Important 解决’ 7.select 在ie6下遮盖 使用iframe

【转】 IE6 IE7 IE8 css bug兼容性解决方法总结归纳

1:li边距“无故”增加 任何事情都是有原因的,li边距也不例外. 先描述一下具体状况:有些时候li边距会突然增 加很多,值也不固定(只在IE6/IE7有这种现象),让人摸不着头脑,仔细“研究”发现是由于其低级元素ul的padding引 起,padding的上下值对li有影响,左右无影 响.所以只好笨手笨脚地把padding去掉,换成margin.这是能解决问题,但往往不是我们想要的结果,或许 还会引起其他不必要的怪现象. 现在终于发现解决这个问题的方法,其实很简单,既然是有ul引 起的,就设置

ie6,ie7,ie8 css bug兼容解决方法

IE浏览器以不支持大量的css 属性出名,同时也因其支持的css属性中存在大量bug. 这里收集了好多的bug以及其解决的办法,都在这个文章里面记录下来了!希望以后解决类似问题的时候能够快速解决,也希望大家能在留言里面跟进自己发现的ie6 7 8bug和解决办法! 普通IE css bug bug名称 影响版本 描述 Image Label Focus Bug IE8,IE7,IE6 <img>元素在<label>元素之内,单击时,焦点不会转移到相应的表单控件 按钮Margin-A

Arduino下LCD1602综合探究(中)——如何减少1602的连线,LiquidCrystal库,LiquidCrystal库中bug的解决方法

一.前言: 上文中,笔者系统的阐述了1602的两种驱动方式,并简单的提到了Arduino的LiquidCrystal库.本文紧接上文,对以下两个问题进行更加深入的探讨:如何能够使1602对Arduino的端口占用降到最少?LiquidCrystal库到底应该如何学习?在Arduino下LCD1602综合探究(下)中,笔者拟介绍一个1602的综合性实验,以期对前文的内容加以综合应用和总结.闲话少说,下面开始进入正文. 二.减少1602对Arduino的端口占用 <1>不使用I2C 在上文中,笔者

android下前端开发诡异bug记录&amp;解决方法

1.border-radius有bug,围不住background 描述:设置了border-radius后,背景色依然会从圆角里冒出来 解决方法:在设置了border-radius的容器加上background-clip:padding-box;一定要把background样式提到background-clip样式前!!(被这个bug坑死了,花了大半天时间在近乎绝望的情况下找出了原因) 不断补充中…

js中hover事件时候的BUG以及解决方法

hover事件是我们在开发前段时候遇到的稀松平常的问题,但是有没有发现会出现有一个BUg,比如,你移动到一个元素上,让它执行一个方法,然后你快速的移入移出的时候,他会进行亮瞎你眼睛的频闪效果,而且跟得了老年痴呆一样会进行延时显示,24K钛合金也会被闪瞎的,鼠标重复在相应区域滑动的时候,动画会一直执行,直到和鼠标经过的次数相同位置.比如鼠标移进3次,移出3次,动画就会出现三次.这显然是极度影响用户体验的.然后我们公司大后端告诉我说把mouseevent和monseleave合并成一个hover事件

IE6常见的bug及解决方法

1.IE6怪异解析之padding与border算入宽高 原因:未加文档声明造成非盒模型解析 解决方法:加入文档声明<!doctype html> 2.IE6在块元素.左右浮动.设定marin时造成margin双倍(双边距) 解决方法:display:inline 3.以下三种其实是同一种bug,其实也不算是个bug,举个例子:父标签高度20,子标签11,垂直居中,20-11=9,9要分给文字的上面与下面,怎么分?IE6就会与其它的不同,所以,尽量避免. 1)字体大小为奇数之边框高度少1px

10个常见的IE bug和解决方法

1.IE6 幽灵文本(Ghost Text bug) 在我写本文之前,我遇到了这个bug.它相当的古怪和滑稽.一块不知哪来的重复的文本,被IE6显示在靠近原文本的下面.(译注:也可以参看 Explorer 6 Duplicate Characters Bug 获得bug演示).我无法解决它,所以我搜索它,果然,这是另一个IE6的bug. 对此有许多解决方法,但是没有一个对我的例子有效(因为网站的复杂性我无法使用其中的一些方法).所以我使用了hack.在原文本之后增加空格看起来能解决这个问题. 但