「Android」消息驱动Looper和Handler类分析
Android系统中的消息驱动工作原理:
1、有一个消息队列,可以往这个消息队列中投递消息;
2、有一个消息循环,不断的从消息队列中取得消息,然后处理。
工作流程:
1、事件源将待处理的消息加入到消息队列中,一般是加至队列尾部(优先级高的消息可以加至队列头),事件源提交的消息可以是按键、触摸等物理事件产生的消息,也可以是系统或应用程序发出的消息;
2、处理线程不断的从消息队列头中取出消息并处理。
在Android系统中,这些工作主要由Looper和Handler实现:
Looper类,用于封装消息循环,并且有一个消息队列;
Handler类,封装消息投递、消息处理等接口。
一、Looper类分析
Looper用于封装了android线程中的消息循环,默认情况下一个线程是不存在消息循环(message loop)的,需要调用Looper.prepare()来给线程创建一个消息循环,调用Looper.loop()来使消息循环起作用,使用Looper.prepare()和Looper.loop()创建了消息队列就可以让消息处理在该线程中完成。
class LooperThread extends Thread
{
public void run()
{
Looper.prepare();
//代码1....
Looper.loop();
//代码2....
}
}
(1)在 Looper.prepare()中,定义一个ThreadLocal对象sT,并构造一个Looper对象设置到调用线程的局部变量sT中。
ThreadLocal是java中的线程局部变量类(Thread Local Variable),该类有两个关键函数:
- set:设置调用线程的局部变量
- get:获取调用线程的局部变量
因此,prepareh函数会在调用线程的局部变量中设置一个Looper对象。这个调用线程就是LooperThread的run线程。
private Looper(){
//构造一个消息队列
mQueue = new MessageQueue();
//得到当前线程的Thread对象
mThread = Thread.currentThread();
}
prepare函数中设置了一个Looper对象,对象保存在这个调用线程的局部变量中。而Looper 对象内部封装了一个消息队列。
(2)Looper循环
> 在Loop()方法中,首先通过ThreadLocal的get方法获取创建的Looper对象;
> 之后取出这个Looper的消息队列 MessageQueue queue = looper.mQueue;
> while循环中,处理消息:
while(true){
Message msg = queue.next();
// 处理i消息,Message对象中有一个target(Handler类型)
// 如果target为空,则退出消息循环
if (msg != null ) {
if (msg.target == null) { return; }
// 调用该消息的Handler,交给他的dispatchMessage函数处理。
msg.target.dispatchMessage(msg);
msg.recyle();
}
}
因此,分析prepare和loop函数后,Looper的作用有:
1、封装了一个消息队列;
2、prepare函数把这个Looper和调用prepare的线程(最终的处理线程)关联在i一起;
3、处理线程调用loop函数,处理来自消息队列的消息
当事件源向Looper发送消息时,消息加到Looper的消息队列。该消息将由和Looper绑定的处理线程来处理。
注:Looper、Message、Handler的关系:
1、Looper中有一个Message队列,存储的时一个个待处理的message;
2、Message中有一个Handler,用来处理Message。
二、Handler类分析
Handler中包括的成员:
Hadler.java:
final messageQueue mQueue; //Handler中也有一个消息队列
final Looper mLooper;
final Callback mCallback; //i回调用的类
在Handler的构造函数中,Handler中的消息队列最终会指向Looper的消息队列。
(1)插入消息到Looper消息队列
Handler提供了一系列帮助完成创建消息和插入消息队列的函数。
例如Handler.java中sendMessage发送一个消息,将消息添加到消息队列末尾:
public final boolean sendMessage(Message msg) {
return sendMessageDelayed(msg, );
}
public final boolean senMessageDelayed(Message msg, long delayMilis){
......
return senMessage(msg, SystemClock.uptimeMillis() + delayMillis); // 当前时间
}
public boolean sendMessageTime(Message msg, long uptimeMillis) {
boolean sent = false;
MessageQueue queue = mQueue;
if (queue != null) {
msg.target = this; // 将targt设置为自己,然后加入到消息队列
sent = queue.enqueueMessage(msg, uptimeMillis);
}
return sentl
}
(2)Handler的消息处理
在loop方法中,如果获得消息后会调用target的dispatchMessage函数,然后将这个消息派发给Handler处理。
dispatchMessage定义了一套消息处理的优先级机制:
> Messagu如果自带callback处理,则交给callback处理;
> Handler如果设置了全局的mCallback,则交给mCallback处理;
> 如果上述都没有,消息则会被交给Handler子类实现的handleMessage 来处理。(这需要从Handler派生并重载handleMessage函数)
「Android」消息驱动Looper和Handler类分析的更多相关文章
- Android的消息循环机制 Looper Handler类分析
Android的消息循环机制 Looper Handler类分析 Looper类说明 Looper 类用来为一个线程跑一个消息循环. 线程在默认情况下是没有消息循环与之关联的,Thread类在ru ...
- Android中消息系统模型和Handler Looper
http://www.cnblogs.com/bastard/archive/2012/06/08/2541944.html Android中消息系统模型和Handler Looper 作为Andro ...
- Android的消息机制: Message/MessageQueue/Handler/Looper
概览 * Message:消息.消息里面可包含简单数据.Object和Bundle,还可以包含一个Runnable(实际上可看做回调). * MessageQueue:消息队列,供Looper线程 ...
- Android之MessageQueue、Looper、Handler与消息循环
在android的activity中有各种各样的事件,而这些事件最终是转换为消息来处理的.android中的消息系统涉及到: * 消息发送 * 消息队列 * 消息循环 * 消息分发 * 消息 ...
- 「Android」SurfaceFlinger分析
本篇针对surfaceFlinger模块进行分析,目录如下: 1.SurfaceFlinger功能 1.1.BufferQueue原理(native/libs/gui模块) 1.2 layer显示 ...
- Android应用程序消息处理机制(Looper、Handler)分析
文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6817933 Android应用程序是通过消息来 ...
- 「Android」 Surface分析
本篇针对Surface模块进行分析,从Java层的Activity创建开始,到ViewRoot.WindowsManagerService,再到JNI层和Native层. 首先推荐一个Android源 ...
- 「Android」adb调试源码(针对dumpsys SurfceFlinger、trace.txt获取)
首先对ADB作简单的阐述,接下来对adb shell dumpsys SurfaceFlinger服务的dump信息的查看.以及ANR问题如何获取trace文件并简单分析. -×*********** ...
- 「Android」系统架构概述
目录: 1.Android系统架构 2.Android类库 3.四大组件 --------------------------------------------------------------- ...
随机推荐
- Event Loop浅谈
event loop 即事件循环.最初了解到js的event loop机制是通过自己对js中异步.同步的疑惑.今天聊一聊自己的理解,希望和大家一起学习. 首先,让我们看一个经典的setTimeOut的 ...
- Java内存溢出异常(下)
此篇是上一篇文章Java内存溢出异常(上)的续篇,没有看过的同学,可以先看一下上篇.本篇文章将介绍剩余的两个溢出异常:方法区和运行时常量池溢出. 方法区和运行时常量池溢出 这部分为什么会放在一起呢?在 ...
- Excel 斜线表头制作方法
Excel 斜线表头制作方法
- [译]ASP.NET Core Web API 中使用Oracle数据库和Dapper看这篇就够了
[译]ASP.NET Core Web API 中使用Oracle数据库和Dapper看这篇就够了 本文首发自:博客园 文章地址: https://www.cnblogs.com/yilezhu/p/ ...
- ionic2 关于启动后白屏问题跟app启动慢的问题
问题描述: 在ionic2下创建的项目打包生成apk,运行在真机上,进入启动页然后有5秒左右的白屏情况才进入首页,在真实项目中更严重,启动画面后更有时候十几秒都是白屏,体验性非常差. 在各种搜索之下, ...
- python 分享一个通过 (key1.key2.key3) 形式获取嵌套字典值的方法
最近在做接口自动化测试,响应的内容大多数是多层嵌套的json数据,如果一层层的去剥,效率不高,脚本繁重,所以写了一个可以通过(key1.key2.key3)形式获取嵌套字典值的方法,如有不对或者需要优 ...
- Python快速学习09: 函数的参数
前言 系列文章:[传送门] 继续干起来!! 正文 我们已经接触过函数,函数是可以被引用的(访问或者以其他变量作为其别名),也作为参数传入函数,以及作为列表和字典等等容器对象的元素(function)的 ...
- Python快速学习04:循环 & 函数
前言 系列文章:[传送门] 也就今天认识了 LC ,很开心. 本文目录 循环 for while 中断 函数 函数定义 函数调用 for循环 Python 中的for 循环象shell 脚本里的for ...
- 08 训练Tensorflow下围棋
这里介绍一下开源项目Mugo,它基于Tensorflow,可以使用sgf的棋谱训练围棋机器人,跟你下围棋,这里直接给出本人修改完善好的项目,只介绍一下用法. 链接:http://pan.baidu.c ...
- 解读经典《C#高级编程》第七版 Page38-45.核心C#.Chapter2
前言 控制流是语言中最基础的部分,我们不谈具体的细节,只讲讲一些关键和有趣的点. 01 流控制 条件语句:if, else if, else if语句的使用非常值得细讲,如何是好的使用习惯.有一点非常 ...