位置: 编程技术 - 正文

Android系统触屏事件传递派发浅析(android触屏事件的处理)

编辑:rootadmin

推荐整理分享Android系统触屏事件传递派发浅析(android触屏事件的处理),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:安卓系统触摸屏,安卓触屏失灵修复方法,安卓显示触摸操作,安卓触屏,android触屏事件的处理,安卓触屏,安卓触屏设置在哪里,安卓触屏,内容如对您有帮助,希望把文章链接给更多的朋友!

之前浅显的看过事件传递的过程,但是有一些细节还是不太清除,借这次机会,可以好好的整理一下之前没有想清楚的地方.(基于android 5.0源码),记录一下事件分发流程.

1. 准备InputManagerService和WindowManagerService

SystemServer中new一个InputManagerSerivce实例, 并将其作为一个输入参数, new 一个WindowManagerService实例, 将他们都注册到ServiceManager中.

看看InputManagerService的构造方法

调用了nativeInit()方法返回一个长整型,跟进nativeInit()方法

原来该整型保存的是NativeInputManager实例的指针.

2. NativeInputManager实例化InputManager

看看NativeInputManager的构造方法

3 InputManager准备实际工作类

看看InputManager的构造方法

InputManager会构造两个实际工作的实例, InputDispather和InputReader两个实例.故名思意,InputReader是用来读取事件,InputDispatcher用来向上层框架和应用分发事件,当然InputDispatcher也会根据策略处理一些事件或者丢弃一些事件.这个类比较简单,就是以InputReader 和 InputDispatcher为参数分别创建两个线程, 线程函数中分别调用InputReader.loopOnce()方法和InputDispatcher.disptachOnce()方法.

4 InputReader 一直运行的工厂

InputReader主要工作是一直获取事件,处理加工事件.

4.1 EventHub 辛勤的小蜜蜂

EventHub主要功能是管理设备文件,对设备分类,读取事件. EventHub中的getEvent()方法流程比较繁琐,用inotify接口来监控/dev/input目录,观察是否有新设备插入和设备移除, 并打开目录下的所有文件,封装成Device结构,并创建了管道用于唤醒睡眠线程, 使用epoll管理所有的文件描述符.主要的功能是从/dev/input目录下的设备文件读取事件,该方法会一直阻塞,直到有用户事件才会返回. 第一次调用该方法会扫描该目录下的所有文件,获取设备名,设备版本,物理路径,id和设备类型等信息.

4.2 InputReader构造函数

可以发现InputReader构造函数需要传入EventHub, InputReaderPolicyInterface, InputListenerInterface. InputReader构造方法最后一个参数是mDispatcher, mReader中用mQueuedListener来保存.

InputReader主要用来读取和处理事件,具体的处理是由InputMapper及其子类的process方法来完成, 在loopOnce方法中会调用EventHub的getEvents方法不断读取原始事件,并对事件分类,设置不同的InputMapper, 最后调用mQueueListener->flush()方法.

processEventLocked()方法中, 第一次调用loopOnce方法会调用 addDeviceLocked(), addDeviceLocked() 会调用createDeviceLocked()方法.

createDeviceLocked()方法会根据设备类型,添加不同的InputMapper. processEventLocked()方法中,不是第一次调用loopOnce时会调用 processEventsForDeviceLocked(). 该方法直接调用每个InputDevice的process方法.

跟进InputDevice的process方法

可以发现InputDevice.process()方法最终是调用InputMapper的process方法. class InputMapper 是用来处理加工原始事件, 表示可以处理某一相同类型的事件. 常见的InputMapper有SwitchInputMapper, KeyboardInputMapper, TrackballInputMapper, MultiTouchInputMapper和SingleTouchInputMapper. InputReader处理完原始事件后构造了一个NofifyArgs, NotifyArgs也有很多子类,如NotifySwitchArgs, NotifyMotionArgs, NotifyKeyArgs等. 通过调用getListener()->notfiy()方法把它投入mQueueListener中. mQueueListener 是类QueuedInputListener的实例.

