Prevent onCreateDialog being called when process is killed then relaunched - android

I have an Activity with ProgressDialog being updated by an AsyncTask. I am using onCreateDialog to setup the dialog. The AsyncTask is writing to the SDCard. During normal scenarious (rotation, going to background, etc.) I have no issues.
The problem is that the dialog gets recreated if the process gets killed. Thus, I end up with a "newly" opened activity and a dialog that is not supposed to be shown at all because there is no AsyncTask set up to update it.
For example in case when SD card gets ejecter then the Reaper comes and kills the process (no onDestroy, noPause, noResume has been called by the framework). When, however, the application is resumed (for example from the recently used applications) there is no clue that there is no AsyncTask and I am forced to show the dialog. I cannot return null in onCreateDialog, because the app will crash.
How can I prevent a dialog to be recreated after the process is killed?
Example:
- Activity gets shown
- onCreateDialog/onPrepareDialog show a progress dialog
- AsyncTask gets started exporting to SD card
=> SD card gets unmounted
- Process is killed
- User selects the application from task switched
- Activity gets created as new
=> Android calls onCreateDialog/onPrepareDialog with the previously shown dialog ID
By the time the activity is recreated as new there is no AsyncTask, there is even no SD card. Still, Android insist that I show a dialog.
How can I prevent onCreate/PrepareDialog methods to be called during the recreate? Or the only choice is to bring up an error dialog instead.

you can make check over SD card if it is inserted or ejected thru
String state = Environment.getExternalStorageState();
and over it's return value you can control your dialog...

OnCreateDialog method is like onCreate method which will be called only once in your activity. You cannot control your dialog using this method. Instead your activity should also have the following piece of code which will be called each time Dialog is shown. So you have to handle things inside this method instead.
#Override
protected void onPrepareDialog(int id, Dialog dialog) {
super.onPrepareDialog(id, dialog);
}

Related

Force method to run *after* AlertDialog

I'm calling an AlertDialog that exists in a different class. Directly after, I use a callback method to refresh the view. However, it appears the dialog runs on a separate thread, because the callback method gets called before the user makes a choice in the AlertDialog, instead of after.
How do I make sure the callback method is only called after the user has made a choice?
mClientManager.deleteClientConfirmationDialog ( getActivity (), id );
mCallback.refresh ();
However, it appears the dialog runs on a separate thread
No, it does not.
because the callback method gets called before the user makes a choice in the AlertDialog, instead of after
The dialog is not being shown until well after deleteClientConfirmationDialog() and refresh() have been called. You may be requesting the dialog to be shown somewhere in there, but all that does it put a message on a queue, to be processed by the main application thread, sometime after you return control of that thread to the framework.
How do I make sure the callback method is only called after the user has made a choice?
Put the logic in an appropriate event listener. Lance's suggestion of setOnDismissListener() is a reasonable choice, if you want refresh() to be called regardless of how or why the dialog is going away.

prevent aynctask getting killed before completion?

in my activity, i have an asynctask that downloads a series of images...(it may take some time depending on the size of the images)... before i execute the asynctask, i display a progress dialog in onPreExecute and a notification (when user clicks on notification it is redirected to my activity with the progress dialog). when my asynctask completes, in onPostExecute, i remove the dialog and the notification.. i handle screen orientation by using onRetainNonConfigurationInstanceto save my asynctask so that when screen is rotated, i check if task is still running and i display the progress dialog if it is still running in onCreate
Problem : sometimes: my asynctask downloads only 1 file and it seems that it gets killed...(no exception in logcat)... as a result, my notication is always there and my progress dialog also... and they remain there indefinitely....
i have tried the solution by Jeff Axelrod there: How can I ensure an AsyncTask is completed before my activity is killed?:
It looks like if I override the onPause() event in my activity, and from within the overridden onPause(), I call cancel(false) on the AsyncTasks, then the activity is not destroyed until the AsyncTasks are completed.
seems to do the trick but problem is that my onPostExecute is not called anymore; all images download fine but as onPostExecute is not executed, notification and progress dialog still remain there forever.
waiting for your solutions guys! i read use asyntask only for short task; will the use of thread and handler solves my problem? will android kills my activity or thread if the latter is not finished??
Best way how to handle Asynctask is described in this article.
In short, the idea is to keep AsyncTask in fragment with setRetainInstance(true); these will keep You AsyncTask alive all time user is in activity holding this fragment and won't be destroyed on configuration change (orientation change).
If You need Your AsyncTask to run after user leaves Activity, for example goes to next Activity but You wish download to continue You should use services.

Show ProgressDialog while loading AppState from file

