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

Reply via email to