Hi all.  I'm working on an Android app which makes use of an
AnimatedRotateDrawable.  Specifically, it's being used in a
ProgressBar which has been themed to use it (it's one of those little
spinny kinds of progress bars), which is itself part of a
PreferenceCategory header (the use-case is that the PreferenceCategory
can take some time to populate with items, so the ProgressBar in the
header spins until it's completely full.)  I've been tracking down a
rather insidious memory leak in this Activity, which I believe is due
to the specific way in which I'm using the AnimatedRotateDrawable.  I
was wondering if I could get any opinions on the proper way to fix
this.

What I'm seeing is the following.  Every time a new item becomes
available for the PreferencesCategory, it gets added with addPreference
().  This notifies the associated adapter that the contents of the
list changed, so the core code re-calls Preference.getView() to make a
new PreferencesCategory object.  This inflates my custom resource
layout, which creates a new ProgressBar.  This entire process repeats
each time my PreferencesCategory gets a new item, and finally
completes when all items are populated.  So far so good.

However, in the process, we've created a lot of intermediate
ProgressBar objects.  This isn't necessarily a problem, except for the
fact that nobody ever called stopAnimation() on them.  This means that
all of those ProgressBars' AnimatedRotateDrawables continue to post
themselves into the handler in order to draw their next frames, even
though none of them are actually visible anymore.  Worse, since the
Drawables all have a callback set on them (the ProgressBar), which in
turn contains a reference to its context, this process ends up pinning
the entire Activity in memory until the process exits.

Normally, I could hack around this, either by making the ProgressBar
invisible or calling setIndeterminate(false) when it's time for the
activity to go away.  However, in this case, I don't really have
access to the ProgressBars, as they come and go whenever the
ListAdapter feels like creating them, so there's no time that I can
call setVisibility() on them.  More to the point, though, even if I
could, this seems like something the ProgressBar ought to be taking
care of by itself, lest there be a secret requirement that everybody
who uses it must call setVisibility(INVISIBLE) or setIntermediate
(false), or else suffer a memory leak.  I tried putting a call to
stopAnimation() in onDetachedFromWindow(), but this doesn't seem to
get called in all circumstances.  I can't seem to find any place in
the ProgressBar class which reliably gets called when the view is
going away, where I would be able to put a stopAnimation() call.

Can somebody provide any advice on how best to deal with this problem?

Thanks,
Matt

-- 
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

Reply via email to