Activty嵌套多个Fragment,而后Fragment里面再嵌套多个Fragment,外层的Fragment切换得快了或者横竖屏切换就会报错:
java.lang.IllegalStateException: Activity has been destroyed
at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1460)
at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:634)
at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:613)java
报错的是外层Fragment内的下面这段代码:android
IndexListFragment indexHotFragment = new IndexListFragment(); Bundle bundle = new Bundle(); switch (id) { case 1: bundle.putSerializable("list", audit_handles); bundle.putInt("id", 1); break; case 2: bundle.putSerializable("list", pos_handles); bundle.putInt("id", 2); break; case 3: bundle.putSerializable("list", audit_lists); bundle.putInt("id", 3); break; case 4: bundle.putSerializable("list", pos_lists); bundle.putInt("id", 4); break; default: break; } indexHotFragment.setArguments(bundle); FragmentManager fragmentManager = getChildFragmentManager(); FragmentTransaction ft = fragmentManager.beginTransaction(); ft.replace(flContainer, indexHotFragment); ft.commit();
产生异常的缘由是什么呢?根据查阅的资料网上是这么说的
当使用一个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,即:app
@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); } }
可是通过试验,这个方法并无效果
为何在onDetach行不通呢,由于按照activity跟fragment的生命周期图来看,onDetach阶段fragment已经与activity脱离关系即fragment持有的activity对象已被置null,而onDestroyView阶段fragment中仍然保留与activity之间的关系,此时fragment持有的activity对象仍然有效,那么把这段代码放在onDestoryed里面吧,但仍是不行,
经过管理childFragmentManager的方法是行不通了,因而我想到了另一种方法:判断Fragment所在的Activity是否存在,在调用上面报错的一段代码以前加上判断if(getActivity != null && getActivity().isFinishing());ide