In my app I use DialogFragments.
Some times, i am getting
Fragment already added IllegalStateException
and the app crashes. These crashes seen on crashlytics.
This problem seems to happen when trying to show the same dialog fragment twice before the first instance dismissed.
This issue already discussed many times like here or here but the problem is, that it's not constant behavior on all devices.
I couldn't reproduce this problem on my desk.
Even when I try to show the same dialog twice, I am not getting this exception.
I even used fragment.isAdded() to make sure that it is shown, and then show it again. Just to catch the error of course. but no success.
Any Idea?
I can add fragment.isAdded() condition before showing the dialog to prevent this, but I want to understand the root cause of this. I am concerned that I cannot reproduce this.
Here is a portion of my code to show the dialog:
MyDialog extends DialogFragment
MyDialog dialog = (MyDialog) getSupportFragmentManager().findFragmentByTag(MyDialog.TAG);
if(dialog == null) { //create and show the dialog
dialog = new MyDialog();
dialog.setCancelable(false);
}
dialog.show(getSupportFragmentManager(), MyDialog.TAG);
I think I've found the problem.
First, using dialog.isAdded() helped here..
But the issue here was related to instanceState of the app.
As I said, this error not happen on all devices or users, so it was hard to catch.
First, My app is configured to be portrait only.
When the dialog opens, if the user navigates to some other app from some reason (e.g a phone call or other app) which in turn causes the my app to go into onStop and also that other app causing configuration change.
For instance, when the dialog opens, press the home button and go to phone settings and change the language, this will cause configuration change a the app will be recreated when navigating back to it.
When the user navigate back to my app, it killed by the system and it tries to recreate the stack and onSaveInstanceState is not null, the dialog is already in the stack and my app tries to show it again.
This kills the app.
Related
I am developing a small app which shows passwords of the user through a Dialog screen.
When home button is pressed, I need to dim the screen (on the multi tasking window) so that any other person cannot see the password.
When user re-opens the app, it asks an application lock. But if the user leaves the password Dialog open and presses the home button, dialog and the password which user last looked at stays visible (on the multi tasking window) for a while (3-4 seconds!!) until a new dialog asks the lock.
So far I tried ever possible dialog.dissmiss() options. Dialog dismisses only when app is opened again (until a new lock dialog appears) even I put dismiss() in onPause, onStop etc.
Any idea appreciated.
I also tried,
android.os.Process.killProcess(android.os.Process.myPid());
this.finish();
System.exit(0);
none of them actually worked.
Suggestion 1: Double-check your implementation. Tying your dialog to the activity lifecycle seems like a good idea (especially to avoid leaked window errors as described here)
The following example works out well for me (with coachMark being derived from Dialog)
#Override
protected void onResume()
{
log.debug("onResume");
super.onResume();
// Show the coachMark depending on saved preference values
coachMark.mayBeShow();
}
#Override
protected void onPause()
{
log.debug("onPause");
// Hide the coachMark if it is showing to avoid leakedWindow errors
coachMark.maybeHide();
super.onPause();
}
onPause definately gets called when you press the home button, so if this approach does not work for you, try not recreating the dialog in the restarting part of the acitivty lifecycle (onRestart(), onStart() and onResume()) and see, if it gets dismissed correctly.
Suggestion 2: Should all of the above fail, you might consider overriding the home button as described here. I highly advise against it though, since this may cause the app to work in an way that the user does not expect it to.
I have an AlertDialog appear whenever I find that the device location has changed. This happens pretty much at anytime the application sees fit.
The problem is that if the dialog appears just before a new Activity is started the dialog disappears with the old Activity. Is there anyway to have the AlertDialog block new Intents? Or translate over to the new Activity (could I update the Context)?
I noticed that AlertDialogs don't even handle the case where the device rotates, so my hope for this isn't too high, but any input would help.
I would simply use a SharedPreference setting and check it whenever your potentially interruptive Activity starts.
Ex;
set shared preference value to 1
start dialogue
when finished, save the shared preference to 0
if activity starts and shared preference is 1, it interrupted so start an alert dialogue. if it is 0, move on.
Again, an AlertDialog is meant to attach itself to an activity, so you really can't stop it from dieing, if your previous activity is pushed back or loses focus of the screen (ui thread basically put on hold!)
Hope you can fix your problem with this minor fixup.
To add what Daniel commented, Custom toasts can be awesome. They are, however, limited to about 3.5 seconds (I think)
More on Custom Toasts; http://developer.android.com/guide/topics/ui/notifiers/toasts.html#CustomToastView
Your question is not clear for me,As I understood you need to show a Alertdialog whenever the device location is changed that too above a new activity.My suggestion is that when ever the device location changes get the need values,bundle it with the intent and pass it starting a new activity.With the bundle also pass a boolean flag.If the boolean flag is true in the new activity show a Alertdialog box in onCreate,I hope you will get what you wanted.This will be the best scenario for you to do this as I understood.Also keeping the history of these activity's may affect the app while implementing this.
I'm just not getting why this is happening:
Successfully create dialog and instantiate it when user clicks on an item. Zero problems getting dialog to show when desired and to go away when back is pressed....
The problem is:
If the dialog is still displaying when the application/activity goes away (pause, die), when it returns, the dialog is still presented but no variables which are context specific are presented. Note: I do issue removeDialog() for the dialog in the onPause(). Yet mystically when the app returns, it's somehow cycled thru onPrepareDialog() and loaded up with missing variables (xml names show).
What I want is for the dialog to go away and let the user make a different choice from the main activity and then redisplay the dialog - if that's what they want. Or said another way - I want dialog to always go away if the app goes away.
I've looked into persisting the data but there doesn't seem to be a "right" spot in the restore process to do that (or I'm just ignorant). I can't figure out why onPrepareDialog is getting invoked during onResume()....
Hi my app has 3 activities one of which is a dialog. I've done this by using this code in the AndroidManifest.xml
android:theme="#android:style/Theme.Dialog"
the application also has a service which can open the dialog even if the application is not visible, however when it does this it also opens one of the other activities in the background. Is there a way to stop this happening so it opens the dialog in front of the current activity (even if the activity is from a different application)?
Thanks,
ng93
I solved this by adding:
android:taskAffinity=".MyDialog"
to my dialog in the AndroidManifest.xml. Then it is not related to your other tasks and can be shown without bringing up the suspended activity.
You're not able to display something in front of another application's activity. "in front" is somewhat ambiguous, so I'll clarify in that your application can't simultaneously share the screen with another application.
The way I understand it, Android's design inherently requires that when you're doing something on-screen, your app's process/task is in the foreground and in focus, thus bringing the other activities for that task into focus. This implies that other applications are not running with UI focus while your application is in focus.
This means that, for example, when your app launches an activity, it brings your app's stack of activities into focus and puts the new activity (in this case, your dialog box) on top of your app's stack. The result is that if you hit 'back' while displaying the dialog, you'll go back to the activity that was previously displayed. If the stack is cleared of previous activities, 'back' will take you to the application that was previously being displayed on screen.
There are ways of clearing the stack such as: http://developer.android.com/reference/android/content/Intent.html#FLAG_ACTIVITY_CLEAR_TOP
Depending on your scenario you might want to clear the stack, or you might "exit" the app when the user closes the dialog. Additionally, the dialog activity could override onBackPressed so that if the user hits 'back' the activity "exits" your app, returning the user to what they were doing before the dialog.
Further reading for activities and stacks: http://developer.android.com/guide/topics/fundamentals.html#acttask
i ended up closing all my apps activities before opening the dialog activity, not ideal but seems like the only way to get the functionality im after
I have an android application having an AlertDialog with OK and Cancel buttons. When the dialog shows without pressing the OK or Cancel button, just press Home button of device. The Home screen will show. Now open another application suppose Camera. Take some picture or Video. Now get out from the Camera application. Now open my android application and surprisingly the alertdialog have disappeared. Why?
I'm guessing you are creating this AlertDialog onCreate() method.
First, you should read up on the Activity Lifecycle.
And what happens is that when you go to another app, the Activity goes to onPause method, which cleans up a bit.
Called when the system is about to start resuming a previous activity. This is typically used to commit unsaved changes to persistent data, stop animations and other things that may be consuming CPU, etc. Implementations of this method must be very quick because the next activity will not be resumed until this method returns.
Then because you return to the app, it calls the onResume method, which doesn't create your dialog again.
If you want to show dialog on startup of application then write this code in
onResume()
method, it will show dialog every time when user returns to this screen.
Or you can manage its state in
onPause()