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 ...
随机推荐
- Zookeeper 简单操作
1. 连接到zookeeper服务 [java2000_wl@localhost zookeeper-3]$ bin/zkCli.sh -server 127.0.0.1:2181 也可以连接远端的 ...
- Linux——系统调用笔记1
底层文件访问: 进程:运行中的程序,它有一些与值关联的文件描述符,有多少个文件描述符取决于系统配置情况. 当一个程序开始运行时,一般会打开三个文件描述符: 0:标准输入 ...
- properties文件读取配置信息
public static void main(String[] args){ String printerName=""; String path = "C:\\Bar ...
- hdu 1251 统计
他妹的.敲完了.电脑死机了,所有消失了,又从新打了一遍,... 这是什么节奏 #include <stdio.h> #include <string.h> #include & ...
- oracle 10g 实例用localhost无法访问的处理
我在笔记本上安装了一个Oracle10g,安装好了之后,查看E:\oracle\product\10.2.0\db_1\network\ADMIN\tnsnames.ora文件,发现SID对应的IP地 ...
- atom及其插件activate-power-mode下载安装
Atom是Github推出的一个文本编辑器,其中包含很多插件可以自行下载安装,其中一个最近比较火的就是插件activate-power-mode,可以实现打字屏振效果, 打字带特效哦,所以最近就尝试安 ...
- (19)javaWeb项目名称修改
1,选中项目,[右键]-[Refactor]-[Rename] 在弹出面板中,填写New Name 点击[OK] 2,改变运行时目录名称 选中项目[右键]-[Properties] 在弹框中选择选择[ ...
- Lightoj 1011 - Marriage Ceremonies
You work in a company which organizes marriages. Marriages are not that easy to be made, so, the job ...
- Expression Blend实例中文教程(11) - 视觉管理器快速入门Visual State Manager(VSM)
Expression Blend实例中文教程(11) - 视觉管理器快速入门Visual State Manager(V 时间:2010-04-12 16:06来源:SilverlightChina. ...
- jfreechart应用1--环境配置
jfreechart应用1--环境配置 JFreeChart是一组功能强大.灵活易用的Java绘图API,使用它可以生成多种通用性的报表,包括柱状图.饼图.曲线图.甘特图等.它能够用在Swing和We ...