问题
I'm getting the above error when calling finish() and then re-opening the app. Here's the code that manages navigation onBackPressed().
android.app.FragmentManager settingsFragmentManager = getFragmentManager();
FragmentManager fragmentManager = getSupportFragmentManager();
if (settingsFragmentManager.getBackStackEntryCount() > 0)
settingsFragmentManager.popBackStackImmediate();
else if (fragmentManager.getBackStackEntryCount() > 0)
fragmentManager.popBackStackImmediate();
if (fragmentManager.getBackStackEntryCount() == 0 && endIfEmpty) finish();
if (fragmentManager.getBackStackEntryCount() == 0 && !endIfEmpty) loadView(0);
if (fragmentManager.getBackStackEntryCount() == 0 && !userHasLoggedIn)
{
LocalBroadcastManager.getInstance(getApplicationContext()).unregisterReceiver(loginBroadcastReceiver);
finish();
}
The method loadView calls is in charge of adding a fragment, based on what the user selected. When it is invoked with 0 as argument, it adds the default fragment.
This the method:
private void loadView(int position)
{
FragmentManager fragmentManager = getSupportFragmentManager();
Bundle fragmentArgs = new Bundle();
if (drawerOpened)
mDrawerLayout.closeDrawer(drawerHolderLayout);
switch (position) {
case 0:
ProfileEditFragment activityList = new ProfileEditFragment();
fragmentArgs.clear();
fragmentArgs.putString(ProfileEditFragment.ARG_AGENT_ID, String.valueOf(prefClass.getAgentId()));
fragmentArgs.putString(ProfileEditFragment.ARG_USERNAME, prefClass.getUsername());
fragmentArgs.putString(ProfileEditFragment.ARG_PASSWORD, prefClass.getHashedPassword());
fragmentArgs.putInt(ProfileEditFragment.ARG_OPERATION, ProfileEditFragment.LOAD_ALL_DATA);
activityList.setArguments(fragmentArgs);
fragmentManager.beginTransaction().add(R.id.main_activity_content, activityList).addToBackStack(null).commit();
//activityList.retrieveActivityFromServer(ProfileEditFragment.LOAD_ALL_DATA);
break;
}
}
The exception occurrs when this line is executed:
fragmentManager.beginTransaction().add(R.id.main_activity_content, activityList).addToBackStack(null).commit();
However, this exception does not occurr when the app is launched for the FIRST TIME. It only appears when it is re-launched after a call to finish(). It is worth mentioning that the first fragment added is a LoginFragment. Once the login process is done, popBackstack is invoked, the backstack becomes empty and loadView(0) is called. So, why does it crash with the exception when the loadView is called but doesn't when LoginFragment is added?
Thanks in advance.
回答1:
In my case I opened a DialogFragment after an application moved to a background.
You can emulate this state this way: open a request, run Thread.sleep(2000)
, quickly press "Power off" on smartphone (or press "Menu" button), then "Power on" (or open the application). If a request brings error and DialogFragment shows, it will write in log: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
, corresponding line is dialogFragment.show(supportFragmentManager, TAG)
.
I tried a solution https://stackoverflow.com/a/22414366/2914140, it works fine, but contains this bug. So, add one more check:
if (supportFragmentManager?.isStateSaved == false) {
dialogFragment.show(supportFragmentManager, TAG)
}
In this case after turning off a screen and turning on you simply won't see this dialog (sad to say), but your application won't crash.
UPDATE
Sorry, the old answer is outdated. See On showing dialog i get "Can not perform this action after onSaveInstanceState".
public class CustomDialogFragment extends DialogFragment {
@Override
public void show(FragmentManager manager, String tag) {
try {
FragmentTransaction ft = manager.beginTransaction();
ft.add(this, tag);
ft.commit();
} catch (IllegalStateException e) {
}
}
}
In this case the dialog fragment will be shown.
回答2:
Are you sure the Fragment commit is occurring on the Activity instance that you think it is?
I'm not sure if my situation applies to you, but I did have similar symptoms in that I'd only see the exception after stopping and restarting an Activity. I also found that Alex Lockwood's (very excellent) article on the subject didn't seem to help me, just like you mentioned in the comments.
Anyway I eventually realized I caused this exception by initializing a long-living object (a Facebook session object in my case) and providing it a reference to the Activity for callbacks. I'd only initialize the session object if Session.getActiveSession() indicated that a session was unavailable. This meant that the second time I started the Activity, the session from the previous Activity would be used, along with its callback that points to the previous Activity. The previous Activity had since been destroyed and had its onSaveInstanceState. When the callback was triggered, the old Activity would try to get its Fragment on, and boom, the exception occurred. I had been wracking my brain trying to figure out why I was getting this exception when the new Activity was in a valid state for a Fragment commit, but all along I was trying to commit a Fragment to an old, since-destroyed Activity.
You might not be using Facebook sessions per se, but perhaps you're doing something similar with a long-living object?
Good luck!
来源:https://stackoverflow.com/questions/28288311/android-java-lang-illegalstateexception-cannot-perform-this-action-after-onsa