(一文弄懂!!超详细!!)安卓事件分发机制-程序员宅基地

技术标签: 安卓  移动开发(AndroidStudio)  android  软件工程  

一、安卓事件分发的整个流程

Android 的事件分发流程是一个从顶至底的层级传递过程,涉及 Activity、ViewGroup 和 View。这个流程确保了触摸事件(如屏幕触摸操作)能够被正确地处理和响应。我们将首先概括一下一次事件触发的整个流程,再逐一对其中的细节进行分别介绍:

1. 事件生成:

  • 当用户触摸屏幕时,底层的硬件和操作系统生成一个触摸事件(如 MotionEvent)。

2. InputManager 处理:

  • InputManager 接收这个事件,并确定哪个窗口(通常对应一个 Activity)应该接收这个事件。

3. Activity 分发:

  • 事件首先到达 Activity,通过 Activity 的 dispatchTouchEvent() 方法开始处理。
  • 如果 Activity 没有完全拦截这个事件,它将事件传递给它的根视图(一个 ViewGroup)。

4. ViewGroup 分发:

  • 在 ViewGroup 中,dispatchTouchEvent() 同样被调用。
  • ViewGroup 可以选择拦截这个事件,通过实现 onInterceptTouchEvent() 方法。如果 ViewGroup 拦截了事件(返回 true),则事件不再向下传递,而是交由 ViewGroup 的 onTouchEvent() 方法处理。
  • 如果 ViewGroup 没有拦截(onInterceptTouchEvent() 返回 false),事件将继续传递给它的子视图。

5. 子视图处理:

  • 事件接着被传递到子视图(可能是另一个 ViewGroup 或一个 View)的 dispatchTouchEvent()
  • 这一过程递归进行,直到找到最终的事件接收者。

6. 事件响应:

  • 最终的视图(View)通过它的 onTouchEvent() 方法处理这个事件。
  • 如果这个视图没有处理(onTouchEvent() 返回 false),事件会回溯到它的父 ViewGroup,以此类推,直到找到能处理这个事件的视图。

7. 事件消费:

  • 一旦事件被一个视图的 onTouchEvent() 方法处理并消费(方法返回 true),事件分发流程结束。这个视图成为了该触摸序列(如一次点击或滑动操作)的消费者,后续的事件(如触摸移动或抬起)也会直接分发给这个视图。

这个流程确保了 Android 应用可以灵活处理用户的触摸输入,同时也提供了多个层级对事件进行截获和响应的能力。
接下来我们将分别对InputManager事件对象涉及的方法以及事件类型逐一进行详细讲解。

二、InputManager

InputManager 在 Android 系统中是一个核心的服务组件,负责管理和分发从各种输入设备(如触摸屏、键盘、鼠标等)来的输入事件。Android 的输入系统架构中处于较为底层的位置,它不仅负责将输入事件从硬件传递到应用,还处理了输入事件的多种复杂场景它在,主要功能和特点包括:

1. 事件接收和处理:

  • InputManager 负责从底层的 Linux 内核接收原始的输入事件。这些事件可能来自触摸屏、物理键盘、鼠标、游戏手柄、陀螺仪等多种输入源。
  • 它对这些原始事件进行预处理,如合成、转换或调整事件数据。

2. 事件分发:

  • 经过处理后,InputManager 将这些事件分发到正确的窗口和视图(View)。这个分发过程涉及判断哪个应用或窗口应该接收事件,并将事件传递给它。
  • 在这个过程中,InputManager 会考虑焦点控制、窗口的布局和层级关系等因素。

3. 多点触控和手势识别:

  • InputManager 能够处理复杂的多点触控数据,识别并分发与多点触控相关的手势事件。
  • 它为应用提供了一个相对简化的接口来处理这些高度复杂的输入。

4. 设备管理:

  • InputManager 还负责管理输入设备,提供查询连接的输入设备、它们的能力和状态等功能。

5. 与应用层的交互:

  • 虽然 InputManager 主要在系统层面运作,但它为应用层提供了接口,使得应用可以查询输入设备的信息、注册以接收特定设备的事件等。
  • 例如,游戏应用可能需要查询游戏手柄的状态或注册接收其输入事件。

6. 安全性和权限管理:

  • InputManager 在处理输入事件时,也需要考虑安全性和权限。例如,它需要确保敏感的输入数据(如密码输入)不会被未授权的应用捕获。
    总的来说,InputManager 是 Android 输入系统的核心,它不仅负责将输入事件从硬件传递到应用,还处理了输入事件的多种复杂场景,确保了输入事件的高效和安全处理。

三、三个事件传递对象

在Android中,事件分发机制主要涉及三个层级的对象:Activity、ViewGroup和View。它们的主要区别如下:

1. Activity:

  • Activity是Android应用中的一个重要组件,代表了一个屏幕上的一个单独的窗口。
  • 它不直接参与触摸事件的处理,但是是事件分发的起点。当一个触摸事件发生时,系统首先将事件传递给当前处于活动状态的Activity。
  • Activity通常包含一个或多个ViewGroup和View,负责整个应用界面的布局和显示。

