I have an Activity that shows different kinds of Dialog; some are AlertDialog that can only be dismissed by the user others are ProgressDialog that monitor an AsyncTask and some are CustomDialog.
My question is what happens if Android decide to destroy my Activity and one of these dialog is shown? (I have nothing in onDestroy that dismiss the dialog because there are too many and in different classes.) Will the Dialog gets dismissed or I end up with a crash?
Related
I have asynctask running, when finish, I dismiss the progressDialog and call AlertDialog accordingly:
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Test")
.setCancelable(false)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
});
AlertDialog alert = builder.create();
alert.show();
Standy on app
Standby on app
Asynctask on going
Asynctask is finished, progressDialog is dismissed
(Still standby on app) AlertDialog appears as it should be
Home screen
Asynctask on going
Go to home screen
Asynctask is finished, progressDialog is dismissed
AlertDialog is called to show
Goes back to app, but alertdialog doesn't appear, it gives me greyed screen instead.
Is there any way to solve this? I tried to search it but couldn't find someone has same issue..
Ok. (As from your comments).
You can not have your dialog automatically appear while your app is in the background. The dialog is displayed within the context of your Activity(along with its window manager), if the activity is not displayed, nor is your dialog.
To display content while your activity is in the background you have a few options, non of which will be straight forward though.
Attach views directly to Android's WindowManager. This will not work with a dialog, you would have to construct a dialog layout and manually attach it, it would remain foreground above everything else.
Launch your dialog from a transparent activity. Problem here is if you are say on your homescreen then the transparent activity/dialog launches and you then call you application the transparent activity/dialog will be dismissed into the background.
Launch an activity with a dialog theme. This "may" work as needed, if you call your main application keeping the stack correct. Would have to test to be sure.
According to the Android Design Guide you should show a Notification instead of the AlertDialog when your AsyncTask has finished and the Activity is in background (paused). To decide what you should show, maintain a boolean variable in your Activity. Set the variable to true inActivity.onResume() and false in Activity.onPaused().
Basically you implement onPostExecute in your AsyncTask. In there you make the ProgressBar invisible and show the Alert Dialog with the code you show in your question.
More about AsyncTask is here
More about Notifications is here
The Design Guide in question is here. Scroll down to 'Sending Notifications to the User'. Essentially, what you do with the AsyncTask in background is like running a Service. At least from the user experience standpoint. Differences between your approach and a Service are internal, e.g. Android will kill your process when it needs space differently.
In my app I have several activities one after the other. After my login screen I have Home screen and after that several screens. Now When user select device home button or power off button I want to display login screen when user again comes to my app and then Home screen. Rest all activity I am finishing it from my base class. Now till here I have done, My problem is when I show a dialog in some other activity and at that instance if user click on home or power button, then i am getting WINDOW LEAKED EXCEPTION.
Like I have TempActivity is displaying a dialog and user clicked home button so StoreActivity and TempActivity will finish but Dialog never got chance to be dismissed. So What would be the best way to deal with this situation.
Is there some better way to dismiss the dialog so that I don't get any exception.
Override onDestroy, there, check whether the dialog is present, if so, dismiss it.
dismiss() in onDestroy() doesn't solve this problem. Try to override activity.finish() like:
#Override
public void finish() {
if(mDialog != null) {
mDialog.dismiss();
}
super.finish();
}
Put the Dialog handle in a member object, then when you finish the top activities, dismiss the dialog first.
You could make this more neat by creating abstract Activity class (which all your activities extends), which dismisses possible dialog when calling finish()
In my application I want to handle the state if my displayed dialog looses focus(e.g. if my dialog is show and any system dialog(like low battery dialog or Power button dialog) appears on top of that).
Is there any way to capture this scenario? I did not find any method for dialog having onWindowFocusChanged method.
My activity's onWindowFocusChanged does not work here.
If you use a DialogFragment when the activity goes to the background (or something comes in foreground of your app) the dialog onPause will be called, then upon returning to your app/activity/dialog, the onResume will be called.
Always use DialogFragment, the Activity dialog lifecycle methods are depreciated for a reason.
Examples of how to use DialogFragment can be found in the docs here.
I have a customDialog with input fields. I want possible entries to be removed once the dialog is closed (either via back or when a certain button is pressed), i.e. the state should not be saved.
How can I do that?
If the back button is pressed means that dialog is canceled. Implement DialogInterface.OnCancelListener for your dialog and empty/delete/null the entries you want.
I think you might be getting another problem.
Say that you have shown a dialog which was dismissed. If the same dialog is going to be shown a second time, it won't be rebuilt. It will just be shown again.
This means that if you setup your dialog in the onCreateDialog method, the second time that the dialog is shown, this method isn't invoked! Instead, onPrepareDialog is invoked.
Alternatives? You can call Activity.removeDialog or take care of the setup process in the onPrepareDialog hook.
I write a program support download file. When in this download activity, I start a progress bar and then run a thread to do the download things. This thread send message to UI thread to notify how many has been downloaded frequently. In the main(UI) thread, I update the progress bar display when receive the message. If any problem happen in download progress, it will send another message. When main thread receive the message, it stop the progress bar and pop up a new AlertDialog to show the error reason.
Here is a special test for it. When downloading, switch the program to settings. Turn off the WIFI/GPRS to make the network off.
When I back to my program, it should display the background ui and a pop up AlertDialog to show the reason as I wish. But it only display the background ui(which means the main activity) and with a half-light of backlight just as the popup windows still there. When I press back for first time, nothing happens except the backlight is bright just like I have close a pop up window.
I think maybe it is because when I start the AlertDialog my activity is not in foreground.
I tried to use:
ActivityManager am = (ActivityManager)Update.this.getSystemService(Context.ACTIVITY_SERVICE);
ComponentName cn = am.getRunningTasks(1).get(0).topActivity;
to judge whether the top activity is mine. But I want to show the dialog. If the activity isn't being seen by the user, when he gets back to my activity, I want it to show the dialog.
Indeed the dialog already shown but not visible to the user and it would become visible if you rotate the device.
There seemed a refresh/drawing issue if dismiss a progress dialog and show another new dialog immediately when the activity is not in foreground.
During my testing, such issue not happen if wait for the dismiss action finished for the progress dialog and then show the new dialog.
So one solution is that show the AlertDialog first and then dismiss the ProgressDialog. That worked for my application.
I think, there is some king of bug in Dialog. I have the same situation, and only solution was dismiss curent dialog by dialogDismiss(id) and show it again by showDialog(id).