3

In runOnUiThread() of an Activity, I'm trying to show a ProgressDialog.

 FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
 ProgressDialogFragment mProgressDialogFragment = new ProgressDialogFragment();
 mProgressDialogFragment.show(fragmentTransaction, TAG);

Here ProgressDialogFragment extends DialogFragment. I have tested this in many devices and didn't get any crash. But whereas in Asus, I'm constantly getting the below crash whenever I show the dialog. OS version on Asus is 4.4.2 .

java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
       at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1360)
       at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1378)
       at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:595)
       at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:574)
       at android.support.v4.app.DialogFragment.show(DialogFragment.java:155)
       at com.trimble.android.trimbleone.activity.ProgressDialogHandlerActivity.showProgressDialog(ProgressDialogHandlerActivity.java:72)
       at com.trimble.android.trimbleone.activity.UICallbackHandlerActivity$processThread$7.run(UICallbackHandlerActivity.java:222)
       at android.os.Handler.handleCallback(Handler.java:733)
       at android.os.Handler.dispatchMessage(Handler.java:95)
       at android.os.Looper.loop(Looper.java:149)
       at android.app.ActivityThread.main(ActivityThread.java:5061)
       at java.lang.reflect.Method.invokeNative(Method.java)
       at java.lang.reflect.Method.invoke(Method.java:515)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:788)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:604)
       at dalvik.system.NativeStart.main(NativeStart.java)
Daniel Nugent
  • 43,104
  • 15
  • 109
  • 137
Pavani Reddy
  • 81
  • 1
  • 6
  • which are those many devices? Version of those devices? – Paresh Mayani May 25 '15 at 06:40
  • @PareshMayani Just an FYI, the only reason I edited further was to do a `Reject and Edit` of a questionable edit suggestion after yours. – Daniel Nugent May 25 '15 at 06:50
  • 1
    @DanielNugent no problem! I just formatted the code to understand it perfectly and missed to format other required stuffs! – Paresh Mayani May 25 '15 at 06:51
  • @PareshMayani Nexus, LG G3, Motorola, Those devices are running lollipop verison – Pavani Reddy May 25 '15 at 07:47
  • Possible duplicate of [getting exception "IllegalStateException: Can not perform this action after onSaveInstanceState"](http://stackoverflow.com/questions/7469082/getting-exception-illegalstateexception-can-not-perform-this-action-after-onsa) – rds Nov 19 '15 at 09:57

1 Answers1

6
@Override
protected void onSaveInstanceState(Bundle outState) {
    //No call for super(). Bug on API Level > 11.
}

don't make the call to super() on the saveInstanceState method. This was messing things up...

After some more research, this is a know bug in the support package.

If you need to save the instance, and add something to your outState Bundle you can use the following :

@Override
protected void onSaveInstanceState(Bundle outState) {
    outState.putString("WORKAROUND_FOR_BUG_19917_KEY", "WORKAROUND_FOR_BUG_19917_VALUE");
    super.onSaveInstanceState(outState);
}

In the end the proper solution was (as seen in the comments) to use :

transaction.commitAllowingStateLoss();

when adding or performing the FragmentTransaction that was causing the Exception.

The above solutions were fixing issues in the early support.v4 libraries from what I can remember. But if you still have issues with this you MUST also read @AlexLockwood 's blog : Fragment Transactions & Activity State Loss

Summary from the blog post (but I strongly recommend you to read it) :

NEVER commit() transactions after onPause() on pre-Honeycomb, and onStop() on post-Honeycomb Be careful when committing transactions inside Activity lifecycle methods. Use onCreate(), onResumeFragments() and onPostResume() Avoid performing transactions inside asynchronous callback methods Use commitAllowingStateLoss() only as a last resort
Updated : For showing the DialogFragment using stateLoss use the following lines.

DialogFragment loadingDialog = createDialog();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
                    transaction.add(loadingDialog, "loading");
                    transaction.commitAllowingStateLoss();
Community
  • 1
  • 1
Kartheek
  • 7,104
  • 3
  • 30
  • 44
  • @Override protected void onSaveInstanceState(Bundle outState) { //No call for super(). Bug on API Level > 11. } This method should be added to the class that extends DialogFragment?? – Pavani Reddy May 25 '15 at 07:50
  • after this line mProgressDialogFragment.show(fragmentTransaction, TAG); should I add transaction.commitAllowingStateLoss(); ?? – Pavani Reddy May 25 '15 at 07:53
  • If you want to save the data while changing the configuration then you have call the super method of onSaveInstanceState(). transaction.commitAllowingStateLoss() is the last option for solving this problem. – Kartheek May 25 '15 at 07:57
  • When I add transaction.commitAllowingStateLoss() after mProgressDialogFragment.show(fragmentTransaction, TAG) Im getting the following crash. E/AndroidRuntime﹕ FATAL EXCEPTION: main java.lang.IllegalStateException: commit already called at android.support.v4.app.BackStackRecord.commitInternal(:582) at android.support.v4.app.BackStackRecord.commitAllowingStateLoss(:578) – Pavani Reddy May 25 '15 at 09:18
  • Do not call `dialog.show()` after calling `transaction.commitAllowingStateLoss()`. It basically is the same call. Doing so might give you an error saying something like **Transaction is already committed.** or **Can't change tag of fragment.....** since you might be calling `dialog.show(transaction,"some_new_tag")`. – sud007 Oct 19 '16 at 06:56