View onDraw调用流程分析

文章详细解析了Android系统中Choreographer的工作流程,特别是CALLBACK_TRAVERSAL的作用,它负责布局和绘制。DisplayEventReceiver用于接收硬件垂直同步事件,VSync事件的处理涉及EventThread、CallbackRepeater和TimeKeeper等组件,形成了一个复杂的同步机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这里插入图片描述

我们直接分析 Choreographer 。

1 Choreographer :

mChoreographer.postCallback(
Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
然后会调用 ViewRootImpl 的 mTraversalRunnable ,到 doTraversal()方法 。

Choreographer.CALLBACK_TRAVERSAL 是指什么 ?

/**
* Callback type: Traversal callback. Handles layout and draw. Runs
* after all other asynchronous messages have been handled.
* @hide
*/
public static final int CALLBACK_TRAVERSAL = 3;

首先 有5种 :

public static final int CALLBACK_INPUT = 0;
public static final int CALLBACK_ANIMATION = 1;
public static final int CALLBACK_INSETS_ANIMATION = 2;
public static final int CALLBACK_TRAVERSAL = 3;
public static final int CALLBACK_COMMIT = 4;

doFrame 依次调用上述的 5类 doCallbacks 。

什么是DisplayEventReceiver?:

DisplayEventReceiver :用来接受硬件的 vertical sync 事件 。
在构造函数中调用 jni的 nativeInit 。
jni: android_view_DisplayEventReceiver.cpp
何时回调 onVsync ?
在 jni的nativeInit中 ,创建了一个NativeDisplayEventReceiver, 并调用它的initialize()方法;

##########################以下分析都是Native代码####################################

什么是NativeDisplayEventReceiver?:

NativeDisplayEventReceiver 继承 DisplayEventDispatcher,

DisplayEventDispatcher解析:

native 端也有 一个 DisplayEventReceiver 类 :

DisplayEventReceiver 解析:

有一个变量mDataChannel, 这个是来自于调用 sf 的createDisplayEventConnection方法,
这个 mDataChannel 就是

EventThreadConnection::postEvent方法会发送事件到 mDataChannel 这个fd , ,

EventThread::dispatchEvent 调用 EventThreadConnection::postEvent ,

EventThread::threadMain 调用 EventThread::dispatchEvent ,

EventThread的 mPendingEvents表示还没有处理的事件,还没有发给客户端的事件,

EventThread 收到VSync事件的处理如下:

void EventThread::onVSyncEvent(nsecs_t timestamp, VSyncSource::VSyncData vsyncData) {
    std::lock_guard<std::mutex> lock(mMutex);

    LOG_FATAL_IF(!mVSyncState);
    mPendingEvents.push_back(makeVSync(mVSyncState->displayId, timestamp, ++mVSyncState->count,
                                       vsyncData.expectedPresentationTime,
                                       vsyncData.deadlineTimestamp));
    mCondition.notify_all();
}

就是往 mPendingEvents 插入一个 VSync事件 ,然后唤醒发送线程。

EventThread::onVSyncEvent 被谁调用?

被DispSyncSource::onVsyncCallback 调用

DispSyncSource::onVsyncCallback 被谁调用?

CallbackRepeater 的 callback 方法调用 。
其实是调用了 VSyncDispatch 的registerCallback 方法 。

VSyncDispatch 的子类有 VSyncDispatchTimerQueue:
最终是把这个方法放进去了 VSyncDispatchTimerQueue 的 mCallbacks 中 。

VSyncDispatchTimerQueue::timerCallback() 被谁调用?

TimeKeeper的 alarmAt 在指定时间执行callback 。
实现原理是创建了一个timerfd ,然后放入epoll 中 。

CallbackRepeater 解析:

VSyncCallbackRegistration 解析:

VSyncDispatch::CallbackToken mToken;
方法:
schedule :
cancel :

何时调用DisplayEventDispatcher::handleEvent 方法 ?:

handleEvent 是 LooperCallback 的方法 。
所以这个方法自然是looper所监听的fd有事件发生时调用的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值