2. ViewGroup:

  • ViewGroup是一个抽象类,继承自View,是所有布局容器的基类,如LinearLayout、RelativeLayout等。
  • 它不仅是View的容器,而且还负责管理其子View(包括其他ViewGroup)的布局和绘制。
  • 在事件分发过程中,ViewGroup有能力决定是否拦截某个事件(通过onInterceptTouchEvent()方法),如果不拦截,事件则会继续向下传递给其子View。

3. View:

  • View是Android中所有用户界面组件的基类,如按钮、文本框等。
  • View是用户交互的基本单元,用于绘制和处理用户的交互事件,如触摸、点击。
  • 在事件分发机制中,View是事件链的最末端,如果事件传递到了View,它将通过onTouchEvent()方法来处理这个事件。

四、涉及的方法

在Android的事件分发过程中,主要涉及以下几个方法:

1. dispatchTouchEvent():

  • 这是事件分发的起始方法。
  • 在Activity、ViewGroup和View中都有这个方法。
  • 它负责将触摸事件(MotionEvent)分发到正确的子View或者自身。
  • 在ViewGroup中,它还会决定是否调用自己的onInterceptTouchEvent()方法来判断是否要拦截事件。

2. onInterceptTouchEvent():

  • 这个方法只存在于ViewGroup中。
  • 它用于决定当前的ViewGroup是否应该拦截触摸事件。
  • 如果这个方法返回true,表示ViewGroup决定拦截并处理这个事件,事件将不会继续向下传递。
  • 如果返回false,事件会继续传递给子View。

3. onTouchEvent():

  • 这个方法存在于Activity、ViewGroup和View中。
  • 它用于处理触摸事件。
  • 如果事件未被拦截且当前View是事件传递链上的最后一层,该事件最终会传递到这里。

4. dispatchKeyEvent():

  • 虽然主要用于键盘事件的分发,但也是事件分发机制的一部分。
  • 它类似于dispatchTouchEvent(),用于分发按键事件。

5. onKeyDown() 和 onKeyUp():

  • 这些方法用于处理按键事件的按下和释放。
  • 它们存在于Activity和View中。

6. onKeyLongPress():

  • 这个方法用于处理长按键事件。
  • 它通常存在于Activity和View中。

五、涉及的事件类型

1. 触摸事件(Touch Events)

  • MotionEvent 是处理触摸事件的主要类。它包含了诸如触摸屏幕的动作类型(如按下、移动、抬起等)、触摸点的位置、压力、时间戳等信息。
  • 触摸事件的动作类型主要包括 ACTION_DOWN(按下)、ACTION_MOVE(移动)、ACTION_UP(抬起)、ACTION_CANCEL(取消)等。

2. 按键事件(Key Events)

  • KeyEvent 用于处理按键事件,比如用户按下或释放手机上的物理按键(如音量键、返回键等)。
  • 主要的动作类型包括 ACTION_DOWN(按键按下)和 ACTION_UP(按键释放),以及 ACTION_MULTIPLE(多个连续的按键动作)。

3. 滚动事件(Scroll Events)

  • 涉及到滚动操作,如列表滚动。这些通常是由触摸事件触发的,但它们有自己的特殊处理逻辑。

4. 长按事件(Long Press Events)

  • 当用户长时间按住屏幕的某个点时触发。虽然这是基于触摸事件的,但通常需要特殊的处理来区分普通的触摸事件。

5. 焦点变化事件(Focus Change Events)

  • 当用户界面中的焦点发生变化时触发,例如从一个文本框移动到另一个文本框。

6. 手势事件(Gesture Events)

  • 如双指缩放、旋转等。这些事件通常是由多个触摸点组合起来的复杂动作。

7. 其他特定于设备的事件

  • 如陀螺仪事件、加速度计事件等,这些通常用于高级的用户界面交互,例如在游戏或增强现实应用中。
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Moonsev/article/details/135919109

智能推荐

class和struct的区别-程序员宅基地

文章浏览阅读101次。4.class可以有⽆参的构造函数,struct不可以,必须是有参的构造函数,⽽且在有参的构造函数必须初始。2.Struct适⽤于作为经常使⽤的⼀些数据组合成的新类型,表示诸如点、矩形等主要⽤来存储数据的轻量。1.Class⽐较适合⼤的和复杂的数据,表现抽象和多级别的对象层次时。2.class允许继承、被继承,struct不允许,只能继承接⼝。3.Struct有性能优势,Class有⾯向对象的扩展优势。3.class可以初始化变量,struct不可以。1.class是引⽤类型,struct是值类型。

android使用json后闪退,应用闪退问题:从json信息的解析开始就会闪退-程序员宅基地

