Obsolete
Status Update
Comments
da...@gmail.com <da...@gmail.com> #2
I have the same sort of problem. When an activity is paused when running on honeycomb the mStateSaved flag is set when the instance state is saved. While this flag is set any attempt to show a dialog fragment will fail with the exception noted. It should be possible for an activity being resumed to show a dialog fragment in its onResume(), however if that activity is never stopped then the activity's onResume() will be invoked before the FragmentManager clears the mStateSaved flag (this happens when the fragments are resumed during the activity's onPostResume()) thus resulting in the exception. I suspect you could work around this by moving the code that shows the dialog into your activity's onPostResume() method. Just be sure to call through to super.onPostResume() before showing your dialog fragment.
ma...@gmail.com <ma...@gmail.com> #3
Thanks Danita, your suggestion worked perfectly for my application. However I think Google should change the behaviour of FragmentActivity as:
1. The behaviour of native ICS Activity is different from that of FragmentActivity, even if the FragmentActivity is being started in ICS.
2. The documentation of onPostResume() says "Applications will generally not implement this method", and onPostResume() is not documented in the activity lifecycle.
Thanks again for your help.
1. The behaviour of native ICS Activity is different from that of FragmentActivity, even if the FragmentActivity is being started in ICS.
2. The documentation of onPostResume() says "Applications will generally not implement this method", and onPostResume() is not documented in the activity lifecycle.
Thanks again for your help.
fl...@gmail.com <fl...@gmail.com> #4
I was having the same issue. Danita's suggestion made it work. =)
jm...@android.com <jm...@android.com> #5
I was running into this issue as well and talked with hackbod about this, naturally she had a solution.
The root of the problem is that for cross-platform compatibility reasons FragmentManager sometimes needs to delay restarting its fragments. Happily there is a simple and reliable workaround.
Attach a Fragment (probably a one just for this purpose and probably a non-UI one) to FragmentManager. When that Fragment receives onResume your app will known its okay to proceed with activities like the one here that is resulting in a crash.
The root of the problem is that for cross-platform compatibility reasons FragmentManager sometimes needs to delay restarting its fragments. Happily there is a simple and reliable workaround.
Attach a Fragment (probably a one just for this purpose and probably a non-UI one) to FragmentManager. When that Fragment receives onResume your app will known its okay to proceed with activities like the one here that is resulting in a crash.
mu...@gmail.com <mu...@gmail.com> #6
Thanks for the reliable workaround!
Here's my empty fragment if someone needs, to use it:
- add this fragment in your activity,
- implement the listener in your activity.
The listener will be called each time the fragment pass onResume.
public class EmptyFragmentWithCallbackOnResume extends Fragment {
OnFragmentAttachedListener mListener = null;
@Override
public void onAttach(SupportActivity activity) {
super.onAttach(activity);
try {
mListener = (OnFragmentAttachedListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement OnFragmentAttachedListener");
}
}
@Override
public void onResume() {
super.onResume();
if (mListener != null) {
mListener.OnFragmentAttached();
}
}
public interface OnFragmentAttachedListener {
public void OnFragmentAttached();
}
}
Here's my empty fragment if someone needs, to use it:
- add this fragment in your activity,
- implement the listener in your activity.
The listener will be called each time the fragment pass onResume.
public class EmptyFragmentWithCallbackOnResume extends Fragment {
OnFragmentAttachedListener mListener = null;
@Override
public void onAttach(SupportActivity activity) {
super.onAttach(activity);
try {
mListener = (OnFragmentAttachedListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement OnFragmentAttachedListener");
}
}
@Override
public void onResume() {
super.onResume();
if (mListener != null) {
mListener.OnFragmentAttached();
}
}
public interface OnFragmentAttachedListener {
public void OnFragmentAttached();
}
}
co...@gmail.com <co...@gmail.com> #7
I have been hunting to this post for months. Thank you, the onPostResume() and using some Boolean got my app back on track.
co...@gmail.com <co...@gmail.com> #8
When the fragment is being created from inside a handler's handleMessage function, I still see this behavior. Is that intended?
ad...@gmail.com <ad...@gmail.com> #9
thanks for your workaround. sometimes working with fragments seems like walking on eggs
je...@gmail.com <je...@gmail.com> #10
here's an easy, though inelegant solution,
public abstract class CommitSafeDialogFragment extends DialogFragment {
@Override
public int show(FragmentTransaction transaction, String tag) {
try {
return super.show(transaction, tag);
} catch (IllegalStateException e) {
// ignore
}
return -1;
}
@Override
public void show(FragmentManager manager, String tag) {
try {
super.show(manager, tag);
} catch (IllegalStateException e) {
// ignore
}
}
public abstract class CommitSafeDialogFragment extends DialogFragment {
@Override
public int show(FragmentTransaction transaction, String tag) {
try {
return super.show(transaction, tag);
} catch (IllegalStateException e) {
// ignore
}
return -1;
}
@Override
public void show(FragmentManager manager, String tag) {
try {
super.show(manager, tag);
} catch (IllegalStateException e) {
// ignore
}
}
ma...@gmail.com <ma...@gmail.com> #11
overriding onPostResume() seems like the best workaround so far...
jo...@gmail.com <jo...@gmail.com> #12
Is the onPostResume method override in the fragment or Activity?
jo...@gmail.com <jo...@gmail.com> #13
I currently have a fragment that calls another dialogfragment with ok/no buttons. The ok button will call a progressdialogfragment. It seems that if i call the first dialog and then rotate the screen and press the ok button i get this error in the line where it calls the second fragment(progressdialogfragment). Any solution for this?
ar...@gmail.com <ar...@gmail.com> #14
For the first time i've seen this error. The problem is not triggered in onResume() but in onCreate() because I show dialogfragment only once in fact of previous activities so I can't do it in onPostResume(). Is there another solutino ?
jn...@gmail.com <jn...@gmail.com> #15
hi,
i'm getting the error in onDestroy(). i'm displaying an AlertDialog to see if user wants to save db changes.
john
i'm getting the error in onDestroy(). i'm displaying an AlertDialog to see if user wants to save db changes.
john
ke...@gmail.com <ke...@gmail.com> #16
i am try this : tx.commitAllowingStateLoss(); and it is ok
/*
FragmentTransaction tx = getSupportFragmentManager().beginTransaction();
tx.replace(R.id.main, Fragment.instantiate(mystyle, str));
tx.commitAllowingStateLoss();
*/
/*
FragmentTransaction tx = getSupportFragmentManager().beginTransaction();
tx.replace(R.id.main, Fragment.instantiate(mystyle, str));
tx.commitAllowingStateLoss();
*/
ms...@gmail.com <ms...@gmail.com> #17
Using commitAllowingStateLoss can have unwanted siteeffects.
Seehttp://stackoverflow.com/questions/17184653/commitallowingstateloss-in-fragment-activities for more information on that.
Therefore onPostResume should be the better solution (or empty fragment).
See
Therefore onPostResume should be the better solution (or empty fragment).
sk...@gmail.com <sk...@gmail.com> #18
onPostResume is not working for me - I still get the error:
java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
when creating a DialogFragment inside that function. Does anybody else have a solution that works?
I've tested on Android 4.0 and 4.4, neither works.
java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
when creating a DialogFragment inside that function. Does anybody else have a solution that works?
I've tested on Android 4.0 and 4.4, neither works.
en...@google.com <en...@google.com>
[Deleted User] <[Deleted User]> #19
I found that for FragmentActivity we should Override onResumeFragments() instead of OnPostResume. In this case it works for me.
Finally:
1) You should override OnPostResume, if you extends Activity (for API 11+).
2) You should override onResumeFragments, if you extends FragmentActivity.
Finally:
1) You should override OnPostResume, if you extends Activity (for API 11+).
2) You should override onResumeFragments, if you extends FragmentActivity.
Description
In my application I want to display a dialog no matter which activity the user is in, therefore I created a FragmentActivity (let's call it AlarmActivity) with launchMode = singleTask and taskAffinity different from the main application. Then AlarmActivity will create a DialogFragment to display a dialog. AlarmActivity is started at specific time using AlarmManager.
Moreover, I want my dialog to pop up even if the device is sleeping, so I have used the following code:
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
My code worked perfectly in 2.x emulators and Nexus One running on 2.3.6, however my application crashed in the following situations, when I tested on Android 4.0 emulator and Galaxy Nexus:
case 1:
When the device is sleeping, AlarmActivity successfully wakes up the device, however the dialog cannot be displayed. The following error messages are found in LogCat:
12-18 23:57:01.005: E/AndroidRuntime(4267): FATAL EXCEPTION: main
12-18 23:57:01.005: E/AndroidRuntime(4267): java.lang.RuntimeException: Unable to resume activity {com.mydomain.myapp/com.mydomain.myapp.AlarmActivity}: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
12-18 23:57:01.005: E/AndroidRuntime(4267): at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2443)
12-18 23:57:01.005: E/AndroidRuntime(4267): at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2471)
12-18 23:57:01.005: E/AndroidRuntime(4267): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1172)
12-18 23:57:01.005: E/AndroidRuntime(4267): at android.os.Handler.dispatchMessage(Handler.java:99)
12-18 23:57:01.005: E/AndroidRuntime(4267): at android.os.Looper.loop(Looper.java:137)
12-18 23:57:01.005: E/AndroidRuntime(4267): at android.app.ActivityThread.main(ActivityThread.java:4340)
12-18 23:57:01.005: E/AndroidRuntime(4267): at java.lang.reflect.Method.invokeNative(Native Method)
12-18 23:57:01.005: E/AndroidRuntime(4267): at java.lang.reflect.Method.invoke(Method.java:511)
12-18 23:57:01.005: E/AndroidRuntime(4267): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
12-18 23:57:01.005: E/AndroidRuntime(4267): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
12-18 23:57:01.005: E/AndroidRuntime(4267): at dalvik.system.NativeStart.main(Native Method)
12-18 23:57:01.005: E/AndroidRuntime(4267): Caused by: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
12-18 23:57:01.005: E/AndroidRuntime(4267): at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1299)
12-18 23:57:01.005: E/AndroidRuntime(4267): at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1310)
12-18 23:57:01.005: E/AndroidRuntime(4267): at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:541)
12-18 23:57:01.005: E/AndroidRuntime(4267): at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:525)
12-18 23:57:01.005: E/AndroidRuntime(4267): at android.support.v4.app.DialogFragment.show(DialogFragment.java:123)
12-18 23:57:01.005: E/AndroidRuntime(4267): at com.mydomain.myapp.AlarmActivity.showAlarm(AlarmActivity.java:357)
12-18 23:57:01.005: E/AndroidRuntime(4267): at com.mydomain.myapp.AlarmActivity.onResume(AlarmActivity.java:241)
12-18 23:57:01.005: E/AndroidRuntime(4267): at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1154)
12-18 23:57:01.005: E/AndroidRuntime(4267): at android.app.Activity.performResume(Activity.java:4539)
12-18 23:57:01.005: E/AndroidRuntime(4267): at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2433)
12-18 23:57:01.005: E/AndroidRuntime(4267): ... 10 more
I added some debug code and found the activity life cycle callbacks of AlarmActivity are called in the following sequence:
AlarmActivity onCreate
AlarmActivity onStart
AlarmActivity onResume
AlarmActivity onsaveInstanceState
AlarmActivity onResume
(Then the application crashed)
case 2:
I have another Activity (let's call it MainActivity) which load some data from database and then display the data to user. I want to reload the data every time MainActivity become visible to user (e.g after user select the activity from the recent application list, or when another Activity is started by MainActivity, then user return to MainActivity by pressing the back button). A dialog is displayed to let user know some time consuming I/O is in progress, so that he/she will be patient. I used the following code in onResume():
@Override
protected void onResume() {
super.onResume();
showLoadingAlarmListDialog(); // create and display dialog
(new LoadAlarmListThread()).start(); // create thread to load data from database
}
When AlarmActivity pops up when user is at MainActivity, the dialog in AlarmActivity is displayed correctly. However after AlarmActivity is finished, MainActivity crashed when it try to display the dialog to tell user DB I/O is in progress.
The following error messages are found in LogCat:
12-19 00:45:18.745: E/AndroidRuntime(6211): FATAL EXCEPTION: main
12-19 00:45:18.745: E/AndroidRuntime(6211): java.lang.RuntimeException: Unable to resume activity {com.mydomain.myapp/com.mydomain.myapp.MainActivity}: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
12-19 00:45:18.745: E/AndroidRuntime(6211): at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2443)
12-19 00:45:18.745: E/AndroidRuntime(6211): at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2471)
12-19 00:45:18.745: E/AndroidRuntime(6211): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1172)
12-19 00:45:18.745: E/AndroidRuntime(6211): at android.os.Handler.dispatchMessage(Handler.java:99)
12-19 00:45:18.745: E/AndroidRuntime(6211): at android.os.Looper.loop(Looper.java:137)
12-19 00:45:18.745: E/AndroidRuntime(6211): at android.app.ActivityThread.main(ActivityThread.java:4340)
12-19 00:45:18.745: E/AndroidRuntime(6211): at java.lang.reflect.Method.invokeNative(Native Method)
12-19 00:45:18.745: E/AndroidRuntime(6211): at java.lang.reflect.Method.invoke(Method.java:511)
12-19 00:45:18.745: E/AndroidRuntime(6211): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
12-19 00:45:18.745: E/AndroidRuntime(6211): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
12-19 00:45:18.745: E/AndroidRuntime(6211): at dalvik.system.NativeStart.main(Native Method)
12-19 00:45:18.745: E/AndroidRuntime(6211): Caused by: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
12-19 00:45:18.745: E/AndroidRuntime(6211): at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1299)
12-19 00:45:18.745: E/AndroidRuntime(6211): at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1310)
12-19 00:45:18.745: E/AndroidRuntime(6211): at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:541)
12-19 00:45:18.745: E/AndroidRuntime(6211): at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:525)
12-19 00:45:18.745: E/AndroidRuntime(6211): at android.support.v4.app.DialogFragment.show(DialogFragment.java:123)
12-19 00:45:18.745: E/AndroidRuntime(6211): at com.mydomain.myapp.MainActivity.showLoadingAlarmListDialog(MainActivity.java:324)
12-19 00:45:18.745: E/AndroidRuntime(6211): at com.mydomain.myapp.MainActivity.onResume(MainActivity.java:253)
12-19 00:45:18.745: E/AndroidRuntime(6211): at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1154)
12-19 00:45:18.745: E/AndroidRuntime(6211): at android.app.Activity.performResume(Activity.java:4539)
12-19 00:45:18.745: E/AndroidRuntime(6211): at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2433)
12-19 00:45:18.745: E/AndroidRuntime(6211): ... 10 more
The following is the call sequence of activity life cycle callbacks:
MainActivity onCreate
MainActivity onStart
MainActivity onResume
(another activity is started from MainActivity)
MainActivity onSaveInstanceState
(user pressed back button)
MainActivity onStart
MainActivity onResume
(PendingIntent fired by AlarmManager)
MainActivity onSaveInstanceState
AlarmActivity onCreate
AlarmActivity onStart
AlarmActivity onResume
(AlarmActivity is finished)
MainActivity onResume
(MainActivity crashed)
Everything worked again if I do not use the support package, i.e. remove the support package from build path, set the build target to Android 4.0 and replace FragmentActivity with Activity and every getSupportFragmentManager() call with getFragmentManager(). However my apps will no worker be compatible with older version of Android.
Again, I have catpured the call sequence of activity life cycle callbacks:
For case 1:
AlarmActivity onCreate
AlarmActivity onStart
AlarmActivity onResume
AlarmActivity onSaveInstanceState
AlarmActivity onResume
For case 2:
MainActivity onCreate
MainActivity onStart
MainActivity onResume
(another activity is started from MainActivity)
MainActivity onSaveInstanceState
(user pressed back button)
MainActivity onStart
MainActivity onResume
(PendingIntent fired by AlarmManager)
MainActivity onSaveInstanceState
AlarmActivity onCreate
AlarmActivity onStart
(AlarmActivity is finished)
AlarmActivity onResume
MainActivity onResume
The call sequence is just the same as if the support package is used, so I think there may be some problem with the support package.