InputReader 依然是输入系统(Input System)的核心组件,负责从内核读取原始事件数据。需要将其放在 InputDispatcher 进行派发处理。
一、 核心流程概览
- 系统事件流程
c++
InputDispatcher::dispatchOnce()
-> dispatchOnceInnerLocked()
-> dispatchMotionLocked() // 处理 Motion 事件
-> findTouchedWindowTargetsLocked(currentTime, motionEntry, inputTargets, nextWakeupTime) //计算目标窗口 (核心算法),该函数决定了事件最终去向哪里窗口
-> dispatchEventLocked(nsecs_t currentTime,std::shared_ptr<const EventEntry> eventEntry,const std::vector<InputTarget>& inputTargets)
-> prepareDispatchCycleLocked(nsecs_t currentTime,const std::shared_ptr<Connection>& connection,std::shared_ptr<const EventEntry> eventEntry,const InputTarget& inputTarget)
-> enqueueDispatchEntryAndStartDispatchCycleLocked(nsecs_t currentTime, const std::shared_ptr<Connection>& connection,std::shared_ptr<const EventEntry> eventEntry, const InputTarget& inputTarget)
-> enqueueDispatchEntryLocked(const std::shared_ptr<Connection>& connection,std::shared_ptr<const EventEntry> eventEntry,const InputTarget& inputTarget)//构建DispatchEntry,将事件封装进每个目标窗口的 outboundQueue
-> startDispatchCycleLocked(nsecs_t currentTime,const std::shared_ptr<Connection>& connection)//实际执行 Socket 发送
- 应用层接收反馈
c++
InputDispatcher
-> InputChannel
-> WindowInputEventReceiver
-> ViewRootImpl.enqueueInputEvent
-> ViewRootImpl.doProcessInputEvents
-> deliverInputEvent
-> InputStage pipeline
-> View.dispatchTouchEvent
-> View.onTouchEvent
-> finishInputEvent
二、 详细调用链路分析
1. dispatchOnce(): 主循环入口
c++
void InputDispatcher::dispatchOnce() {
nsecs_t nextWakeupTime = LLONG_MAX;
{
std::scoped_lock _l(mLock);
mDispatcherIsAlive.notify_all();
// 省略代码
if (!haveCommandsLocked()) {
dispatchOnceInnerLocked(/*byref*/ nextWakeupTime);
}
// 省略代码
}
// 省略代码
}
2. dispatchOnceInnerLocked(): 事件分发的核心逻辑所在
c++
void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
// [步骤 1] 检查 ANR: 在派发新事件前,必须先处理超时的连接
processAnrsLocked();
// [步骤 2] 获取并处理队列中的事件 (mPendingEvent)
if (mPendingEvent) {
// ... (省略部分逻辑) ...
// [步骤 3] 分发 Motion 事件
if (dispatchMotionLocked(currentTime, static_cast<MotionEntry*>(mPendingEvent), ...)) {
// ...
}
}
}
3. dispatchMotionLocked() (以触摸事件为例):
c++
bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime,
std::shared_ptr<const MotionEntry> entry,
DropReason* dropReason, nsecs_t& nextWakeupTime) {
// 省略代码
if (isPointerEvent) {
// 省略代码
// 根据当前所有窗口的层级 (Z-order)、坐标范围、以及 WindowInfo 的标志位(如 FLAG_NOT_TOUCH_MODAL)来计算谁该接收这个触摸
Result<std::vector<InputTarget>, InputEventInjectionResult> result =
findTouchedWindowTargetsLocked(currentTime, *entry);
// 省略代码
} else {
// 省略代码
addWindowTargetLocked(focusedWindow, InputTarget::DispatchMode::AS_IS,
InputTarget::Flags::FOREGROUND, getDownTime(*entry),
inputTargets);
// 省略代码
}
// 省略代码
// 开始处理DispatchEntry数据
dispatchEventLocked(currentTime, entry, inputTargets);
return true;
}
4. dispatchEventLocked()
c++
void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
std::shared_ptr<const EventEntry> eventEntry,
const std::vector<InputTarget>& inputTargets) {
ATRACE_CALL();
// 省略代码
for (const InputTarget& inputTarget : inputTargets) {
std::shared_ptr<Connection> connection = inputTarget.connection;
prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
}
}
5. prepareDispatchCycleLocked()
c++
void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
const std::shared_ptr<Connection>& connection,
std::shared_ptr<const EventEntry> eventEntry,
const InputTarget& inputTarget) {
// 省略代码
if (connection->status != Connection::Status::NORMAL) {
if (DEBUG_DISPATCH_CYCLE) {
ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
connection->getInputChannelName().c_str(),
ftl::enum_string(connection->status).c_str());
}
return;
}
// 分屏split
if (inputTarget.flags.test(InputTarget::Flags::SPLIT)) {
const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
if (inputTarget.getPointerIds().count() != originalMotionEntry.getPointerCount()) {
// 省略代码
enqueueDispatchEntryAndStartDispatchCycleLocked(currentTime, connection,
std::move(splitMotionEntry),
inputTarget);
return;
}
}
// 单屏
enqueueDispatchEntryAndStartDispatchCycleLocked(currentTime, connection, eventEntry,
inputTarget);
}
6. enqueueDispatchEntryAndStartDispatchCycleLockeds()
c++
void InputDispatcher::enqueueDispatchEntryAndStartDispatchCycleLocked(
nsecs_t currentTime, const std::shared_ptr<Connection>& connection,
std::shared_ptr<const EventEntry> eventEntry, const InputTarget& inputTarget) {
// 构建DispatchEntry,将事件封装进每个目标窗口的
enqueueDispatchEntryLocked(connection, eventEntry, inputTarget);
// 发送分发消息给应用
if (wasEmpty && !connection->outboundQueue.empty()) {
startDispatchCycleLocked(currentTime, connection);
}
}
7. enqueueDispatchEntryLocked()
构建DispatchEntry,塞入outboundQueue
c++
void InputDispatcher::enqueueDispatchEntryLocked(const std::shared_ptr<Connection>& connection,
std::shared_ptr<const EventEntry> eventEntry,
const InputTarget& inputTarget) {
// 省略代码
eventEntry = dispatchEntry->eventEntry;
switch (eventEntry->type) {
// 省略代码
case EventEntry::Type::MOTION: {
std::shared_ptr<const MotionEntry> resolvedMotion =
std::static_pointer_cast<const MotionEntry>(eventEntry);
{
const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
int32_t resolvedAction = motionEntry.action;
int32_t resolvedFlags = motionEntry.flags;
if (inputTarget.dispatchMode == InputTarget::DispatchMode::OUTSIDE) {
resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
} else if (inputTarget.dispatchMode == InputTarget::DispatchMode::HOVER_EXIT) {
resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
} else if (inputTarget.dispatchMode == InputTarget::DispatchMode::HOVER_ENTER) {
resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
} else if (inputTarget.dispatchMode == InputTarget::DispatchMode::SLIPPERY_EXIT) {
resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
} else if (inputTarget.dispatchMode == InputTarget::DispatchMode::SLIPPERY_ENTER) {
resolvedAction = AMOTION_EVENT_ACTION_DOWN;
}
if (resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE &&
!connection->inputState.isHovering(motionEntry.deviceId, motionEntry.source,
motionEntry.displayId)) {
if (DEBUG_DISPATCH_CYCLE) {
LOG(DEBUG) << "channel '" << connection->getInputChannelName().c_str()
<< "' ~ enqueueDispatchEntryLocked: filling in missing hover "
"enter event";
}
resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
}
if (resolvedAction == AMOTION_EVENT_ACTION_CANCEL) {
resolvedFlags |= AMOTION_EVENT_FLAG_CANCELED;
}
if (dispatchEntry->targetFlags.test(InputTarget::Flags::WINDOW_IS_OBSCURED)) {
resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
}
if (dispatchEntry->targetFlags.test(
InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED)) {
resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
}
if (dispatchEntry->targetFlags.test(InputTarget::Flags::NO_FOCUS_CHANGE)) {
resolvedFlags |= AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE;
}
dispatchEntry->resolvedFlags = resolvedFlags;
if (resolvedAction != motionEntry.action) {
std::optional<std::vector<PointerProperties>> usingProperties;
std::optional<std::vector<PointerCoords>> usingCoords;
if (resolvedAction == AMOTION_EVENT_ACTION_HOVER_EXIT ||
resolvedAction == AMOTION_EVENT_ACTION_CANCEL) {
const bool hovering = resolvedAction == AMOTION_EVENT_ACTION_HOVER_EXIT;
std::optional<std::pair<std::vector<PointerProperties>,
std::vector<PointerCoords>>>
pointerInfo =
connection->inputState.getPointersOfLastEvent(motionEntry,
hovering);
if (pointerInfo) {
usingProperties = pointerInfo->first;
usingCoords = pointerInfo->second;
}
}
{
// Generate a new MotionEntry with a new eventId using the resolved action
// and flags, and set it as the resolved entry.
auto newEntry = std::make_shared<
MotionEntry>(mIdGenerator.nextId(), motionEntry.injectionState,
motionEntry.eventTime, motionEntry.deviceId,
motionEntry.source, motionEntry.displayId,
motionEntry.policyFlags, resolvedAction,
motionEntry.actionButton, resolvedFlags,
motionEntry.metaState, motionEntry.buttonState,
motionEntry.classification, motionEntry.edgeFlags,
motionEntry.xPrecision, motionEntry.yPrecision,
motionEntry.xCursorPosition,
motionEntry.yCursorPosition, motionEntry.downTime,
usingProperties.value_or(
motionEntry.pointerProperties),
usingCoords.value_or(motionEntry.pointerCoords));
if (mTracer) {
ensureEventTraced(motionEntry);
newEntry->traceTracker =
mTracer->traceDerivedEvent(*newEntry,
*motionEntry.traceTracker);
}
resolvedMotion = newEntry;
}
if (ATRACE_ENABLED()) {
std::string message = StringPrintf("Transmute MotionEvent(id=0x%" PRIx32
") to MotionEvent(id=0x%" PRIx32 ").",
motionEntry.id, resolvedMotion->id);
ATRACE_NAME(message.c_str());
}
dispatchEntry->eventEntry = resolvedMotion;
eventEntry = resolvedMotion;
}
}
std::unique_ptr<EventEntry> cancelEvent =
connection->inputState.cancelConflictingInputStream(*resolvedMotion);
if (cancelEvent != nullptr) {
LOG(INFO) << "Canceling pointers for device " << resolvedMotion->deviceId << " in "
<< connection->getInputChannelName() << " with event "
<< cancelEvent->getDescription();
if (mTracer) {
static_cast<MotionEntry&>(*cancelEvent).traceTracker =
mTracer->traceDerivedEvent(*cancelEvent, *resolvedMotion->traceTracker);
}
std::unique_ptr<DispatchEntry> cancelDispatchEntry =
createDispatchEntry(mIdGenerator, inputTarget, std::move(cancelEvent),
ftl::Flags<InputTarget::Flags>(), mWindowInfosVsyncId,
mTracer.get());
// 生成cancel事件,加入队列
connection->outboundQueue.emplace_back(std::move(cancelDispatchEntry));
}
// 省略代码
break;
}
// 省略代码
}
// 省略代码
// 塞入waitQueue
connection->outboundQueue.emplace_back(std::move(dispatchEntry));
traceOutboundQueueLength(*connection);
}
8. startDispatchCycleLocked()
发送消息个应用侧
c++
oid InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
const std::shared_ptr<Connection>& connection) {
ATRACE_NAME_IF(ATRACE_ENABLED(),
StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
connection->getInputChannelName().c_str()));
if (DEBUG_DISPATCH_CYCLE) {
ALOGD("channel '%s' ~ startDispatchCycle", connection->getInputChannelName().c_str());
}
while (connection->status == Connection::Status::NORMAL && !connection->outboundQueue.empty()) {
std::unique_ptr<DispatchEntry>& dispatchEntry = connection->outboundQueue.front();
dispatchEntry->deliveryTime = currentTime;
const std::chrono::nanoseconds timeout = getDispatchingTimeoutLocked(connection);
dispatchEntry->timeoutTime = currentTime + timeout.count();
// Publish the event.
status_t status;
const EventEntry& eventEntry = *(dispatchEntry->eventEntry);
switch (eventEntry.type) {
// 省略代码
case EventEntry::Type::MOTION: {
if (DEBUG_OUTBOUND_EVENT_DETAILS) {
LOG(INFO) << "Publishing " << *dispatchEntry << " to "
<< connection->getInputChannelName();
}
const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
// 发送sockets给应用侧
status = publishMotionEvent(*connection, *dispatchEntry);
if (status == BAD_VALUE) {
logDispatchStateLocked();
LOG(FATAL) << "Publisher failed for " << motionEntry;
}
if (mTracer) {
ensureEventTraced(motionEntry);
mTracer->traceEventDispatch(*dispatchEntry, *motionEntry.traceTracker);
}
break;
}
// 省略代码
}
// 省略代码
const nsecs_t timeoutTime = dispatchEntry->timeoutTime;
// 加入等待队列,用于判断ANR
connection->waitQueue.emplace_back(std::move(dispatchEntry));
//移除oq中数据
connection->outboundQueue.erase(connection->outboundQueue.begin());
traceOutboundQueueLength(*connection);
if (connection->responsive) {
// 加入等待队列,用于判断ANR
mAnrTracker.insert(timeoutTime, connection->getToken());
}
traceWaitQueueLength(*connection);
}
}
三、ANR的产生分析
1、ANR 主要分为 4 类:
| 类型 | 触发位置 | 超时时间 |
|---|---|---|
| Input ANR | InputDispatcher | 默认 5s |
| Broadcast ANR | AMS | 前台 10s / 后台 60s |
| Service ANR | AMS | 20s |
| ContentProvider ANR | AMS | 10s |
2、我们看最常碰到Input ANR
startDispatchCycleLocked()构建DispatchEntry时候加入waitQueue和mAnrTracher用于判断超时:
c++
oid InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
const std::shared_ptr<Connection>& connection) {
ATRACE_NAME_IF(ATRACE_ENABLED(),
StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
connection->getInputChannelName().c_str()));
if (DEBUG_DISPATCH_CYCLE) {
ALOGD("channel '%s' ~ startDispatchCycle", connection->getInputChannelName().c_str());
}
while (connection->status == Connection::Status::NORMAL && !connection->outboundQueue.empty()) {
std::unique_ptr<DispatchEntry>& dispatchEntry = connection->outboundQueue.front();
// 省略代码
const EventEntry& eventEntry = *(dispatchEntry->eventEntry);
switch (eventEntry.type) {
// 省略代码
case EventEntry::Type::MOTION: {
// 省略代码
const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
// 发送sockets给应用侧
status = publishMotionEvent(*connection, *dispatchEntry);
// 省略代码
break;
}
// 省略代码
}
// 省略代码
const nsecs_t timeoutTime = dispatchEntry->timeoutTime;
// 加入等待队列,用于判断ANR
connection->waitQueue.emplace_back(std::move(dispatchEntry));
//移除oq中数据
connection->outboundQueue.erase(connection->outboundQueue.begin());
traceOutboundQueueLength(*connection);
if (connection->responsive) {
// 加入等待队列,用于判断ANR
mAnrTracker.insert(timeoutTime, connection->getToken());
}
traceWaitQueueLength(*connection);
}
}
- processAnrsLocked()判断是否ANR
系统通过 mAnrTracker 维护每一个 Connection 的超时定时器。
| 返回值 | 含义 |
|---|---|
| LLONG_MIN | 立即重新循环(刚触发 ANR) |
| 某个时间戳 | 下一次应检查 ANR 的时间 |
| LLONG_MAX | 当前没有任何需要检查的 ANR |
c++
nsecs_t InputDispatcher::processAnrsLocked() {
const nsecs_t currentTime = now();
nsecs_t nextAnrCheck = LLONG_MAX;
// 没焦点anr
if (mNoFocusedWindowTimeoutTime.has_value() && mAwaitedFocusedApplication != nullptr) {
if (currentTime >= *mNoFocusedWindowTimeoutTime) {
processNoFocusedWindowAnrLocked();
mAwaitedFocusedApplication.reset();
mNoFocusedWindowTimeoutTime = std::nullopt;
return LLONG_MIN;
} else {
nextAnrCheck = *mNoFocusedWindowTimeoutTime;
}
}
// 来获取最早的一个超时时间
nextAnrCheck = std::min(nextAnrCheck, mAnrTracker.firstTimeout());
// 没超时直接返回
if (currentTime < nextAnrCheck) {
return nextAnrCheck;
}
std::shared_ptr<Connection> connection = getConnectionLocked(mAnrTracker.firstToken());
// 没有等待的connection
if (connection == nullptr) {
return nextAnrCheck;
}
connection->responsive = false;
// 从监控列表中移除该连接,防止重复触发。
mAnrTracker.eraseToken(connection->getToken());
// 触发ANR
onAnrLocked(connection);
return LLONG_MIN;
}
- 应用侧接收 (Native 接入点) App 进程中的 NativeInputEventReceiver 通过 Looper 监听到 Socket 可读。
java
// frameworks/native/android/native_input_event_receiver.cpp
int NativeInputEventReceiver::handleEvent(int receiveFd, int events, void* data) {
if (events & ALOOPER_EVENT_INPUT) {
// 1. 从 Socket 读取数据
// 2. 调用 JNI 方法通知 Java 层
JNIEnv* env = AndroidRuntime::getJNIEnv();
env->CallVoidMethod(mReceiverObjGlobal.get(), gInputEventReceiverClassInfo.dispatchInputEvent, ...);
}
return 1; // Keep monitoring
}
- Java 层调度 (ViewRootImpl 入口) 通过 JNI,事件进入 Java 层的 WindowInputEventReceiver。
java
// frameworks/base/core/java/android/view/InputEventReceiver.java
// JNI 调用此方法
public void dispatchInputEvent(int seq, InputEvent event) {
// 放入 MessageQueue,唤醒 App 主线程
onInputEvent(event, seq);
}
- 事件处理分发 deliverInputEvent 被调用的地方。
java
// frameworks/base/core/java/android/view/ViewRootImpl.java
final class WindowInputEventReceiver extends InputEventReceiver {
public void onInputEvent(InputEvent event, int seq) {
enqueueInputEvent(event, this, seq, true); // 放入主线程队列
}
}
// 最终由主线程 Handler 执行:
void doProcessInputEvents() {
while (mPendingInputEventHead != null) {
QueuedInputEvent q = mPendingInputEventHead;
// 核心调用链在此:
deliverInputEvent(q);
}
}
void deliverInputEvent(QueuedInputEvent q) {
// 这一步将事件交给第一个 Stage (流水线处理)
q.mStage.deliver(q);
}
- finishInputEvent回调
java
final class WindowInputEventReceiver extends InputEventReceiver {
public WindowInputEventReceiver(InputChannel inputChannel, Looper looper) {
super(inputChannel, looper);
}
@Override
public void onInputEvent(InputEvent event) {
Trace.traceBegin(Trace.TRACE_TAG_VIEW, "processInputEventForCompatibility");
List<InputEvent> processedEvents;
try {
processedEvents =
mInputCompatProcessor.processInputEventForCompatibility(event);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_VIEW);
}
if (processedEvents != null) {
if (processedEvents.isEmpty()) {
// 告诉InputDispatcher完成事件,不然可能导致,Input dispatching timed out (ANR)
finishInputEvent(event, true);
} else {
for (int i = 0; i < processedEvents.size(); i++) {
// 生成新事件,兼容层把 一个事件变成多个事件。deliverInputEvent()
enqueueInputEvent(
processedEvents.get(i), this,
QueuedInputEvent.FLAG_MODIFIED_FOR_COMPATIBILITY, true);
}
}
} else {
// 生成新事件,兼容层把 一个事件变成多个事件。最终调用deliverInputEvent()
enqueueInputEvent(event, this, 0, true);
}
}
}
- deliverInputEvent()
java
private void deliverInputEvent(QueuedInputEvent q) {
// 省略代码
try {
if (mInputEventConsistencyVerifier != null) {
Trace.traceBegin(Trace.TRACE_TAG_VIEW, "verifyEventConsistency");
try {
mInputEventConsistencyVerifier.onInputEvent(q.mEvent, 0);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_VIEW);
}
}
InputStage stage;
if (q.shouldSendToSynthesizer()) {
stage = mSyntheticInputStage;
} else {
stage = q.shouldSkipIme() ? mFirstPostImeInputStage : mFirstInputStage;
}
if (q.mEvent instanceof KeyEvent) {
Trace.traceBegin(Trace.TRACE_TAG_VIEW, "preDispatchToUnhandledKeyManager");
try {
// key事件预派发处理
mUnhandledKeyManager.preDispatch((KeyEvent) q.mEvent);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_VIEW);
}
}
if (stage != null) {
// 窗口焦点处理
handleWindowFocusChanged();
stage.deliver(q);
} else {
// 告诉InputDispatcher完成事件,不然可能导致,Input dispatching timed out (ANR)
finishInputEvent(q);
}
} finally {
Trace.traceEnd(Trace.TRACE_TAG_VIEW);
}
}