文章浏览阅读586次。想实现的功能是点击顶部按钮之后按关键字进行搜索,已经可以从服务器收到反馈的json信息,但从json信息的解析开始就会闪退,加载listview也不知道行不行public abstract class loadlistview{public ListView plv;public String js;public int listlength;public int listvisit;public..._rton转json为什么会闪退

如何使用wordnet词典,得到英文句子的同义句_get_synonyms wordnet-程序员宅基地

文章浏览阅读219次。如何使用wordnet词典,得到英文句子的同义句_get_synonyms wordnet

系统项目报表导出功能开发_积木报表 多线程-程序员宅基地

文章浏览阅读521次。系统项目报表导出 导出任务队列表 + 定时扫描 + 多线程_积木报表 多线程

ajax 如何从服务器上获取数据?_ajax 获取http数据-程序员宅基地

文章浏览阅读1.1k次,点赞9次,收藏9次。使用AJAX技术的好处之一是它能够提供更好的用户体验,因为它允许在不重新加载整个页面的情况下更新网页的某一部分。另外,AJAX还使得开发人员能够创建更复杂、更动态的Web应用程序,因为它们可以在后台与服务器进行通信,而不需要打断用户的浏览体验。在Web开发中,AJAX(Asynchronous JavaScript and XML)是一种常用的技术,用于在不重新加载整个页面的情况下,从服务器获取数据并更新网页的某一部分。使用AJAX,你可以创建异步请求,从而提供更快的响应和更好的用户体验。_ajax 获取http数据

Linux图形终端与字符终端-程序员宅基地

文章浏览阅读2.8k次。登录退出、修改密码、关机重启_字符终端

随便推点

Python与Arduino绘制超声波雷达扫描_超声波扫描建模 python库-程序员宅基地

文章浏览阅读3.8k次,点赞3次,收藏51次。前段时间看到一位发烧友制作的超声波雷达扫描神器,用到了Arduino和Processing,可惜啊,我不会Processing更看不懂人家的程序,咋办呢?嘿嘿,所以我就换了个思路解决,因为我会一点Python啊,那就动手吧!在做这个案例之前先要搞明白一个问题:怎么将Arduino通过超声波检测到的距离反馈到Python端?这个嘛,我首先想到了串行通信接口。没错!就是串口。只要Arduino将数据发送给COM口,然后Python能从COM口读取到这个数据就可以啦!我先写了一个测试程序试了一下,OK!搞定_超声波扫描建模 python库

凯撒加密方法介绍及实例说明-程序员宅基地

文章浏览阅读4.2k次。端—端加密指信息由发送端自动加密,并且由TCP/IP进行数据包封装,然后作为不可阅读和不可识别的数据穿过互联网,当这些信息到达目的地,将被自动重组、解密,而成为可读的数据。不可逆加密算法的特征是加密过程中不需要使用密钥,输入明文后由系统直接经过加密算法处理成密文,这种加密后的数据是无法被解密的,只有重新输入明文,并再次经过同样不可逆的加密算法处理,得到相同的加密密文并被系统重新识别后,才能真正解密。2.使用时,加密者查找明文字母表中需要加密的消息中的每一个字母所在位置,并且写下密文字母表中对应的字母。_凯撒加密

工控协议--cip--协议解析基本记录_cip协议embedded_service_error-程序员宅基地

文章浏览阅读5.7k次。CIP报文解析常用到的几个字段:普通类型服务类型:[0x00], CIP对象:[0x02 Message Router], ioi segments:[XX]PCCC(带cmd和func)服务类型:[0x00], CIP对象:[0x02 Message Router], cmd:[0x101], fnc:[0x101]..._cip协议embedded_service_error

如何在vs2019及以后版本(如vs2022)上添加 添加ActiveX控件中的MFC类_vs添加mfc库-程序员宅基地

文章浏览阅读2.4k次,点赞9次,收藏13次。有时候我们在MFC项目开发过程中,需要用到一些微软已经提供的功能,如VC++使用EXCEL功能,这时候我们就能直接通过VS2019到如EXCEL.EXE方式,生成对应的OLE头文件,然后直接使用功能,那么,我们上篇文章中介绍了vs2017及以前的版本如何来添加。但由于微软某些方面考虑,这种方式已被放弃。从上图中可以看出,这一功能,在从vs2017版本15.9开始,后续版本已经删除了此功能。那么我们如果仍需要此功能,我们如何在新版本中添加呢。_vs添加mfc库

frame_size (1536) was not respected for a non-last frame_frame_size (1024) was not respected for a non-last-程序员宅基地

文章浏览阅读785次。用ac3编码,执行编码函数时报错入如下:[ac3 @ 0x7fed7800f200] frame_size (1536) was not respected for anon-last frame (avcodec_encode_audio2)用ac3编码时每次送入编码器的音频采样数应该是1536个采样,不然就会报上述错误。这个数字并非刻意固定,而是跟ac3内部的编码算法原理相关。全网找不到,国内音视频之路还有很长的路,音视频人一起加油吧~......_frame_size (1024) was not respected for a non-last frame

Android移动应用开发入门_在安卓移动应用开发中要在活动类文件中声迷你一个复选框变量-程序员宅基地

文章浏览阅读230次,点赞2次,收藏2次。创建Android应用程序一个项目里面可以有很多模块,而每一个模块就对应了一个应用程序。项目结构介绍_在安卓移动应用开发中要在活动类文件中声迷你一个复选框变量

推荐文章

热门文章

相关标签