Choreographer Init

frameworks/base/core/java/android/view/ViewRootImpl.java

[ViewRootImpl.java–>ViewRootImpl.ViewRootImpl()]

  public ViewRootImpl(Context context, Display display) {        mContext = context;        mWindowSession = WindowManagerGlobal.getWindowSession();        mDisplay = display;        ......        /**           创建Choreographer         */        mChoreographer = Choreographer.getInstance();        mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);        loadSystemProperties();    }

/frameworks/base/core/java/android/view/Choreographer.java

[Choreographer.java–>Choreographer.getInstance()]

  /**     * Gets the choreographer for the calling thread.  Must be called from     * a thread that already has a {@link android.os.Looper} associated with it.     *     * @return The choreographer for this thread.     * @throws IllegalStateException if the thread does not have a looper.     */    public static Choreographer getInstance() {        return sThreadInstance.get();    } ``` [Choreographer.java-->Choreographer.sThreadInstance()] ```   // Thread local storage for the choreographer.      private static final ThreadLocal sThreadInstance =              new ThreadLocal() {          @Override          protected Choreographer initialValue() {              Looper looper = Looper.myLooper();              if (looper == null) {                  throw new IllegalStateException("The current thread must have a looper!");              }              return new Choreographer(looper);          }      };

[Choreographer.java–>Choreographer.Choreographer()]

private Choreographer(Looper looper) {           mLooper = looper;           mHandler = new FrameHandler(looper);           mDisplayEventReceiver = USE_VSYNC ? new FrameDisplayEventReceiver(looper) : null;           mLastFrameTimeNanos = Long.MIN_VALUE;           mFrameIntervalNanos = (long)(1000000000 / getRefreshRate());           mCallbackQueues = new CallbackQueue[CALLBACK_LAST + 1];           for (int i = 0; i <= CALLBACK_LAST; i++) {               mCallbackQueues[i] = new CallbackQueue();           }       }

1.mLooper

2.mHandler

3.mDisplayEventReceiver

4.mCallbackQueues

1.mLooper

mLooper = looper –> looper = Looper.myLooper()

/frameworks/base/core/java/android/os/Looper.java

[Looper.java–>Looper.myLooper()]

    /**     * Return the Looper object associated with the current thread.  Returns     * null if the calling thread is not associated with a Looper.     */    /**       返回和当前线程绑定的Looper     */    public static @Nullable Looper myLooper() {        return sThreadLocal.get();    }

2.mHandler

mHandler = new FrameHandler(looper)

/frameworks/base/core/java/android/view/Choreographer.java

[Choreographer.java–>Choreographer.Choreographer().FrameHandler()]

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

3.mDisplayEventReceiver

mDisplayEventReceiver = USE_VSYNC ? new FrameDisplayEventReceiver(looper) : null;

/frameworks/base/core/java/android/view/Choreographer.java
[Choreographer.java–>FrameDisplayEventReceiver]

    private final class FrameDisplayEventReceiver extends DisplayEventReceiver            implements Runnable {        private boolean mHavePendingVsync;        private long mTimestampNanos;        private int mFrame;        public FrameDisplayEventReceiver(Looper looper) {            super(looper);        }    }

frameworks/base/core/java/android/view/DisplayEventReceiver.java
[DisplayEventReceiver.java–>DisplayEventReceiver()]

    /**     * Creates a display event receiver.     *     * @param looper The looper to use when invoking callbacks.     */    public DisplayEventReceiver(Looper looper) {        if (looper == null) {            throw new IllegalArgumentException("looper must not be null");        }        mMessageQueue = looper.getQueue();        mReceiverPtr = nativeInit(new WeakReference(this), mMessageQueue);        mCloseGuard.open("dispose");    }

/frameworks/base/core/jni/android_view_DisplayEventReceiver.cpp
[android_view_DisplayEventReceiver.cpp–>nativeInit()]

