专栏首页编程思想之路Android源码分析之鼠标事件监听(二)

Android源码分析之鼠标事件监听(二)

本文是一篇很长~很长~很长~~~的技术笔记 如果有什么问题,欢迎指正.

Zero 前言

前边儿已经说过,要想了解鼠标就要研究三个东西

  • 鼠标的挂载/卸载
  • 鼠标事件处理,也就是鼠标操作
  • 鼠标绘制

不论是鼠标挂载/卸载还是鼠标操作,基本上算是对输入事件的一个监听了,属于一类东西 但是鼠标绘制,这涉及到surface绘制鼠标,对于我本人,基本上没接触过那么多绘制的东西,一点点尝试分析. 鼠标事件本身又包括什么?

  • 事件监听
  • 事件处理

接下来实现一个阶段性的小目标,就先愉快的分析一下鼠标事件的监听吧. ok,怎么分析? 从宏观角度出发,千万别一头扎进某个小片段里. 先整体看下整个流程,再来特殊分析. 鼠标也属于输入设备对吧,那鼠标是不是遵循针对输入设备的处理逻辑? 你总不至于给每一种输入设备都配置一套独特的逻辑吧?那岂不是太冗余了. 逻辑是一套,只不过在处理时需要区分一下type而已. 所以呢,本文就来分析手机是如何监听输入事件InputEvent的?

One IMS

这个有时候也需要一些基础和经验. 源码中管理输入的服务是什么?IMS(InputManagerService) 那就从InputManager.h(目录位于/frameworks/native/services/inputflinger/)出发 为啥我先看头文件? 第一,头文件一般会有注释说明,交代整个文件作用,便于代码理解 第二,头文件可以直接看出代码结构structure.一眼就可以知道有哪些方法,哪些filed 果然没让我失望,这个文件里的注释完全表明了framework层所做的工作. 原文就不贴了,有想看的可以在线查看源码,传送门-->http://androidxref.com/9.0.0_r3/xref/frameworks/native/services/inputflinger/InputManager.h 意思是什么,IM是系统核心进程(这不是废话吗?要不然怎么输入). 接下来关键了 说IM管理着两个进程InputReaderThread和InputDispatcherThread,也终于找到了管理输入的重点 顾名思义,一个负责(read)读取inputEvent,一个负责(dispatch)分发inputEvent,各司其职 读取时的事件成为原始输入事件,叫做rawEvent.分发出去的是处理之后的输入事件inputEvent. 那为什么要分两个线程呢?

TWO 饭来了

其实很好理解,就像是饭店门口总有迎宾带路的,坐下之后又会有点餐员一个道理.两个角色都需要等待,也就是都会有阻塞. 迎宾的服务员相当于是在一直监听有哪些顾客进来,并把这些顾客带到对应位置,对于迎宾员而言,只知道顾客是来吃饭的,不知道具体吃什么. 点餐员相当于需要去记录对应顾客的菜单menu,并且分发给对应厨师来进行处理. 那么饭店相当于什么呢?饭店是不是相当于一个储存消息的队列?迎宾员把顾客放到这个队列,之后点餐员开始和队列中的顾客接洽,并生成顾客的菜单传递给厨师. 那为什么要分两个人处理呢?如果一个人会是什么情况? 比如来了一波儿顾客,服务员需要把他领导座位,并且下单结束,之后再把单交给厨师.如果在这个过程中又来了一波儿人,那就只能等待…. 随便问一句,现在谁有那么多耐心去等啊.更别说电子设备这种需要及时响应的了. 从这儿看,生活真是无处不符合逻辑知识啊~ 输入事件的处理也是这个逻辑.流程也就出来了 InputReaderThread需要在系统准备好就要开启监听输入事件的到来,相当于饭店营业开始时,迎宾人员开始等候 在InputReaderThread监听到输入事件时,就要把原始事件rawEvent插入到队列中,相当于一层透传,也就相当于迎宾人员将顾客带到座位 至此,InputReaderThread的任务就完成了,接下来就该点餐员上场了 InputDispatcherThread要干什么?要循环从队列中取数据,也就是要去观察是否有新的顾客落座,并开始下单. 下单的过程也是相当于一个处理的过程,完成了原始事件到系统特定输入事件的转换rawEvent--->inputEvent. 紧接着就是把菜单交给厨师,任务over 到这儿dispatcher的任务也完成了,接下来就是需要厨师根据菜单做菜了.这就相当于不同应用对应不同输入事件的处理. 比如在应用中监听按钮点击事件,当点击按钮时会触发该事件. 在这个过程中,有一个逻辑,点餐员在下完单之后需要告诉迎宾员吗?不需要的,所以呀,这个事件的处理是单向的. 分两个线程处理可以实现快速响应输入事件. reader线程监听到事件后直接插入到队列中,就可以继续监听,来保证缩短用户输入开始到接收到输入事件的时间 dispatcher线程会一直取出新的输入事件,重点是异步分发给对应应用处理.缩短分发时间. 好了,为了方便理解和记忆,以上都是口语化的解释,接下来该官方描述一下了

