浅谈Android Fragment嵌套使用存在的一些BUG以及解决方法
自从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存在的原因之后,就可以完美的解决问题。
浅谈Android Fragment嵌套使用存在的一些BUG以及解决方法的更多相关文章
- 浅谈Android保护技术__代码混淆
浅谈Android保护技术__代码混淆 代码混淆 代码混淆(Obfuscated code)亦称花指令,是将计算机程序的代码,转换成一种功能上等价,但是难于阅读和理解的形式的行为.将代码中的各种元 ...
- 浅谈Android应用保护(一):Android应用逆向的基本方法
对于未进行保护的Android应用,有很多方法和思路对其进行逆向分析和攻击.使用一些基本的方法,就可以打破对应用安全非常重要的机密性和完整性,实现获取其内部代码.数据,修改其代码逻辑和机制等操作.这篇 ...
- 安卓开发_浅谈Android动画(四)
Property动画 概念:属性动画,即通过改变对象属性的动画. 特点:属性动画真正改变了一个UI控件,包括其事件触发焦点的位置 一.重要的动画类及属性值: 1. ValueAnimator 基本属 ...
- 浅谈Android应用性能之内存
本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! 文/ jaunty [博主导读]在Android开发中,不免会遇到许多OOM现象,一方面可能是由于开 ...
- 浅谈Android五大布局
Android的界面是有布局和组件协同完成的,布局好比是建筑里的框架,而组件则相当于建筑里的砖瓦.组件按照布局的要求依次排列,就组成了用户所看见的界面.Android的五大布局分别是LinearLay ...
- [转]浅谈Android五大布局(二)——RelativeLayout和TableLayout
在浅谈Android五大布局(一)中已经描述了LinearLayout(线性布局).FrameLayout(单帧布局)和AbsoulteLayout(绝对布局)三种布局结构,剩下的两种布局Relati ...
- [转]浅谈Android五大布局(一)——LinearLayout、FrameLayout和AbsoulteLayout
Android的界面是有布局和组件协同完成的,布局好比是建筑里的框架,而组件则相当于建筑里的砖瓦.组件按照布局的要求依次排列,就组成了用户所看见的界面.Android的五大布局分别是LinearLay ...
- 浅谈Android Studio3.0更新之路(遇坑必入)
>可以参考官网设置-> 1 2 >> Fantasy_Lin_网友评论原文地址是:简书24K纯帅豆写的我也更新一下出处[删除]Fa 转自脚本之家 浅谈Android Studi ...
- 浅谈android代码保护技术_ 加固
浅谈android代码保护技术_加固 导语 我们知道Android中的反编译工作越来越让人操作熟练,我们辛苦的开发出一个apk,结果被人反编译了,那心情真心不舒服.虽然我们混淆,做到native层,但 ...
随机推荐
- JavaScript异步机制
单线程异步执行的JavaScript JavaScript是单线程异步执行的,单线程意味着代码在任务队列中会按照顺序一个接一个的执行.异步代表JavaScript代码在任务队列中的顺序并不完全等同于代 ...
- Java虚拟机JVM学习06 自定义类加载器 父委托机制和命名空间的再讨论
Java虚拟机JVM学习06 自定义类加载器 父委托机制和命名空间的再讨论 创建用户自定义的类加载器 要创建用户自定义的类加载器,只需要扩展java.lang.ClassLoader类,然后覆盖它的f ...
- Android开发实战(十八):Android Studio 优秀插件:GsonFormat
Android Studio 优秀插件系列: Android Studio 优秀插件(一):GsonFormat Android Studio 优秀插件(二): Parcelable Code Gen ...
- Object-c字符串操作
字符串操作: -(void) testString{ NSString *str1 = @"some string"; NSLog(@"%@", str1); ...
- Xcode cannot launch because the device is locked.
When you plug in your iPhone, it will ask you to trust the computer. If you already trust and unlock ...
- 转载:jsp中jstl标签的类似 if - else 语句 的语法
原文链接:http://www.cnblogs.com/wanggd/archive/2013/05/27/3101788.html 在jsp中引入jstl的标签库和函数库 <%@ taglib ...
- Android简单加密保护自有图片资源
现在大部分android应用的图片资源,被反编译后就可以直接拿来用,如果不想让自己的图片资源直接被反编译后使用,首先想到的应该是把图片加密.这里笔者抛砖引玉,草草写了一个对图片进行简单加密的方法,希望 ...
- 集群服务器 时间同步 - Chrony
greenplum,openstack等云计算项目需要集群服务器部署,服务器之间的时间需要同步,但并不是所有机器可以 直接连外网,这时可以用Chrony工具解决. 解决方法是将其中一台设为时间服务器, ...
- CDC 2013 北京站手记
受搜狐畅游的邀请,这次能够有机会参与2013中国开发者大会北京站的活动. 本次大会的主题是“游戏”和“移动”,因此上午的峰会安排了5个主讲,分别就搜索.云存储服务器.游戏媒体.移动应用和游戏渠道等多方 ...
- js实现页面跳转的几种方式
第一种: <script language="javascript" type="text/javascript"> wi ...