今天分享的文章是来自小米的Cheeeelok同学,本文主要从系统源码的角度带你一步步了解Android Input子系统。今天是周六,不知道有多少同学周末还会看技术文章呢?觉得文章不错,可以打赏或转发,文章的打赏将归作者所有。
原文地址:https://zhuanlan.zhihu.com/p/29152319
从我个人的理解来看,Android的Input系统其实就是系统级的事件处理、分发框架,它需要的功能模块大致有:事件读取、事件分类、事件分发。那么我们就从整个Input系统的输入源入手,了解事件是如何被输入到Input系统中的。
在看代码前我们先想一想,如果要我们设计一个事件分发框架的输入读取模块,要考虑到哪些子模块:
-
事件生成模块(当用户对设备进行操作产生InputEvent,硬件产生中断将事件交给驱动,驱动交给内核,内核交给framework)
-
事件监听模块(这里就很像设计一个服务器,为了及时响应来自客户端的请求,则需要启动一个线程监听)
-
事件读取模块
-
事件分发模块
那么现在我们最起码可以知道整个学习的起点了,就是Input系统中,负责监听的线程是谁,监听的过程中它们做了什么。在开始之前,给大家分享一张我根据本文内容画的图:
InputManagerService初始化概览
首先,有几点共识我们都可以达成:
-
Android Framework层的Service(Java)都是由system_server进程创建的(由于没有fork,因此都运行在system_server进程中)
-
Service创建后就会交给运行在system_server进程中的ServiceManager管理。
因此对于InputManagerService的创建,我们可以在SystemServer的startOtherServices()方法中找到,该方法做了以下事情:
-
创建InputManagerService对象
-
将它交给ServiceManager管理
-
将WindowManagerService的InputMonitor注册到InputManagerService中作为窗口响应事件后的回调
-
完成以上工作后启动InputManagerService。
SystemServer.javastartOtherServices(){
……
inputManager = new InputManagerService(context);
……
inputManager.setWindowManagerCallbacks(wm.getInputMonitor());
inputManager.start();
……
}
接下来我们就逐部分学习相应的处理。
InputManagerService对象的创建
创建InputManagerService对象时会完成以下工作:
-
创建一个负责处理DisplayThread线程中的Message的Handler
-
调用nativeInit初始化native层的InputManagerService,初始化的时候传入了DisplayThread的消息队列
-
用mPtr保存native层的InputManagerService
-
初始化完成后将Service添加到LocalServices,通过Map以键值对的形式存储