From 58606db8be7e64a4317955b87fba4ee51f353630 Mon Sep 17 00:00:00 2001 From: Doris Liu Date: Wed, 13 Apr 2016 13:28:38 -0700 Subject: [PATCH] Add api check to guard AnimatorSet behavior change For pre-N, we have inconsistent behavior between ValueAnimator and AnimatorSet in the case of calling end() when already ended: ValueAnimator would start() and immediately end, whereas AnimatorSet would be no-op. We made a decision to be consistent within Animation Framework from N forward, which means that AnimatorSet will have the new behavior of starting and immediately ending just like ValueAnimator. This new behavior will be guarded by an API check. Bug: 25601129 Change-Id: I2d952a93d8521c547ec8cde173c80d1d8ead0639 --- core/java/android/animation/AnimatorSet.java | 21 ++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/core/java/android/animation/AnimatorSet.java b/core/java/android/animation/AnimatorSet.java index 3385a17002bce..e788d2749d172 100644 --- a/core/java/android/animation/AnimatorSet.java +++ b/core/java/android/animation/AnimatorSet.java @@ -16,6 +16,9 @@ package android.animation; +import android.app.ActivityThread; +import android.app.Application; +import android.os.Build; import android.util.ArrayMap; import android.util.Log; @@ -133,10 +136,25 @@ public final class AnimatorSet extends Animator { // The total duration of finishing all the Animators in the set. private long mTotalDuration = 0; + // In pre-N releases, calling end() before start() on an animator set is no-op. But that is not + // consistent with the behavior for other animator types. In order to keep the behavior + // consistent within Animation framework, when end() is called without start(), we will start + // the animator set and immediately end it for N and forward. + private final boolean mShouldIgnoreEndWithoutStart; + public AnimatorSet() { super(); mNodeMap.put(mDelayAnim, mRootNode); mNodes.add(mRootNode); + // Set the flag to ignore calling end() without start() for pre-N releases + Application app = ActivityThread.currentApplication(); + if (app == null || app.getApplicationInfo() == null) { + mShouldIgnoreEndWithoutStart = true; + } else if (app.getApplicationInfo().targetSdkVersion < Build.VERSION_CODES.N) { + mShouldIgnoreEndWithoutStart = true; + } else { + mShouldIgnoreEndWithoutStart = false; + } } /** @@ -365,6 +383,9 @@ public final class AnimatorSet extends Animator { */ @Override public void end() { + if (mShouldIgnoreEndWithoutStart && !isStarted()) { + return; + } mTerminated = true; if (isStarted()) { endRemainingAnimations();