InputDispatcher:事件的"派发员"
InputDispatcher 从 InputReader 接收事件后,并不会立即盲目发送。它内部维护了一个由 WMS(WindowManagerService) 实时更新的窗口状态表,记录了所有窗口的焦点、层级、可见性等信息。InputDispatcher 会查阅这张表,找到事件的正确目标窗口,然后通过与该窗口建立的 InputChannel(基于Socket)将事件发送过去。整个派发过程是异步和非阻塞的,保证了系统对用户操作的快速响应。
rust
//frameworks/native/services/inputflinger/dispatcher/InputDispatcher.cpp
dispatchMotionLocked(nsecs_t currentTime, std::shared_ptr<MotionEntry> entry,
DropReason* dropReason, nsecs_t* nextWakeupTime) {
ATRACE_CALL();
// Preprocessing.
if (!entry->dispatchInProgress) {
//标记事件正在分发,防止重复处理
entry->dispatchInProgress = true;
}
// Clean up if dropping the event.
//这是一个关键检查。如果 `dropReason` 不是 `NOT_DROPPED`,
意味着事件应该被丢弃(例如被策略决策拦截)。代码会直接根据丢弃原因(
是策略丢弃还是其他)设置注入结果,并返回 `true` 结束处理
if (*dropReason != DropReason::NOT_DROPPED) {
setInjectionResult(*entry,
*dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
: InputEventInjectionResult::FAILED);
return true;
}
bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
// Identify targets.
std::vector<InputTarget> inputTargets;
bool conflictingPointerActions = false;
InputEventInjectionResult injectionResult;
//指针事件
if (isPointerEvent) {
// Pointer event. (eg. touchscreen)
//它通过触摸点坐标,在窗口层级的"命中测试"中寻找最顶层的、可接收触摸的窗口
injectionResult =
findTouchedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime,
&conflictingPointerActions);
} else {
//非指针事件
injectionResult =
findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
}
//返回的 `injectionResult` 决定了后续流程:
//`PENDING`: 事件需要等待(例如等待某个窗口就绪),函数直接返回 `false`。
//`PERMISSION_DENIED` 或其他错误: 事件会被丢弃,并可能生成取消事件。
//`SUCCEEDED`: 成功找到目标窗口,继续下一步。
if (injectionResult == InputEventInjectionResult::PENDING) {
return false;
}
setInjectionResult(*entry, injectionResult);
if (injectionResult == InputEventInjectionResult::PERMISSION_DENIED) {
ALOGW("Permission denied, dropping the motion (isPointer=%s)", toString(isPointerEvent));
return true;
}
if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
CancelationOptions::Mode mode(isPointerEvent
? CancelationOptions::CANCEL_POINTER_EVENTS
: CancelationOptions::CANCEL_NON_POINTER_EVENTS);
CancelationOptions options(mode, "input event injection failed");
synthesizeCancelationEventsForMonitorsLocked(options);
return true;
}
// Add monitor channels from event's or focused display.
//添加全局监控
addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
if (isPointerEvent) {
std::unordered_map<int32_t, TouchState>::iterator it =
mTouchStatesByDisplay.find(entry->displayId);
if (it != mTouchStatesByDisplay.end()) {
const TouchState& state = it->second;
//**处理 Portal 窗口**: 这是一个较新的机制,用于处理跨显示器的触摸事件。
如果事件穿过了一个 `Portal` 窗口,代码需要为这个 `Portal` 窗口所对应
的显示器也添加全局监控目标
if (!state.portalWindows.empty()) {
// The event has gone through these portal windows, so we add monitoring targets of
// the corresponding displays as well.
for (size_t i = 0; i < state.portalWindows.size(); i++) {
const InputWindowInfo* windowInfo = state.portalWindows[i]->getInfo();
addGlobalMonitoringTargetsLocked(inputTargets, windowInfo->portalToDisplayId,
-windowInfo->frameLeft, -windowInfo->frameTop);
}
}
}
}
// Dispatch the motion.
//冲突处理: 如果在处理多点触摸时检测到有冲突的动作(如两根手指同时按下),
会调用 `synthesizeCancelationEventsForAllConnectionsLocked` 生成取消
事件,确保所有相关窗口的状态一致**
if (conflictingPointerActions) {
CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
"conflicting pointer actions");
synthesizeCancelationEventsForAllConnectionsLocked(options);
}
dispatchEventLocked(currentTime, entry, inputTargets);
return true;
}
void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
std::shared_ptr<EventEntry> eventEntry,
const std::vector<InputTarget>& inputTargets) {
ATRACE_CALL();
...
for (const InputTarget& inputTarget : inputTargets) {
sp<Connection> connection =
getConnectionLocked(inputTarget.inputChannel->getConnectionToken());
if (connection != nullptr) {
//遍历目标列表,为每个有效的 `Connection` 启动一个异步的分发周期
prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
} else {
}
}
}
}
void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
const sp<Connection>& connection,
std::shared_ptr<EventEntry> eventEntry,
const InputTarget& inputTarget) {
...
if (wasEmpty && !connection->outboundQueue.empty()) {
startDispatchCycleLocked(currentTime, connection);
}
}
void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
const sp<Connection>& connection) {
...
//不断从发送队列中获取DispatchEntry并将事件发送到InputChannel
while (connection->status == Connection::STATUS_NORMAL && !connection->outboundQueue.empty()) {
//获取 `outboundQueue` 队首的 `DispatchEntry` 指针,不删除
DispatchEntry* dispatchEntry = connection->outboundQueue.front();
//设置事件的投递时间为当前时间,用于后续性能统计和 ANR 判断
dispatchEntry->deliveryTime = currentTime;
//根据连接令牌获取分发超时时长(通常来自 `WindowManager` 配置)。
//计算事件的绝对超时时间点 = 当前时间 + 超时时长
//超时后若应用未处理完成,会触发 ANR
const std::chrono::nanoseconds timeout =
getDispatchingTimeoutLocked(connection->inputChannel->getConnectionToken());
dispatchEntry->timeoutTime = currentTime + timeout.count();
// Publish the event.
status_t status;
const EventEntry& eventEntry = *(dispatchEntry->eventEntry);
//根据不同类型的事件选择不同的发送函数
switch (eventEntry.type) {
//按键事件
case EventEntry::Type::KEY: {
//将 `EventEntry` 向下转型为 `KeyEntry`
const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
//生成 HMAC 签名,用于安全验证,防止恶意应用伪造输入事件
std::array<uint8_t, 32> hmac = getSignature(keyEntry, *dispatchEntry);
// Publish the key event.
//通过 `InputPublisher` 将按键事件发布到目标应用
status = connection->inputPublisher
.publishKeyEvent(dispatchEntry->seq,
dispatchEntry->resolvedEventId, keyEntry.deviceId,
keyEntry.source, keyEntry.displayId,
std::move(hmac), dispatchEntry->resolvedAction,
dispatchEntry->resolvedFlags, keyEntry.keyCode,
keyEntry.scanCode, keyEntry.metaState,
keyEntry.repeatCount, keyEntry.downTime,
keyEntry.eventTime);
break;
}
//触摸事件
case EventEntry::Type::MOTION: {
const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
//定义 `scaledCoords` 数组用于存储缩放后的坐标
PointerCoords scaledCoords[MAX_POINTERS];
//`usingCoords` 指针指向实际要使用的坐标数据,默认指向原始坐标
const PointerCoords* usingCoords = motionEntry.pointerCoords;
//事件源属于指针类(触摸/鼠标)**且**目标标志
未设置 `FLAG_ZERO_COORDS`
if ((motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) &&
!(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
//全局缩放因子(例如在显示缩放设置中)
float globalScaleFactor = dispatchEntry->globalScaleFactor;
if (globalScaleFactor != 1.0f) {
for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
scaledCoords[i] = motionEntry.pointerCoords[i];
//对每个指针坐标进行缩放。
//`windowXScale` 和 `windowYScale` 传入 1,
//表示不额外进行窗口缩放。
scaledCoords[i].scale(globalScaleFactor, 1 /* windowXScale */,
1 /* windowYScale */);
}
//缩放完成后,将 `usingCoords` 指向缩放后的数组
usingCoords = scaledCoords;
}
} else {
//如果目标标志包含 `FLAG_ZERO_COORDS`(通常用于
系统级监听者,如手势导航),将所有坐标清零,防止敏感位置信息泄露。
if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
scaledCoords[i].clear();
}
usingCoords = scaledCoords;
}
}
std::array<uint8_t, 32> hmac = getSignature(motionEntry, *dispatchEntry);
//发布触摸事件
status = connection->inputPublisher
.publishMotionEvent(dispatchEntry->seq,
dispatchEntry->resolvedEventId,
motionEntry.deviceId, motionEntry.source,
motionEntry.displayId, std::move(hmac),
dispatchEntry->resolvedAction,
motionEntry.actionButton,
dispatchEntry->resolvedFlags,
motionEntry.edgeFlags, motionEntry.metaState,
motionEntry.buttonState,
motionEntry.classification,
dispatchEntry->transform,
motionEntry.xPrecision, motionEntry.yPrecision,
motionEntry.xCursorPosition,
motionEntry.yCursorPosition,
dispatchEntry->displaySize.x,
dispatchEntry->displaySize.y,
motionEntry.downTime, motionEntry.eventTime,
motionEntry.pointerCount,
motionEntry.pointerProperties, usingCoords);
break;
}
...
}
// Check the result.
if (status) {
//表示发送通道(Socket/管道)已满,目标应用处理速度跟不上
if (status == WOULD_BLOCK) {
//意味着通道满但没有任何事件等待确认,这是不一致状态,
调用 `abortBrokenDispatchCycleLocked` 中断分发。
if (connection->waitQueue.empty()) {
abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
} else {
//如果 `waitQueue` 非空,说明应用正在处理之前的事件,
只是暂时阻塞,等待应用消费后自然恢复
}
} else {
//其他任何错误都被视为严重问题,记录错误日志后
调用 `abortBrokenDispatchCycleLocked` 中断分发周期。
abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
}
return;
}
// Re-enqueue the event on the wait queue.
//使用erase-remove从 `outboundQueue` 中移除已发布的 `dispatchEntry`
//`std::remove` 按值删除,但由于指针唯一,会准确移除
connection->outboundQueue.erase(std::remove(connection->outboundQueue.begin(),
connection->outboundQueue.end(),
dispatchEntry));
//追踪 `outboundQueue` 长度变化(用于 Systrace)
traceOutboundQueueLength(*connection);
//将 `dispatchEntry` 追加到 `waitQueue`(等待队列)尾部,
表示该事件已发送但尚未收到完成确认
connection->waitQueue.push_back(dispatchEntry);
//连接是否响应式(通常为 true)
if (connection->responsive) {
//将事件的超时时间点注册到 ANR 监控器中。如果超时前未收到完成
通知,`InputDispatcher` 会触发 ANR
mAnrTracker.insert(dispatchEntry->timeoutTime,
connection->inputChannel->getConnectionToken());
}
//追踪 `waitQueue` 长度变化
traceWaitQueueLength(*connection);
}
}
status_t InputPublisher::publishKeyEvent(uint32_t seq, int32_t eventId, int32_t deviceId,
int32_t source, int32_t displayId,
std::array<uint8_t, 32> hmac, int32_t action,
int32_t flags, int32_t keyCode, int32_t scanCode,
int32_t metaState, int32_t repeatCount, nsecs_t downTime,
nsecs_t eventTime) {
...
//声明一个 `InputMessage` 结构体实例,用于承载所有事件数据
InputMessage msg;
msg.header.type = InputMessage::Type::KEY;
msg.header.seq = seq;
msg.body.key.eventId = eventId;
msg.body.key.deviceId = deviceId;
msg.body.key.source = source;
msg.body.key.displayId = displayId;
msg.body.key.hmac = std::move(hmac);
msg.body.key.action = action;
msg.body.key.flags = flags;
msg.body.key.keyCode = keyCode;
msg.body.key.scanCode = scanCode;
msg.body.key.metaState = metaState;
msg.body.key.repeatCount = repeatCount;
msg.body.key.downTime = downTime;
msg.body.key.eventTime = eventTime;
//调用InputChannel::sendMessage` 将构建好的 `InputMessage` 发送到目标应用进程
return mChannel->sendMessage(&msg);
}
status_t InputPublisher::publishMotionEvent(
uint32_t seq, int32_t eventId, int32_t deviceId, int32_t source, int32_t displayId,
std::array<uint8_t, 32> hmac, int32_t action, int32_t actionButton, int32_t flags,
int32_t edgeFlags, int32_t metaState, int32_t buttonState,
MotionClassification classification, const ui::Transform& transform, float xPrecision,
float yPrecision, float xCursorPosition, float yCursorPosition, int32_t displayWidth,
int32_t displayHeight, nsecs_t downTime, nsecs_t eventTime, uint32_t pointerCount,
const PointerProperties* pointerProperties, const PointerCoords* pointerCoords) {
...
//声明一个 `InputMessage` 结构体实例,用于承载所有事件数据
InputMessage msg;
msg.header.type = InputMessage::Type::MOTION;
msg.header.seq = seq;
msg.body.motion.eventId = eventId;
msg.body.motion.deviceId = deviceId;
msg.body.motion.source = source;
msg.body.motion.displayId = displayId;
msg.body.motion.hmac = std::move(hmac);
msg.body.motion.action = action;
msg.body.motion.actionButton = actionButton;
msg.body.motion.flags = flags;
msg.body.motion.edgeFlags = edgeFlags;
msg.body.motion.metaState = metaState;
msg.body.motion.buttonState = buttonState;
msg.body.motion.classification = classification;
msg.body.motion.dsdx = transform.dsdx();
msg.body.motion.dtdx = transform.dtdx();
msg.body.motion.dtdy = transform.dtdy();
msg.body.motion.dsdy = transform.dsdy();
msg.body.motion.tx = transform.tx();
msg.body.motion.ty = transform.ty();
msg.body.motion.xPrecision = xPrecision;
msg.body.motion.yPrecision = yPrecision;
msg.body.motion.xCursorPosition = xCursorPosition;
msg.body.motion.yCursorPosition = yCursorPosition;
msg.body.motion.displayWidth = displayWidth;
msg.body.motion.displayHeight = displayHeight;
msg.body.motion.downTime = downTime;
msg.body.motion.eventTime = eventTime;
msg.body.motion.pointerCount = pointerCount;
for (uint32_t i = 0; i < pointerCount; i++) {
msg.body.motion.pointers[i].properties.copyFrom(pointerProperties[i]);
msg.body.motion.pointers[i].coords.copyFrom(pointerCoords[i]);
}
//调用InputChannel::sendMessage` 将构建好的 `InputMessage` 发送到目标应用进程
return mChannel->sendMessage(&msg);
}
publishMotionEvent和publishKeyEvent只是数据发送的开端。最终,事件会通过Socket发送到应用进程。应用端的 NativeInputEventReceiver 会监听Socket,当有数据可读时,其 handleEvent 被回调,进而调用 InputConsumer::consume 从Socket中读取 InputMessage 并还原成 MotionEvent 和KeyEvent 对象,最后通过JNI回调到Java层的 InputEventReceiver.dispatchInputEvent,交由应用处理。
scss
//frameworks/base/core/jni/android_view_InputEventReceiver.cpp
int NativeInputEventReceiver::handleEvent(int receiveFd, int events, void* data) {
...
if (events & ALOOPER_EVENT_INPUT) {
JNIEnv* env = AndroidRuntime::getJNIEnv();
//核心
status_t status = consumeEvents(env, false /*consumeBatches*/, -1, nullptr);
//会将 JNI 环境中可能发生的异常抛回 Java 层,
并以 `handleReceiveCallback` 作为上下文
mMessageQueue->raiseAndClearException(env, "handleReceiveCallback");
return status == OK || status == NO_MEMORY ? KEEP_CALLBACK : REMOVE_CALLBACK;
}
...
return KEEP_CALLBACK;
}
status_t NativeInputEventReceiver::consumeEvents(JNIEnv* env,
bool consumeBatches, nsecs_t frameTime, bool* outConsumedBatch) {
...
for (;;) {
uint32_t seq;
InputEvent* inputEvent;
//从 `InputChannel` 的 Socket 中读取一个 `InputMessage`,
解析并构建 `InputEvent` 对象。
status_t status = mInputConsumer.consume(&mInputEventFactory,
consumeBatches, frameTime, &seq, &inputEvent);
//OK成功消费一个事件,WOULD_BLOCK没有更多事件可读
if (status != OK && status != WOULD_BLOCK) {
return status;
}
//无事件可读时
if (status == WOULD_BLOCK) {
//检查是否有批量事件等待处理(系统端可能会将多个 `ACTION_MOVE`
事件打包)。
if (!skipCallbacks && !mBatchedInputEventPending && mInputConsumer.hasPendingBatch()) {
// There is a pending batch. Come back later.
//通过弱引用获取 `InputEventReceiver` 对象
if (!receiverObj.get()) {
receiverObj.reset(jniGetReferent(env, mReceiverWeakGlobal));
if (!receiverObj.get()) {
return DEAD_OBJECT;
}
}
mBatchedInputEventPending = true;
if (kDebugDispatchCycle) {
ALOGD("channel '%s' ~ Dispatching batched input event pending notification.",
getInputChannelName().c_str());
}
//通知 Java 层有批量事件待处理,Java 层会在下一个
VSYNC 时主动调用 `consumeBatchedInputEvents` 来消费
env->CallVoidMethod(receiverObj.get(),
gInputEventReceiverClassInfo.onBatchedInputEventPending,
mInputConsumer.getPendingBatchSource());
if (env->ExceptionCheck()) {
//如果回调发生异常,重置 `mBatchedInputEventPending`
mBatchedInputEventPending = false; // try again later
}
}
return OK;
}
assert(inputEvent);
if (!skipCallbacks) {
//获取 Java 层 InputEventReceiver 对象
if (!receiverObj.get()) {
receiverObj.reset(jniGetReferent(env, mReceiverWeakGlobal));
if (!receiverObj.get()) {
ALOGW("channel '%s' ~ Receiver object was finalized "
"without being disposed.", getInputChannelName().c_str());
return DEAD_OBJECT;
}
}
jobject inputEventObj;
//事件类型
switch (inputEvent->getType()) {
//按键事件
case AINPUT_EVENT_TYPE_KEY:
//通过 JNI 辅助函数创建一个 Java `KeyEvent` 对象。
inputEventObj = android_view_KeyEvent_fromNative(env,
static_cast<KeyEvent*>(inputEvent));
break;
//触摸事件
case AINPUT_EVENT_TYPE_MOTION: {
MotionEvent* motionEvent = static_cast<MotionEvent*>(inputEvent);
//如果是 `ACTION_MOVE` 事件,标记 `outConsumedBatch = true`
(表示消费了批量事件)。
if ((motionEvent->getAction() & AMOTION_EVENT_ACTION_MOVE) && outConsumedBatch) {
*outConsumedBatch = true;
}
//创建 Java `MotionEvent` 对象
inputEventObj = android_view_MotionEvent_obtainAsCopy(env, motionEvent);
break;
}
...
if (inputEventObj) {
//将 C++ 的 `InputEvent` 转换为 Java 对象。
//调用 Java 层的 `dispatchInputEvent` 方法,将事件传递给应用
env->CallVoidMethod(receiverObj.get(),
gInputEventReceiverClassInfo.dispatchInputEvent, seq, inputEventObj);
if (env->ExceptionCheck()) {
//如果发生异常,设置 `skipCallbacks = true`,并立即
发送 `finished` 信号(`handled = false`)告知系统服务端事件
已处理(无论应用是否消费)。
skipCallbacks = true;
}
env->DeleteLocalRef(inputEventObj);
} else {
skipCallbacks = true;
}
}
if (skipCallbacks) {
//应用端在消费完输入事件后,**向系统侧的 `InputDispatcher` 发送
"事件已处理"确认信号**的关键步骤。这个信号是实现整个输入系统"同步-反馈"闭环
的核心,也是 ANR(应用无响应)检测机制的基础
mInputConsumer.sendFinishedSignal(seq, false);
}
}
}
//frameworks/base/core/java/android/view/InputEventReceiver.java
//InputEventReceiver是抽象类,WindowInputEventReceiver实现了InputEventReceiver
private void dispatchInputEvent(int seq, InputEvent event) {
mSeqMap.put(event.getSequenceNumber(), seq);
onInputEvent(event);
}
//frameworks/base/core/java/android/view/ViewRootImpl.java
@Override
public void onInputEvent(InputEvent event) {
List<InputEvent> processedEvents;
try {
//负责处理输入事件的兼容性适配
processedEvents =
mInputCompatProcessor.processInputEventForCompatibility(event);
} finally {
}
if (processedEvents != null) {
if (processedEvents.isEmpty()) {
//表示兼容性处理器已消费该事件(例如,事件被转换为其他行为),
直接调用 `finishInputEvent(event, true)` 通知 Native 层事件已处理
finishInputEvent(event, true);
} else {
for (int i = 0; i < processedEvents.size(); i++) {
//将处理后的每个事件依次入队,
并标记 `FLAG_MODIFIED_FOR_COMPATIBILITY`(
表示该事件已被兼容性修改),最后一个参数 `true` 表示这是
一个**异步**事件(不会阻塞等待)
enqueueInputEvent(
processedEvents.get(i), this,
QueuedInputEvent.FLAG_MODIFIED_FOR_COMPATIBILITY, true);
}
}
} else {
//直接使用原始事件入队,无特殊标记
enqueueInputEvent(event, this, 0, true);
}
}
//输入事件加入待处理队列的核心逻辑
void enqueueInputEvent(InputEvent event,
InputEventReceiver receiver, int flags, boolean processImmediately) {
//从对象池中获取或新创建一个 `QueuedInputEvent` 对象,
将事件、接收器和标志封装进去。
QueuedInputEvent q = obtainQueuedInputEvent(event, receiver, flags);
...
QueuedInputEvent last = mPendingInputEventTail;
if (last == null) {
//队首指针
mPendingInputEventHead = q;
//队尾指针
mPendingInputEventTail = q;
} else {
last.mNext = q;
mPendingInputEventTail = q;
}
mPendingInputEventCount += 1;
if (processImmediately) {
//立即调用 `doProcessInputEvents()` 同步处理队列中的所有事件。
这通常用于触摸事件,需要尽可能快地响应用户交互
doProcessInputEvents();
} else {
//通过 Handler 发送消息,异步调度处理。这通常用于按键事件
或一些不需要立即响应的场景,避免阻塞当前正在执行的操作
scheduleProcessInputEvents();
}
}
void doProcessInputEvents() {
// Deliver all pending input events in the queue.
while (mPendingInputEventHead != null) {
//从队首取出一个 `QueuedInputEvent`
QueuedInputEvent q = mPendingInputEventHead;
//更新头指针指向下一个节点
mPendingInputEventHead = q.mNext;
//如果队列变空,同时将尾指针置为 `null`
if (mPendingInputEventHead == null) {
mPendingInputEventTail = null;
}
//将取出的节点的 `mNext` 置为 `null`(断开与原队列的链接)
q.mNext = null;
mPendingInputEventCount -= 1;
//将事件信息设置到帧信息中,用于后续的渲染调度
//为事件分配一个 `EventReceiver`(用于 Choreographer 的帧调度,
确保输入事件与渲染帧对齐)
mViewFrameInfo.setInputEvent(mInputEventAssigner.processEvent(q.mEvent));
//将事件实际分发给 View 树
deliverInputEvent(q);
}
if (mProcessInputEventsScheduled) {
mProcessInputEventsScheduled = false;
//现在清除该标志并移除消息。避免重复处理
mHandler.removeMessages(MSG_PROCESS_INPUT_EVENTS);
}
}
private void deliverInputEvent(QueuedInputEvent q) {
...
try {
...
InputStage stage;
//`mSyntheticInputStage`:合成输入阶段(处理游戏手柄等)。
//`mFirstPostImeInputStage`:IME 之后的阶段(通常用于 View 树分发)。
//`mFirstInputStage`:默认阶段(经过 IME)。
//是否应发送到合成器(用于处理游戏手柄、传感器等模拟输入
if (q.shouldSendToSynthesizer()) {
stage = mSyntheticInputStage;
} else {
//是否跳过 IME(输入法)处理。例如,某些系统按键或注入事件不需要经过输入法。
stage = q.shouldSkipIme() ? mFirstPostImeInputStage : mFirstInputStage;
}
if (q.mEvent instanceof KeyEvent) {
try {
//按键事件进行预分发
mUnhandledKeyManager.preDispatch((KeyEvent) q.mEvent);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_VIEW);
}
}
if (stage != null) {
//在分发事件前确保窗口焦点状态是最新的
handleWindowFocusChanged();
//将事件传递给选定的 `InputStage` 进行处理
stage.deliver(q);
} else {
//如果没有可用 Stage(异常情况),直接完成事件。
finishInputEvent(q);
}
} finally {
}
}