Is it necessary to keep a reference to your spawned AlertDialog in your Activity and dismiss it in onDestroy() or could you just create it and forget it? It seems to be dismissed when your leave the Activity?
I suppose the AlertDialog holds a reference to the Activity Context normally, which might prevent the Activity from being garbage collected. What is the procedure to avoid possible memory leak here?
Does an AlertDialog belong to the Activity, i.e. does it follow the Activity lifecycle, being destroyed at the same time as the Activity and so on...?
I think, if you spawned the alert Dialog using the activity context or activity scope... It will be automatically destroyed whenever the activity is destroyed.
Maybe the problem arises when you want to spawn an Alert dialog from a reusable Utility class which doesn't have access to activity context, and ended up using Global Application context, then you need to manually destroy the dialog, since it may outlive the current activity, causing leak.
Related
Why should I call dismiss() method for AlertDialog before Activity is destroyed? Something leaks, but what exactly? Why then PopupWindow can handle Activity destroying?
I've found in Android sources that each alert dialog creates window:
Window w = PolicyManager.makeNewWindow(mContext);
What does that mean? Why it cannot just use PhoneWindow obtained from activity?
ADDED
Say, AlertDialog references Context, Context references nothing, then GC should garbage collect both objects (as they are not referenced from 'outside'). What else has a reference to AlertDialog? In other words where is exactly memory leak?
Alertdialogs are attached to our activity using a id,This Link shows the activity of a alertdialog, once the alertdialog is displayed it is a seperate window (u set cancel false then u r forced to manage it) if it is running on back and your activity gets destroyed Every memory associated with it will be released including the id of the AlertDialog. Thats y the error pops up .I think its clear now.
I am asking this because I am always getting the Activity has leaked window.. error
Couldn't figure out a way to destroy some of the dialogs on activity destroy since these dialogs
are dynamically generated outside the activity(on some listener).
So is there a way for android to detect and kill all the visible/live dialogs?
Thanks
I believe that you can keep a member reference to your dialogs as you create them. Then you can check the isShowing() method to see if its showing. Then hide and destroy the dialogs that are showing.
In my activity, I have an instance variable of AlertDialog aDialog;
under some condition, my activity will pop up a dialog.
My question is if I create aDialog, do I need to dismiss() in my onDestory() or onPause() of my activity?
From my experience, no. If you've called aDialog.show() and it's still showing while the activity is ending or pausing, it may be good to call dismiss(). I don't remember too clearly, but I have had experiences where forgetting to dismiss/close a dialog when switching activities caused a slight undesired, but not problematic, flickering of the dialog on the next activity as it tries to force close the dialog. Hope this answers your question!
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.
I have a singleton in an activity. When I end my application (like pressing back button), and start it again after some time, the singleton is not recreated, but is holding previous state. Singleton is not destroyed if the application is destroyed? Do I have to null its static members in onDestroy() to avoid memory leak?
Thanks.
When you are 'ending' your activity it is just going in background. So state will be maintained. If you want to do something when the activity is not 'visible' you have to implement the onStop() method and not onDestroy().
Please refer how android manages stack of Tasks and activities. Also refer Activity Lifecycle.
Activity is stopped if it is
completely obscured by another
activity. It still retains all state
and member information. However, it is
no longer visible to the user so its
window is hidden and it will often be
killed by the system when memory is
needed elsewhere.