歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Android的postOnAnimation分析

在Android中繪圖中,線程可以使用postOnAnimation函數,用於在系統進行下一次動畫操作時,運行當前的線程,postOnAnimation(this):
 
    public void postOnAnimation(Runnable action) {
        final AttachInfo attachInfo = mAttachInfo;
        if (attachInfo != null) {
            attachInfo.mViewRootImpl.mChoreographer.postCallback(
                    Choreographer.CALLBACK_ANIMATION, action, null);
        } else {
            // Assume that post will succeed later
            ViewRootImpl.getRunQueue().post(action);
        }
    }
 
只看attachInfo不為空的情況,會執行if裡面的語句,可以看到屬性的Choreographer,看一下Choreographer的postCallback:
 
    public void postCallback(int callbackType, Runnable action, Object token) {
        postCallbackDelayed(callbackType, action, token, 0);
    }
 
postCallbackDelayed: 

  public void postCallbackDelayed(int callbackType,
            Runnable action, Object token, long delayMillis) {
        if (action == null) {
            throw new IllegalArgumentException("action must not be null");
        }
        if (callbackType < 0 || callbackType > CALLBACK_LAST) {
            throw new IllegalArgumentException("callbackType is invalid");
        }
 
        postCallbackDelayedInternal(callbackType, action, token, delayMillis);
    }
 
可見最終的實現是在postCallbackDelayedInternal裡面,看一下postCallbackDelayedInternal的代碼:
 
  private void postCallbackDelayedInternal(int callbackType,
            Object action, Object token, long delayMillis) {
        if (DEBUG) {
            Xlog.d(TAG, "PostCallback: type=" + callbackType
                    + ", action=" + action + ", token=" + token
                    + ", delayMillis=" + delayMillis + ",this = " + this);
        }
            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);
            }
        }
    }
 
可以看到在postCallbackDelayedInternal裡,在mCallbackQueues隊列裡面的callbackType添加一個元素。mCallbackQueues是一個CallbackQueue,從命名裡就可以看出現,是一個用於回調的隊列,並且是安時間先後順序排好的,與鬧鐘原理一樣,並且裡面有一個CallbackRecord類,記錄回調相關的信息。callbackType的類型有三種:CALLBACK_INPUT、CALLBACK_ANIMATION、CALLBACK_TRAVERSAL,這裡我們用的是CALLBACK_ANIMATION。在postOnAnimation沒有delay,所以只要收到Vsync信號,便立即會被執行 。當有Vsync到來是,會執行doFrame,doFrame裡有:
 
...
 
        doCallbacks(Choreographer.CALLBACK_INPUT, frameTimeNanos);
        doCallbacks(Choreographer.CALLBACK_ANIMATION, frameTimeNanos);
        doCallbacks(Choreographer.CALLBACK_TRAVERSAL, frameTimeNanos);
 

doCallbacks裡面有如下語句:
 

...
 
 callbacks = mCallbackQueues[callbackType].extractDueCallbacksLocked(now);
 

...
 
        try {
            for (CallbackRecord c = callbacks; c != null; c = c.next) {
                if (DEBUG) {
                    Xlog.d(TAG, "RunCallback: type=" + callbackType
                            + ", action=" + c.action + ", token=" + c.token
                            + ", latencyMillis=" + (SystemClock.uptimeMillis() - c.dueTime)
                            + ",this = " + this);
                }
                c.run(frameTimeNanos);
            }
        } finally {
 

...
 
doCallbacks遍歷postCallbackDelayedInternal裡面添加的元素,並執行元素裡的run函數,整個流程也就跑了一遍。

更多Android相關信息見Android 專題頁面 http://www.linuxidc.com/topicnews.aspx?tid=11

Copyright © Linux教程網 All Rights Reserved