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 <[email protected]> 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 <[email protected]> wrote:
> >> On Mar 9, 7:17 pm, Greg Krimer <[email protected]> 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
> [email protected]
>
> 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 [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en