@@ -536,6 +536,9 @@ private static class AnimationHandler implements Runnable {
536536 // The per-thread list of all active animations
537537 private final ArrayList <ValueAnimator > mAnimations = new ArrayList <ValueAnimator >();
538538
539+ // Used in doAnimationFrame() to avoid concurrent modifications of mAnimations
540+ private final ArrayList <ValueAnimator > mTmpAnimations = new ArrayList <ValueAnimator >();
541+
539542 // The per-thread set of animations to be started on the next animation frame
540543 private final ArrayList <ValueAnimator > mPendingAnimations = new ArrayList <ValueAnimator >();
541544
@@ -605,28 +608,18 @@ private void doAnimationFrame(long frameTime) {
605608 // Now process all active animations. The return value from animationFrame()
606609 // tells the handler whether it should now be ended
607610 int numAnims = mAnimations .size ();
608- int i = 0 ;
609- while (i < numAnims ) {
610- ValueAnimator anim = mAnimations .get (i );
611- if (anim .doAnimationFrame (frameTime )) {
611+ for (int i = 0 ; i < numAnims ; ++i ) {
612+ mTmpAnimations .add (mAnimations .get (i ));
613+ }
614+ for (int i = 0 ; i < numAnims ; ++i ) {
615+ ValueAnimator anim = mTmpAnimations .get (i );
616+ if (mAnimations .contains (anim ) && anim .doAnimationFrame (frameTime )) {
612617 mEndingAnims .add (anim );
613618 }
614- if (mAnimations .size () == numAnims ) {
615- ++i ;
616- } else {
617- // An animation might be canceled or ended by client code
618- // during the animation frame. Check to see if this happened by
619- // seeing whether the current index is the same as it was before
620- // calling animationFrame(). Another approach would be to copy
621- // animations to a temporary list and process that list instead,
622- // but that entails garbage and processing overhead that would
623- // be nice to avoid.
624- --numAnims ;
625- mEndingAnims .remove (anim );
626- }
627619 }
620+ mTmpAnimations .clear ();
628621 if (mEndingAnims .size () > 0 ) {
629- for (i = 0 ; i < mEndingAnims .size (); ++i ) {
622+ for (int i = 0 ; i < mEndingAnims .size (); ++i ) {
630623 mEndingAnims .get (i ).endAnimation (this );
631624 }
632625 mEndingAnims .clear ();
0 commit comments