7

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)
CodeWithVikas
  • 1,105
  • 9
  • 33
Lee Boon Kong
  • 1,007
  • 1
  • 8
  • 17

3 Answers3

9

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;
    }
Sreekant Shenoy
  • 1,420
  • 14
  • 23
1

maybe you can use parentFragmentManager.beginTransaction() instead of childFragmentManager in code will look like

dialog.show(parentFragmentManager.beginTransaction(), BaseFragment.TAG_DIALOG)
Dharman
  • 30,962
  • 25
  • 85
  • 135
Vanya Rachel
  • 1,329
  • 1
  • 18
  • 20
-1

Hi you can just use it like this way

declare a handler

Handler handler = new Handler()

and Then put commit in to post delayed of handler

// this is a hack to fix fragment has been destroyed issue do not put Transaction.replace
        // into handler post delayed
        handler.postDelayed({
            // transaction.addToBackStack(null)
            transaction.commit()
        },500)

Do not place other things in post delayed ie. adding fragment to transaction (or replace transaction.replace(fragment,containerid,tag))

Kiran Benny Joseph
  • 6,755
  • 4
  • 38
  • 57