When my activity is being closed, I serialize the application state data to file to give me a chance to reload the state if the app gets killed by the system.
This approach (saving and restoring state) works fine. But, sometimes, when the process was killed, and depending on the amount of data to load, the loading state process can least some seconds to complete.
So, I can't load the state on a separeted thread because my activity will crash if the data isn't there on the onLoad.
So, I'd like to display a progress dialogue while loading the content, but, ensure that the Activity's onLoad method will be called only after the loading state process.
Does anybody knows how could I achieve this? Thanks a lot.
Hmmm.. could you Override the onLoad() function, then add a boolean that states whether you're displaying the dialog or not. If the dialog is being displayed (the boolean is true), don't let onLoad() do anything; otherwise, carry on as usual. That way once the dialog is dismissed, you can set the boolean to false again, and if onLoad() isn't called by default afterwards, perhaps you could manually call it? This is just an idea.
In other words: the dialog can be displayed using an AsyncTask. In the onPreExecute() method, set the boolean to true, do everything you need in doInBackground(), and in onPostExecute(), set the boolean to false and call onLoad().
On a side note... do you mean onCreate() or onResume()? I've actually not heard of onLoad(), unless this is a function you created.

Loading Dialog while rotating device

I have an activity with in which there is a async task that will do some download stuff. AT the time of downlaoding it will show a loading dialog.
My problem is, it worked fine for me when me doing it in only one orentiaon. But when i rotate at the time of download, it shows window leaked and will crash at the
dialog.cancel in my post excute.
From my study on it more i understood it due the change in the context when device is rotated.
That is when a device is rotated the activity will be recreated so the context will be changed.
But i have created the dialog with old one and that wasn't the current context. So when i cancel it it shows error
What is the solution for this, any idea frnds.
Me using honeycomb, me tried but with fragment but didnt get a good sample for that. Me now mainly trying that,
if anyone can give me some links for that it will be
great
First of all: open your dialog using the showDialog method (there are a lot of examples in the official documentation). If you do so, the activity will take care of dismissing the dialog on destroy, and re-showing it after the activity has been recreated.
Also... if the dialog shows a progress bar (not a wheel), you will want to update the progress of the dialog after orientation changes. In order to do so, I recommend to use the onRetainNonConfigurationInstance to return the current state of the dialog and/or the activity itself. Then, you can use getLastNonConfigurationInstance to recover that state. Google about those two methods if you want to see examples.
Another thing to keep in mind: if you are updating the state of the dialog an/or any other UI element from the AsyncTask, you must be aware that after the activity is recreated, the AsyncTask may be pointing to the wrong UI references. In order to handle this, you can create a proxy class (Proxy design pattern) to detach the AsyncTask progress notifications from the current UI elements.

Android: Window leaks on finish

I have read the other window leak posts and have tried what what suggested there to no avail.
I have 3 activities: A, B, and C. Activity A gathers information from the user. Activity B displays a spinning ProgressDialog while it communicates with a server on another thread. When the thread finishes, it dismisses the ProgressDialog and starts the next activity. Activity C displays the information from the server to the user. Activity B is set up so that when the user hits back from C, they fall back to A.
It is important that these tasks be in separate Activities.
As of now the app successfully does what it is supposed to in most cases, except in the following scenario: If the user changes the orientation while in activity C before returning to Activity A, the app crashes due to a window leak.
I am dismissing the ProgressDialog inthe onPause() of Activity B before istart C.
I have tried dismissing the
ProgressDialog on the main thread
using a handler as well as in the
separate thread.
When the user does not change the
orientation in C, no window leak
occurs.
Any ideas? TIA
This often happens where ProgressDialogs are used. I experimented with ProgressDialog a while back and found the thing to do was dismiss() it from onPause() and create it anew from onResume(). The background task obviously needs to survive your Activity & dialog so I used onRetainNonConfigurationInstance() to pass the task instance from the destroyed Activity to the new one.
An alternative, cheatier workaround might be to simply prevent your Activity from being destroyed and created anew merely because the screen orientation changed. Do this by adding android:configChanges="orientation" to the tag(s) in your AndroidManifest.xml.
I solved my problem by completely changing how i handled everything. I now have only two activities (A and B) and display the ProgessDialog in activity B while handling the savedInstanceState as needed in order to work around the problem.
Even though I have fixed the problem on my app, I still dont know why it was occuring before and would like to learn more about window leaks and why i was having problems. If anyone knows more about the problem i was having, please post as I'm sure there are others with the same problem.
Thanks
Not sure if this was related to your specific problem, but I had a similar issue which had to do with leaky windows for dialogs that are created in the onCreate method of an activity. So if your activity starts up showing a dialog, and you do a config change, the OS remembers which dialogs were shown, so when the activity is killed & restarted, the OS attempts to restore your old dialog while your activity tries to show the same dialog again (since it's in onCreate). I found by only showing the dialog during onCreate if it's not a config change (ie. savedInstanceState != null), the leaky window problem went away.

Categories

Resources