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类分析的更多相关文章

  1. Android的消息循环机制 Looper Handler类分析

    Android的消息循环机制 Looper Handler类分析 Looper类说明   Looper 类用来为一个线程跑一个消息循环. 线程在默认情况下是没有消息循环与之关联的,Thread类在ru ...

  2. Android中消息系统模型和Handler Looper

    http://www.cnblogs.com/bastard/archive/2012/06/08/2541944.html Android中消息系统模型和Handler Looper 作为Andro ...

  3. Android的消息机制: Message/MessageQueue/Handler/Looper

    概览   * Message:消息.消息里面可包含简单数据.Object和Bundle,还可以包含一个Runnable(实际上可看做回调). * MessageQueue:消息队列,供Looper线程 ...

  4. Android之MessageQueue、Looper、Handler与消息循环

    在android的activity中有各种各样的事件,而这些事件最终是转换为消息来处理的.android中的消息系统涉及到: *  消息发送 *  消息队列 *  消息循环 *  消息分发 *  消息 ...

  5. 「Android」SurfaceFlinger分析

    本篇针对surfaceFlinger模块进行分析,目录如下: 1.SurfaceFlinger功能 1.1.BufferQueue原理(native/libs/gui模块) 1.2   layer显示 ...

  6. Android应用程序消息处理机制(Looper、Handler)分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6817933 Android应用程序是通过消息来 ...

  7. 「Android」 Surface分析

    本篇针对Surface模块进行分析,从Java层的Activity创建开始,到ViewRoot.WindowsManagerService,再到JNI层和Native层. 首先推荐一个Android源 ...

  8. 「Android」adb调试源码(针对dumpsys SurfceFlinger、trace.txt获取)

    首先对ADB作简单的阐述,接下来对adb shell dumpsys SurfaceFlinger服务的dump信息的查看.以及ANR问题如何获取trace文件并简单分析. -×*********** ...

  9. 「Android」系统架构概述

    目录: 1.Android系统架构 2.Android类库 3.四大组件 --------------------------------------------------------------- ...

随机推荐

  1. c++模板参数——数值类型推断

    模板类中,或模板函数中,若限定模板参数为数值类型,可以使用如下方式进行判断. template<typename T> Fmt::Fmt(const char *fmt, T val) { ...

  2. python函数学习1

    函数1 (1)定义: def 函数名(参数列表) 函数体 (2)参数传递: 在python中,一切都是对象,类型也属于对象,变量是没有类型的. a = [1,2,3] a = "hellow ...

  3. struts2--使用<s:token></s:token>标签防止重复提交

    取个小例子:这是网页: <body> <s:actionerror/> <s:form action="LoginAction" method=&qu ...

  4. Maven内置属性、POM属性

    1.内置属性(Maven预定义,用户可以直接使用) ${basedir}表示项目根目录,即包含pom.xml文件的目录; ${version}表示项目版本; ${project.basedir}同${ ...

  5. Mybatis学习(四)————— 高级映射,一对一,一对多,多对多映射

    一.单向和双向 包括一对一,一对多,多对多这三种情况,但是每一种又分为单向和双向,在hibernate中我们就详细解析过这单向和双向是啥意思,在这里,在重复一遍,就拿一对多这种关系来讲,比如有员工和部 ...

  6. scala程序开发入门

    scala程序开发入门,快速步入scala的门槛: 1.Scala的特性: A.纯粹面向对象(没有基本类型,只有对象类型).Scala的安装与JDK相同,只需要解压之后配置环境变量即可:B.Scala ...

  7. 20.Module 的语法

    Module 的语法 Module 的语法 概述 历史上,JavaScript 一直没有模块(module)体系,无法将一个大程序拆分成互相依赖的小文件,再用简单的方法拼装起来.其他语言都有这项功能, ...

  8. Redis学习笔记(2)-新建虚拟电脑,安装系统CentOSMini

    下载CentOSMini download 点击download,网页显示结果如下 点击红框,跳转至镜像页面,选择任一镜像,下载即可. 新建虚拟机,装载CentOSMini 点击新建 输入名称 输入C ...

  9. C#、Python中分别是怎么实现通过字符串获取实体类的值以及给实体类赋值

    一.引入 最近遇到一个项目里面的功能,在给实体类赋值的时候,由于赋值字段是动态生成的,所以如果用常用的方法(直接实体类的名称.字段名=要赋的值),将会生成很多无用的代码,所以找到了一个通过反射的赋值与 ...

  10. Cookie 用法

    //Cookie:是一个客户端状态保持机制,(网站的数据是存在客户端),与隐藏域与ViewState对象都属于这种客户端状态保持,Cookie中存储的是关于网站相关的文本字符串数据.Cookie的存储 ...