Android的handler消息机制
Hnadler机制中有这么几部分构成,包括 handler、Message、Looper和MessageQueue。要想在一个线程中使用Handler的话必须要有Looper和MessageQueue 的对象。在主线程中Looper不需要我们去创建 系统会自动帮我们调用prepareMainLooper和Looper.prepare方法,looper.prepare首先会到ThreadLocal这个线程级的单例中判断是否已经有了looper对象,如果有了就抛异常,如果没有就new出一个新的对象,并且通过ThreadLocal保存起来。这样就确保了我们的looper对象和当前线程建立起了一一对应的关系。looper对象new自己的时候调用构造方法会创建一个messageQueue对象,并且通过一个final类型的成员变量把MessageQueue保存起来。这样就确保了一个Looper对应唯一的messageQueue。所以 一个线程最多只能有一个looper, 一个looper对应唯一的MessageQueueu。也就是一个线程有唯一的Looper唯一的messageQueue。MessageQueue在创建的过程中会调用nativeInit方法,创建出一个nativeMessageQueue也就是说在jni层也有一个MessageQueue 创建NativeMessaageQueue的时候还会创建一个C++的Looper java层的MessageQueue和NativeMessageQueue通过一个成员变量mPtr建立起关联 mPtr保存了nativeMessageQueue的指针,我们可以通过这个指针随时访问nativeMessageQueue的首地址。需要注意 如果在主线程中调用Looper.prepareMainLooper或者Looper.prepare() 程序会抛出异常,因为系统已经帮我们创建好了无需我们在创建。
looper和messageQueue创建完成之后需要调用Looper.loop让消息循环起来。Looper.loop中有一个死循环,死循环不会阻塞主线程,而且恰恰是因为有这个死循环是我的主线程的代码不会执行完。handler不断的往消息队列中发消息 looper不断的取消息,如果没有消息就会睡在
Message msg = queue.next方法。实际上就是调用了nativeMessageQueue的方法, 利用到了linuxs的管道机制,取出消息之后就通过handler调用disPatchMessage来分发消息。他有三种情况:
如果msg的callback不为空 消息交给这个callback处理
如果msg的callback为空 判断handler mCallback接口 这个接口中就一个方法handleMessage
如果这个callback不为空交给这个handleMessage处理
如果上面两个都为空才交给handler的handleMessage处理消息
创建handler的时候 先到当前的线程中获取looper,如果当前线程没有looper的话那么会抛异常,如果当前线程已经创建了looper,那么我们把这个looper保存到一个final类型的成员变量中,通过这个Lopper找到对应的messageQueue,通过final成员变量进行保存这个messageQueue。这样就可以确保我们在哪个线程创建的handler,消息就会发送到对应的messageQueue中去。如果想在子线程中使用handler,必须首先调用looper.prepare()方法。
handler发送消息:
sendMessage sendEmptyMessage... 实际上都是调用 sendMessageAtTime这个方法,sendMessageAtTime调用了qnqueueMessage方法,这个党法实际上就是把消息放到消息队列中,
消息如何在消息队列中排序:
实际上Messagequeue通过一个成员变量 mMessage保存了消息队列的第一条消息,消息在消息队列中的排序是根据消息要执行的时间先后顺序进行排序。先执行的消息排在前面的,下一条消息通过message的next属性进行保存。enqueueMessage 就是根据新加入进来的消息 要执行的时间跟已有的消息进行比较找到合适的位置放到消息队列中。如果消息需要立即执行,那么就会执行nativeWake方法,实际上就是向管道中写了一个w 那么messageQueue的next方法就不会阻塞可以取出消息。
消息的创建和回收:
如果使用obtain方法来获取消息,那么就会利用到android的消息池。注意这个消息池是全局的,消息池的大小为50条。消息的回收,在Looper.loop()方法中当Handler处理消息之后会调用message.recycle方法回收消息。把要回收的消息所有的成员变量恢复到刚new出来的状态,然后放到消息池中去。
Android的handler消息机制的更多相关文章
- 【Android】Handler消息机制
Handler消息机制主要涉及Looper.Handler.MessageQueue.Message.其中,Looper主要负责获取消息,Handler负责发送消息及处理消息,MessageQueue ...
- Android消息传递之Handler消息机制
前言: 无论是现在所做的项目还是以前的项目中,都会遇见线程之间通信.组件之间通信,目前统一采用EventBus来做处理,在总结学习EventBus之前,觉得还是需要学习总结一下最初的实现方式,也算是不 ...
- Android Handler消息机制不完全解析
1.Handler的作用 Android开发中,我们经常使用Handler进行页面的更新.例如我们需要在一个下载任务完成后,去更新我们的UI效果,因为AndroidUI操作不是线程安全的,也就意味着我 ...
- Handler消息机制的一些原理(直接用code讲解)——Android开发
package com.example.handlertest; import android.os.Bundle; import android.os.Handler; import android ...
- Android Handler消息机制源码解析
好记性不如烂笔头,今天来分析一下Handler的源码实现 Handler机制是Android系统的基础,是多线程之间切换的基础.下面我们分析一下Handler的源码实现. Handler消息机制有4个 ...
- Android全面解析之由浅及深Handler消息机制
前言 很高兴遇见你~ 欢迎阅读我的文章. 关于Handler的博客可谓是俯拾皆是,而这也是一个老生常谈的话题,可见的他非常基础,也非常重要.但很多的博客,却很少有从入门开始介绍,这在我一开始学习的时候 ...
- Android Handler 消息机制原理解析
前言 做过 Android 开发的童鞋都知道,不能在非主线程修改 UI 控件,因为 Android 规定只能在主线程中访问 UI ,如果在子线程中访问 UI ,那么程序就会抛出异常 android.v ...
- Handler消息机制与Binder IPC机制完全解析
1.Handler消息机制 序列 文章 0 Android消息机制-Handler(framework篇) 1 Android消息机制-Handler(native篇) 2 Android消息机制-H ...
- 浅析Android中的消息机制(转)
原博客地址:http://blog.csdn.net/liuhe688/article/details/6407225 在分析Android消息机制之前,我们先来看一段代码: public class ...
随机推荐
- Linux如何更新软件源
Linux软件源的设置方法 1 打开数据源配置文件 vi /etc/apt/sources.list 添加相关的数据源,可以选择以下的数据源,不要写太多,否则会影响更新速度. 之后使用ap ...
- ART虚拟机之Trace原理(转)
一.概述 Android 6.0系统采用的art虚拟机,所有的Java进程都运行在art之上,当应用发生ANR(Application Not Response,其中最终的一个环节便是向目标进程发送信 ...
- SQL yog过期后教你怎么让他不过期
打开注册表 安装sqlyog后,进入注册表编辑器,进入\HEYK_CURRENT_USER\Software\,找到以{}括起来的那项直接干掉! 1, regedit 2,修改 3,
- 在matlab中生成m序列
实验环境为matlab2013b 1.首先编写一个mseq.m文件,内容为: function[mseq]=m_sequence(fbconnection) n=length(fbconnectio ...
- 2016/04/29 smarty模板 1, 初步 目标 : 变量 运算符 表达式 流程控制 函数
① 从配置文件中读取配置: 1,在模板页面加载配置文件 html页面 不是php页面 <{config_load file='fo.conf'}> 2,在需要用到配置的地方加 <{# ...
- 2016/3/17 Mysq select 数学函数 字符串函数 时间函数 系统信息函数 加密函数
一,数学函数主要用于处理数字,包括整型.浮点数等. ABS(X) 返回x的绝对值 SELECT ABS(-1)--返回1 CEll(X),CEILING(x) 返回大于或等于x的最小整数 SELEC ...
- npm, webpack, vue-cli, vue-x, axios
1,什么是node.js,以及npm 简单的来说Node.js就是运行在服务端的JavaScript,是基于Chrome V8引擎的.npm是Node.js包的管理工具. 2,npm的安装和更新 No ...
- Django值中间件
1,还是那句话:写代码的逻辑遵循:简洁,重复性高,可维护性高 1.1>中间件:中间件是一种用来处理Django的请求和响应的框架级别的钩子.它是一个轻量,低级别的插件系统,用于在全局范围内改变D ...
- su: /bin/bash: Permission denied带来的疑惑
>客户一个oracle突然当机了,由于业务启动,客户下意识的重启了服务器,系统是起来了,准备切换到oracle用户下启动数据库,可以怎么都无法su切换,真是火上浇油呀,描述如下: 在root用户 ...
- java语法基础(三)
类和对象 面向对象语言概述 java是一种面向对象的语言,什么是面向对象的语言? 要搞清楚什么是面向对象语言,我们需要相对的了解一下面向过程的语言. java入门阶段,我们又给大家说过一些语言的分类, ...