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 处理 /** * ...
随机推荐
- Codeforces 671 D. Roads in Yusland
题目描述 Mayor of Yusland just won the lottery and decided to spent money on something good for town. Fo ...
- 【The Time Traveller's Wife】
After reading The Time Traveller's Wife: It's a tragedy,I think.But it's mixed with hope.Henry ...
- [bzoj4822][Cqoi2017]老C的任务&[bzoj1935][Shoi2007]Tree 园丁的烦恼
来自FallDream的博客,未经允许,请勿转载,谢谢. 老 C 是个程序员. 最近老 C 从老板那里接到了一个任务——给城市中的手机基站写个管理系统.作为经验丰富的程序员,老 C 轻松地完成 ...
- 一起来Fit TDMA over WiFi(2)
3 收发流程分析与改进 收发流程分析涉及到具体代码,属于SDK驱动内容,不能完全公开,仅供参考,本系列文档中涉及到具体功能或代码时,请在自己的驱动代码中查找. QCA驱动从9.5开始,将原来的htc的 ...
- Python【第四课】 模块 and 包
本篇内容 模块基础和导入(import,from...import...) 包常识和导入(import,from...import...) 函数式第一类对象 1.模块基础和导入 1.1 模块认识 什么 ...
- Linux基本知识总结
一.Linux的基本介绍 起源:大家知道先有Unix,后有的linux就行了,其他的细节可以自己查阅资料. 特点:开源!!! 安全(Linux的病毒远少于window). 免费(商业公司最喜欢这一点) ...
- h5的localStorage和sessionStorage
今天做了个首页的弹窗,要求是打开时显示弹窗,然后点击关闭按钮时弹窗关闭,然后点击不再显示,之后再刷新就不会有弹窗,总结一下需求. 1.弹窗显示隐藏 这个很容易,我们可以用display:none和di ...
- 原生js实现preAll和nextAll方法
一直以来都在好奇,jquery的prevAll和nextAll方法都是咋实现的,那么厉害,而且还那么方便.不得不说,jquery真的帮我们省去了开发中手写大量js代码带来的开发进度问题,而且很好的解决 ...
- hibernate4整合spring3出现java.lang.NoClassDefFoundError: [Lorg/hibernate/engine/FilterDefinition;
解决办法 原先:<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annota ...
- 深入理解Java类加载器(1):Java类加载原理解析
1 基本信息 每个开发人员对Java.lang.ClassNotFoundExcetpion这个异常肯定都不陌生,这背后就涉及到了java技术体系中的类加载.Java的类加载机制是技术体系中比较核心的 ...