Merge "Make animators more robust against ending mid-stream" into jb-mr1-dev

This commit is contained in:
Chet Haase
2012-08-16 15:35:28 -07:00
committed by Android (Google) Code Review

View File

@@ -536,6 +536,9 @@ public class ValueAnimator extends Animator {
// The per-thread list of all active animations // The per-thread list of all active animations
private final ArrayList<ValueAnimator> mAnimations = new ArrayList<ValueAnimator>(); private final ArrayList<ValueAnimator> mAnimations = new ArrayList<ValueAnimator>();
// Used in doAnimationFrame() to avoid concurrent modifications of mAnimations
private final ArrayList<ValueAnimator> mTmpAnimations = new ArrayList<ValueAnimator>();
// The per-thread set of animations to be started on the next animation frame // The per-thread set of animations to be started on the next animation frame
private final ArrayList<ValueAnimator> mPendingAnimations = new ArrayList<ValueAnimator>(); private final ArrayList<ValueAnimator> mPendingAnimations = new ArrayList<ValueAnimator>();
@@ -605,28 +608,18 @@ public class ValueAnimator extends Animator {
// Now process all active animations. The return value from animationFrame() // Now process all active animations. The return value from animationFrame()
// tells the handler whether it should now be ended // tells the handler whether it should now be ended
int numAnims = mAnimations.size(); int numAnims = mAnimations.size();
int i = 0; for (int i = 0; i < numAnims; ++i) {
while (i < numAnims) { mTmpAnimations.add(mAnimations.get(i));
ValueAnimator anim = mAnimations.get(i); }
if (anim.doAnimationFrame(frameTime)) { for (int i = 0; i < numAnims; ++i) {
ValueAnimator anim = mTmpAnimations.get(i);
if (mAnimations.contains(anim) && anim.doAnimationFrame(frameTime)) {
mEndingAnims.add(anim); mEndingAnims.add(anim);
} }
if (mAnimations.size() == numAnims) {
++i;
} else {
// An animation might be canceled or ended by client code
// during the animation frame. Check to see if this happened by
// seeing whether the current index is the same as it was before
// calling animationFrame(). Another approach would be to copy
// animations to a temporary list and process that list instead,
// but that entails garbage and processing overhead that would
// be nice to avoid.
--numAnims;
mEndingAnims.remove(anim);
}
} }
mTmpAnimations.clear();
if (mEndingAnims.size() > 0) { if (mEndingAnims.size() > 0) {
for (i = 0; i < mEndingAnims.size(); ++i) { for (int i = 0; i < mEndingAnims.size(); ++i) {
mEndingAnims.get(i).endAnimation(this); mEndingAnims.get(i).endAnimation(this);
} }
mEndingAnims.clear(); mEndingAnims.clear();