相关重要类
IMS 从操作系统读取原始输入事件 :
IMS 将原始输入事件转成 Android 系统的输入事件 :
mapper 包 , 其中包含了很多种类的 mapper,例如键盘输入事件的 mapper、鼠标输入事件的 mapper。
IMS 将输入事件分派给指定窗口 :
IMS 将输入事件传输给指定窗口 :
InputChannel ,类似 Binder 用来做跨进程通信的类,基于 socket 实现。
Connection , IMS 服务内部对 InputChannel 的封装,包括对该通道的待发布事件的缓存等。
InputMessage,IMS 发送的事件的数据封装。
InputPublisher,Connection 内部对 InputChannel 的封装。
窗口接收输入事件:
InputEventReceiver,接受输入事件的入口,并且负责给 IMS 接受消息的确认。
为什么要使用socket,而不是binder?
转载自:理想主义的许佳佳
1. binder与socket相比太耗资源了。binder通信的逻辑是,每次通信都会去binder线程池里取一个线程,来执行逻辑。binder线程池的大小默认是16,如果不够用还要加线程。与socket”一个场景,一个线程“相比,是不是高下立判?
2. binder线程池不够用。使用binder,一个binder线程池对应这个进程的所有binder操作。这意味着整个input系统所有的app进程共用一个binder线程池。(socket会开多个)再加上本身input的场景就是高频操作,你认为binder线程池要设置多大才能满足要求?
3. binder在高频操作下容易丢事件。binder在binder线程池超负荷工作的情况时会直接报错,如果用来处理input,那么碰到你在玩王者荣耀高频操作的时候,很可能直接crash,或者出现操作无效的情况。
4. 高频的操作必然不会相互依赖,因此binder处理事件没法保证有序。有序情况下,手机来不及处理,你最多会感觉到卡顿。而一旦无法保证有序,打个比方,你玩游戏使用”左下右“搓了个技能,卡顿了一下,得到的结果是”下左右“。
那么现在使用socket的好处有哪些?
1. 保证有序性。性能不够的时候,最多只是卡一下,不会影响操作结果。
2. 除非ANR,一般操作不会丢失。起码不会”操作越快,越容易游戏崩溃“。
3. 节约资源。每条链路开一个线程,一个socket。和binder搞个线程池相比是不是节约多了?
4. 双向通信。其实还是节约资源,一个socket既可以发送也可以接收,使用binder的话,无论哪边发给哪边,每一次通信都需要占有一个线程的资源。