Animator相关源码分析

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_24477797/article/details/82352622

本篇分析与Animator相关的源码

开始

以下为Animator相关类图

Animator是抽象类,ValueAnimator实现了Animator。

通常设置一个ValueAnimator的方法有:

valueAnim = ValueAnimator.ofFloat(0f, 1f);
valueAnim .setDuration(500);
valueAnim .setRepeatMode(ValueAnimator.RESTART);
valueAnim .setRepeatCount(ValueAnimator.INFINITE);
valueAnim .setInterpolator(new LinearInterpolator());
valueAnim .addUpdateListener(animation -> {
    float value = (float) animation.getAnimatedValue();
    ...
});
valueAnim .start();
valueAnim.setStartDelay(500);

下面以几个问题为目标解析ValueAnimator。

一、ValueAnimator如何实现计时?

从start()入手:

...
private void start(boolean playBackwards) { // playBackwards Whether the ValueAnimator                     
    should start playing in reverse.
    ...
    addAnimationCallback(0);// 真正开启计时
    ...
}
...

@Override
public void start() {
    start(false);
}
...
private void addAnimationCallback(long delay) {
    if (!mSelfPulse) {
        return;
    }
    // this 即ValueAnimator实现AnimationFrameCallback接口的doAnimationFrame()
    getAnimationHandler().addAnimationFrameCallback(this, delay); 
}
...

ValueAnimator将计时抛到了AnimatorHandler,ValueAnimator仅接收计时的结果,由doAnimationFrame()接收。

再看AnimationHandler:

...
public void addAnimationFrameCallback(final AnimationFrameCallback callback, long delay) {
    if (mAnimationCallbacks.size() == 0) { // 第一次统一使用mFrameCallback接受计时结果
        getProvider().postFrameCallback(mFrameCallback);
    }
    if (!mAnimationCallbacks.contains(callback)) { // mFrameCallback通过mAnimationCallbacks实现监听分发
        mAnimationCallbacks.add(callback);
    }
    if (delay > 0) {
        mDelayedCallbackStartTime.put(callback, (SystemClock.uptimeMillis() + delay));
    }
}
...
private AnimationFrameCallbackProvider getProvider() {
    if (mProvider == null) {
        mProvider = new MyFrameCallbackProvider();
    }
    return mProvider;
}

AnimationHandler又抛到了MyFrameCallbackProvider:

private class MyFrameCallbackProvider implements AnimationFrameCallbackProvider {
    final Choreographer mChoreographer = Choreographer.getInstance();
    @Override
    public void postFrameCallback(Choreographer.FrameCallback callback) {
        mChoreographer.postFrameCallback(callback);
    }
    ...
}

接着抛到Choreographer:

...
private final FrameHandler mHandler;
...
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);
}
...
private void postCallbackDelayedInternal(int callbackType,
    Object action, Object token, long delayMillis) {
    ...
    synchronized (mLock) {
        final long now = SystemClock.uptimeMillis();
        final long dueTime = now + delayMillis;
        mCallbackQueues[callbackType].addCallbackLocked(dueTime, action, token);
        if (dueTime <= now) { // 此处在MyFrameCallbackProvider没有实现postFrameCallbackDelayed方法,所以不会调用,自定义FrameCallbackProvider可以实现
            scheduleFrameLocked(now);
        } else {
            Message msg = mHandler.obtainMessage(MSG_DO_SCHEDULE_CALLBACK, action);
            msg.arg1 = callbackType;
            msg.setAsynchronous(true);
            mHandler.sendMessageAtTime(msg, dueTime);
        }
    }
}
...
private final class FrameHandler extends Handler {
    public FrameHandler(Looper looper) {
        super(looper);
    }
    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
            case MSG_DO_FRAME:
                doFrame(System.nanoTime(), 0);
            break;
            case MSG_DO_SCHEDULE_VSYNC:
                doScheduleVsync();
            break;
            case MSG_DO_SCHEDULE_CALLBACK:
                doScheduleCallback(msg.arg1);
            break;
        }
    }
}