static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak,        jobject messageQueueObj) {    /**       1. 获取messageQueue     */    sp messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);    if (messageQueue == NULL) {        jniThrowRuntimeException(env, "MessageQueue is not initialized.");        return 0;    }    /**      2. 创建一个NativeDisplayEventReceiver     */    sp receiver = new NativeDisplayEventReceiver(env,            receiverWeak, messageQueue);    /**      3. 调用NativeDisplayEventReceiver的initialize函数     */         status_t status = receiver->initialize();    if (status) {        String8 message;        message.appendFormat("Failed to initialize display event receiver.  status=%d", status);        jniThrowRuntimeException(env, message.string());        return 0;    }    receiver->incStrong(gDisplayEventReceiverClassInfo.clazz); // retain a reference for the object    /**       4. 返回一个NativeDisplayEventReceiver     */    return reinterpret_cast(receiver.get());}

3.1 messageQueue

3.2 NativeDisplayEventReceiver

[android_view_DisplayEventReceiver.cpp–>NativeDisplayEventReceiver]

class NativeDisplayEventReceiver : public DisplayEventDispatcher {public:    NativeDisplayEventReceiver(JNIEnv* env,            jobject receiverWeak, const sp& messageQueue);    void dispose();protected:    virtual ~NativeDisplayEventReceiver();private:    jobject mReceiverWeakGlobal;    sp mMessageQueue;    /**       NativeDisplayEventReceiver中有DisplayEventReceiver,则在创建NativeDisplayEventReceiver       对象时调用DisplayEventReceiver的构造方法     */    DisplayEventReceiver mReceiver;    bool mWaitingForVsync;    virtual void dispatchVsync(nsecs_t timestamp, int32_t id, uint32_t count);    virtual void dispatchHotplug(nsecs_t timestamp, int32_t id, bool connected);};

/frameworks/native/libs/gui/DisplayEventReceiver.cpp
[DisplayEventReceiver.cpp–>DisplayEventReceiver()]

DisplayEventReceiver::DisplayEventReceiver() {    /**       1. 创建ISurfaceComposer     */    sp sf(ComposerService::getComposerService());    if (sf != NULL) {        /**           2. 调用ISurfaceComposer的createDisplayEventConnection()函数创建EventConnection         */        mEventConnection = sf->createDisplayEventConnection();        if (mEventConnection != NULL) {            /**               3. 调用getDataChannel函数,mDataChannel对应的是BitTube             */            mDataChannel = mEventConnection->getDataChannel();        }    }}

3.1.1ComposerService

/frameworks/native/include/private/gui/ComposerService.h
[ComposerService.h]

