Obsolete
Status Update
Comments
js...@android.com <js...@android.com>
ja...@gmail.com <ja...@gmail.com> #2
This is also true if the `Context` changes, such as to inflate with a different theme.
sa...@google.com <sa...@google.com> #3
Thank you for your feedback. We have tried our best to address the issue reported, however our product team has shifted work priority which doesn't include this issue. For now, we will be closing the issue as "Won't Fix (Obsolete)". If this issue still currently exists, we request that you log a new issue along with the latest bug report here: https://goo.gl/TbMiIO and reference this bug for context.
Description
public static Scene getSceneForLayout(ViewGroup sceneRoot, int layoutId, Context context) {
SparseArray<Scene> scenes = sScenes.get();
if (scenes == null) {
scenes = new SparseArray<Scene>();
sScenes.set(scenes);
}
Scene scene = scenes.get(layoutId);
if (scene != null) {
return scene;
} else {
scene = new Scene(sceneRoot, layoutId, context);
scenes.put(layoutId, scene);
return scene;
}
}
The above code creates a new Scene when a cached version does not already exist (keyed by the layout id) and inserts it into a static collection attached to ThreadLocal. If the Scene already exists, the cached object is returned instead.
This creates a problem because the scene's "root" ViewGroup is not always the same instance, but that reference is owned by the Scene. For example, one the first run of an Activity, the scene root will be some ViewGroup in the inflated layout hierarchy. This root gets attached to each scene and that reference cached forever in this collection.
If the user exits the Activity (i.e. hits the back button) and the instance is destroyed, the next time they launch it will be a new Activity, with a new "root" ViewGroup instance attached to the window...but each scene will still reference the old ViewGroup as its scene root. This will cause none of the animations to work on the second time around because all the changes are happening to a ViewGroup that is no longer attached to the window (so OnPreDrawListeners and other triggers never fire).
STEPS TO REPRODUCE:
1. Run the Android-19 API Demos application
2. Select Animation -> Simple Transitions
3. Play around with the Scenes in this demo, they all work great.
4. Press the BACK button
5. Select Simple Transitions once again.
6. This time none of the animations will work (except for those that don't use a Scene)
Obviously the expected behavior is that the animations work the same way each time we run the Activity.
FUNCTIONAL WORKAROUND:
We can get the transitions to work as expected by applying the following workaround. If we avoid ever calling getSceneForLayout(), and instead create new scenes for every Activity, the problem goes away. In the ApiDemos app, we can replace:
mScene1 = Scene.getSceneForLayout(mSceneRoot, R.layout.transition_scene1, this);
mScene2 = Scene.getSceneForLayout(mSceneRoot, R.layout.transition_scene2, this);
mScene3 = Scene.getSceneForLayout(mSceneRoot, R.layout.transition_scene3, this);
with the following:
mScene1 = new Scene(mSceneRoot,
(ViewGroup) LayoutInflater.from(this).inflate(R.layout.transition_scene1, mSceneRoot, false));
mScene2 = new Scene(mSceneRoot,
(ViewGroup) LayoutInflater.from(this).inflate(R.layout.transition_scene2, mSceneRoot, false));
mScene3 = new Scene(mSceneRoot,
(ViewGroup) LayoutInflater.from(this).inflate(R.layout.transition_scene3, mSceneRoot, false));
Although it's unclear at this point if this workaround has other poor performance or memory side effect.