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

以上是在使用Fragment去嵌套Fragment的时候可能会遇到的BUG,了解了BUG存在的原因之后,就可以完美的解决问题。

fragment的一些bug的更多相关文章

  1. Fragment 操作原理

      fragment 本质 fragment 本质上是 view 的容器和控制器,fragment 是 activity 的碎片. activity 是什么呢?activity 是四大组件之一,因为 ...

  2. Android项目开发填坑记-Fragment的onAttach

    背景 现在Android开发多使用一个Activity管理多个Fragment进行开发,不免需要两者相互传递数据,一般是给Fragment添加回调接口,让Activity继承并实现. 回调接口一般都写 ...

  3. Beta 冲刺 二

    团队成员 051601135 岳冠宇 031602629 刘意晗 031602248 郑智文 031602330 苏芳锃 031602234 王淇 照片 项目进展 岳冠宇 昨天的困难 fragment ...

  4. Fragmen的onAttach方法

    现在Android开发多使用一个Activity管理多个Fragment进行开发,不免需要两者相互传递数据,一般是给Fragment添加回调接口,让Activity继承并实现. 回调接口一般都写在Fr ...

  5. 2016 校招, Android 开发,一个本科应届的坎坷求职之路(转)

    转载出处:http://www.nowcoder.com/discuss/3244?type=2&order=0&pos=1&page=1 和大多数的面经不同,我不是大牛,手头 ...

  6. 【软工项目Beta阶段】第10周Scrum会议博客

    第十周会议记录 小组GitHub项目地址https://github.com/ouc-softwareclass/OUC-Market 小组Issue地址https://github.com/ouc- ...

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

    时间 2014-03-18 18:00:55 eoe博客 原文  http://my.eoe.cn/916054/archive/24053.html 主题 安卓开发 自从Android3.0引入了F ...

  8. FragmentActivity + Fragment + Fragment使用过程中出现的bug

    FragmentActivity + Fragment(通过hide和show来显示fragment) + Fragment(通过viewpager来显示fragment) 在Activity中 // ...

  9. Android 多个Fragment嵌套导致的三大BUG

    Android有碎片化的问题,当然本文说的碎片化不是指的系统版本碎片化的问题,而是Fragment组件碎片化的问题. 很久之前,在Android 3.1系统发布的时候,Google推出了使用Fragm ...

随机推荐

  1. dede标签调用

    关键描述调用标签: <meta name="keywords" content="{dede:field name='keywords'/}">&l ...

  2. hdu 1805Expressions(二叉树构造的后缀表达式)

    Expressions Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  3. centOS wget的安装和使用

    CentOS wget是一个从网络上自动下载文件的自由工具.它支持HTTP,HTTPS和FTP协议,可以使用HTTP代理. 所谓的自动下载是指,CentOS wget可以在用户退出系统的之后在后台执行 ...

  4. android - anim translate中 fromXDelta、toXDelta、fromYDelta、toXDelta属性

    <?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http:// ...

  5. Windows上模拟Linux环境

    有两种方法,一直是 MinGW http://jingyan.baidu.com/article/8cdccae985cf7c315413cd35.html 另外可以用 cygwin http://j ...

  6. 从java 转到 c# 知识点

    1. 重写的父类方法 必须是虚方法 用virtual 关键字修饰 而子类必须用 ovrride 关键字 java中不需要,, 2. namespace => packet using => ...

  7. ios基础篇(四)——UILabel的常用属性及方法

    UILabel的常用属性及方法:1.text //设置和读取文本内容,默认为nil label.text = @”文本信息”; //设置内容 NSLog(@”%@”, label.text); //读 ...

  8. kafka consumer属性

    consumer属性 group.id:指定consumer group的唯一标识. consumer.id:唯一标识consumer.默认值为null,不指定时会自动生成. zookeeper.co ...

  9. 实现OAUTH协议 实现 QQ 第三方登录效果

    1.OAuth的简述 OAuth(Open Authorization,开放授权)是为用户资源的授权定义了一个安全.开放及简单的标准,第三方无需知道用户的账号及密码,就可获取到用户的授权信息,并且这是 ...

  10. Tomcat性能调优-让小猫飞奔[转]

      http://blog.csdn.net/lifetragedy/article/details/7708724   http://blog.csdn.net/lifetragedy/articl ...