Android事件分发机制初识

Posted bug樱樱

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android事件分发机制初识相关的知识,希望对你有一定的参考价值。

初识android点击事件

  1. 用户对屏幕的操作的事件可以划分为3种最基础的事件:ACTION_DOWN、ACTION_MOVE、ACTION_UP。

  2. 用户的ACTION_DOWN到ACTION_UP的操作可以称为一个事件序列,主要有以下两种组成:

  • ACTION_DOWN->ACTION_UP
  • ACTION_DOWN->许多个ACTION_MOVE>ACTION_UP
  1. Android 的事件分发机制大体可以分为三部分:事件生产、事件分发 、事件消费。事件的生产是由用户点击屏幕产生,我们这次着重分析事件的分发和消费,因为事件分发和处理联系的过于紧密,这篇文章将把事件的分发和消费放在一起分析。

在Activity上的事件分发和Activity PhoneView DecorView ViewGroup view 密不可分,它们的关系如下图表示:

View树的视图结构可以用下图概括:

事件分发主要有以下几个方法:

  1. dispatchTouchEvent(event):用于进行点击事件的分发
  2. onInterceptTouchEvent(event):用于进行点击事件的拦截 注:只有 ViewGroup才有
  3. onTouchEvent(event):用于处理点击事件

事件的分发到处理过程大致可以用下图简单表示:

总结一下

  1. 所有的dispatchTouchEvent当为true的时候则直接消费(),为false的时候则传递给上一层的onTouchEvent方法,Activity例外false它也会消费掉,当为super方法的时候则向下一层的dispatchTouchEvent传递,注意:ViewGroup由于有onInterceptTouchEvent,他会先传递到onInterceptTouchEvent!!!

  2. onInterceptTouchEvent(ViewGroup特有)为super/false时候可以向下一层传递到dispatchTouchEvent,当为true的时候,则表示要自己消化,则会传递到自身的onTouchEvent方法。

  3. 所有的onTouchEvent方法,当返回为true的时候表示自己要消费(结束),当为super/false的话则传递给上一层的onTouchEvent方法。

对ACTION_MOVE 和ACTION_UP事件的处理

对这两种事件的处理可以总结为下面这些内容ACTION_DOWN事件在哪个控件消费了(return true), 那么ACTION_MOVE和ACTION_UP就会从上往下(通过dispatchTouchEvent)做事件分发往下传,就只会传到这个控件,不会继续往下传,通俗理解就是ACTION_DOWN哪里结束,ACTION_MOVE 和ACTION_UP就传递到哪里结束。

View事件方法执行顺序

先看结论:onTouchListener > onTouchEvent > onLongClickListener > onClickListener

  1. 从dispatchTouchEvent源代码中我们可以看到View会先判断是否设置了OnTouchListener,如果设置了OnTouchListener并且onTouch方法返回了true,那么onTouchEvent不会被调用。当没有设置OnTouchListener或者设置了OnTouchListener但是onTouch方法返回false则会调用View自己的onTouchEvent方法。

  2. 默认点击的时间大于了500ms算是LongClick,onTouchEvent中的ACTION_UP事件处理,也会先检查有没有长按事件的监听,再执行onLongClick

  3. 在View的onTouchEvent中的case ACTION_UP中有对onClickListener的处理,感兴趣的小伙伴可以查看具体源码。

简单总结一下 onLongClickListener 和 onClickListener的处理过程:当ACTION_DOWN到达一个view后,他会想通过handler post一个500ms消息(我称之为长按消息)给主线程,这个消息里面封装着LongClickListener的处理任务,如果在500ms之内收到了ACTION_UP事件,则首先会移除掉主线程消息队列中的长按消息,然后去执行onClickListener对Click的执行逻辑,因为主线程中长按消息已经被移除,所以500ms后不会执行LongClick的任务。

ViewGroup分发中有一种特殊情况,那就是FLAG_ DISALLOW_ INTERCEPT 标记位,这个标记位是通过requestDisallowInterceptTouchEvent 方法来设置的,一般用于子 View中。FLAG_DISALLOW_INTERCEPT 一旦设置后,ViewGroup 将无法拦截除了 ACTION_ DOWN以外的其他点击事件。为什么说是除了ACTION_ DOWN以外的其他事 件呢?这是因为ViewGroup在分发事件时,如果是ACTION DOWN就会重置 FLAG_ DISALLOW_ INTERCEPT这个标记位,将导致子View中设置的这个标记位无效。 因此,当面对ACTION_DOWN事件时,ViewGroup总是会调用自己的onInterceptTouchEvent方法来询问自己是否要拦截事件,这一点从源码中也可以看出来。

注:有个TouchTarget类,观察TouchTarget的字段可以发现,TouchTarget里面存有消费事件的View,它的结构是一个链表结构。

TouchTarget.java

// 观察TouchTarget的字段可以发现吗,TouchTarget里面存有消费事件的View,