看看QueuedInputListener的几个方法 构造方法的innerListener参数也是就是InputReader构造方法的第三个参数,也就是InputDispathcer的实例.

在InputReader中调用getListener->ntotifyMotion()方法就是调用notifyMotion方法, 在InputReader中构造的NotifyMotionArgs结构是保存在栈上的,所以这里需要保存在堆上,然后入队.

InputReader loopOnce最后调用的 flush方法就是这个了

5忙碌的事件快递员Android系统触屏事件传递派发浅析(android触屏事件的处理)

InputDispatcher主要作用是派送InputReader放在队列上的事件,当然,也会处理一些事件或者丢弃一些事件. NotifyArgs结构体里的listener就是InputDispathcer, 此时函数调用进入了InputDispathcer.

5.1 notifyMotion方法

看看InputDispathcerde notfiyMotion方法

删除了调试信息和空行后,就剩下这么多了.流程还是好理解, 首先验证NotifyMotionArgs的有效性, 如何验证没有跟进去看, 然后判断是否入队, 再是判断事件是否过滤, 通过了上面3个检查后, 提取NotifyMotionArgs的字段,构造MotionEntry实例, 入队,唤醒其他线程. 至此, 一个触屏事件从获取到加工全部完成,现在已经入队,那是不是准备分发给应用程序了呢? 其实还有会儿.

5.2 enqueueInboundEventLock 方法

跟进 enqueueInboundEventLocked 这个方法看看

看到了findTouchedWindowAtLocked(displayId, x, y) 这个方法后,感觉把事件派发给应用很近了. 这里的displayId 是在InputReader中设置的, 取值有ADISPLAY_ID_DEFAULT和ADISPLAY_ID_NONE. InputDispatcherThread的线程函数是InputDispatcher类的dispatchOnce()方法.

5.3 dispatchOnce 方法

看看dispatchOnce

5.4 dispatchOnceInnerLocked方法

看下处理触屏事件的处理逻辑

根据inputTarget的inputChannel取得connection, 然后调用prepareDispatchCycleLocked方法. 关于inputChannel 和 Connection 后面再介绍. prepareDispatchCycleLocked方法最后调用enqueueDispatchEntriesLocked方法.

5.5 enqueueDispatchEntriesLocked方法

看enqueueDispatchEntriesLocked方法

这个方法首先调用enqueueDispatchEntryLock方法,enqueueDispatchEntryLock方法第四个参数传入的是一些标识请求模式的整型值,整型值具体代表什么意思,以后再分析,然后将EventEntry入队,最后调用startDispatchCycleLocked .

5.6 startDispatchCycleLocked

一路跟踪startDispatchCycleLocked

发现触屏事件最终是调用connection->inputPublisher.publishMotionEvent方法,这个方法参数有个. 阅读最后几行代码,可以看到InputDispatcher中队列比较多. 到目前为止,InputDispatcher分发完成了.下一步应该就是通知应用来读取了.

分析应用读取事件之前,不得不看看connection的结构,以及它从哪里来. connection是从mConnectionsByFd中检索出来的.在registerInputChannel方法中找到了

Connection是定义在InputDispatcher内部的类,看看定义

注意有两个陌生的类 InputChannel 和 InputPublisher.

InputPubliser在InputTransport.h文件中的定义(去掉了参数)

InputChannel也是在InputTransport.h文件中的定义,只看看openInputChannelPair函数的声明

感觉像是一对socket. 在WindowManagerService的addWindow方法中发现了同名的方法.

到了connection->inputPublisher.publishMotionEvent这里,InputDispatcher已经完成了事件的分发,等待窗口处理了.

下一篇文章将记录从应用程序角度来分析publishMotionEvent方法.

短信发送器 先欣赏下界面:页面布局xml文件:LinearLayoutxmlns:android="