Choreographer内部持有FrameHandler,通过Handler的sendMessageAtTime方法实现。到此,计时的位置已经找到了,但是Animator为什么要抛这么多层?抛的好处是什么呢?在此我们需要先了解一些ValueAnimator与AnimatorHandler之间的关系:

这里不贴源码,只阐述:

1)AnimationHandler内部有:

     public final static ThreadLocal<AnimationHandler> sAnimatorHandler = new ThreadLocal<>();

     确保一个线程下只有一个AnimationHandler。

2)内部Handler一直在计时,不管外部ValueAnimator是否有在运行。当有一个新的Animator开始start时,主动开始一次mHandler.sendMessageAtTime(),所有外部ValueAnimator都能接收到。

3)ValueAnimator的延迟、反转、重复、暂停、唤醒等操作都在其内部内部实现,ValueAnimator与AnimationHandler淡出就是时间片更新监听的关系。

4)我们可以通过ValueAnimator.setFrameDelay(5); // 5ms更新一次时间片,设置的是AnimationHandler -> MyFrameCallbackProvider -> Choreographer 的sFrameDelay字段,会强制对当前线程下所有的ValueAnimator适用。

由上可看出:抛到AnimationHandler是合理的。AnimationHandler再抛到MyFrameCallbackProvider,是桥接模式的使用,方便后续扩展。Choreographer为我们自定义的FrameCallbackProvider提供统一的计时方法,所以MyFrameCallbackProvider将计时再抛到Choreographer。

二、插值器如何实现?

mInterpolator只被ValueAnimator持有:

@Override
public void setInterpolator(TimeInterpolator value) {
    if (value != null) {
        mInterpolator = value;
    } else {
        mInterpolator = new LinearInterpolator();
    }
}
...
void animateValue(float fraction) {
    fraction = mInterpolator.getInterpolation(fraction); // mInterpolator在代码中唯一使用的地方
    mCurrentFraction = fraction;
    int numValues = mValues.length;
    for (int i = 0; i < numValues; ++i) {
        mValues[i].calculateValue(fraction);
    }
    if (mUpdateListeners != null) {
        int numListeners = mUpdateListeners.size();
        for (int i = 0; i < numListeners; ++i) {
            mUpdateListeners.get(i).onAnimationUpdate(this);
        }
    }
}

mInterpolator仅仅在UpdateListener之前对值进行换算,所以可以理解:传递给animateValue是线性的值,根据不同的插值器进行换算实现结果。

三、ValueAnimator如何实现延迟、反转、重复次数?

入口点:ValueAnimator的doAnimationFrame();

