Android事件处理过程,InputDispatchThread和InputReaderThread的协作,(3)

三、另一个线程InputDispatchThread,它的实现核心是InputDispatch。

InputDispatchThread和InputReaderThread是要协同工作的,那是怎么协作的呢?

前面说过这两个线程是在frameworks/native/services/inputflinger/InputManager.cpp中创建的。

InputManager::InputManager(...){

       mDispatcher= new InputDispatcher(dispatcherPolicy);

       mReader= new InputReader(eventHub, readerPolicy, mDispatcher);

}

在创建时,就将InputReader和InputDispatch建立了关联。在InputReader的looponce中,事件是通过InputDispatch来送到Listener的。

void InputReader::loopOnce()@InputReader.cpp{

       mQueuedListener->flush();

}

这里的 mQueuedListener实际是对InputDispatch的一个封装。

这样InputDispatch就可以持续获取到设备中发生的事件。并且可以向InputReader注册监听多种事件。

class QueuedInputListener : publicInputListenerInterface {

   virtual void notifyConfigurationChanged(constNotifyConfigurationChangedArgs* args);

   virtual void notifyKey(const NotifyKeyArgs* args);

   virtual void notifyMotion(const NotifyMotionArgs* args);

   virtual void notifySwitch(const NotifySwitchArgs* args);

   virtual void notifyDeviceReset(const NotifyDeviceResetArgs* args);

}

我们以key事件为例,看下是怎么注册这个监听的?

源头在EventHub,我们知道EventHub负责原始事件的读取,然后通知到InputReader,EventHub还监听设备的插拔,当然这也是事件。

voidInputReader::loopOnce()@InputReader.cpp{

       size_tcount = mEventHub->getEvents(timeoutMillis, mEventBuffer,             

              EVENT_BUFFER_SIZE);

       if (count) {

           processEventsLocked(mEventBuffer, count);

       }

}

getEvents是EventHub很重要的一个方法,就是获取原事件,接着的 processEventsLocked开始处理事件。

如果是添加了输入设备,我们知道系统肯定是要创建一个输入设备的,

void InputReader::processEventsLocked(constRawEvent* rawEvents, size_t count) {

       //这里实际是一个循环,处理读取到的所有原始事件。

       RawEvent*rawEvent = rawEvents;

       switch(rawEvent->type) {

              caseEventHubInterface::DEVICE_ADDED:

                     addDeviceLocked(rawEvent->when,rawEvent->deviceId);

       }

}

我们直接找往InputReader注册监听的地方

void InputReader::addDeviceLocked(nsecs_twhen, int32_t deviceId) {

       InputDevice*device = createDeviceLocked(deviceId, controllerNumber, identifier, classes);

}

InputDevice*InputReader::createDeviceLocked(...){

       //Keyboard-like devices.

       uint32_tkeyboardSource = 0;

          int32_t keyboardType =AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC;

          if (classes & INPUT_DEVICE_CLASS_KEYBOARD){

            keyboardSource |= AINPUT_SOURCE_KEYBOARD;

          }

          if (classes &INPUT_DEVICE_CLASS_ALPHAKEY) {

              keyboardType =AINPUT_KEYBOARD_TYPE_ALPHABETIC;

          }

          if (classes & INPUT_DEVICE_CLASS_DPAD){

              keyboardSource |= AINPUT_SOURCE_DPAD;

          }

          if (classes &INPUT_DEVICE_CLASS_GAMEPAD) {

              keyboardSource |= AINPUT_SOURCE_GAMEPAD;

          }

 

          if (keyboardSource != 0) {

              device->addMapper(newKeyboardInputMapper(device, keyboardSource, keyboardType));

          }    

}

这样就把键盘设备添加到了Vector<InputMapper*>mMappers;

接下来会执行 mMappers的所有设备的process()方法,当然也会执行到KeyboardInputMapper的process方法。

void KeyboardInputMapper::process(constRawEvent* rawEvent) {

       if (isKeyboardOrGamepadKey(scanCode)) {

           processKey(rawEvent->when, rawEvent->value != 0, scanCode,usageCode);

       }  

}

void KeyboardInputMapper::processKey(nsecs_twhen, bool down, int32_t scanCode,

       int32_t usageCode) {

   NotifyKeyArgs args(when, getDeviceId(), mSource, policyFlags,

           down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,

           AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, keyMetaState,            

              downTime);

       getListener()->notifyKey(&args);

}

这里获取的listener实际就是InputReader中mQueuedListener,我们看mQueuedListener的处理。

void QueuedInputListener::notifyKey(constNotifyKeyArgs* args) @InputListener.cpp{

   mArgsQueue.push(new NotifyKeyArgs(*args));

}

也就是把NotifyKeyArgs这个实例添加到Vector<NotifyArgs*> mArgsQueue;中。

还记得前面说InputReader的looponce中,把事件通知给监听这是通过mQueuedListener->flush();就是下面的这个方法,

void QueuedInputListener::flush() {

   size_t count = mArgsQueue.size();

   for (size_t i = 0; i < count; i++) {

       NotifyArgs* args = mArgsQueue[i];

       args->notify(mInnerListener);

       delete args;

    }

   mArgsQueue.clear();

}

在这个方法中会回调具体实例的notify函数,

比如 NotifyKeyArgs的notify函数。

void NotifyKeyArgs::notify(constsp<InputListenerInterface>& listener) const {

   listener->notifyKey(this);

}

注意这里的 mInnerListener来自QueuedInputListener的构造函数,

QueuedInputListener::QueuedInputListener(constsp<InputListenerInterface>& innerListener) :

       mInnerListener(innerListener) {

}

QueuedInputListener又是在InputReader的构造函数实例话的,同时传入的参数是const sp<InputListenerInterface>& listener,实际就是InputDispatch,

class InputDispatcher : publicInputDispatcherInterface ;

class InputDispatcherInterface : publicvirtual RefBase, public InputListenerInterface ;

InputDispatch间接继承了 InputListenerInterface。

通过这个过程,InputReader就把事件传到了InputDispatch。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值