I was trying to use built-in AlertDialog with onDismiss listener (without it result was same) and custom AppCompatDialog subclass. After dialog dismissed, current activity should finish. But few seconds later memory leak push appears. If I put breakpoint in custom dialog's onStop() method (delay is don't matter), this memory leak caption is not shown. Can it be fixed in normal way? Maybe, someone already faced with a similar problem?
This memory leak was related to displaying toast with current activity's context. When I injected application context into class, that displaying toasts, leak was fixed
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 currently trying to define a seperate class for displaying ProgressDialogs as i dont want to create individual progressDialog instances in each and every activity. And i m currently sending the current activities context to that method. Things seems to work fine but at times (very random) it leads to a exception stating window Leaked. I even know that window leak occurs if i m trying to show dialog on a context which is finished. And i think the issue here could be because of some other part of code which is finishing my context before my dialog is shown.so i just want to make sure my method doesn't show the dialog if there is any issue with context.
Is there any way i can know whether my passed context is currently visible on the screen or not so that i will not run into these window leaked exceptions.
And also tried replacing the context with getApplicationContext(). but the progress dialog is not shown at all with this change.
Any help would be greatly appreciated.
Thank you all in advance
Dismiss the dialog in onPause() method .
When I use dismiss to remove a popup window, does it only hide it or removes it from memory?
I tried dismiss, then showAtLocation several times (using the same PopupWindw object, not re-creating it) and the window was displayed and hidden without problems. The question is can I count on it - perhaps it is marked for deletion by the GC, but hasn't been garbage-collected yet?
Thanks.
dismiss() is opposite to showAtLocation(), the object remains in a valid state after dismiss(). So it is safe to toggle dismiss()/showAtLocation()
It can be seen from the Android source code in here - you can look at dismiss() and showAtLocation() implementations
http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/1.5_r4/android/widget/PopupWindow.java#PopupWindow.showAtLocation%28android.view.View%2Cint%2Cint%2Cint%29
http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/1.5_r4/android/widget/PopupWindow.java#PopupWindow.dismiss%28%29
An object will not be marked for deletion as long as you have a reference to it. So you can re-show it later.
You could force the use of Garbage Collector using
System.gc()
While running monkey tool on my app, I am getting android.view.WindowLeaked exception, I referred some stackoverflow threads and found that we need avoid this while creating popups, instead we need to use getApplicationContext() but this is causing BadTokenException
E/AndroidRuntime(5597): android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
Again after searching through I found this answer which says
One cause of this error may be trying to display an application
window/dialog through a Context that is not an Activity
So how to solve this?
Usually window leaks because You don't use showDialog method in Activity but only using Dialog.show() method.
When dialog is displayed and configuration of Your Activity changes (eg. orientation change) dialog has not window to attach, and this results in leak of window.
If You use Compatibility library You should use DialogFragment instead of pure dialog.
the reason behind WindowManager$BadTokenException is that you keep showing dialog or popupwindow on the window whose context is not alive now.
So should always dismiss popup or dialog whenever you switch between activities or dismiss any activity.
Therefore you should probably call dilog.dismiss() in onPause method.
onPause()
{
dilog.dismiss()
}
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.