androidandroid-fragmentsfragmentmanager

FragmentManager has been destroyed


EDIT: It seems that this only happens if my previous activity is in landscape, and the setRequestedOrientation() is portrait, what could possibly be the problem?

I have a code in an activity, which starts a Volley request to a REST API to retrieve some data, and have a callback which will start a fragment if the data was successfully retrieved. However this only works in portrait mode, in landscape mode, it will throw exception with "Fragment Manager Has Been Destroyed".

I can't seem to find the root of this problem, therefore I can't try any alternative solutions.

This is my onCreate() method of this activity:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRequestedOrientation(SettingsManager.getOrientationSettings(this));
        setContentView(R.layout.activity_settings);

        findViews();
        setListeners();
        getSettings();
    }

goSettings() will retrieve the data, set requested orientation will either be ActivityInfo.SCREEN_ORIENTATION_PORTRAIT or ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE.

My loadFirstPage() method:

  private void loadFirstPage() {
        VMSSettingsPageOneFragment fragment = new VMSSettingsPageOneFragment();
        FragmentManager fm = getSupportFragmentManager();

        fm.beginTransaction()
                .replace(R.id.settings_fragment_container, fragment)
                .commit();
    }

The error message:

E/FileUtils: File Write Exception
    java.lang.IllegalStateException: FragmentManager has been destroyed
        at androidx.fragment.app.FragmentManager.enqueueAction(FragmentManager.java:1853)
        at androidx.fragment.app.BackStackRecord.commitInternal(BackStackRecord.java:321)
        at androidx.fragment.app.BackStackRecord.commit(BackStackRecord.java:286)
        at com.timeteccloud.icomm.platformVMS.settingsActivity.VMSSettingsActivity.loadFirstPage(VMSSettingsActivity.java:87)

Solution

  • You can implement a check before committing the fragment transaction, something as follows.

     public boolean loadFragment(Fragment fragment) {
            //switching fragment
            if (fragment != null) {
                FragmentTransaction transaction = fm.beginTransaction();
                transaction.replace(R.id.main_frame_layout, fragment);
    
                if (!fm.isDestroyed())
                    transaction.commit();
                return true;
            }
            return false;
        }