summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Chet Haase <chet@google.com> 2013-09-13 13:29:31 -0700
committer Chet Haase <chet@google.com> 2013-09-14 12:06:18 -0700
commit7660d121b2ef21164ed33e6091e5dd50f5d0f939 (patch)
treecb1046fb4edb97d80f0c23b2621bd0dbbed0f5eb
parent78d0cf7958dfde7951ed1a2c0317e04d6b41f4f3 (diff)
Plug leaks in transitions
Transitions were leaking views due to TransitionsValues holding references to views/parents. The references were fine, but the retention of the transition objects themselves were not. There were a few different places that needed to be plugged: - clones were not making new copies of some fields, leading to caching references in the original object (which was then cloned later to other clones) - Visibility was using a persistent field to cache temporary values. This transition, when cloned, would retain these instances, keeping references to views - ViewTreeObserver had a bug that would leak listeners Issue #10749071 Activity instance leak between TransitionManager and InputMethodManager Change-Id: I1d5d457dc5e020c7b9e8392a95e3b2c488461119
-rw-r--r--core/java/android/transition/Transition.java2
-rw-r--r--core/java/android/transition/TransitionManager.java29
-rw-r--r--core/java/android/transition/Visibility.java5
-rw-r--r--core/java/android/view/ViewTreeObserver.java2
4 files changed, 23 insertions, 15 deletions
diff --git a/core/java/android/transition/Transition.java b/core/java/android/transition/Transition.java
index c588c6bf4c7a..2fb32aafad0c 100644
--- a/core/java/android/transition/Transition.java
+++ b/core/java/android/transition/Transition.java
@@ -1451,6 +1451,8 @@ public abstract class Transition implements Cloneable {
try {
clone = (Transition) super.clone();
clone.mAnimators = new ArrayList<Animator>();
+ clone.mStartValues = new TransitionValuesMaps();
+ clone.mEndValues = new TransitionValuesMaps();
} catch (CloneNotSupportedException e) {}
return clone;
diff --git a/core/java/android/transition/TransitionManager.java b/core/java/android/transition/TransitionManager.java
index 54d801eba443..727a98dceb9a 100644
--- a/core/java/android/transition/TransitionManager.java
+++ b/core/java/android/transition/TransitionManager.java
@@ -22,6 +22,7 @@ import android.util.Log;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
+import java.lang.ref.WeakReference;
import java.util.ArrayList;
/**
@@ -68,8 +69,9 @@ public class TransitionManager {
ArrayMap<Scene, Transition> mSceneTransitions = new ArrayMap<Scene, Transition>();
ArrayMap<Scene, ArrayMap<Scene, Transition>> mScenePairTransitions =
new ArrayMap<Scene, ArrayMap<Scene, Transition>>();
- private static ThreadLocal<ArrayMap<ViewGroup, ArrayList<Transition>>> sRunningTransitions =
- new ThreadLocal<ArrayMap<ViewGroup, ArrayList<Transition>>>();
+ private static ThreadLocal<WeakReference<ArrayMap<ViewGroup, ArrayList<Transition>>>>
+ sRunningTransitions =
+ new ThreadLocal<WeakReference<ArrayMap<ViewGroup, ArrayList<Transition>>>>();
private static ArrayList<ViewGroup> sPendingTransitions = new ArrayList<ViewGroup>();
@@ -184,20 +186,24 @@ public class TransitionManager {
}
private static ArrayMap<ViewGroup, ArrayList<Transition>> getRunningTransitions() {
- ArrayMap<ViewGroup, ArrayList<Transition>> runningTransitions =
+ WeakReference<ArrayMap<ViewGroup, ArrayList<Transition>>> runningTransitions =
sRunningTransitions.get();
- if (runningTransitions == null) {
- runningTransitions = new ArrayMap<ViewGroup, ArrayList<Transition>>();
+ if (runningTransitions == null || runningTransitions.get() == null) {
+ ArrayMap<ViewGroup, ArrayList<Transition>> transitions =
+ new ArrayMap<ViewGroup, ArrayList<Transition>>();
+ runningTransitions = new WeakReference<ArrayMap<ViewGroup, ArrayList<Transition>>>(
+ transitions);
sRunningTransitions.set(runningTransitions);
}
- return runningTransitions;
+ return runningTransitions.get();
}
private static void sceneChangeRunTransition(final ViewGroup sceneRoot,
final Transition transition) {
if (transition != null) {
final ViewTreeObserver observer = sceneRoot.getViewTreeObserver();
- observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
+ final ViewTreeObserver.OnPreDrawListener listener =
+ new ViewTreeObserver.OnPreDrawListener() {
public boolean onPreDraw() {
sceneRoot.getViewTreeObserver().removeOnPreDrawListener(this);
sPendingTransitions.remove(sceneRoot);
@@ -236,7 +242,8 @@ public class TransitionManager {
// values set on them again and avoid artifacts.
return false;
}
- });
+ };
+ observer.addOnPreDrawListener(listener);
}
}
@@ -355,10 +362,10 @@ public class TransitionManager {
// if (transition == null) {
// transition = sDefaultTransition;
// }
-// final Transition finalTransition = transition.clone();
-// sceneChangeSetup(sceneRoot, transition);
+// final Transition transitionClone = transition.clone();
+// sceneChangeSetup(sceneRoot, transitionClone);
// Scene.setCurrentScene(sceneRoot, null);
-// sceneChangeRunTransition(sceneRoot, finalTransition);
+// sceneChangeRunTransition(sceneRoot, transitionClone);
// }
}
}
diff --git a/core/java/android/transition/Visibility.java b/core/java/android/transition/Visibility.java
index 75d3e7c0b4e0..f49821fab1c3 100644
--- a/core/java/android/transition/Visibility.java
+++ b/core/java/android/transition/Visibility.java
@@ -65,9 +65,6 @@ public abstract class Visibility extends Transition {
ViewGroup endParent;
}
- // Temporary structure, used in calculating state in setup() and play()
- private VisibilityInfo mTmpVisibilityInfo = new VisibilityInfo();
-
@Override
public String[] getTransitionProperties() {
return sTransitionProperties;
@@ -161,7 +158,7 @@ public abstract class Visibility extends Transition {
private VisibilityInfo getVisibilityChangeInfo(TransitionValues startValues,
TransitionValues endValues) {
- final VisibilityInfo visInfo = mTmpVisibilityInfo;
+ final VisibilityInfo visInfo = new VisibilityInfo();
visInfo.visibilityChange = false;
visInfo.fadeIn = false;
if (startValues != null) {
diff --git a/core/java/android/view/ViewTreeObserver.java b/core/java/android/view/ViewTreeObserver.java
index 730c4eb01cd0..ad8b51db4a1a 100644
--- a/core/java/android/view/ViewTreeObserver.java
+++ b/core/java/android/view/ViewTreeObserver.java
@@ -992,6 +992,8 @@ public final class ViewTreeObserver {
mData = mDataCopy;
}
mDataCopy = null;
+ mAccess.mData.clear();
+ mAccess.mSize = 0;
}
int size() {