问题

当快速点击切换不同的Fragment的时候部分手机的app竟然挂了,报出了下面的错误 Fragment already added

java.lang.IllegalStateException: Fragment already added: xxxxFragment

上网找了很多,大致得到的原因是当快速双击调用FragmentTransaction.add()方法添加fragmentA,而fragmentA不是每次单独生成的,就会引起这个异常。

上面的内容是网上的解释,不过我认为是因为同一个Fragment被add两次导致的错误,但是奇怪的是我在加载这个Fragment的时候已经做了是否add的判断,为什么还会有这个问题呢。

private void addFragment(FragmentManager fm, Fragment fragment ) {
Log.i( "addFragment", "### " + fragment.getId() + " " + fragment.isAdded() + " " + fragment.isHidden() ); if (!fragment.isAdded() ) {
FragmentTransaction ft = fm.beginTransaction();
fm.executePendingTransactions();
ft.add( R.id.main_content, fragment );
ft.commitAllowingStateLoss();
}

通过打印结果发现,第一次切换到FragmentA的时候,FragmentA明明已经add了,但是isAdded()依然显示false

addFragment: ###1 2131755357  false true
addFragment: ###2 2131755357 false true
addFragment: ###3 2131755357 false true
addFragment: ###4 2131755357 false true

第二次切换到相同FragmentA的时候isAdded()就显示为true了

addFragment: ###1 2131755357  true true
addFragment: ###2 2131755357 true true
addFragment: ###3 2131755357 true true
addFragment: ###4 2131755357 true true

在不断快速切换不同的Fragment的时候,isAdded()偶尔会显示false,就因为isAdded()显示了false,那么 ft.add( R.id.main_content, fragment )就会再次执行一次,就会报错,说明通过isAdded()这个方法判断Fragment是否被add可能并不准确。

方法

解决方法就是每次add的时候加上一个tag,然后不仅要通过isAdded()判断Fragment是否add,还要通过FragmentManager.findFragmentByTag(tag)获取Fragment,然后判断此Fragment是否为null。

 case R.id.home_tab_a:
hideAllFragment( fm );
addFragment( fm, fragmentA, "A" );
showFragment( fm, fragmentA );
break; case R.id.home_tab_b:
hideAllFragment( fm );
addFragment( fm, fragmentB, "B" );
showFragment( fm, fragmentB );
break; case R.id.home_tab_c:
hideAllFragment( fm );
addFragment( fm, fragmentC, "C" );
showFragment( fm, fragmentC );
break;

影藏所有的Fragment

 private void hideAllFragment(FragmentManager fm) {
FragmentTransaction ft = fm.beginTransaction();
if (!shijianFragment.isHidden())
ft.hide( fragmentA ); if (!riliFragment.isHidden())
ft.hide( fragmentB ); if (!gongjuFragment.isHidden()) {
ft.hide( fragmentC );
}
ft.commitAllowingStateLoss();
}

通过isAdded()判断Fragment是否add,同时通过tag获取Fragment,判断Fragment是否为空,双重判断

   private void addFragment(FragmentManager fm, Fragment fragment, String tag) {
if (!fragment.isAdded()&&null == fm.findFragmentByTag( tag )) {
FragmentTransaction ft = fm.beginTransaction();
fm.executePendingTransactions();
ft.add( R.id.main_content, fragment, tag );
ft.commitAllowingStateLoss();
} }

显示Fragment

 private void showFragment(FragmentManager fm, Fragment fragment) {
FragmentTransaction ft = fm.beginTransaction();
ft.show( fragment );
ft.commitAllowingStateLoss();
}

Fragment already added问题的解决的更多相关文章

  1. viewpager和fragment预加载的解决

    在使用Viewpager和fragment处理中会出现预加载的问题,最近看别人的代码,终于找到了一个很好的处理方法 能有效的解决预加载的问题,在fragment都继承一个重写setUserVisibl ...

  2. Activity has leaked window that was originally added(以解决)

     在编写Android程序的时候,遇到一个隐藏性问题.仔细查看LogCat,错误信息如下: 10-31 13:03:34.549: ERROR/WindowManager(444): Activi ...

  3. Android 关于Fragment重叠问题分析和解决

    一.问题描述 相信大家在使用Fragment的过程中,肯定碰到过Fragment重叠的问题,重启应用就好了.然而原因是什么呢? 二.原因分析 首先,Android管理Fragment有两种方式,使用a ...

  4. 多个fragment中重叠问题的解决方法

    这个方法适用性有限. 我的是一个mainActivity,然后下部四个按钮,点击时先隐藏所有的fragment,然后再new一个新的出来,如果存在,则直接显示出来,看上去一切都没有问题. 但是通过fr ...

  5. fragment没有getWindowManager 关于fragment下的报错解决方法

    其实很简单:只需要在getWindowManager().getDefaultDisplay().getMetrics(metric) 前面加上getactivity()即可.

  6. Fragment已经被added了导致的异常。

    java.lang.IllegalStateException: Fragment already added:  ******Effect 出现的原因是commit方法提交是异步的,所以容易出现,判 ...

  7. 【转】解决Fragment already active方法

    http://blog.csdn.net/u011730649/article/details/43227721 今天在项目中使用Fragment的时候出现这样的错误: 01-28 10:53:34. ...

  8. 解决IllegalStateException: Can not perform this action after onSaveInstanceState

    今天使用Fragment的时候,出现了这个错误 IllegalStateException: Can not perform this action after onSaveInstanceState ...

  9. 【转】 解决IllegalStateException: Can not perform this action after onSaveInstanceState

    今天使用Fragment的时候,出现了这个错误 IllegalStateException: Can not perform this action after onSaveInstanceState ...

随机推荐

  1. test20190826 NOIP2019 模拟赛

    100+100+40=240.我觉得如果没做过第三题考场上却能想出来的都是神仙. 基因突变 [问题描述] 邪恶的 707 刚刚从白垩纪穿越回来,心中产生了一个念头:我要统治人类! 但是统治人类是很庞大 ...

  2. Java中判断字符串是否为数字

    转载:https://blog.csdn.net/u013066244/article/details/53197756 用JAVA自带的函数 public static boolean isNume ...

  3. UVA 1672不相交的正规表达式

    题意 输入两个正规表达式,判断两者是否相交(即存在一个串同时满足两个正规表达式).本题的正规表达式包含如下几种情况: 单个小写字符 $c$ 或:($P | Q$). 如果字符串 $s$ 满足 $P$ ...

  4. NOI.ac 模拟赛20181103 排队 翘课 运气大战

    题解 排队 20% 1≤n≤20,1≤x,hi≤201\le n\le 20, 1\le x,h_i\le 201≤n≤20,1≤x,hi​≤20 随便暴力 50% 1≤n≤2000,1≤x,hi≤1 ...

  5. 1.6synchronized代码块

    1.synchronized可以使用任意的Object进行加锁,用法比较灵活 ============================================================= ...

  6. 【JS】知识笔记

    一.JS文件位置 多个.JS文件最好合并到一个文件中,减少加载页面时发送的请求数量. 某个单独页面需要的js,最好放在HTML文档的最后,</body>之前,这样能使浏览器更快地加载页面. ...

  7. 溢出的文字隐藏(text-overflow)

    <body> <div>一定要首先强制一行内显示,再次和overflow搭配使用,三个步骤缺一不可</div> </body> <style> ...

  8. c语言实现杨辉三角形

    #include <stdio.h> int main(void) { int a[9][9]={}; int i,j; for(i=0;i<9;i++){ for(j=0;j< ...

  9. 深度Linux /etc/profile 环境变量生效问题

    /etc/profile 环境变量生效问题 设置了环境变量后 ,使用source /etc/profile生效后,每次关闭终端后,都需要重新输入source /etc/profile命令使环境变量生效 ...

  10. jvm指令手册查看

    00-JVM指令手册 栈和局部变量操作 将常量压入栈的指令 aconst_null 将null对象引用压入栈 iconst_m1 将int类型常量-1压入栈 iconst_0 将int类型常量0压入栈 ...