1、使用属性动画
ObjectAnimator animator = ObjectAnimator.ofFloat(view, "x", 0f, 360f);
animator.setDuration(1000);
animator.start();
以上是使用属性动画的简单例子,从start方法开始执行
2、ObjectAnimator.start
//ObjectAnimator.start
public void start() {
AnimationHandler.getInstance().autoCancelBasedOn(this);
super.start();
}
//ValueAnimator.start
public void start() {
start(false);
}
private void start(boolean playBackwards) {
if (Looper.myLooper() == null) {
throw new AndroidRuntimeException("Animators may only be run on Looper threads");
}
//一大段代码做状态设置,省略了
....
addAnimationCallback(0); //见3
if (mStartDelay == 0 || mSeekFraction >= 0 || mReversing) {
startAnimation();
if (mSeekFraction == -1) {
setCurrentPlayTime(0);
} else {
setCurrentFraction(mSeekFraction);
}
}
}
主要是设置下状态属性,addAnimationCallback(0)跟踪进去
3、ValueAnimator.addAnimationCallback
private void addAnimationCallback(long delay) {
if (!mSelfPulse) {
return;
}
//见4、5
getAnimationHandler().addAnimationFrameCallback(this, delay);
//这里的参数this是AnimationFrameCallback接口的实现,ValueAnimator实现了该接口
}
4、getAnimationHandler
public AnimationHandler getAnimationHandler() {
return AnimationHandler.getInstance();
}
public static AnimationHandler getInstance() {
if (sAnimatorHandler.get() == null) {
sAnimatorHandler.set(new AnimationHandler());
}
return sAnimatorHandler.get();
}
主要是获取当前线程的AnimationHandler实例
5、AnimationHandler.addAnimationFrameCallback
public void addAnimationFrameCallback(final AnimationFrameCallback callback, long delay) {
if (mAnimationCallbacks.size() == 0) {
// 见6
getProvider().postFrameCallback(mFrameCallback);//注意mFrameCallback
}
if (!mAnimationCallbacks.contains(callback)) {
mAnimationCallbacks.add(callback);
}
if (delay > 0) {
mDelayedCallbackStartTime.put(callback, (SystemClock.uptimeMillis() + delay));
}
}
//mFrameCallback的实现
private final Choreographer.FrameCallback mFrameCallback = new Choreographer.FrameCallback() {
@Override
public void doFrame(long frameTimeNanos) {
doAnimationFrame(getProvider().getFrameTime());
if (mAnimationCallbacks.size() > 0) {
getProvider().postFrameCallback(this);
}
}
};
getProvider()方法返回的MyFrameCallbackProvider实例,紧接着调用了postFrameCallback方法,传入mFrameCallback对象
mFrameCallback实际上在AnimationHandler的一个属性
6、MyFrameCallbackProvider
private class MyFrameCallbackProvider implements AnimationFrameCallbackProvider {
final Choreographer mChoreographer = Choreographer.getInstance();
@Override
public void postFrameCallback(Choreographer.FrameCallback callback) {
mChoreographer.postFrameCallback(callback);//见7
}
....
}
MyFrameCallbackProvider.postFrameCallback方法实际调了Choreographer.postFrameCallback方法
7、Choreographer.postFrameCallback
public void postFrameCallback(FrameCallback callback) {
postFrameCallbackDelayed(callback, 0);
}
public void postFrameCallbackDelayed(FrameCallback callback, long delayMillis) {
if (callback == null) {
throw new IllegalArgumentException("callback must not be null");
}
postCallbackDelayedInternal(CALLBACK_ANIMATION,
callback, FRAME_CALLBACK_TOKEN, delayMillis);
}
public void postFrameCallbackDelayed(FrameCallback callback, long delayMillis) {
if (callback == null) {
throw new IllegalArgumentException("callback must not be null");
}
postCallbackDelayedInternal(CALLBACK_ANIMATION,
callback, FRAME_CALLBACK_TOKEN, delayMillis);
}
最后到了postCallbackDelayedInternal方法,注意这里的callbackType是CALLBACK_ANIMATION,callback是上一小节的AnimationHandler的mFrameCallback属性,delayMillis等于0
8、Choreographer.postCallbackDelayedInternal
private void postCallbackDelayedInternal(int callbackType,
Object action, Object token, long delayMillis) {
synchronized (mLock) {
final long now = SystemClock.uptimeMillis();
final long dueTime = now + delayMillis;
//把mFrameCallback(FrameCallback类型),保存到数组mCallbackQueues里面
//下标是callbackType,也就是CALLBACK_ANIMATION,
mCallbackQueues[callbackType].addCallbackLocked(dueTime, action, token);
//因为delayMillis为0,if成立
if (dueTime <= now) {
scheduleFrameLocked(now);//见9
} else {
//如果不成立,通过handler发送延迟消息,结果也是一样的
Message msg = mHandler.obtainMessage(MSG_DO_SCHEDULE_CALLBACK, action);
msg.arg1 = callbackType;
msg.setAsynchronous(true);
mHandler.sendMessageAtTime(msg, dueTime);
}
}
}
9、Choreographer.scheduleFrameLocked
//是否使用垂直同步机制,通常为true
private static final boolean USE_VSYNC = SystemProperties.getBoolean(
"debug.choreographer.vsync", true);
private void scheduleFrameLocked(long now) {
if (!mFrameScheduled) {
mFrameScheduled = true;
if (USE_VSYNC) {
// 运行在looper线程
if (isRunningOnLooperThreadLocked()) {
scheduleVsyncLocked();//见10
} else {
Message msg = mHandler.obtainMessage(MSG_DO_SCHEDULE_VSYNC);
msg.setAsynchronous(true);
mHandler.sendMessageAtFrontOfQueue(msg);
}
} else {
//如果不使用VSYNC垂直同步信号机制,则通过Handler处理,通常不会走到这里
final long nextFrameTime = Math.max(
mLastFrameTimeNanos / TimeUtils.NANOS_PER_MS + sFrameDelay, now);
Message msg = mHandler.obtainMessage(MSG_DO_FRAME);
msg.setAsynchronous(true);
mHandler.sendMessageAtTime(msg, nextFrameTime);
}
}
}
10、Choreographer.scheduleVsyncLocked
private void scheduleVsyncLocked() {
mDisplayEventReceiver.scheduleVsync();
}
public void scheduleVsync() {
if (mReceiverPtr == 0) {
Log.w(TAG, "Attempted to schedule a vertical sync pulse but the display event "
+ "receiver has already been disposed.");
} else {
nativeScheduleVsync(mReceiverPtr);
}
}
nativeScheduleVsync方法到native层了,当初追踪到这里就断了,后来无意间看到下面的dispatchVsync方法的注释
Called from native code. 所以猜测native层调了这个方法回到了java层。
11、dispatchVsync
// Called from native code.
@SuppressWarnings("unused")
private void dispatchVsync(long timestampNanos, int builtInDisplayId, int frame) {
onVsync(timestampNanos, builtInDisplayId, frame); //见12
}
接着传递到了onVsync方法,FrameDisplayEventReceiver重写了该方法
12、FrameDisplayEventReceiver.onVsync
public void onVsync(long timestampNanos, int builtInDisplayId, int frame) {
...
long now = System.nanoTime();
if (timestampNanos > now) {
timestampNanos = now;
}
if (mHavePendingVsync) {
Log.w(TAG, "Already have a pending vsync event. There should only be "
+ "one at a time.");
} else {
mHavePendingVsync = true;
}
mTimestampNanos = timestampNanos;
mFrame = frame;
Message msg = Message.obtain(mHandler, this); //callback传了this, 执行下面的run方法
msg.setAsynchronous(true);
mHandler.sendMessageAtTime(msg, timestampNanos / TimeUtils.NANOS_PER_MS);
}
@Override
public void run() {
mHavePendingVsync = false;
doFrame(mTimestampNanos, mFrame);//见13
}
将vsync事件通过Handler去处理。
13、Choreographer.doFrame
void doFrame(long frameTimeNanos, int frame) {
final long startNanos;
synchronized (mLock) {
if (!mFrameScheduled) {
return; // no work to do
}
long intendedFrameTimeNanos = frameTimeNanos;
startNanos = System.nanoTime();
final long jitterNanos = startNanos - frameTimeNanos;
if (jitterNanos >= mFrameIntervalNanos) {
final long skippedFrames = jitterNanos / mFrameIntervalNanos;
if (skippedFrames >= SKIPPED_FRAME_WARNING_LIMIT) {//SKIPPED_FRAME_WARNING_LIMIT默认30
//注意1 -----------------------------------------------------------
Log.i(TAG, "Skipped " + skippedFrames + " frames! "
+ "The application may be doing too much work on its main thread.");
}
final long lastFrameOffset = jitterNanos % mFrameIntervalNanos;
frameTimeNanos = startNanos - lastFrameOffset;
}
...
}
//以下几个callback方法做对应事件的处理
//注意2 -----------------------------------------------------------
try {
Trace.traceBegin(Trace.TRACE_TAG_VIEW, "Choreographer#doFrame");
AnimationUtils.lockAnimationClock(frameTimeNanos / TimeUtils.NANOS_PER_MS);
mFrameInfo.markInputHandlingStart();
doCallbacks(Choreographer.CALLBACK_INPUT, frameTimeNanos);
mFrameInfo.markAnimationsStart();
doCallbacks(Choreographer.CALLBACK_ANIMATION, frameTimeNanos);
mFrameInfo.markPerformTraversalsStart();
doCallbacks(Choreographer.CALLBACK_TRAVERSAL, frameTimeNanos);
doCallbacks(Choreographer.CALLBACK_COMMIT, frameTimeNanos);
} finally {
AnimationUtils.unlockAnimationClock();
Trace.traceEnd(Trace.TRACE_TAG_VIEW);
}
}
注意1:这段日志信息相信大家都见过,其实就是vsync传递过来的时间到当前的时间之间没处理的帧数是否大于SKIPPED_FRAME_WARNING_LIMIT(默认30);嗯,Choreographer可以做刷新率的计算
注意2:可以看到回调顺序为
- input事件
- 动画
- view的绘制
14、Choreographer.doCallbacks
void doCallbacks(int callbackType, long frameTimeNanos) {
CallbackRecord callbacks;
...
try {
Trace.traceBegin(Trace.TRACE_TAG_VIEW, CALLBACK_TRACE_TITLES[callbackType]);
for (CallbackRecord c = callbacks; c != null; c = c.next) {
c.run(frameTimeNanos);//见15
}
} finally {
...
}
}
这个方法主要是CallbackRecord.run的执行
15、CallbackRecord.run
public void run(long frameTimeNanos) {
if (token == FRAME_CALLBACK_TOKEN) {
((FrameCallback)action).doFrame(frameTimeNanos);//AnimatorHandler 见16
} else {
((Runnable)action).run();
}
}
action是FrameCallback的实例引用,实际上此处就是前文提到的AnimationHandler的mFrameCallback
16、doFrame
public void doFrame(long frameTimeNanos) {
doAnimationFrame(getProvider().getFrameTime());//见17
if (mAnimationCallbacks.size() > 0) {
getProvider().postFrameCallback(this);这里重复了第5小节的,所以整个动画框架就构成了一个循环,不断的去更新
}
}
getProvider().postFrameCallback(this);
这行代码重复了第5小节的的内容,所以整个动画框架就构成了一个循环,不断的去更新。
小结:到这里可以说已经清楚了整个框架大致的更新机制了,ObjectAnimator/ValueAnimator通过AnimationHandler间接去调用Choreography,而Choreography封装了DisplayEventReceiver,DisplayEventReceiver能接收VSYNC垂直同步机制的信号。然后把收到的事件回调给AnimationHandler,而后AnimationHandler在传递回去给ObjectAnimator/ValueAnimator。
接着看看AnimationHandler.doAnimationFrame方法是如何把事件传递给ValueAnimator的
17、AnimationHandler.doAnimationFrame
private void doAnimationFrame(long frameTime) {
long currentTime = SystemClock.uptimeMillis();
final int size = mAnimationCallbacks.size();
for (int i = 0; i < size; i++) {
final AnimationFrameCallback callback = mAnimationCallbacks.get(i);
if (callback == null) {
continue;
}
if (isCallbackDue(callback, currentTime)) {
callback.doAnimationFrame(frameTime);//见18
...
}
}
cleanUpList();
}
主要调了callback.doAnimationFrame(frameTime)方法,callback就是第3小节ValueAnimator.addAnimationCallback方法内部传递给AnimationHandler的this对象,所以接下来就是ValueAnimator.doAnimationFrame方法
18、ValueAnimator.doAnimationFrame
public final boolean doAnimationFrame(long frameTime) {
//省略一大段逻辑
...
final long currentTime = Math.max(frameTime, mStartTime);
//animateBasedOnTime返回值代表动画是否结束
boolean finished = animateBasedOnTime(currentTime);//见19
//如果结束
if (finished) {
endAnimation();
}
return finished;
}
19、ValueAnimator.animateBasedOnTime
boolean animateBasedOnTime(long currentTime) {
boolean done = false;
if (mRunning) {
final long scaledDuration = getScaledDuration();
//fraction表示单次动画进度,基于时间,范围 0~1f
final float fraction = scaledDuration > 0 ?
(float)(currentTime - mStartTime) / scaledDuration : 1f;
final float lastFraction = mOverallFraction;
final boolean newIteration = (int) fraction > (int) lastFraction;
final boolean lastIterationFinished = (fraction >= mRepeatCount + 1) &&
(mRepeatCount != INFINITE);
if (scaledDuration == 0) {
// 0 duration animator, ignore the repeat count and skip to the end
done = true;
} else if (newIteration && !lastIterationFinished) {
// Time to repeat
if (mListeners != null) {
int numListeners = mListeners.size();
for (int i = 0; i < numListeners; ++i) {
mListeners.get(i).onAnimationRepeat(this);//动画重复回调
}
}
} else if (lastIterationFinished) {
done = true;
}
//mOverallFraction总的动画进度,包括重复动画
mOverallFraction = clampFraction(fraction);
float currentIterationFraction = getCurrentIterationFraction(
mOverallFraction, mReversing);
animateValue(currentIterationFraction);//见20
}
return done;
}
这个方法基于时间做了计算当前动画进度,然后把进度传递给了animateValue方法
20、ValueAnimator.animateValue
@CallSuper
void animateValue(float fraction) {
//mInterpolator是通过setInterpolator方法设置的,默认是AccelerateDecelerateInterpolator
//getInterpolation返回的fraction是经过TimeInterpolator处理的,getInterpolation方法接收一个基于时间的fraction
fraction = mInterpolator.getInterpolation(fraction);//见22
mCurrentFraction = fraction;
int numValues = mValues.length;
for (int i = 0; i < numValues; ++i) {
mValues[i].calculateValue(fraction);//见23 根据fraction计算动画真正的值
}
if (mUpdateListeners != null) {
int numListeners = mUpdateListeners.size();
for (int i = 0; i < numListeners; ++i) {
mUpdateListeners.get(i).onAnimationUpdate(this);//回调
}
}
}
把基于时间的fraction通过插值器转换为基于数值的fraction,然后根据新的fraction通过估值器计算动画当前真正的数值。
另外可以看到这个方法用了@CallSuper注解,不难猜出子类ObjectAnimator很有可能重写了该方法。跟进看看
21、ObjectAnimator.animateValue
void animateValue(float fraction) {
final Object target = getTarget();
if (mTarget != null && target == null) {
// We lost the target reference, cancel and clean up. Note: we allow null target if the
/// target has never been set.
cancel();
return;
}
super.animateValue(fraction);
int numValues = mValues.length;
for (int i = 0; i < numValues; ++i) {
mValues[i].setAnimatedValue(target);//这里应该是通过反射做动画了
}
}
大胆的猜测mValues[i].setAnimatedValue是通过反射做动画了,不再跟进了
22、Interpolator.getInterpolation
TimeInterpolator是一个接口,看下最简单的实现LinearInterpolator
public float getInterpolation(float input) {
return input;
}
果然够简单,直接返回输入的参数
23、mValues[i].calculateValue(fraction)
mValues是PropertyValuesHolder数组,PropertyValuesHolder.calculateValue最终会走到TypeEvaluator.evaluate方法,看下TypeEvaluator的一个实现IntEvaluator
public class IntEvaluator implements TypeEvaluator<Integer> {
public Integer evaluate(float fraction, Integer startValue, Integer endValue) {
int startInt = startValue;
return (int)(startInt + fraction * (endValue - startInt));
}
}
结果就是 开始值+(结束值-开始值)*进度,这里的fraction就是估值器TimeInterpolator计算的结果