java.lang.IllegalStateException: Activity has been destroyed解決方案

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

相關文章
相關標籤/搜索