Android Study Day 3 --Android File Read And Write ReadFilereadfilebypathin/data/data/appName/appPackageName/files:usemethodopenFileInput(StringfileName)ofclassContext.example:publicStringread(StringfileName)throwsException{try(FileInputStreaminput=co

XMPP聊天软件客户端开发(2) 步骤3:开始follow文档来实践基础功能。(文档在压缩包里的releasedocs文件夹内,有中文版的,大家可以在网上找找,但是注意版本问题)·建立连接:Con

标签: android触屏事件的处理

本文链接地址:https://www.jiuchutong.com/biancheng/379723.html 转载请保留说明!

上一篇:insmod: init_module 'hello.ko' failed (Exec format error)

下一篇:短信发送器

  • 应纳税额等于已缴税额
  • 不动产租赁税率2023
  • 实收资本的期末余额在借方还是贷方
  • 小规模纳税人增值税减免账务处理
  • 收到商业承兑汇票到期,向银行办妥有关入账手续
  • 二季度申报时间
  • 办理个体户营业执照需要什么条件
  • 收到赞助商品的发票
  • 公司注销之后股东还承担责任吗
  • 以房屋抵顶的工程叫什么
  • 持有至到期投资是什么意思
  • 销售发票红冲会计分录怎么做?
  • 民间非营利组织会计报表
  • 房地产企业的土地使用税起始时间
  • 企业个人补偿款需要缴税吗?
  • 增值税专用发票和普通发票的区别
  • 取得增值税专用发票
  • 航天信息开票步骤
  • 餐饮企业员工
  • 技术转让免征增值税
  • 企业为什么要缴纳增值税
  • 税务局退的教育费附加怎么做账
  • 无形资产的入账价值包括宣传费吗
  • 不动产进项税额转出分录
  • 出口货物免抵退税额确认会计分录
  • 不动产抵押合同管辖法院
  • 甲方代付农民工工资合同
  • 怎么修改以前年度的账
  • 远程桌面连接的用户名和密码在哪里看
  • newdot.exe - newdot是什么进程 有什么用
  • 交易性金融资产属于什么科目
  • 广告行业物料
  • 老电脑更新系统会怎么样
  • 苹果手机最贵的软件是哪个
  • 企业无偿提供劳务
  • 企业之间可以背书吗
  • laravel app接口
  • php实现数组排序,所有奇数在前偶数在后怎么排序
  • 固定资产已提完折旧后丢失怎么处理
  • 人工智能助力中国创新发展
  • pytorch广播相乘
  • 总结的拼音
  • 中小型科技企业所面临的普遍问题是资金缺乏
  • js闭包示例
  • 政府会计制度下基建账
  • 车险代买的出了事故怎么办
  • 充值卡赠送金额属于什么性质
  • 财务规定保险柜存放现金最多不超过多少
  • 既有从价又有从租如何计算房产税
  • 在胖东来买到过期的食品
  • 费用报销单怎么写 样本图片
  • 空调销售又安装如何税收筹划
  • 医院收费单可以当发票吗
  • 高效的sql语句
  • win7users移动其它盘
  • 在基于Xen的CentOS系统VPS上配置PPTP VPN的教程
  • win8的ie浏览器
  • windows102021年更新
  • 电脑卡 硬盘100%
  • linux修改软件源
  • centos查看inode
  • 深度探索linux操作系统:系统构建和原理解析
  • 双系统电脑怎么装系统
  • centos运行程序
  • win7系统怎么调出运行窗口
  • 获取windows的最新信息要跳过吗
  • linux使用shell脚本创建文件
  • javascript怎么做
  • 安卓病毒查杀软件
  • shell循环遍历目录
  • javascrpt绑定事件之匿名函数无法解除绑定问题
  • [置顶]游戏名:chivalry2
  • Unity3D游戏开发毕业论文
  • javascript密码框
  • jquery判断checkbox是否选中及改变checkbox状态的实现方法
  • 个税申报系统如何增加新单位
  • 请问各位专家金线吊乌龟有什么功效
  • 房地产的营业税税率
  • 江苏地税局如何交社保
  • 审计双轨制什么意思
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设