class ComposerService : public Singleton{    sp mComposerService;    sp mDeathObserver;    Mutex mLock;    ComposerService();    void connectLocked();    void composerServiceDied();    friend class Singleton;public:    // Get a connection to the Composer Service.  This will block until    // a connection is established.    static sp getComposerService();};

/frameworks/native/libs/gui/SurfaceComposerClient.cpp
[SurfaceComposerClient.cpp]

/**   ComposerService单例模式,在/system/core/include/utils/Singleton.h中有定义 */ANDROID_SINGLETON_STATIC_INSTANCE(ComposerService);/**   ComposerService构造函数,调用connectLocked()函数 */ComposerService::ComposerService(): Singleton() {    Mutex::Autolock _l(mLock);    connectLocked();}/**   获取mComposerService,即SurfaceFlinger服务的连接 */void ComposerService::connectLocked() {    const String16 name("SurfaceFlinger");    /**       >sp mComposerService;       getService将mComposerService实例化成一个BpSurfaceComposer对象,定义在ISurfaceComposer.cpp中       其中这里的BpSurfaceComposer已经获得了SurfaceFlinger的service的在binder驱动中的handle值       mComposerService是一个 BpSurfaceComposer(new BpBinder(handle))对象        >getService是从ServiceManager进程中查找"SurfaceFlinger"的Binder对应的handle值,       返回的out型参数mComposerService对应的就是"SurfaceFlinger" binder 服务端的客户端Binder对象,通过这个       mComposerService就可以和"SurfaceFlinger"进行通信     */    while (getService(name, &mComposerService) != NO_ERROR) {        usleep(250000);    }    assert(mComposerService != NULL);    // Create the death listener.    class DeathObserver : public IBinder::DeathRecipient {        ComposerService& mComposerService;        virtual void binderDied(const wp& who) {            ALOGW("ComposerService remote (surfaceflinger) died [%p]",                  who.unsafe_get());            mComposerService.composerServiceDied();        }     public:        DeathObserver(ComposerService& mgr) : mComposerService(mgr) { }    };    mDeathObserver = new DeathObserver(*const_cast(this));    IInterface::asBinder(mComposerService)->linkToDeath(mDeathObserver);}/*static*/ sp ComposerService::getComposerService() {    /**       static方法获取单例模式下的BpSurfaceComposer(new BpBinder(handle))对象     */    ComposerService& instance = ComposerService::getInstance();    Mutex::Autolock _l(instance.mLock);    if (instance.mComposerService == NULL) {        ComposerService::getInstance().connectLocked();        assert(instance.mComposerService != NULL);        ALOGD("ComposerService reconnected");    }    return instance.mComposerService;}void ComposerService::composerServiceDied(){    Mutex::Autolock _l(mLock);    mComposerService = NULL;    mDeathObserver = NULL;}

/frameworks/native/include/binder/IServiceManager.h
[IServiceManager.h–>IServiceManager::getService()]

templatestatus_t getService(const String16& name, sp* outService){    /**       defaultServiceManager返回的进程范围内唯一的BpServiceManager,即       sm = new BpServiceManager(new BpBinder(0));     */    const sp sm = defaultServiceManager();    if (sm != NULL) {        /**            sm->getService(name): 会调用BpServiceManager中的getService函数,            经过binder驱动程序和service_manager守护进程进行通信,得到service名            称为name的service的handle值,返回的是一个BpBinder(handle)         */         /**            interface_cast(new BpBinder(handle))会创建一个BpINTERFACE对象,           */        *outService = interface_cast(sm->getService(name));        if ((*outService) != NULL) return NO_ERROR;    }    return NAME_NOT_FOUND;}

sm返回的是一个BpServiceManager对象,该对象是一个Binder的客户端,也就是Service_Manager
服务守护进程的Bp客户端,相当于是BpServiceManager(new BpBinder(0)),根据前面的服务名称
”SurfaceFlinger”,最终outService返回的是一个BpSurfaceComposer对象

/frameworks/native/services/surfaceflinger/SurfaceFlinger.h

[SurfaceFlinger.h]

 /**    SurfaceFlinger是BnSurfaceComposer的实现者,因此ComposerService::getComposerService()获取的服务,即是SurfaceFlinger  */class SurfaceFlinger : public BnSurfaceComposer,                       private IBinder::DeathRecipient,                       private HWComposer::EventHandler{

ComposerService::getComposerService()返回的是一个与SurfaceFlinger进程建立Binder进程通信的客户端,服务端就SurfaceFlinger对象本身

3.1.2mEventConnection

mEventConnection = sf->createDisplayEventConnection();

/frameworks/native/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
[SurfaceFlinger_hwc1.cpp–>SurfaceFlinger_hwc1::createDisplayEventConnection()]

/**    返回DisplayEventReceiver构造函数中的mEventConnection是一个BpDisplayEventConnection对象 */sp SurfaceFlinger::createDisplayEventConnection() {    return mEventThread->createEventConnection();}

/frameworks/native/services/surfaceflinger/EventThread.cpp

[EventThread.cpp–>EventThread::createEventConnection()]

sp EventThread::createEventConnection() const {    return new Connection(const_cast(this));}

[EventThread.cpp–>EventThread::Connection::Connection()]

/**   onnection的构造函数会创建一个BitTube对象,BitTube对象中包含一对互联的socket,   一端发送另一端就能收到。并将BitTube对象存储在EventThread::Connection.mChannel里面 */EventThread::Connection::Connection(        const sp& eventThread)    : count(-1), mEventThread(eventThread), mChannel(new BitTube()){}

frameworks/native/libs/gui/BitTube.cpp
[BitTube.cpp–>BitTube::BitTube()]

static const size_t DEFAULT_SOCKET_BUFFER_SIZE = 4 * 1024;BitTube::BitTube()    : mSendFd(-1), mReceiveFd(-1){    init(DEFAULT_SOCKET_BUFFER_SIZE, DEFAULT_SOCKET_BUFFER_SIZE);}

[BitTube.cpp–>BitTube::init()]

void BitTube::init(size_t rcvbuf, size_t sndbuf) {    int sockets[2];    if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets) == 0) {        size_t size = DEFAULT_SOCKET_BUFFER_SIZE;        setsockopt(sockets[0], SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf));        setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf));        // sine we don't use the "return channel", we keep it small...        setsockopt(sockets[0], SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));        setsockopt(sockets[1], SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));        fcntl(sockets[0], F_SETFL, O_NONBLOCK);        fcntl(sockets[1], F_SETFL, O_NONBLOCK);        mReceiveFd = sockets[0];        mSendFd = sockets[1];    } else {        mReceiveFd = -errno;        ALOGE("BitTube: pipe creation failed (%s)", strerror(-mReceiveFd));    }}

