Android消息循环机制(三)View postDelayed和postOnAnimationDelayed区别

在最近做开发的时候,刚好用到了这两个方法,细研究了一下两者的区别。

我们一般长用的是postDelayed,其实很简单,就是用Handler把message放到消息列队里,让主线程去执行。

主要是postOnAnimationDelayed,第一次用,在做嵌套滑动的时候,需要去处理fling,用到了这个函数。

    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);
        }
    }

调用了ViewRootImpl中Choreographer的postCallbackDelayed函数

    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);
            }
        }
    }

我们看主要逻辑,其实就是把Message设置成异步消息,异步消息简单来说就是这类消息会优先执行,不会受屏障的影响。具体可以看Android消息循环机制(二)Meassage、MessageQueue源码解析

猜你喜欢

转载自blog.csdn.net/lizhongyisailang/article/details/129257070