Android message loop mechanism (3) Difference between View postDelayed and postOnAnimationDelayed

When doing development recently, I just used these two methods, and studied the difference between the two in detail.

We generally use postDelayed for a long time. In fact, it is very simple. It is to use Handler to put the message in the message queue and let the main thread execute it.

It is mainly postOnAnimationDelayed, which is used for the first time. When doing nested sliding, it needs to process fling, and this function is used.

    public void postOnAnimationDelayed(Runnable action, long delayMillis) {
    
    
        final AttachInfo attachInfo = mAttachInfo;
        if (attachInfo != null) {
    
    
            attachInfo.mViewRootImpl.mChoreographer.postCallbackDelayed(
                    Choreographer.CALLBACK_ANIMATION, action, null, delayMillis);
        } else {
    
    
            // Postpone the runnable until we know
            // on which thread it needs to run.
            getRunQueue().postDelayed(action, delayMillis);
        }
    }

The postCallbackDelayed function of Choreographer in ViewRootImpl is called

    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) {
    
    
            final long now = SystemClock.uptimeMillis();
            final long dueTime = now + delayMillis;
            mCallbackQueues[callbackType].addCallbackLocked(dueTime, action, token);

            if (dueTime <= now) {
    
    
                scheduleFrameLocked(now);
            } else {
    
    
                Message msg = mHandler.obtainMessage(MSG_DO_SCHEDULE_CALLBACK, action);
                msg.arg1 = callbackType;
                msg.setAsynchronous(true);
                mHandler.sendMessageAtTime(msg, dueTime);
            }
        }
    }

    private void scheduleFrameLocked(long now) {
    
    
        if (!mFrameScheduled) {
    
    
            mFrameScheduled = true;
            if (USE_VSYNC) {
    
    
                if (DEBUG_FRAMES) {
    
    
                    Log.d(TAG, "Scheduling next frame on vsync.");
                }

                // If running on the Looper thread, then schedule the vsync immediately,
                // otherwise post a message to schedule the vsync from the UI thread
                // as soon as possible.
                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);
            }
        }
    }

Let's look at the main logic. In fact, it is to set the Message as an asynchronous message. Simply put, an asynchronous message means that this type of message will be executed first and will not be affected by the barrier. For details, you can see the Android message loop mechanism (2) Meassage, MessageQueue source code analysis

Guess you like

Origin blog.csdn.net/lizhongyisailang/article/details/129257070