本文基于Android-4.0

理论层次解读

  请看:www.cnblogs.com/lcw/p/3373214.html

如何管理各种驱动设备

  在理论中谈到EventHub,这个一看就是一个做实事的,肯定不是领导,哪它的领导是谁呢?

  从以下几方面来分析此问题:

  1. 每个功能模块是怎么产生的?
  2. 读取设备输入流程?
  3. 事件分发流程?

各个功能模块是怎么产生的?

  先看一下每个模块的工作职责:EventHub, InputReader, InputManager...

模块功能

EventHub

  它是系统中所有事件的中央处理站。它管理所有系统中可以识别的输入设备的输入事件,此外,当设备增加或删除时,EventHub将产生相应的输入事件给系统。

  EventHub通过getEvents函数,给系统提供一个输入事件流。它也支持查询输入设备当前的状态(如哪些键当前被按下)。而且EventHub还跟踪每个输入调入的能力,比如输入设备的类别,输入设备支持哪些按键。 

InputReader

  InputReader从EventHub中读取原始事件数据(RawEvent),并由各个InputMapper处理之后输入对应的input listener.

  InputReader拥有一个InputMapper集合。它做的大部分工作在InputReader线程中完成,但是InputReader可以接受任意线程的查询。为了可管理性,InputReader使用一个简单的Mutex来保护它的状态。

  InputReader拥有一个EventHub对象,但这个对象不是它创建的,而是在创建InputReader时作为参数传入的。

InputDispatcher

  InputDispatcher负责把事件分发给输入目标,其中的一些功能(如识别输入目标)由独立的policy对象控制。

InputManager

  InputManager是系统事件处理的核心,它虽然不做具体的事,但管理工作还是要做的,比如接受我们客户的投诉和索赔要求,或者老板的出所筒。

     InputManager使用两个线程:

  1. InputReaderThread叫做"InputReader"线程,它负责读取并预处理RawEvent,applies policy并且把消息送入DispatcherThead管理的队列中。
  2. InputDispatcherThread叫做"InputDispatcher"线程,它在队列上等待新的输入事件,并且异步地把这些事件分发给应用程序。

  InputReaderThread类与InputDispatcherThread类不共享内部状态,所有的通信都是单向的,从InputReaderThread到InputDispatcherThread。两个类可以通过InputDispatchPolicy进行交互。

  InputManager类从不与Java交互,而InputDispatchPolicy负责执行所有与系统的外部交互,包括调用DVM业务。

 


创建流程

  1. 在android_server_InputManager_nativeInit中创建NativeInputManager对象,并保存到gNativeInputManager中;
  2. 在创建NativeInputManager对象时,它会创建EventHub对象<且创建是其成员mNeedToScanDevices的值为true>,然后把刚创建的EventHub对象作为参数创建InputManager对象;
  3. 在创建InputManager对象时,创建InputReader对象,然后把它作为参数创建InputReaderThread;创建InputDispatcher对象,然后把它作为参数创建InputDispatcherThread对象;注意:以上两个线程对象都有自己的threadLoop函数,它将在Thread::_threadLoop中被调用,这个Thread::_threadLoop是线程入口函数,线程在Thread::run中被真正地创建)

创建InputReader对象

  1. 把EventHub、readerPolicy<实质为NativeInputManager对象>和创建的InputDispatcher对象作为参数创建InputReader对象:mReader = new InputReader(eventHub, readerPolicy, mDispatcher);
  2. 在创建InputReader时, 保存EventHub对象到mEventHub中,并创建QueuedInputListener对象并保存在mQueuedListener中

创建InputDispatcher对象

  1. 把传入的参数dispatcherPolicy<实质为NativeInputManager对象>作为参数创建InputDispatcher对象:mDispatcher = new InputDispatcher(dispatcherPolicy);
  2. 在创建InputDispatcher时,创建了一个looper对象:mLooper = new Looper(false);

 


启动流程

  1. 在android_server_InputManager_nativeStart中调用InputManager::start,代码如下:
    result = gNativeInputManager->getInputManager()->start();

     

  2. 在InputManager::start中,调用mDispatcherThread->run和mReaderThread->run,代码如下:
    result = mDispatcherThread->run("InputDispatcher", PRIORITY_URGENT_DISPLAY);
    result = mReaderThread->run("InputReader", PRIORITY_URGENT_DISPLAY);

  在上面的Thread::run中,调用createThreadEtc函数,并以Thread::_threadLoop作为入口函数,以上面的mDispatcherThread或mReaderThread作为userdata创建线程。

  至此InputReader线程和InputDispatcher线程都已经工作,详细信息见Thread::_threadLoop,在此函数中它将调用mDispatcherThread或mReaderThread的threadLoop函数来做真正的事。

mReaderThread->threadLoop

bool InputReaderThread::threadLoop() {
    mReader->loopOnce();
    return true;
}

mDispatcherThread->threadLoop

bool InputDispatcherThread::threadLoop() {
    mDispatcher->dispatchOnce();
    return true;
} 

EventInput对象关系图 

  【Android】事件输入系统-代码层次解读

 


设备操作流程

  从EventHub::getEvents读取的事件数据结构如下:

struct RawEvent {  
    nsecs_t when;        //事件发生的时间  
    int32_t deviceId;    //产生此事件的设备,比如发送FINISHED_DEVICE_SCAN,不需要填此项  
    int32_t type;        //事件类型(如:DEVICE_ADDED,DEVICE_REMOVED,FINISHED_DEVICE_SCAN)  
    int32_t scanCode;  
    int32_t keyCode;  
    int32_t value;  
    uint32_t flags;  
};  
View Code

相关文章:

  • 2022-12-23
  • 2021-07-03
  • 2021-05-28
  • 2021-06-13
  • 2022-12-23
  • 2022-12-23
  • 2021-10-30
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-04-12
  • 2022-01-22
  • 2021-05-26
  • 2021-05-21
相关资源
相似解决方案