Three 源码

  • InputReaderThread:用于读取和预处理原始输入事件,并且把事件插入到由dispatcherThread管理的队列中.在输入事件来临前一直阻塞
  • InputDispatcherThread:等待队列中有新的输入事件(来临前阻塞),并且异步分发给对应的应用

理论结束,接下来大致看一下代码:

InputManager

InputManager.h中超级简单,四个filed,五个方法(排除掉构造方法)

 1public:
 2    virtual status_t start();//开启两个线程(执行run方法)
 3   virtual status_t stop();//退出两个线程(requestExitAndWait)
 4
 5    virtual sp<InputReaderInterface> getReader();
 6    virtual sp<InputDispatcherInterface> getDispatcher();
 7
 8private:
 9    sp<InputReaderInterface> mReader;
10    sp<InputReaderThread> mReaderThread;//readerThread实例
11
12    sp<InputDispatcherInterface> mDispatcher;
13    sp<InputDispatcherThread> mDispatcherThread;//dispatcherThread实例
14
15    void initialize();//用于初始化两个thread对象
16};

方法实现也很简单,不再贴出.接下来看下两个线程做了什么?

InputReader

InputReaderThread在InputReader文件中.目录为: /frameworks/native/services/inputflinger/InputReader.cpp 传送门---> http://androidxref.com/9.0.0_r3/xref/frameworks/native/services/inputflinger/InputReader.cpp 在线程run之后,会触发threadLoop方法,来看看InputReaderThread的线程做了什么?

1bool InputReaderThread::threadLoop() {
2    mReader->loopOnce();
3    return true;
4}

就是这么easy,触发了InputReader的loopOnce.一级级的追吧

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Android蓝牙配对弹出框过程分析 Android蓝牙配对弹出框过程分析

    Android蓝牙配对弹出框过程分析 根据远程蓝牙设备(remote devices)的要求,手机端发起与远程蓝牙设备Bluetooth remote ...

    fanfan
  • Android蓝牙配对弹出框过程分析

    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.n...

    fanfan
  • Android中View研究自学之路 Android6.0源码分析之View(一)Android6.0源码分析之View(二)

    Android中View研究自学之路 http://blog.csdn.net/zrf1335348191/article/details/54171263 ...

    fanfan
  • 【Vue原理】Watch - 源码版

    没错,当你调用 Vue 创建实例过程中,会去处理各种选项,其中包括处理 watch

    神仙朱
  • 内存管理之堆、栈、RAII

    最近在极客时间上看到吴老师的《现代C++实战30讲》,觉得很是不错,于是学习一下,本文中的一些文字概念引用自这里。同时,对于这个课的代码我放在了我的《C++那些...

    公众号guangcity
  • Uncaught SyntaxError: Unexpected token ' in JSON at position 1

    玩蛇的胖纸
  • 腾讯云服务器DDoS 基础防护功能有哪些?

    腾讯云 DDoS 基础防护应用于攻击频率不高且攻击峰值不超过基础防护阈值的 DDoS 攻击防护场景。当攻击流量超过一定流量时,将自动启动 DDoS 清洗设备进行...

    用户5915077
  • Oracle跨平台迁移的简单总结(r10笔记第91天)

    前段时间测试了一下GoldenGate,结合我之前的一些尝试,对于小机环境的迁移,思路是逐步清晰了起来。 需求的核心是跨平台迁移数据库,最好能够升级到新的版本,...

    jeanron100
  • API接口成企业数字化转型基石,85%企业已采用API开发模式

    在CA近日所披露的《API与数字化企业:由运营效率到数字化颠覆》全球调查报告中显示,中国大陆82%以上的组织已经采用了API,而有35%的组织已经达到了API应...

    BestSDK
  • API接口成企业数字化转型基石,85%企业已采用API开发模式

    在CA近日所披露的《API与数字化企业:由运营效率到数字化颠覆》全球调查报告中显示,中国大陆82%以上的组织已经采用了API,而有35%的组织已经达到了API应...

    BestSDK

扫码关注云+社区

领取腾讯云代金券