summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChet Haase <chet@google.com>2011-11-10 17:03:12 -0800
committerChet Haase <chet@google.com>2011-11-10 17:53:31 -0800
commit30f03ac650f2ffaafe9cc49942a4a8a7858dbd88 (patch)
tree357fcaaaa51e71fe00e216cea0fcaf90c10eebce
parentca5c881374d051361eb5f9a191d51b5716ef2366 (diff)
downloadframeworks_base-30f03ac650f2ffaafe9cc49942a4a8a7858dbd88.zip
frameworks_base-30f03ac650f2ffaafe9cc49942a4a8a7858dbd88.tar.gz
frameworks_base-30f03ac650f2ffaafe9cc49942a4a8a7858dbd88.tar.bz2
DO NOT MERGE. Fix leak in LayoutTransition
LayoutTransition was making an incorrect assumption that there could only be one transition animation on a child of a transitioning container. But if multiple children are added/removed to/from that container, there would be multiple calls to set up changing animations for each existing child of that container. This meant that the child would have multiple, new OnLayoutChangeListeners added to it as part of the setup process. Meanwhile, we would cache only the latest listener in a hashmap that used the child as a key for the listener. Then when we cleaned up the hashmap later, we would remove only the latest listener from the child, leaving the rest there for eternity. The fix is to skip the setup entirely for children that already have listeners set on them; they must, if that's the case, already have been set up and are already listening for layout changes. Setting up the animation is redundant, and adding another listener is a leak. issue #5588509: memory leak in systemui Change-Id: Ie2192593d84702be7243c18760dfdb3a027b761c
-rw-r--r--core/java/android/animation/LayoutTransition.java9
1 files changed, 9 insertions, 0 deletions
diff --git a/core/java/android/animation/LayoutTransition.java b/core/java/android/animation/LayoutTransition.java
index f383af9..7f0ea99 100644
--- a/core/java/android/animation/LayoutTransition.java
+++ b/core/java/android/animation/LayoutTransition.java
@@ -657,6 +657,15 @@ public class LayoutTransition {
*/
private void setupChangeAnimation(final ViewGroup parent, final int changeReason,
Animator baseAnimator, final long duration, final View child) {
+
+ // If we already have a listener for this child, then we've already set up the
+ // changing animation we need. Multiple calls for a child may occur when several
+ // add/remove operations are run at once on a container; each one will trigger
+ // changes for the existing children in the container.
+ if (layoutChangeListenerMap.get(child) != null) {
+ return;
+ }
+
// Make a copy of the appropriate animation
final Animator anim = baseAnimator.clone();