如何防止FragmentManager在旋转后被销毁

How to prevent FragmentManager from being destroyed after rotation

当我单击“显示更多”按钮时,会打开一个新片段。但是,如果我旋转设备然后单击它,则会出现错误。

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.rekijan.initiativetrackersecondedition, PID: 4673
    java.lang.IllegalStateException: FragmentManager has been destroyed
        at androidx.fragment.app.FragmentManager.enqueueAction(FragmentManager.java:1878)
        at androidx.fragment.app.BackStackRecord.commitInternal(BackStackRecord.java:329)
        at androidx.fragment.app.BackStackRecord.commit(BackStackRecord.java:294)
        at com.rekijan.initiativetrackersecondedition.ui.activities.MainActivity.replaceCharacterDetailFragment(MainActivity.java:207)
        at com.rekijan.initiativetrackersecondedition.character.adapter.CharacterAdapter.onClick(CharacterAdapter.java:305)
        at android.view.View.performClick(View.java:7448)
        at android.view.View.performClickInternal(View.java:7425)
        at android.view.View.access00(View.java:810)
        at android.view.View$PerformClick.run(View.java:28305)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:223)
        at android.app.ActivityThread.main(ActivityThread.java:7656)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

所以代码在 RecyclerViewAdapter 中

holder.showCharacterDetailButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                ((MainActivity)context).replaceCharacterDetailFragment(holder.getAdapterPosition());
            }
        });

然后在MainActivity

public void replaceCharacterDetailFragment(int position) {
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        if (getResources().getBoolean(R.bool.isTablet)) {
            transaction.replace(R.id.second_fragment_container, CharacterDetailFragment.newInstance(position));
            transaction.commit();
        } else {
            transaction.replace(R.id.main_fragment_container, CharacterDetailFragment.newInstance(position));
            transaction.addToBackStack(null);
            transaction.commit();
            //Enable the back button in action bar
            if (getSupportActionBar() != null) getSupportActionBar().setDisplayHomeAsUpEnabled(true);
            AppExtension app = (AppExtension) this.getApplicationContext();
            app.setShowBackNavigation(true);
        }
    }

更多代码可以在 github 中找到,因为开源是 https://github.com/ej-krielen/pf2initiativetracker

一个常见的 'solution' 是使用 isDestroyed 或 isFinishing。当然,如果我使用它,应用程序不会崩溃,但也不会制作片段。

所以重申一下:

是的,有时在更新旧项目时您会忘记自己的逻辑。问题是在我的适配器中我使用了对上下文的引用。但是,适配器是在 AppExtension 中创建的,因此在重新创建 Activity 时不会再次设置。所以现在当 Activity 重新创建时,我再次将上下文传递给适配器,一切正常。