前言:
在android2.3版本的时候,详细的对照代码了解了遍按键事件从驱动到framework的流程。并在高仿机上实现新增按键从驱动到系统的功能。随着时间的不断推进,工作的重点越来越向驱动集中,对HAL和系统的了解停留在之前的理解上。近来看一个windowstate的提交,实现发现对按键流程还有不太明白的地方。现在回过头来详细的再对按键梳理一遍,首先来着个大体的序列图:
在这里按照序列图的标号,对照着代码大体的理下思路:
InputFlinger
1.InputManager.cpp这个类是inputflinger的入口类,在JNI里面会通过new生成一个实体对象,然后start启动inputflinger的功能。构造函数如图所示

上面的图涉及到4个非常重要的类,就是这四个类实现事件的读取和派发
1.InputReader :这个类主要是从input目录下,读取所有设备产生的所有按键事件。并根据设备的不同(如键盘,单点触摸,多点触摸,轨迹球…)对数据进行处理
2.InputDispatcher :这个类主要的功能就是派发事件,会涉及到两次按键拦截
3.InputReaderThread : 创建一个线程不停的调用inputReader读取事件
3.InputDispatcherThread :创建一个线程不停的轮询事件队列和命令队列是否有数据并处理
start()接口调用后,上面两个线程就run起来了。这里首先从读按键线程开始看
2-3:read线程的启动
bool InputReaderThread::threadLoop() {
mReader->loopOnce();
return true;
}

以上可以看出looponce,线程循环主要作用有2:
1.通过eventhub获取按键事件,并将事件保存在Buffer里面。并返回事件个数
2.如果事件数不为0,则进行对事件的处理
4.事件获取getEvents接口解读
getEvents这个接口在不同的android版本变化比较大,在最开始的2.3及后继一段时间内的版本实现,都是不停的主动循询/dev/input 目录下的所有设备并从中读取可能的事件。在android8.0也就是我目前使用的版本上,实现方式优化了些,但原理不变。
首先:来看下EventHub的构造函数

这里通过inotify的方式监控dev/input/目录
然后把inofity添加到epoll上,通过epoll_wait的方式等待数据的到来,比不停的轮询效率要高。下面来看看getEvent的比较核心的代码:
int pollResult = epoll_wait(mEpollFd, mPendingEventItems, EPOLL_MAX_EVENTS, timeoutMillis);
//监听并等待事件到来

本文详细介绍了Android系统中按键事件从驱动到框架的处理流程,重点解析InputFlinger的工作机制,包括InputReader的事件读取、InputDispatcher的事件派发、InputReaderThread和InputDispatcherThread的线程逻辑,以及事件的处理和拦截过程。通过对EventHub、InputMapper等关键组件的分析,展示了按键事件如何被读取、处理并最终传递到应用程序。
最低0.47元/天 解锁文章
993

被折叠的 条评论
为什么被折叠?



