导航:首页 > 操作系统 > android消息处理机制

android消息处理机制

发布时间:2023-08-30 09:26:39

android View 事件分发机制

Android 事件机制包含系统启动流程、输入管理(InputManager)、系统服务和 UI 的通信(WindowManagerService + ViewRootImpl + Window)、事件分发等一系列的环节。

Android 系统中将输入事件定义为 InputEvent,根据输入事件的类型又分为了 KeyEvent(键盘事件) 和 MotionEvent(屏幕触摸事件)。这些事件统一由系统输入管理器 InputManager 进行分发。

在系统启动的时候,SystemServer 会启动 WindowManagerService,WMS 在启动的时候通过 InputManager 来负责监控键盘消息。

InputManager 负责从硬件接收输入事件,并将事件通过 ViewRootImpl 分发给当前激活的窗口处理,进而分发给 View。

Window 和 InputManagerService 之间通过 InputChannel 来通信,底层通过 socket 进行通信。

Android Touch 事件的基础知识:

KeyEvent 对应了键盘的输入事件;MotionEvent 就是手势事件,鼠标、笔、手指、轨迹球等相关输入设备的事件都属于 MotionEvent。

InputEvent 统一由 InputManager 进行分发,负责与硬件通信并接收输入事件。

system_server 进程启动时会创建 InputManagerService 服务。

system_server 进程启动时同时会启动 WMS,WMS 在启动的时候就会通过 IMS 启动 InputManager 来监控键盘消息。

App 端与服务端建立了双向通信之后,InputManager 就能够将产生的输入事件从底层硬件分发过来,Android 提供了 InputEventReceiver 类,以接收分发这些消息:

Window 和 IMS 之间通过 InputChannel 通信。InputChannel 是一个 pipe,底层通过 socket 进行通信。在 ViewRootImpl.setView() 过程中注册 InputChannel。

Android 事件传递机制是 先分发再处理 ,先由外部的 View 接收,然后依次传递给其内层的 View,再从最内层 View 反向依次向外层传递。

三个方法的关系如下:

分发事件:

应用了树的 深度优先搜索算法 (Depth-First-Search,简称 DFS 算法),每个 ViewGroup 都持有一个 mFirstTouchTarget, 当接收到 ACTION_DOWN 时,通过递归遍历找到 View 树中真正对事件进行消费的 Child,并保存在 mFirstTouchTarget 属性中,依此类推组成一个完整的分发链。在这之后,当接收到同一事件序列的其它事件如 ACTION_MOVE、ACTION_UP 时,则会跳过递归流程,将事件直接分发给下一级的 Child。

ViewGroup 分发事件的主要的任务是找一个 Target,并且用这个 Target 处理事件,主要逻辑如下 :

为什么倒序查找 TouchTarget?
如果按添加顺序遍历,当 View 重叠时(FrameLayout),先添加的 View 总是能消费事件,而后添加的 View 不可能获取到事件。

拦截事件:

[1] Android 事件分发机制的设计与实现
[2] Android 事件拦截机制的设计与实现

㈡ 详解Android消息机制之Message

在分析Message这个类之前,有必要先看看它的类注释其中有这么一段话:

从这段话得知,尽管Message本身的构造方式是公共的,但实现Message对象的最好方法确实是通过Message.obtain()函数返回,或者通过Handler.obtainMessage()方法,查看其最终还是调用了obtain函数。

如果使用new来实现我们初步的推测,应该是会构建大量的Message对象,对内存有一定的影响。
在这还是先看一下谷歌给这个函数的注释:

从obtain函数的注释中也能看出其作用就是用避免大量的构建Message对象,但它是究竟是如何处理的呢?带着疑问查看obtain函数:

实现很简单:

但看到这里还是很模糊,虽然sPool看上去像一个消息池,但再仔细看居然是一个Message对象,这样真的就能避免多次构建Message对象吗?继续看会发现一个next字段,再看它的注释 sometimes we store linked lists of these things ,Message的消息池原来是一个链表,如下图所示 。

每一个Message 对象通过next指向下一个Message(最后一个Message的next为null)形成一个链表,Message对象就成了一个可用的Message池。

到这终于知道Message对象原来是从链表中获取的,但还有一个疑问:Message对象是什么时候放入链表中的呢?从obtain函数并没有看见存储Message的操作。这时候又要回到文章开头的那段类注释的最后一句话: which will pull them from a pool of recycled objects。
消息池是一些回收的对象,也就是说Message对象是在回收的时候将其添加到链表中的。通过查看在Message中有个recycle方法:

