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