/frameworks/native/services/surfaceflinger/EventThread.h
[EventThread.h–>EventThread]

class EventThread : public Thread, private VSyncSource::Callback {    /**       Connection是一个BnDisplayEventConnection对象     */    class Connection : public BnDisplayEventConnection {    public:        Connection(const sp& eventThread);        status_t postEvent(const DisplayEventReceiver::Event& event);        // count >= 1 : continuous event. count is the vsync rate        // count == 0 : one-shot event that has not fired        // count ==-1 : one-shot event that fired this round / disabled        int32_t count;    private:        virtual ~Connection();        virtual void onFirstRef();        virtual sp getDataChannel() const;        virtual void setVsyncRate(uint32_t count);        virtual void requestNextVsync();    // asynchronous        sp const mEventThread;        /**           mChannel是一个BitTube         */        sp const mChannel;    };

3.1.3mDataChannel

mDataChannel= mEventConnection->getDataChannel();
BpDisplayEventConnection.getDataChannel() //IDisplayEventConnection.cpp –>BnDisplayEventConnection.onTransact //IDisplayEventConnection.cpp
–>EventThread::Connection.getDataChannel() //EventThread.cpp

/frameworks/native/services/surfaceflinger/EventThread.cpp

sp<BitTube> EventThread::Connection::getDataChannel() const {    return mChannel;}

[BnDisplayEventConnection.onTransact //IDisplayEventConnection.cpp]

status_t BnDisplayEventConnection::onTransact(    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags){    switch(code) {        case GET_DATA_CHANNEL: {            /**               调用Connection.getDataChannel()函数返回前面创建的BitTube对象:             */            CHECK_INTERFACE(IDisplayEventConnection, data, reply);            sp channel(getDataChannel());            channel->writeToParcel(reply);            return NO_ERROR;        }        case SET_VSYNC_RATE: {            CHECK_INTERFACE(IDisplayEventConnection, data, reply);            setVsyncRate(data.readUint32());            return NO_ERROR;        }        case REQUEST_NEXT_VSYNC: {            CHECK_INTERFACE(IDisplayEventConnection, data, reply);            requestNextVsync();            return NO_ERROR;        }    }    return BBinder::onTransact(code, data, reply, flags);}

/frameworks/native/libs/gui/BitTube.cpp
[BitTube.cpp–>BitTube::writeToParcel()]

status_t BitTube::writeToParcel(Parcel* reply) const{    if (mReceiveFd < 0)        return -EINVAL;    status_t result = reply->writeDupFileDescriptor(mReceiveFd);    close(mReceiveFd);    mReceiveFd = -1;    return result;}

[BpDisplayEventConnection.getDataChannel() //IDisplayEventConnection.cpp]

    virtual sp<BitTube> getDataChannel() const    {        Parcel data, reply;        data.writeInterfaceToken(IDisplayEventConnection::getInterfaceDescriptor());        remote()->transact(GET_DATA_CHANNEL, data, &reply);        return new BitTube(reply);    }

frameworks/native/libs/gui/BitTube.cpp
[BitTube.cpp–>BitTube::BitTube(const Parcel& data)]

/**   构造函数从Parcel中读取前面在SurfaceFlinger进程中写入的socket接收端的描述符 */BitTube::BitTube(const Parcel& data)    : mSendFd(-1), mReceiveFd(-1){    mReceiveFd = dup(data.readFileDescriptor());    if (mReceiveFd < 0) {        mReceiveFd = -errno;        ALOGE("BitTube(Parcel): can't dup filedescriptor (%s)",                strerror(-mReceiveFd));    }}

native层的NativeDisplayEventReceiver对象已经创建结束,这时候客户端进程已经有了一个和SurfaceFlinger服务端相连的socket接收端描述符

3.3 NativeDisplayEventReceiver->initialize()

/frameworks/base/libs/androidfw/DisplayEventDispatcher.cpp
[DisplayEventDispatcher.cpp–>DisplayEventDispatcher::initialize()]

status_t DisplayEventDispatcher::initialize() {    status_t result = mReceiver.initCheck();    if (result) {        ALOGW("Failed to initialize display event receiver, status=%d", result);        return result;    }    /**       参数mReceiver.getFd()返回的是在创建NativeDisplayEventReceiver时从SurfaceFlinger服务端接收回来的socket接收端描述符     */    int rc = mLooper->addFd(mReceiver.getFd(), 0, Looper::EVENT_INPUT,            this, NULL);    if (rc < 0) {        return UNKNOWN_ERROR;    }    return OK;}

/system/core/libutils/Looper.cpp

[Looper.cpp–>Looper::addFd()]

int Looper::addFd(int fd, int ident, int events, Looper_callbackFunc callback, void* data) {   /**      将上面传进来的NativeDisplayEventReceiver对象封装成一个SimpleLooperCallback对象    */    return addFd(fd, ident, events, callback ? new SimpleLooperCallback(callback) : NULL, data);}int Looper::addFd(int fd, int ident, int events, const sp& callback, void* data) {#if DEBUG_CALLBACKS    ALOGD("%p ~ addFd - fd=%d, ident=%d, events=0x%x, callback=%p, data=%p", this, fd, ident,            events, callback.get(), data);#endif    if (!callback.get()) {        if (! mAllowNonCallbacks) {            ALOGE("Invalid attempt to set NULL callback but not allowed for this looper.");            return -1;        }        if (ident < 0) {            ALOGE("Invalid attempt to set NULL callback with ident < 0.");            return -1;        }    } else {        ident = POLL_CALLBACK;    }    { // acquire lock        AutoMutex _l(mLock);        Request request;        request.fd = fd;        request.ident = ident;        request.events = events;        request.seq = mNextRequestSeq++;        request.callback = callback;        request.data = data;        if (mNextRequestSeq == -1) mNextRequestSeq = 0; // reserve sequence number -1        /**           1. 创建一个struct epoll_event结构体对象,将对应的内存全部用清0,并作对应的初始化         */        struct epoll_event eventItem;        request.initEventItem(&eventItem);        /**           2. 查询通过addFd方法已经添加到epoll中监听的文件描述符         */        ssize_t requestIndex = mRequests.indexOfKey(fd);        if (requestIndex < 0) {            /**                查询不到的话,则调用epoll_ctl方法设置EPOLL_CTL_ADD属性将对应的文件描述符添加到epoll监听的描述符中             */            int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, fd, & eventItem);            if (epollResult < 0) {                ALOGE("Error adding epoll events for fd %d: %s", fd, strerror(errno));                return -1;            }            mRequests.add(fd, request);        } else {            int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_MOD, fd, & eventItem);            if (epollResult < 0) {                if (errno == ENOENT) {                    // Tolerate ENOENT because it means that an older file descriptor was                    // closed before its callback was unregistered and meanwhile a new                    // file descriptor with the same number has been created and is now                    // being registered for the first time.  This error may occur naturally                    // when a callback has the side-effect of closing the file descriptor                    // before returning and unregistering itself.  Callback sequence number                    // checks further ensure that the race is benign.                    //                    // Unfortunately due to kernel limitations we need to rebuild the epoll                    // set from scratch because it may contain an old file handle that we are                    // now unable to remove since its file descriptor is no longer valid.                    // No such problem would have occurred if we were using the poll system                    // call instead, but that approach carries others disadvantages.#if DEBUG_CALLBACKS                    ALOGD("%p ~ addFd - EPOLL_CTL_MOD failed due to file descriptor "                            "being recycled, falling back on EPOLL_CTL_ADD: %s",                            this, strerror(errno));#endif                    epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, fd, & eventItem);                    if (epollResult < 0) {                        ALOGE("Error modifying or adding epoll events for fd %d: %s",                                fd, strerror(errno));                        return -1;                    }                    scheduleEpollRebuildLocked();                } else {                    ALOGE("Error modifying epoll events for fd %d: %s", fd, strerror(errno));                    return -1;                }            }            mRequests.replaceValueAt(requestIndex, request);        }    } // release lock    return 1;}

addFd传入的参数EVENT_INPUT,说明当前应用线程的native层的Looper对象中的epoll机制已经开始监听来自于SurfaceFlinger服务端socket端的写入事件

4.mCallbackQueues

/frameworks/base/core/java/android/view/Choreographer.java
[Choreographer.java]

    /**     * Callback type: Input callback.  Runs first.     * @hide     */    public static final int CALLBACK_INPUT = 0;    /**     * Callback type: Animation callback.  Runs before traversals.     * @hide     */    public static final int CALLBACK_ANIMATION = 1;    /**     * Callback type: Traversal callback.  Handles layout and draw.  Runs     * after all other asynchronous messages have been handled.     * @hide     */    public static final int CALLBACK_TRAVERSAL = 2;    /**     * Callback type: Commit callback.  Handles post-draw operations for the frame.     * Runs after traversal completes.  The {@link #getFrameTime() frame time} reported     * during this callback may be updated to reflect delays that occurred while     * traversals were in progress in case heavy layout operations caused some frames     * to be skipped.  The frame time reported during this callback provides a better     * estimate of the start time of the frame in which animations (and other updates     * to the view hierarchy state) actually took effect.     * @hide     */    public static final int CALLBACK_COMMIT = 3;    private static final int CALLBACK_LAST = CALLBACK_COMMIT;
           mCallbackQueues = new CallbackQueue[CALLBACK_LAST + 1];           for (int i = 0; i <= CALLBACK_LAST; i++) {               mCallbackQueues[i] = new CallbackQueue();           }

[Choreographer.java–>CallbackQueue]

private final class CallbackQueue {        private CallbackRecord mHead;        public boolean hasDueCallbacksLocked(long now) {            return mHead != null && mHead.dueTime <= now;        }        public CallbackRecord extractDueCallbacksLocked(long now) {            CallbackRecord callbacks = mHead;            if (callbacks == null || callbacks.dueTime > now) {                return null;            }            CallbackRecord last = callbacks;            CallbackRecord next = last.next;            while (next != null) {                if (next.dueTime > now) {                    last.next = null;                    break;                }                last = next;                next = next.next;            }            mHead = next;            return callbacks;        }        public void addCallbackLocked(long dueTime, Object action, Object token) {            CallbackRecord callback = obtainCallbackLocked(dueTime, action, token);            CallbackRecord entry = mHead;            if (entry == null) {                mHead = callback;                return;            }            if (dueTime < entry.dueTime) {                callback.next = entry;                mHead = callback;                return;            }            while (entry.next != null) {                if (dueTime < entry.next.dueTime) {                    callback.next = entry.next;                    break;                }                entry = entry.next;            }            entry.next = callback;        }        public void removeCallbacksLocked(Object action, Object token) {            CallbackRecord predecessor = null;            for (CallbackRecord callback = mHead; callback != null;) {                final CallbackRecord next = callback.next;                if ((action == null || callback.action == action)                        && (token == null || callback.token == token)) {                    if (predecessor != null) {                        predecessor.next = next;                    } else {                        mHead = next;                    }                    recycleCallbackLocked(callback);                } else {                    predecessor = callback;                }                callback = next;            }        }    }

[Choreographer.java–>CallbackRecord]

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

UML图

Android Choreographer 初始化_第1张图片
Choreographer Init UML

更多相关文章

  1. C语言函数以及函数的使用
  2. Android 对象序列化之 Parcelable 取代 Serializable ?
  3. Android 对象序列化之追求完美的 Serial
  4. Android学习札记12:对Parcelable中describeContents()函数的一种
  5. android常用函数参数补充
  6. Android跨进程通信IPC系列
  7. Android跨进程通信IPC之9——Binder之Framework层C++篇2
  8. Android跨进程通信IPC之9——Binder之Framework层C++篇1

随机推荐

  1. android 谷歌地图开发
  2. Android基础知识之Manifest文件的组织结
  3. android手机屏幕适配方法
  4. Android 五种布局简单介绍
  5. Android(安卓)FOTA 升级流程
  6. Android 横屏竖屏切换
  7. Android 体系结构介绍
  8. EditText属性大全
  9. Android怎么让RadioButton图片居中显示
  10. Android NDK带来什么