From bcd41ee79880a7c4b979ed34e87d9475c6f614f8 Mon Sep 17 00:00:00 2001 From: yoshiki iguchi Date: Fri, 12 Apr 2019 23:23:37 +0900 Subject: [PATCH] Not to remove the same animator twice Transition.forceToEnd may be called during the execution of method itself. In that case, an item of the map was removed during the previous iteration and ArrayIndexOutOfBoundsException was raised. This CL updates the loop to iterate the copy of map instead of the original map instance, so we don't break the iteration and see exception anymore. Bug: 120675604 Test: Ran 'cts-tradefed run commandAndExit cts --module CtsWidgetTestCases --test android.widget.cts.ToolbarTest#testMenuOverflowSubmenu' 20 times and no failure was observed. Change-Id: Iaba2f74f29d6ed22f84d92e0d4ca106cdfca904c --- core/java/android/transition/Transition.java | 23 ++++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/core/java/android/transition/Transition.java b/core/java/android/transition/Transition.java index 8819d220e7485..0feab4d027a99 100644 --- a/core/java/android/transition/Transition.java +++ b/core/java/android/transition/Transition.java @@ -1947,16 +1947,21 @@ public abstract class Transition implements Cloneable { * @hide */ void forceToEnd(ViewGroup sceneRoot) { - ArrayMap runningAnimators = getRunningAnimators(); + final ArrayMap runningAnimators = getRunningAnimators(); int numOldAnims = runningAnimators.size(); - if (sceneRoot != null) { - WindowId windowId = sceneRoot.getWindowId(); - for (int i = numOldAnims - 1; i >= 0; i--) { - AnimationInfo info = runningAnimators.valueAt(i); - if (info.view != null && windowId != null && windowId.equals(info.windowId)) { - Animator anim = runningAnimators.keyAt(i); - anim.end(); - } + if (sceneRoot == null || numOldAnims == 0) { + return; + } + + WindowId windowId = sceneRoot.getWindowId(); + final ArrayMap oldAnimators = new ArrayMap(runningAnimators); + runningAnimators.clear(); + + for (int i = numOldAnims - 1; i >= 0; i--) { + AnimationInfo info = oldAnimators.valueAt(i); + if (info.view != null && windowId != null && windowId.equals(info.windowId)) { + Animator anim = oldAnimators.keyAt(i); + anim.end(); } } }