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 <gkri...@gmail.com> 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. > > > > > > > > > -- > Romain Guy > Android framework engineer > romain...@android.com > > Note: please don't send private questions to me, as I don't have time > to provide private support. All such questions should be posted on > public forums, where I and others can see and answer them > -- 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