在recycleUnchecked函数中会先清空该消息的各个字段,并且把flags设置为FLGA_IN_USE,表明该消息已经被使用了。然后判断是否要将消息回收到消息池中,如果池的大小小于MAX_POOL_SIZE,就将自身添加到链表的表头,sPoolSize++。
例如最开始的开始的时候链表中没有任何消息,将第一个Message对象添加到表中,此时的sPool为空,因此next也为空,sPool又指向this,这时sPool就指向当前这个被回收的Message对象,sPoolSize加1。我们把这个Message命名为m1,这时的链表应该如下:

如果再次插入一个名为m2的Message,那么m2将被插入表头,sPool指向m2,这时sPool的链表中结构如下:

对象池默认的大小为50,如果池的大小小于50,被回收的消息将会被插入到链表头部。

如果池中有元素,这时候再调用obtain函数时,实际上是就获取链表中表头的元素,也就是sPool。再把sPool指针往后移动一个。在obtain汉中,首先会声明一个Message对象m,并且让m指向sPool.sPool实际上指向了m2,因此m实际上指向的也是m2,这里相当于保持了m2这个元素。下一步是sPool指向m2的下一个元素,也就是m1。sPool也完成后移之后此时把m.next置空,也就相当于m2.next变成了null。最后就是m指向了m2元素,m2的next为空,sPool从原来的表头m2指向了下一个元素m1,最后将对象的元素减1,这样m2就顺利的脱离了消息池队伍,就返回给了调用obtain函数的。

㈢ Android的handler机制的原理

Android的handler机制的原理分为异步通信准备,消息发送,消息循环,消息处理。

1、异步通信准备

在主线程中创建处理器对象(Looper)、消息队列对象(Message Queue)和Handler对象。

2、消息入队

工作线程通过Handler发送消息(Message) 到消息队列(Message Queue)中。

3、消息循环

消息出队: Looper循环取出消息队列(Message Queue) 中的的消息(Message)。

消息分发: Looper将取出的消息 (Message) 发送给创建该消息的处理者(Handler)。

4、消息处理

处理者(Handler) 接收处理器(Looper) 发送过来的消息(Message),根据消息(Message) 进行U操作。

handler的作用

handler是android线程之间的消息机制,主要的作用是将一个任务切换到指定的线程中去执行,(准确的说是切换到构成handler的looper所在的线程中去出处理)android系统中的一个例子就是主线程中的所有操作都是通过主线程中的handler去处理的。

Handler的运行需要底层的 messagequeue和 looper做支撑。



㈣ Android消息推送原理

产品的角度:功能需要,比如说资讯类产品的新闻推送、工具类产品的公告推送等等
运营的角度:活动运营需要,比如说电商类产品的促销活动;召回用户 / 提高活跃度等等
作为开发者,不要有需求就接,应该多思考、多理解用户 / 功能的使用场景,有助于我们更好地去选择合适的开发方式

系统级别:任何时候都可以推送给用户,且不会被系统杀死
Android的消息推送服务称为:C2DM(Cloudto Device Messaging)

消息推送的本质是:App将服务器更新的信息推送给用户,即App获取服务器信息,再推送给用户
App从服务器获取最新消息的基本方式(原理)有3种:Push、Pull 和 SMS

经总结,Android中实现消息推送的有7种主流解决方案,接下来将一一介绍。

4.1 C2DM

定义:Cloud to Device Messaging,云端推送
Android系统级别的消息推送服务-Google出品
原理:基于Push方式,C2DM服务负责处理诸如消息排队等事务,并向运行于目标设备上的应用程序分发这些消息。如下图:

定义:轻量级的消息发布/订阅协议
原理:基于Push方式,wmqtt.jar 是IBM提供的MQTT协议的实现,原理如下图:

其他三种:

客户端

通信能够在这三者的任意两个之间双向发生。

原理流程

现今主流的推送平台分为

手机厂商类:小米推送、华为推送。
第三方平台类:友盟推送、极光推送、云巴(基于MQTT)
BAT大厂的平台推送:阿里云移动推送、腾讯信鸽推送、网络云推送

阅读全文

与android消息处理机制相关的资料

热点内容
政策pdf 浏览:290
有什么好玩的文娱app 浏览:807
python教学合集 浏览:955
有什么好用的小众app吗 浏览:116
芋道app源码 浏览:447
计算机程序员怎么找 浏览:280
智联发pdf 浏览:236
c语言编译错误变黑 浏览:72
手机软件加密了怎么解开 浏览:887
linux中的ln命令例子 浏览:142
为什么玩cf第一次进入服务器很慢 浏览:967
工作单源码 浏览:619
安卓如何关闭app自动升级 浏览:137
new文件夹怎么打开 浏览:633
安卓51如何优化 浏览:178
活塞式压缩机原理图 浏览:846
水环式压缩机工作原理 浏览:716
阿里云服务器安装后怎么使用 浏览:935
去做APP开户有什么危险没得啊 浏览:698
8分之1乘58算法 浏览:172