Android View框架总结(九)KeyEvent事件分发机制
请尊重分享成果,转载请注明出处:
http://blog.csdn.net/hejjunlin/article/details/52335094
本篇开始分析按键消息事件分发(PS:本篇文章中源码均是android 6.0,请知晓)先看下Agenda:
- ViewRootImpl中的dispatchInputEvent方法
- View.dispatchKeyEvent方法
- ViewGroup.dispatchKeyEvent方法
- Activity.dispatchKeyEvent方法
- 按键消息事件时序图
ViewRootImpl中的dispatchInputEvent方法
WMS中接受到消息后,会调用ViewRootImpl中的dispatchInputEvent方法,
如下:
ViewRootImpl.java -> dispatchInputEvent()
下面看ViewRootHandler的handleMessage方法:
ViewRootImpl$ViewRootHandler.java -> handleMessage()
以上获取msg中的event,及receiver后,接着调用enqueueInputEvent方法
ViewRootImpl.java -> enqueueInputEvent()
以上方法,由于默认是false,会执行2:
ViewRootImpl.java -> scheduleProcessInputEvents()
以上方法,再给Handler发一条MSG_PROCESS_INPUT_EVENTS(处理的消息)
ViewRootImpl$ViewRootHandler.java -> handleMessage()
ViewRootImpl.java -> doProcessInputEvents()
上面有个循环操作,就是把QueuedInputEvent传递到deliverInputEvent方法中,主要的作用,就是把上面来的按键消息放到队列中去。
ViewRootImpl.java -> deliverInputEvent()
ViewRootImpl提供一个setView方法,是一个public的,会把mView(也就是DecorView),WMS调用这个方法,注意ViewRootImpl并不是一个View,它实际上是一个Handler,它的作用如下:
向DecorView分发收到的用户发起的event事件,如按键,触屏,轨迹球等事件;(这个是在内部类中实现,下面会说)
与WindowManagerService交互,完成整个Activity的GUI的绘制。
看下setView方法
上面有两个内部类,ViewPostImeInputStage,
ViewRootImpl.java$ViewPostImeInputStage
在看processKeyEvent之前,先看onProcess方法:
ViewRootImpl$ViewPostImeInputStage.java -> processKeyEvent
ViewRootImpl.java -> handleDispatchWindowAnimationStopped()
上面有些代码比较长,了解下就行,主要是明白processKeyEvent方法:
KeyEvent是InputEvent的子类,而InputEvent是一个事件的基类。
处理接收的事件及分发事件的过程,那么问题来了?view或者viewGroup是如何收到按键消息派发下来的呢?ViewRootImpl内部类ViewPostImeInputStage中的processKeyEvent()方法中有这么一段
if (mView.dispatchKeyEvent(event)) {//mView是DecorView(书名),但本质上也是View(乳名)
return FINISH_HANDLED;
}
另外键盘消息派发到view或ViewGroup中,在ViewRootImpl另一个内部类ViewPreImeInputStage中的processKeyEvent()方法中也有这么一段如下:
View.dispatchKeyEvent方法
可以看到从这开始就把按键消息派发到了view中去,然后看view中的dispatchKeyEvent():
KeyEvent.java -> dispatch()
ViewGroup.dispatchKeyEvent方法
再来看下ViewGroup中的dispatchKeyEvent()
上面代码总结为:ViewGroup是重写了View的dispatchKeyEvent,如果有子view时,分发按键消息到子view中去。没有,直接由父view分发。
Activity.dispatchKeyEvent方法
到这就完了么?没有,Activity中dispatchKeyEvent,这不是个重写方法:
以上代码总结为:先让actionbar优先处理keyEvent,然后通过window处理,处理不了,到window上的DecorView处理。window和decorview的关系,相当于一个是窗户,一个是粘在窗户上的纸。所以,decorview可理解为窗户上的纸。Activity的dispatchKeyEvent,是用于处理KeyEvent相关,子类可以重写拦截所以的key event消息在分发到window这一层去的时候,所以我们最好做一些正常的处理流程。
主要过程如下:
1、调用onUserInteraction(),可重载该函数在消息派发前做一些处理
2、回调Activity包含的Window对象的superDispatchKeyEvent,该函数继而调用mDecor.superDispatchKveyEent,该函数继而又调用super.dispatchKeyEvent,DecorView的父类是FrameLayout,而FrameLayout未重载dispatchKeyEvent,因此最终调用ViewGroup的dispatchKeyEvent
3、如果DecorView未消耗消息,则调用event的dispatch()函数,这里的第一个参数receiver是Activity对象
写到这,有一个疑问?就是一个消息怎么从window派发到viewRoot中去呢?或者说ViewRoot中的按键消息是从哪来的?
ViewRoot中有一个内部类: W,W是一个Binder子类(static class W extends IWindow.Stub ),用于接收global window manager的各种消息, 如按键消息, 触摸消息等。 ViewRoot有一个W类型的成员mWindow,ViewRoot在构造中创建一个W的instance并赋值给mWindow(mWindow = new W(this);)。 ViewRoot是Handler的子类, W会通过Looper把消息传递给ViewRoot。
按键消息事件时序图
一张图,总结上面的流程:
第一时间获得博客更新提醒,以及更多android干货,源码分析,欢迎关注我的微信公众号,扫一扫下方二维码或者长按识别二维码,即可关注。
如果你觉得好,随手点赞,也是对笔者的肯定,也可以分享此公众号给你更多的人,原创不易
Android View框架总结(九)KeyEvent事件分发机制的更多相关文章
- Android:30分钟弄明白Touch事件分发机制
Touch事件分发中只有两个主角:ViewGroup和View.Activity的Touch事件事实上是调用它内部的ViewGroup的Touch事件,可以直接当成ViewGroup处理. View在 ...
- 【Android开发坑系列】之事件分发机制
总结一下: 事件序列的定义:从手触摸屏幕(含)到离开屏幕(含)期间所发生的一系列交互事件.主要由ACTION_DOWN.ACTION_MOVE.ACTOIN_UP.ACTION_CANCEL等组成,其 ...
- Android View框架总结(八)ViewGroup事件分发机制
请尊重分享成果,转载请注明出处: http://blog.csdn.net/hejjunlin/article/details/52298780 上篇分析了View的事件分发流程,留了一个问题:如果上 ...
- Android View框架总结(七)View事件分发机制
请尊重分享成果,转载请注明出处: http://blog.csdn.net/hejjunlin/article/details/52282833 View布局告一段落,从本篇开始View事件相关分析, ...
- 【朝花夕拾】Android自定义View篇之(六)Android事件分发机制(中)从源码分析事件分发逻辑及经常遇到的一些“诡异”现象
前言 转载请注明,转自[https://www.cnblogs.com/andy-songwei/p/11039252.html]谢谢! 在上一篇文章[[朝花夕拾]Android自定义View篇之(五 ...
- Android View的事件分发机制探索
概述 Android事件传递机制也是Android系统中比较重要的一块,事件类型有很多种,这里主要讨论TouchEvent的事件在framework层的传递处理机制.因为对于App开发人员来说,理解f ...
- Android面试必问!View 事件分发机制,看这一篇就够了!
在 Android 开发当中,View 的事件分发机制是一块很重要的知识.不仅在开发当中经常需要用到,面试的时候也经常被问到. 如果你在面试的时候,能把这块讲清楚,对于校招生或者实习生来说,算是一块不 ...
- Android View 事件分发机制 源码解析 (上)
一直想写事件分发机制的文章,不管咋样,也得自己研究下事件分发的源码,写出心得~ 首先我们先写个简单的例子来测试View的事件转发的流程~ 1.案例 为了更好的研究View的事件转发,我们自定以一个My ...
- Android view 的事件分发机制
1 事件的传递顺序是 Activity -> Window -> 顶层View touch 事件产生后,最先由 activity 的 dispatchTouchEvent 处理 /** * ...
随机推荐
- [WC2013]糖果公园
Description 题库链接 给你一棵 $n$ 个节点,有 $m$种颜色的树.每个节点上有一个颜色.定义一条树上路径的价值为 $sum_c V_c(\sum_{i=1}^{tim_c}W_i)$ ...
- POJ2449 Remmarguts' Date
"Good man never makes girls wait or breaks an appointment!" said the mandarin duck father. ...
- poj 1269 线段与线段相交
Intersecting Lines Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 13605 Accepted: 60 ...
- hdu 5532(最长上升子序列)
Input The first line contains an integer T indicating the total number of test cases. Each test case ...
- [NOI2011]
来自FallDream的博客,未经允许,请勿转载,谢谢. 省选完挂.但是善良的教练今天丢了一套NOI2011给我们训练 6道题233(虽然一道题做过了,一道题普及组的都会,就算是4道吧) 熬了一天,总 ...
- Windows下使用notepad++对文本进行行列转换
行转列: Ctrl + F 选择替换 查找目标:填写指定的内容 替换为:\r\n 查找模式:正则表达式 单击替换或全部替换按钮 列转行: Ctrl + F 选择替换 查找目标:\r\n 替换为:不 ...
- 视频人脸检测——OpenCV版(三)
视频人脸检测是图片人脸检测的高级版本,图片检测详情点击查看我的上一篇<图片人脸检测——OpenCV版(二)> 实现思路: 调用电脑的摄像头,把摄像的信息逐帧分解成图片,基于图片检测标识出人 ...
- 开源小工具 - swagger API访问代码生成器(js/typescript)
现在流行前后端分离,后端通常会使用swagger生成api文档,提供给前端的同事来调用,一般前端是查看这个文档,根据文档说明编写调用代码.其实,swagger已经提供了足够多的描述信息,我们可以基于s ...
- 索引法则--少用OR,它在连接时会索引失效
Mysql 系列文章主页 =============== 1 准备数据 1.1 建表 DROP TABLE IF EXISTS staff; CREATE TABLE IF NOT EXISTS st ...
- java.sql.SQLException: **** [SQLServer]对象名 "XXXX"无效
原因:进到数据库里面,但是没有选择数据库. 方法:检查数据源配置,这玩意容易看出.难得是多数据库操作时,切换数据源!