Как работает хореограф

Я просто изучал код платформы Android (v4.1).

Я знаю, что сообщение пользовательского интерфейса, инициированное invalidate(), теперь отправляется напрямую в Choreographer вместо UI messageQueue, и эти сообщения не будут выполняться до тех пор, пока не придет следующий сигнал VSYNC.

Прежде чем эта операция публикации будет выполнена, ViewRootImpl вызывает postSyncBarrier() Looper один раз, чтобы заблокировать UI MessageQueue, что означает, что сообщения, которые позже отправляются в messagesQueue, не будут выполняться до тех пор, пока этот блок не будет удален, что происходит перед функцией performTraversals().

Основываясь на вышеизложенном понимании,

Если еще один invalidate() вызывается хотя бы один раз где-то в пределах performTraversals() (например, onDraw() любого экземпляра представления), UI messageQueue будет навсегда заблокирован?

Из практических наблюдений знаю, что такого никогда не бывает.
Итак, где я не прав?


person Simon Lee    schedule 30.08.2013    source источник


Ответы (1)


Я думаю, вы можете получить ответ на этот вопрос, посмотрев код для scheduleTraversals:

void scheduleTraversals() {
    if (!mTraversalScheduled) {
        mTraversalScheduled = true;
        mTraversalBarrier = mHandler.getLooper().postSyncBarrier();
        mChoreographer.postCallback(
                Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
        if (!mUnbufferedInputDispatch) {
            scheduleConsumeBatchedInput();
        }
        notifyRendererOfFramePending();
    }
}

После первого вызова scheduleTraversals mTraversalScheduled устанавливается в true. Последующие вызовы не влияют, postSyncBarrier не вызывается и в очередь не ставится второй барьер, пока не будет вызван unscheduleTraversals.

person G. Blake Meike    schedule 09.08.2015