From 40a67888f91c2bb94c8654fbfe402f84795d17cf Mon Sep 17 00:00:00 2001 From: Adam Powell Date: Wed, 23 Oct 2013 13:26:03 -0700 Subject: [PATCH] Cache Scene objects by layout ID on the scene root The current tracking of scene objects in a static ThreadLocal is problematic as it leaks the Context associated with the SceneRoot and returns the wrong Scene object if the same layout ID is used across different scene roots. Track Scene objects on the scene root view instead to avoid these issues. Change-Id: I891986897f757f2666897c937b5ebb0ed1d531c1 --- core/java/android/transition/Scene.java | 17 +++++++++-------- core/res/res/values/ids.xml | 1 + core/res/res/values/symbols.xml | 1 + 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/core/java/android/transition/Scene.java b/core/java/android/transition/Scene.java index d798abec5a33b..5800bd586bd03 100644 --- a/core/java/android/transition/Scene.java +++ b/core/java/android/transition/Scene.java @@ -36,27 +36,28 @@ public final class Scene { private ViewGroup mSceneRoot; private ViewGroup mLayout; // alternative to layoutId Runnable mEnterAction, mExitAction; - private static ThreadLocal> sScenes = new ThreadLocal>(); /** * Returns a Scene described by the resource file associated with the given - * layoutId parameter. If such a Scene has already been created, - * that same Scene will be returned. This caching of layoutId-based scenes enables - * sharing of common scenes between those created in code and those referenced - * by {@link TransitionManager} XML resource files. + * layoutId parameter. If such a Scene has already been created for + * the given sceneRoot, that same Scene will be returned. + * This caching of layoutId-based scenes enables sharing of common scenes + * between those created in code and those referenced by {@link TransitionManager} + * XML resource files. * * @param sceneRoot The root of the hierarchy in which scene changes * and transitions will take place. * @param layoutId The id of a standard layout resource file. * @param context The context used in the process of inflating * the layout resource. - * @return + * @return The scene for the given root and layout id */ public static Scene getSceneForLayout(ViewGroup sceneRoot, int layoutId, Context context) { - SparseArray scenes = sScenes.get(); + SparseArray scenes = (SparseArray) sceneRoot.getTag( + com.android.internal.R.id.scene_layoutid_cache); if (scenes == null) { scenes = new SparseArray(); - sScenes.set(scenes); + sceneRoot.setTag(com.android.internal.R.id.scene_layoutid_cache, scenes); } Scene scene = scenes.get(layoutId); if (scene != null) { diff --git a/core/res/res/values/ids.xml b/core/res/res/values/ids.xml index 15df295e57847..5c0baaa4998f8 100644 --- a/core/res/res/values/ids.xml +++ b/core/res/res/values/ids.xml @@ -81,4 +81,5 @@ + diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index e17b650ff969f..dc0841ab1041d 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -55,6 +55,7 @@ +