public final boolean doAnimationFrame(long frameTime) { // 返回值其实外部并没有处理
    if (mStartTime < 0) {
        // mStartDelay为设置(setStartDelay())的延迟时间ms,默认sDurationScale = 1.0f
        mStartTime = mReversing ? frameTime : frameTime + (long) (mStartDelay * sDurationScale);
    }
    // 暂停和唤醒处理
    if (mPaused) {
        mPauseTime = frameTime;
        removeAnimationCallback();
        return false;
    } else if (mResumed) {
        mResumed = false;
        if (mPauseTime > 0) {            
            mStartTime += (frameTime - mPauseTime);
        }
    }
    if (!mRunning) {
        if (mStartTime > frameTime && mSeekFraction == -1) { // 不在我们ValueAnimator工作时间内,不处理
            return false;
        } else { // 从没有运行 -> 运行
            mRunning = true;
            startAnimation();
        }
    }
    // 以下执行都为运行状态
    if (mLastFrameTime < 0) {
        if (mSeekFraction >= 0) {
            long seekTime = (long) (getScaledDuration() * mSeekFraction);
            mStartTime = frameTime - seekTime;
            mSeekFraction = -1;
        }
        mStartTimeCommitted = false;
    }
    mLastFrameTime = frameTime;
    // 比较当前时间片是否在ValueAnimator工作时间内
    final long currentTime = Math.max(frameTime, mStartTime);
    boolean finished = animateBasedOnTime(currentTime);
    if (finished) {
        endAnimation();
    }
    return finished;
}
...
boolean animateBasedOnTime(long currentTime) {
    boolean done = false;
    if (mRunning) {
        final long scaledDuration = getScaledDuration();
        // 计算出当前执行的次数
        final float fraction = scaledDuration > 0 ?
            (float)(currentTime - mStartTime) / scaledDuration : 1f;
        // 上一次执行的次数
        final float lastFraction = mOverallFraction;
        // 是否开始新的Repeat
        final boolean newIteration = (int) fraction > (int) lastFraction;
        final boolean lastIterationFinished = (fraction >= mRepeatCount + 1) &&
            (mRepeatCount != INFINITE); // mRepeatCount == INFINITE,lastIterationFinished永远为false,再根据newIteration执行下方的①
        if (scaledDuration == 0) {// 时间为0时,不考虑其它
            done = true;
        } else if (newIteration && !lastIterationFinished) {// ① 需要开始新的Repeat
            if (mListeners != null) { // 执行Repeat监听
                int numListeners = mListeners.size();
                for (int i = 0; i < numListeners; ++i) {
                    mListeners.get(i).onAnimationRepeat(this);
                }
            }
        } else if (lastIterationFinished) {// 不需要开始新的repeat的正常情况
            done = true;
        }
        mOverallFraction = clampFraction(fraction);
        float currentIterationFraction = getCurrentIterationFraction(
            mOverallFraction, mReversing); // 取值
            animateValue(currentIterationFraction);
        }
        return done;
}
...
private float getCurrentIterationFraction(float fraction, boolean inReverse) {
    fraction = clampFraction(fraction);
    int iteration = getCurrentIteration(fraction);
    float currentFraction = fraction - iteration;
    return shouldPlayBackward(iteration, inReverse) ? 1f - currentFraction : currentFraction; // 反转判断
}

看代码中的注释,我们就将以下三个方法都了解完了

valueAnim .setRepeatMode(ValueAnimator.RESTART);

valueAnim .setRepeatCount(ValueAnimator.INFINITE);

valueAnim.setStartDelay(500);

四、再看下ObjectAnimator和TimeAnimator

ObjectAnimator

ObjectAnimator继承于ValueAnimator,先看其构造源码:

...
private <T> ObjectAnimator(T target, Property<T, ?> property) {
    setTarget(target);
    setProperty(property);
}
...
public static ObjectAnimator ofInt(Object target, String propertyName, int... values) {
    ObjectAnimator anim = new ObjectAnimator(target, propertyName);
    anim.setIntValues(values);
    return anim;
}
...
@Override
public void setTarget(@Nullable Object target) {
    final Object oldTarget = getTarget();
    if (oldTarget != target) {
        if (isStarted()) {
            cancel();
        }
        mTarget = target == null ? null : new WeakReference<Object>(target);
        mInitialized = false;
    }
}
...
public void setValues(PropertyValuesHolder... values) {
    int numValues = values.length;
    mValues = values;
    mValuesMap = new HashMap<String, PropertyValuesHolder>(numValues);
    for (int i = 0; i < numValues; ++i) {
        PropertyValuesHolder valuesHolder = values[i];
        mValuesMap.put(valuesHolder.getPropertyName(), valuesHolder);
    }
    mInitialized = false;
}

target为ObjectAnimator内部弱引用,mValues是ValueAnimator的成员变量,大部分动画的代码都由ValueAnimator来实现了。

再看ObjectAnimator如何为成员变量进行动态赋值的:

...
public Object getTarget() {
    return mTarget == null ? null : mTarget.get();
}
...
@Override
void animateValue(float fraction) {
    final Object target = getTarget();
    if (mTarget != null && target == null) {
        cancel();
        return;
    }
    super.animateValue(fraction);
    int numValues = mValues.length;
    for (int i = 0; i < numValues; ++i) {
        mValues[i].setAnimatedValue(target);
    }
}

重载animateValue(),而后对所有的values进行赋值。

TimeAnimator

TimeAnimator.TimeListener:

这个类比较简单,代码很少,主要是对ValueAnimator扩展,实现对动画每一帧的监听。

猜你喜欢

转载自blog.csdn.net/qq_24477797/article/details/82352622