'IllegalStateException:在活动重启后调用'getSupportFragmentManager()'时,活动已被销毁

Mil*_*ilo 9 android illegalstateexception android-fragments android-viewpager

我有一个父片段活动,其ViewPager包含一个子ViewPager.子ViewPager包含每个页面的片段.我使用回调接口在这些子页面片段和顶级父片段活动之间进行通信,例如

public interface Callbacks {
    public void onItemSelected(Link link);
}
Run Code Online (Sandbox Code Playgroud)

在父片段活动中,我会监听onItemSelected事件,例如

@Override
public void onItemSelected(Link link) {
    Bundle argumentsFront = new Bundle();
    argumentsFront.putParcelable(FragmentComments.ARG_ITEM_ID, link);
    fragmentComments = new FragmentComments();
    fragmentComments.setArguments(argumentsFront);
    getSupportFragmentManager().beginTransaction().replace(R.id.post_container, fragmentComments).commitAllowingStateLoss();
}
Run Code Online (Sandbox Code Playgroud)

现在,当应用程序首次启动时,此功能正常.

如果您转动设备以更改方向,则活动将重新启动.所有片段在我使用时重新初始化setRetainInstance(true);(我不在子ViewPager的页面片段中调用setRetainInstance(true),因为它不受支持).但是,如果我单击子ViewPager的片段中的列表项,我会得到以下异常:

FATAL EXCEPTION: main
java.lang.IllegalStateException: Activity has been destroyed
at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1342)
at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:595)
at android.support.v4.app.BackStackRecord.commitAllowingStateLoss(BackStackRecord.java:578)
Run Code Online (Sandbox Code Playgroud)

有谁知道为什么会这样?

谢谢

Ste*_*yle 11

当你旋转设备,Android的节省,销毁,并重新创建你Activity和它ViewPagerFragments.由于ViewPager使用了FragmentManager你的Activity,它会Fragments为你保存并重复使用它们(并且不会创建新的),因此它们将保留对你的(现在已销毁的)原始文件的旧引用Activity,并且你得到了它IllegalStateException.

在你的孩子Fragments,尝试这样的事情:

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    Log.v(TAG, "onAttach");

    // Check if parent activity implements our callback interface
    if (activity != null) {
        try {
            mParentCallback = (Callbacks) activity;
        }
        catch (ClassCastException e) {
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后当选择发生时:

if(mParentCallback != null) {
    mParentCallback.onItemSelected(selectedLink);
}
Run Code Online (Sandbox Code Playgroud)

由于onAttach作为Fragment生命周期的一部分被调用,因此您Fragments将在轮换时更新其回调引用.

  • 我找到了解决方案.因为我有这样的嵌套片段:( FragmentActivity - > Fragment 1 - > Fragment 2(with ViewPager) - > ViewPager Child Fragments)我不得不将回调移动到Fragment 1(其中onAttach和onDetach被调用).然后我从ViewPager的子片段中的`onItemSelected`方法进行静态调用,到父片段(片段1)中的回调.这看起来有点像黑客,但运作良好.我在片段1中使用`setRetainInstance(true)`,因此子片段也保留状态. (3认同)
  • 啊,我看到你的架构有点复杂了.之前我做过类似的事情,其中​​一个`Fragment`回调它的父亲'Fragment`.我在onAttach中使用了与上面相同的代码,但是我没有将父`Activity`转换为我的回调,而是使用`getParentFragment()`来获取实现回调的父`Fragment`的引用.也许这有助于制定一个更清洁的解决方案,但很高兴你找到了一个方法. (2认同)