美文网首页
ValueAnimator源码解析-基于Android API3

ValueAnimator源码解析-基于Android API3

作者: Ray206 | 来源:发表于2022-03-10 15:23 被阅读0次
    时序图.png

    先上个时序图,整个调用链都在图里了。

    源码

    ValueAnimator.java

        public void start() {
            start(false);
        }
    
    private void start(boolean playBackwards) {
            //所以在线程中执行时必须得Looper.prepare()
            if (Looper.myLooper() == null) {
                throw new AndroidRuntimeException("Animators may only be run on Looper threads");
            }
           ...省略
            addAnimationCallback(0);
            //如果不延迟启动
            if (mStartDelay == 0 || mSeekFraction >= 0 || mReversing) {
                // If there's no start delay, init the animation and notify start listeners right away
                // to be consistent with the previous behavior. Otherwise, postpone this until the first
                // frame after the start delay.
                //开始动画,回调动画开始了
                startAnimation();
                if (mSeekFraction == -1) {
                    // No seek, start at play time 0. Note that the reason we are not using fraction 0
                    // is because for animations with 0 duration, we want to be consistent with pre-N
                    // behavior: skip to the final value immediately.
                    setCurrentPlayTime(0);
                } else {
                    setCurrentFraction(mSeekFraction);
                }
            }
        }
    
        private void addAnimationCallback(long delay) {
            if (!mSelfPulse) {
                return;
            }
            getAnimationHandler().addAnimationFrameCallback(this, delay);
        }
    
        public AnimationHandler getAnimationHandler() {
            return mAnimationHandler != null ? mAnimationHandler : AnimationHandler.getInstance();
        }
    

    初始化动画,并将监听添加到AnimationHandler

    AnimationHandler.java

        private final Choreographer.FrameCallback mFrameCallback = new Choreographer.FrameCallback() {
            @Override
            public void doFrame(long frameTimeNanos) {
                doAnimationFrame(getProvider().getFrameTime());
                //动画回调不为空,继续请求信号量
                if (mAnimationCallbacks.size() > 0) {
                    getProvider().postFrameCallback(this);
                }
            }
        };
    
        public void addAnimationFrameCallback(final AnimationFrameCallback callback, long delay) {
            if (mAnimationCallbacks.size() == 0) {
                //Frame监听
                getProvider().postFrameCallback(mFrameCallback);
            }
            if (!mAnimationCallbacks.contains(callback)) {
                //动画回调
                mAnimationCallbacks.add(callback);
            }
    
            if (delay > 0) {
                //延迟
                mDelayedCallbackStartTime.put(callback, (SystemClock.uptimeMillis() + delay));
            }
        }
    
        private AnimationFrameCallbackProvider getProvider() {
            if (mProvider == null) {
                mProvider = new MyFrameCallbackProvider();
            }
            return mProvider;
        }
    
        private class MyFrameCallbackProvider implements AnimationFrameCallbackProvider {
    
            final Choreographer mChoreographer = Choreographer.getInstance();
    
            @Override
            public void postFrameCallback(Choreographer.FrameCallback callback) {
                //添加Frame监听
                mChoreographer.postFrameCallback(callback);
            }
    
            @Override
            public void postCommitCallback(Runnable runnable) {
                mChoreographer.postCallback(Choreographer.CALLBACK_COMMIT, runnable, null);
            }
    
            @Override
            public long getFrameTime() {
                return mChoreographer.getFrameTime();
            }
    
            @Override
            public long getFrameDelay() {
                return Choreographer.getFrameDelay();
            }
    
            @Override
            public void setFrameDelay(long delay) {
                Choreographer.setFrameDelay(delay);
            }
        }
    

    将Frame监听添加到Choreographer

    Choreographer.java

        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) {
            if (DEBUG_FRAMES) {
                Log.d(TAG, "PostCallback: type=" + callbackType
                        + ", action=" + action + ", token=" + token
                        + ", delayMillis=" + delayMillis);
            }
    
            synchronized (mLock) {
                 ...省略
                scheduleFrameLocked(now);
            }
        }
    
        private void scheduleFrameLocked(long now) {
            if (!mFrameScheduled) {
                mFrameScheduled = true;
                if (USE_VSYNC) {
                    if (DEBUG_FRAMES) {
                        Log.d(TAG, "Scheduling next frame on vsync.");
                    }
    
                    //是否在主线程,如果没有在主线程则发送同步消息,最终还是会执行scheduleVsyncLocked
                    if (isRunningOnLooperThreadLocked()) {
                        scheduleVsyncLocked();
                    } else {
                        Message msg = mHandler.obtainMessage(MSG_DO_SCHEDULE_VSYNC);
                        msg.setAsynchronous(true);
                        mHandler.sendMessageAtFrontOfQueue(msg);
                    }
                } else {
                    final long nextFrameTime = Math.max(
                            mLastFrameTimeNanos / TimeUtils.NANOS_PER_MS + sFrameDelay, now);
                    if (DEBUG_FRAMES) {
                        Log.d(TAG, "Scheduling next frame in " + (nextFrameTime - now) + " ms.");
                    }
                    Message msg = mHandler.obtainMessage(MSG_DO_FRAME);
                    msg.setAsynchronous(true);
                    mHandler.sendMessageAtTime(msg, nextFrameTime);
                }
            }
        }
        
        private void scheduleVsyncLocked() {
            //请求下一个信号
            mDisplayEventReceiver.scheduleVsync();
        }
    

    请求下一个信号,不明白信号的可看《Android 底层渲染 - 屏幕刷新机制源码分析》

    FrameDisplayEventReceiver.java

    private final class FrameDisplayEventReceiver extends DisplayEventReceiver
                implements Runnable {
            private boolean mHavePendingVsync;
            private long mTimestampNanos;
            private int mFrame;
    
            public FrameDisplayEventReceiver(Looper looper, int vsyncSource) {
                super(looper, vsyncSource, CONFIG_CHANGED_EVENT_SUPPRESS);
            }
    
            //信号来了处理
            @Override
            public void onVsync(long timestampNanos, long physicalDisplayId, int frame) {
                // Post the vsync event to the Handler.
                // The idea is to prevent incoming vsync events from completely starving
                // the message queue.  If there are no messages in the queue with timestamps
                // earlier than the frame time, then the vsync event will be processed immediately.
                // Otherwise, messages that predate the vsync event will be handled first.
                long now = System.nanoTime();
                if (timestampNanos > now) {
                    Log.w(TAG, "Frame time is " + ((timestampNanos - now) * 0.000001f)
                            + " ms in the future!  Check that graphics HAL is generating vsync "
                            + "timestamps using the correct timebase.");
                    timestampNanos = now;
                }
    
                if (mHavePendingVsync) {
                    Log.w(TAG, "Already have a pending vsync event.  There should only be "
                            + "one at a time.");
                } else {
                    mHavePendingVsync = true;
                }
                //handler发送同步消息,message的callback就是FrameDisplayEventReceiver
                mTimestampNanos = timestampNanos;
                mFrame = frame;
                Message msg = Message.obtain(mHandler, this);
                msg.setAsynchronous(true);
                mHandler.sendMessageAtTime(msg, timestampNanos / TimeUtils.NANOS_PER_MS);
            }
    
            @Override
            public void run() {
                //handler执行
                mHavePendingVsync = false;
                doFrame(mTimestampNanos, mFrame);
            }
        }
    

    当来了信号量后,执行onvsync,发送Handler同步消息,Message的Callback就是FrameDisplayEventReceiver,最终通过Handler执行了FrameDisplayEventReceiver.run()方法

    DisplayEventReceiver.java

        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);
            }
        }
        private static native void nativeScheduleVsync(long receiverPtr);
        //分发信号量
        private void dispatchVsync(long timestampNanos, long physicalDisplayId, int frame) {
            onVsync(timestampNanos, physicalDisplayId, frame);
        }
    

    请求信号量,并分发处理

    FrameDisplayEventReceiver.java

    void doFrame(long frameTimeNanos, int frame) {
            final long startNanos;
            synchronized (mLock) {
            ...省略
            try {
                ...省略
                doCallbacks(Choreographer.CALLBACK_ANIMATION, frameTimeNanos);
               ...省略
            } finally {
                AnimationUtils.unlockAnimationClock();
                Trace.traceEnd(Trace.TRACE_TAG_VIEW);
            }
    
            if (DEBUG_FRAMES) {
                final long endNanos = System.nanoTime();
                Log.d(TAG, "Frame " + frame + ": Finished, took "
                        + (endNanos - startNanos) * 0.000001f + " ms, latency "
                        + (startNanos - frameTimeNanos) * 0.000001f + " ms.");
            }
        }
    
        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) {
                    if (DEBUG_FRAMES) {
                        Log.d(TAG, "RunCallback: type=" + callbackType
                                + ", action=" + c.action + ", token=" + c.token
                                + ", latencyMillis=" + (SystemClock.uptimeMillis() - c.dueTime));
                    }
                    c.run(frameTimeNanos);
                }
            } finally {  
                回收CallbackRecord,和Handler回收Message类似
                synchronized (mLock) {
                    mCallbacksRunning = false;
                    do {
                        final CallbackRecord next = callbacks.next;
                        recycleCallbackLocked(callbacks);
                        callbacks = next;
                    } while (callbacks != null);
                }
                Trace.traceEnd(Trace.TRACE_TAG_VIEW);
            }
        }
    

    处理回调
    Choreographer.CallbackRecord.java

        private static final class CallbackRecord {
            public CallbackRecord next;
            public long dueTime;
            public Object action; // Runnable or FrameCallback
            public Object token;
    
            @UnsupportedAppUsage
            public void run(long frameTimeNanos) {
                if (token == FRAME_CALLBACK_TOKEN) {
                    //执行Frame回调
                    ((FrameCallback)action).doFrame(frameTimeNanos);
                } else {
                    ((Runnable)action).run();
                }
            }
        }
    

    执行Frame回调

    AnimationHandler.java

        private final Choreographer.FrameCallback mFrameCallback = new Choreographer.FrameCallback() {
            @Override
            public void doFrame(long frameTimeNanos) {
                doAnimationFrame(getProvider().getFrameTime());
                if (mAnimationCallbacks.size() > 0) {
                    getProvider().postFrameCallback(this);
                }
            }
        };
    
        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);
                }
            }
            cleanUpList();
        }
    

    帧回调到动画回调
    ValueAnimator.java

        public final boolean doAnimationFrame(long frameTime) {
            ...省略
            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;
                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 = clampFraction(fraction);
                float currentIterationFraction = getCurrentIterationFraction(
                        mOverallFraction, mReversing);
                //当前进度
                animateValue(currentIterationFraction);
            }
            return done;
        }
    
        void animateValue(float fraction) {
            fraction = mInterpolator.getInterpolation(fraction);
            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);
                }
            }
        }
    
        //结束动画
        private void endAnimation() {
            if (mAnimationEndRequested) {
                return;
            }
            //移除动画监听,所以再也不会有帧相关的计时监听
            removeAnimationCallback();
    
            mAnimationEndRequested = true;
            mPaused = false;
            boolean notify = (mStarted || mRunning) && mListeners != null;
            if (notify && !mRunning) {
                // If it's not yet running, then start listeners weren't called. Call them now.
                notifyStartListeners();
            }
            mRunning = false;
            mStarted = false;
            mStartListenersCalled = false;
            mLastFrameTime = -1;
            mFirstFrameTime = -1;
            mStartTime = -1;
            if (notify && mListeners != null) {
                ArrayList<AnimatorListener> tmpListeners =
                        (ArrayList<AnimatorListener>) mListeners.clone();
                int numListeners = tmpListeners.size();
                for (int i = 0; i < numListeners; ++i) {
                    tmpListeners.get(i).onAnimationEnd(this, mReversing);
                }
            }
            // mReversing needs to be reset *after* notifying the listeners for the end callbacks.
            mReversing = false;
            if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
                Trace.asyncTraceEnd(Trace.TRACE_TAG_VIEW, getNameForTrace(),
                        System.identityHashCode(this));
            }
        }
    

    整个流程就分析完了。动画的核心驱动是,利用屏幕的刷新机制,请求信号,然后在通过Handler的同步消息,执行Frame回调。Frame回调中在执行动画回调。动画回调中根据时间和动画插值。计算出最新的动画值,回调给用户。ValueAnimation中animateBasedOnTime方法会返回当前动画是否结束,如果已经结束就移除动画回调,如果未结束FrameCallback的doFrame中处理完这一帧后,会继续请求下一个信号量。

    相关文章

      网友评论

          本文标题:ValueAnimator源码解析-基于Android API3

          本文链接:https://www.haomeiwen.com/subject/tbdfdrtx.html