问题

当快速点击切换不同的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. LG4723 【模板】常系数线性递推

    P4723 [模板]常系数齐次线性递推 题目描述 求一个满足$k$阶齐次线性递推数列${a_i}$的第$n$项. 即:$a_n=\sum\limits_{i=1}^{k}f_i \times a_{n ...

  2. GBDT(梯度提升树) 原理小结

    在之前博客中,我们对Boosting家族的Adaboost算法做了总结,本文就对Boosting家族中另一个重要的算法梯度提升树(Gradient Boosting Decison Tree, 以下简 ...

  3. 【小技巧】O(1)快速乘

    问题:求 \(a\times b\bmod p\),\(a,b,p\) 在 long long 范围内. 在 CRT 等算法中应用广泛. 为了处理模数在 int 范围外的情况,就是两数相乘可能会爆 l ...

  4. SP1825 【FTOUR2 - Free tour II】

    # \(SP1825\) 看到没有人用老师的办法,于是自己写一下思路 思路第一步:排除旧方法 首先这道题和\(4178\)不一样,因为那道题是计数,而这道题是求最值,最值有个坏处,就是对于来自相同子树 ...

  5. Restful API 指南

    作为软件开发人员,我们大多数人在日常生活中使用或构建 REST api.API 是系统之间的默认通信方式.亚马逊是如何有效地使用 api 进行通信的最佳例子. 在这篇文章中,我将讨论如何更好地设计 R ...

  6. Acwing P288 休息时间 题解

    Analysis 首先假设一天的第N小时与后一天的第一个小时不相连, 这种情况下DP转移比较好想 dp[i][j][0/1]dp[i][j][0/1]表示 考虑一天的前i个小时,已经休息了j小时,且第 ...

  7. Apache Kylin v3.0.0-alpha 发布

    Apache Kylin v3.0.0-alpha 发布 Apr 19, 2019 • Shaofeng Shi 近日 Apache Kylin 社区很高兴地宣布,Apache Kylin v3.0. ...

  8. easyui181版本使用记录

    easyui181版本下载地址 简单java+easyui181版本demo下载 注意前端页面的ajax请求路径对应后端 如果再加强样式可使用adminLTE

  9. codevs6003一次做对算我输

    6003 一次做对算我输 时间限制: 1 s 空间限制: 1000 KB 题目等级 : 大师 Master       题目描述 Description 更新数据了!!!!!!!更新数据了!!!!!! ...

  10. setitimer()函数

    定时器时间函数 struct itimerval: struct itimerval *new_value,其定义如下: struct itimerval { struct timeval it_in ...