//pointerIdBits(和多点触碰有关),还有指向下一个节点的引用

  private static final class TouchTarget 

        private static final int MAX_RECYCLED = 32;

        private static final Object sRecycleLock = new Object[0];

        private static TouchTarget sRecycleBin;

        private static int sRecycledCount;

        public static final int ALL_POINTER_IDS = -1; // all ones

        // The touched child view.

        @UnsupportedAppUsage

        public View child;

        // The combined bit mask of pointer ids for all pointers captured by the target.

        public int pointerIdBits;

        // The next target in the target list.

        public TouchTarget next;

写这个博客的时候参考很多优秀的博客和书籍,在这里向各位作者表示感谢!

作者:ChristZc
链接:https://www.jianshu.com/p/a1ff7f15c137

最后

如果想要成为架构师或想突破20~30K薪资范畴,那就不要局限在编码,业务,要会选型、扩展,提升编程思维。此外,良好的职业规划也很重要,学习的习惯很重要,但是最重要的还是要能持之以恒,任何不能坚持落实的计划都是空谈。

如果你没有方向,这里给大家分享一套由阿里高级架构师编写的《Android八大模块进阶笔记》,帮大家将杂乱、零散、碎片化的知识进行体系化的整理,让大家系统而高效地掌握Android开发的各个知识点。

相对于我们平时看的碎片化内容,这份笔记的知识点更系统化,更容易理解和记忆,是严格按照知识体系编排的。

一、架构师筑基必备技能

1、深入理解Java泛型
2、注解深入浅出
3、并发编程
4、数据传输与序列化
5、Java虚拟机原理
6、高效IO
……

二、Android百大框架源码解析

1.Retrofit 2.0源码解析
2.Okhttp3源码解析
3.ButterKnife源码解析
4.MPAndroidChart 源码解析
5.Glide源码解析
6.Leakcanary 源码解析
7.Universal-lmage-Loader源码解析
8.EventBus 3.0源码解析
9.zxing源码分析
10.Picasso源码解析
11.LottieAndroid使用详解及源码解析
12.Fresco 源码分析——图片加载流程

三、Android性能优化实战解析

  • 腾讯Bugly:对字符串匹配算法的一点理解
  • 爱奇艺:安卓APP崩溃捕获方案——xCrash
  • 字节跳动:深入理解Gradle框架之一:Plugin, Extension, buildSrc
  • 百度APP技术:Android H5首屏优化实践
  • 支付宝客户端架构解析:Android 客户端启动速度优化之「垃圾回收」
  • 携程:从智行 Android 项目看组件化架构实践
  • 网易新闻构建优化:如何让你的构建速度“势如闪电”?

四、高级kotlin强化实战

1、Kotlin入门教程
2、Kotlin 实战避坑指南
3、项目实战《Kotlin Jetpack 实战》

  • 从一个膜拜大神的 Demo 开始

  • Kotlin 写 Gradle 脚本是一种什么体验?

  • Kotlin 编程的三重境界

  • Kotlin 高阶函数

  • Kotlin 泛型

  • Kotlin 扩展

  • Kotlin 委托

  • 协程“不为人知”的调试技巧

  • 图解协程:suspend

五、Android高级UI开源框架进阶解密

1.SmartRefreshLayout的使用
2.Android之PullToRefresh控件源码解析
3.Android-PullToRefresh下拉刷新库基本用法
4.LoadSir-高效易用的加载反馈页管理框架
5.Android通用LoadingView加载框架详解
6.MPAndroidChart实现LineChart(折线图)
7.hellocharts-android使用指南
8.SmartTable使用指南
9.开源项目android-uitableview介绍
10.ExcelPanel 使用指南
11.Android开源项目SlidingMenu深切解析
12.MaterialDrawer使用指南

六、NDK模块开发

1、NDK 模块开发
2、JNI 模块
3、Native 开发工具
4、Linux 编程
5、底层图片处理
6、音视频开发
7、机器学习

七、Flutter技术进阶

1、Flutter跨平台开发概述
2、Windows中Flutter开发环境搭建
3、编写你的第一个Flutter APP
4、Flutter开发环境搭建和调试
5、Dart语法篇之基础语法(一)
6、Dart语法篇之集合的使用与源码解析(二)
7、Dart语法篇之集合操作符函数与源码分析(三)

八、微信小程序开发

1、小程序概述及入门
2、小程序UI开发
3、API操作
4、购物商场项目实战……

全套视频资料:

一、面试合集

二、源码解析合集


三、开源框架合集


欢迎大家一键三连支持,若需要文中资料,直接点击文末CSDN官方认证微信卡片免费领取【保证100%免费】↓↓↓

以上是关于Android事件分发机制初识的主要内容,如果未能解决你的问题,请参考以下文章

android 事件分发机制

android-----事件分发机制测试系列

Android面试老生常谈的 View 事件分发机制,看这一篇就够了!

最新Android高级面试知识点--事件分发Binder机制

最新Android高级面试知识点--事件分发Binder机制

Android面试老生常谈的 View 事件分发机制,看这一篇就够了