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
This commit is contained in:
yoshiki iguchi
2019-04-12 23:23:37 +09:00
parent 9620e07e4f
commit bcd41ee798

View File

@@ -1947,16 +1947,21 @@ public abstract class Transition implements Cloneable {
* @hide
*/
void forceToEnd(ViewGroup sceneRoot) {
ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators();
final ArrayMap<Animator, AnimationInfo> 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<Animator, AnimationInfo> 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();
}
}
}