网站建设经验,做个人网站到哪里做,汉唐皓月网站推广方案,flash打开网站源码在Android系统中#xff0c;键盘按键事件是由SystemServer服务来管理的#xff1b;然后在以消息的形式分发给应用程序处理。产生键盘按键事件则是有Linux kernel的相关驱动来实现。键盘消息有别于其他类型的消息#xff1b;需要从Linux kernel drivers产生由上层APP来处理。…在Android系统中键盘按键事件是由SystemServer服务来管理的然后在以消息的形式分发给应用程序处理。产生键盘按键事件则是有Linux kernel的相关驱动来实现。键盘消息有别于其他类型的消息需要从Linux kernel drivers产生由上层APP来处理。同时按键有着不同的映射值因此从模块独立性角度各个独立的模块应该拥有不同的键盘映射。这样以来kernel产生的按键事件必然回经过不同的映射才到APP。 Android使用标准的Linux输入事件设备(/dev/input/)和驱动按键定义在Linux内核include/linux/input.h中,按键的定义形式如下仅以BACK HOME MENU为例:
Kernel内核驱动会产生事件在这里就不讨论了不是本文的范畴下面分析Framework事件处理流程。
SystemServer.java
可以看到在系统启动的时候会首先创建一个系统级别的Handler线程wmHandlerThread用于处理键盘消息(仅说明键盘消息)。然后在创建输入管理服务inputManagerInputManagerService的第二个参数就是用于处理按键消息的Handler。
InputManagerService.java 进入InputManagerService的构造函数
这里做了重要的两件事情第一将SystemServer级别的Handler赋值给InputManagerService自己的消息处理Handler第二调用nativeInit继续进行初始化。
com_android_server_input_InputManagerService.java 那就看看本地初始化
进入NativeInputManager构造函数 这里需要特别注意最后两行代码。第一创建了EventHub第二创建InputManager并将EventHub作为参数传入InputManager。
InputManager.cpp 接下来继续看看InputManager的构造函数 创建了InputDispatcher和InputReader,请注意00032行mDispatcher作为了InputReader参数你看看InputReader的构造函数就知道为什么要这么做了后面调用了initialize函数创建了InputReaderThread和InputDispatcherThread。InputDispatcher类是负责把键盘消息分发给当前激活的Activity窗口的而InputReader类则是通过EventHub类来实现读取键盘事件的InputReader实列mReader就是通过这里的InputReaderThread线程实列mReaderThread来读取键盘事件的而InputDispatcher实例mDispatcher则是通过这里的InputDispatcherThread线程实例mDisptacherThread来分发键盘消息的;到这里相关的组件都已经被创建了。 在systemServer.java中创建inputManager之后。将InputManagerServer进行注册并运行start()在第一页有相关代码。
com_android_server_input_InputManagerService.java 会来到这里
继续往下则会调用到InputManager.cpp的start函数 这个函数主要就是分别启动一个InputDispatcherThread线程和一个InputReaderThread线程来读取和分发键盘消息的了。这里的InputDispatcherThread线程对象mDispatcherThread和InputReaderThread线程对象mReaderThread是在前面的第三页中创建的调用了它们的run函数后就会进入到它们的threadLoop函数中去只要threadLoop函数返回true函数threadLoop就会一直被循环调用于是这两个线程就起到了不断地读取和分发键盘消息的作用。 继续看loopOnce()这个函数: 这里面需要注意像神一样的函数mEventHub-getEvents()。其实现原理还有点不是很清楚但是其功能就是负责键盘消息的读取工作如果当前有键盘事件发生或者有键盘事件等待处理通过mEventHub的**getEvent这个函数里面很有讲究有空自己分析这里不做深入的讲解**函数就可以得到这个事件然后交给processEventsLocked函数进行处理。同样需要特别注意最后一行太长了没有截过来后面回解释。我们还会回来的…不过还想补充一点的就是读取的数据的路径为
机型为OK1000:
通过getEvents获取事件消息后就得开始处理消息了回到第六页00314行
如果是一般的消息就调用*processEventsForDeviceLocked*函数否者去处理设备的ADDED、REMOVED、SCAN事件那我们就先分析设备的ADD吧因为后面的处理是在这个基础上的回到上一页00372行
在行00400create一个InputDevice
所有类型的设备都在这里生产然后统一添加到00412行的mDivices提供给后续具体设备处理下面就是具体设备的处理过程。 在第七页*processEventsForDeviceLocked*函数,根据deviceId来处理相应的事件消息 我就在想问什么不直接到process函数呢其实我觉得这里体现了设计模式中的单一职责原则多态这种设计可以有效的控制函数粒度(有个类粒度这里自创函数粒度)的大小函数承担的职责越多其复用的可能性就越小并且当期中某一个职责发生变化可能会影响其他职责的运作继续往下走吧…
这里的每一个事件都要做一个循环处理代码在01022行至于为什么你看行00993注释就会明白了。
行02107函数processKey的原型中有部分代码片段如下 看到关键行02216了吧再回头看看第三页就知道跳转到哪里去了。
总结
一不小心来到了这里… InputDispatcher.cpp 在函数notifyKey中有这样的代码片段 行02421函数的功能其实很简单主要是把EventEntry添加到一个待发的事件队列当中源代码如下
在看看行02424功能就是唤醒InputDispatcherThread线程然后就开始执行InputDispatcher的threadLoop函数之后就调用InputDispatcher的dispatchOnce方法代码如下
进入行00230其中有这样代码片段
进入行00365其中有这样代码片段
行00780查找焦点窗口然后进入行00794 dispatchEventLocked()- prepareDispatchCycleLocked()- enqueueDispatchEntriesLocked()- startDispatchCycleLocked()-
其中函数startDispatchCycleLocked有这样代码片段
看到publishKeyEvent了吧
InputTransprot.cpp
继续走 总算send出去了。
总结
至于外面怎么接收到消息的后续再分析内容太多了自己还没有完全搞懂等搞懂了再补上…
参考文献 http://blog.sina.com.cn/s/blog_6268defa0101ad1o.html http://www.cnblogs.com/haiming/p/3318614.html http://blog.chinaunix.net/uid-27167114-id-3347185.html http://my.oschina.net/u/994235/blog/294227 http://blog.csdn.net/zjq2008wd/article/details/39225539 http://blog.csdn.net/powq2009/article/details/8426271 http://blog.sina.com.cn/s/blog_89f592f50101394l.html http://www.cnblogs.com/lcw/p/3374466.html http://blog.sina.com.cn/s/blog_89f592f50101394l.html http://blog.csdn.net/zjq2008wd/article/category/1283349
觉得本文对您有用麻烦点赞、关注、收藏您的肯定是我创作的无限动力谢谢