概述
源码分析
1 2 3 4
| bool InputDispatcherThread::threadLoop() { mDispatcher->dispatchOnce(); return true; }
|
时间分发流程图
dispatchOnce
threadLoop()函数只是调用了InputDispatcher的dispatchOnce()函数,这个函数的代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| void InputDispatcher::dispatchOnce() { nsecs_t nextWakeupTime = LONG_LONG_MAX; { AutoMutex _l(mLock); mDispatcherIsAliveCondition.broadcast(); if (! haveCommandsLocked()) { dispatchOnceInnerLocked(&nextWakeupTime); } if (runCommandsLockedInterruptible()) { nextWakeupTime = LONG_LONG_MIN; } } nsecs_t currentTime = now(); int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime); mLooper->pollOnce(timeoutMillis); }
|
dispatchOnce()调用dispatchOnceInnerLocked()函数来分发消息,dispatchOnceInnerLocked()函数又调用了dispatchOnceInnerLocked()函数,这个函数的代码如下所示:
1 2 3 4 5 6 7 8 9 10 11 12
| void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) { ...... mPendingEvent = mInboundQueue.dequeueAtHead(); ...... switch (mPendingEvent->type) { case EventEntry::TYPE_KEY: { ...... done = dispatchKeyLocked(currentTime, typedEntry, &dropReason, nextWakeupTime); break; } }
|
dispatchOnceInnerLocked()函数从mInboundQueue队列中把输入消息取出来后,根据消息的类型,调用不同的函数处理,其中Key Event调用dispatchKeyLocked()函数处理。从dispatchKey Locked()函数开始,一直到消息传递出去,还要调用InputDispatcher类的多个函数,如图16.3所示。
Event传递的中间过程就不分析了,我们直接看图16.3中的最后一个函数startDispatchCycle Locked(),它的代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection) { ...... switch (eventEntry->type) { case EventEntry::TYPE_KEY: { KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry); status = connection->inputPublisher.publishKeyEvent(dispatchEntry->seq, keyEntry->deviceId, keyEntry->source, dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags, keyEntry->keyCode, keyEntry->scanCode, keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime, keyEntry->eventTime); break; } ...... }
|
startDispatchCycleLocked()函数会根据Event的类型来分别处理,我们保留了处理key消息的分支。这个分支调用了connection对象的inputPublisher变量的publishKeyEvent()函数。
这个connection对象从哪里来的呢?回答这个问题我们要看看InputManagerService的registerInputChannel()方法,下一节我们会介绍这个方法从哪里调用的。方法的代码如下:
1 2 3 4 5
| public void registerInputChannel(InputChannel inputChannel, InputWindowHandle inputWindowHandle) { ...... nativeRegisterInputChannel(mPtr, inputChannel, inputWindowHandle, false); }
|
registerInputChannel()函数调用了nativeRegisterInputChannel()方法,其对应的本地函数如下:
1 2 3 4 5 6 7 8
| static void nativeRegisterInputChannel(JNIEnv* env, jclass clazz, ......) { sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env, inputChannelObj); ...... status_t status = im->registerInputChannel( env, inputChannel, inputWindowHandle, monitor); ...... }
|
归纳总结
InputDispatcher
在拿到 InputReader
获取的事件之后,对事件进行包装后,寻找并分发到目标窗口;