It's also pretty easy to remove outstanding messages in an activity or fragment's end-of-lifecycle callbacks. Good idea anyway if those messages are supposed to trigger UI changes -- you won't want them to arrive after the activity/fragment has shut down.
-- K 2012/7/20 joebowbeer <joe.bowb...@gmail.com> > Note that there is now an Android Lint check for non-static inner classes > that extend Handler. See HandlerLeak: > > http://tools.android.com/tips/lint-checks > > I've implemented a Handler.Callback wrapper that wraps the Callback > (usually an inner class) in a WeakReference, and I construct the Handler > instance using the wrapped Callback. This way, the code that used to exist > in the leaky Handler inner class now exists in the Callback implementation. > This seems to have the least impact on the source code, while still > removing the potential leak. > > > On Friday, July 13, 2012 6:01:49 AM UTC-7, Michael Rozumyanskiy wrote: > >> But what about a Handler.Callback interface which can be passed to the >> Handler's constructor. According to the source code it is stored in the >> Handler class as a strong reference, so if the Message lives in the queue >> for a long time, the callback will not be gc'ed. And the callback may be an >> Activity or an inner class of an activity. But I can't see any checks in >> the source code and any recommendations in the documentation. As far as I >> understand, there isn't any right way to use the Handler.Callback with the >> Handler, is there? >> >> On Saturday, April 4, 2009 9:52:06 PM UTC+4, Romain Guy wrote: >> >>> I wrote that debugging code because of a couple of memory leaks I >>> found in the Android codebase. Like you said, a Message has a >>> reference to the Handler which, when it's inner and non-static, has a >>> reference to the outer this (an Activity for instance.) If the Message >>> lives in the queue for a long time, which happens fairly easily when >>> posting a delayed message for instance, you keep a reference to the >>> Activity and "leak" all the views and resources. It gets even worse >>> when you obtain a Message and don't post it right away but keep it >>> somewhere (for instance in a static structure) for later use. >>> >>> If you want to use the equivalent of an inner-class but not risk a >>> leak, here's a simple pattern: >>> >>> class OuterClass { >>> class InnerClass { >>> private final WeakReference<OuterClass> mTarget; >>> >>> InnerClass(OuterClass target) { >>> mTarget = new WeakReference<OuterClass>(**target); >>> } >>> >>> void doSomething() { >>> OuterClass target = mTarget.get(); >>> if (target != null) target.do(); >>> } >>> } >>> } >>> >>> On Sat, Apr 4, 2009 at 12:15 AM, Greg Krimer wrote: >>> > >>> > Thank you very much for the reply! After reading what Fadden said >>> > weeks ago, I happily converted my static inner handler classes to non- >>> > static ones. >>> > >>> > Just recently, I was browsing the source code of Handler and came >>> > across this bit of internal Android debugging: >>> > >>> > /* >>> > * Set this flag to true to detect anonymous, local or member >>> > classes >>> > * that extend this Handler class and that are not static. These >>> > kind >>> > * of classes can potentially create leaks. >>> > */ >>> > private static final boolean FIND_POTENTIAL_LEAKS = false; >>> > >>> > There is some code further down that uses reflection to locate such >>> > subclasses if this flag is true. >>> > >>> > My handlers fall into the category of non-static member classes, so I >>> > am curious how such classes could cause a memory leak. My initial >>> > thinking was that handlers could perhaps accumulate in a collection >>> > associated with the MessageQueue. But handlers are never placed into >>> > collections, as far as I can tell. The reference to the handler is in >>> > the message. Clever! (And in any case if the memory leak is due to an >>> > ever-growing collection of handlers somewhere then that has nothing to >>> > do with whether or not the handler class is static or not.) >>> > >>> > Just wondering if someone can shed some light on this comment in the >>> > Android source code. >>> > >>> > Thanks, >>> > >>> > Greg >>> > >>> > On Mar 10, 4:08 pm, fadden <fad...@android.com> wrote: >>> >> On Mar 9, 7:17 pm, Greg Krimer <gkri...@gmail.com> wrote: >>> >> >>> >> > I have been finding it convenient to extend Handler in many of my >>> >> > activities to handle messages specific to the activity. The handler >>> >> > sublass is an inner class of the activity and needs to access its >>> >> > state. I am wondering if there is any performance difference >>> between >>> >> > making the handler subclassstaticand passing in the activity >>> >> > explicitly in its constructor or making the subclass an "instance >>> >> > class" and letting the vm worry about my accessing members of the >>> >> > containing activity. >>> >> >>> >> There's no real difference between explicitly and implicitly passing >>> >> the outer-class reference around. Your example above is essentially >>> >> doing what javac does automatically. >>> >> >>> >> Staticinner classes have some useful properties, e.g. you know >>> >> they're not modifying state in the parent, and you can use >>> >> Class.newInstance() with them. There's no performance magic though. >>> >> >>> >> If you're really curious, write it both ways in trivial source files, >>> >> compile them, then view them with "javap -private -verbose <Class>" >>> or >>> >> "dx --dump <Class.class>". They should look about the same. >>> > > >>> > >>> >>> -- > You received this message because you are subscribed to the Google > Groups "Android Developers" group. > To post to this group, send email to android-developers@googlegroups.com > To unsubscribe from this group, send email to > android-developers+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/android-developers?hl=en > -- You received this message because you are subscribed to the Google Groups "Android Developers" group. To post to this group, send email to android-developers@googlegroups.com To unsubscribe from this group, send email to android-developers+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/android-developers?hl=en