一、Looper

Looper对象,顾名思义,直译过来就是循环的意思,从MessageQueue中不断取出message。

Class used to run a message loop for a thread. Threads by default do not have a message loop associated with them; to create one, call prepare() in the thread that is to run the loop, and then loop() to have it process messages until the loop is stopped.

1.Looper的成员变量:

static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
private static Looper sMainLooper; // guarded by Looper.class final MessageQueue mQueue; //一个MQ
final Thread mThread; //一个thread

Looper的代码是非常简单的。在官方文档的注释中,它推荐我们这样来使用它:

class LooperThread extends Thread {
public Handler mHandler; public void run() {
Looper.prepare(); mHandler = new Handler() {
public void handleMessage(Message msg) {
// process incoming messages here
}
}; Looper.loop();
}
}

先看看prepare方法。

Looper.prepare

public static void prepare() {
prepare(true);
} private static void prepare(boolean quitAllowed) {
if (sThreadLocal.get() != null) {//每个线程只能有一个looper
throw new RuntimeException("Only one Looper may be created per thread");
}
//设置本线程的looper。
sThreadLocal.set(new Looper(quitAllowed));
}

  注意prepare(boolean)方法中,有一个sThreadLocal变量(ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本),这个变量有点像一个哈希表,它的key是当前的线程,也就是说,它可以存储一些数据/引用,这些数据/引用是与当前线程是一一对应的,在这里的作用是,它判断一下当前线程是否有Looper这个对象,如果有,那么就报错了,"Only one Looper may be created per thread",一个线程只允许创建一个Looper,如果没有,就new一个。然后它调用了Looper的构造方法。

Looper 的构造方法

在上边调用了构造方法:Looper(quitAllowed),初始化了messageQueue并绑定当前线程。

private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}

此时的初始化动作已经结束了,接下来看Looper.loop():

public static void loop() {
final Looper me = myLooper();//返回当前的looper
if (me == null) {
throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
}
final MessageQueue queue = me.mQueue;//取得messageQueue for (;;) {
Message msg = queue.next(); // might block
if (msg == null) {
// No message indicates that the message queue is quitting.
return;
}
。。。。
msg.target.dispatchMessage(msg);
。。。
msg.recycleUnchecked();
}
}

loop()方法,省去了一些不关心的部分。剩下的部分非常的清楚了,首先调用了静态方法myLooper()获取当前Looper对象。没有looper则抛出异常。

public static @Nullable Looper myLooper() {
return sThreadLocal.get();
}

1. myLooper()同样是静态方法,它是直接从这个ThreadLocal中去获取Looper对象,拿到当前线程的Looper后;

2. MessageQueue queue = me.mQueue;拿到与这个Looper对应的MQ,就开始无限循环,不断的从消息队列中取出Message,当获取到一个消息后,它调用了Message.target.dispatchMessage()方法来对消息进行处理。dispatchMessage这个方法在Handler中,就是处理message。

3.msg.recycleUnchecked(),当这个msg处理完了,就没有用啦,把它回收到全局池中,注意不是销毁。

总结

Looper的代码看完了,我们得到了几个信息:

  • Looper调用静态方法prepare()来进行初始化,一个线程只能创建一个与之对应的LooperLooper初始化的时候会创建一个MQ,并和当前线程绑定,因此,有了这样的对应关系,一个线程对应一个Looper,一个Looper对应一个MQ。

  • Looper调用静态方法loop()开始无限循环的取消息,messageQueue调用next()方法来获取消息(这也是个无限循环)。

MessageQueue源码解析:http://www.cnblogs.com/jycboy/p/5786682.html

Handler源码解析:http://www.cnblogs.com/jycboy/p/5791457.html

Message源码解析:http://www.cnblogs.com/jycboy/p/5786551.html

Android Handler机制(三)----Looper源码解析的更多相关文章

  1. Android Handler机制(二)---MessageQueue源码解析

    MessageQueue 1.变量 private final boolean mQuitAllowed;//表示MessageQueue是否允许退出 @SuppressWarnings(" ...

  2. Handler机制原理图、源码、使用!!!!!

    android的消息处理机制——Looper,Handler,Message  (原理图.源码) 转自:http://my.oschina.net/u/1391648/blog/282892 在开始讨 ...

  3. Android IntentService使用介绍以及源码解析

    版权声明:本文出自汪磊的博客,转载请务必注明出处. 一.IntentService概述及使用举例 IntentService内部实现机制用到了HandlerThread,如果对HandlerThrea ...

  4. 【Android应用开发】EasyDialog 源码解析

    示例源码下载 : http://download.csdn.net/detail/han1202012/9115227 EasyDialog 简介 : -- 作用 : 用于在界面进行一些介绍, 说明; ...

  5. ThreadPoolExecutor系列三——ThreadPoolExecutor 源码解析

    ThreadPoolExecutor 源码解析 本文系作者原创,转载请注明出处:http://www.cnblogs.com/further-further-further/p/7681826.htm ...

  6. Handler Looper源码解析(Android消息传递机制)

    Android的Handler类应该是常用到的,多用于线程间的通信,以及子线程发送消息通知UI线程刷新View等等.这里我主要总结下我对整个消息传递机制,包括Handler,Looper,Messag ...

  7. Android 手势识别类 ( 三 ) GestureDetector 源码浅析

    前言:上 篇介绍了提供手势绘制的视图平台GestureOverlayView,但是在视图平台上绘制出的手势,是需要存储以及在必要的利用时加载取出手势.所 以,用户绘制出的一个完整的手势是需要一定的代码 ...

  8. Android HandlerThread使用介绍以及源码解析

    摘要: 版权声明:本文出自汪磊的博客,转载请务必注明出处. 一.HandlerThread的介绍及使用举例              HandlerThread是什么鬼?其本质就是一个线程,但是Han ...

  9. 多线程与高并发(三)—— 源码解析 AQS 原理

    一.前言 AQS 是一个同步框架,关于同步在操作系统(一)-- 进程同步 中对进程同步做了些概念性的介绍,我们了解到进程(线程同理,本文基于 JVM 讲解,故下文只称线程)同步的工具有很多:Mutex ...

随机推荐

  1. Head插件——学习Elasticsearch的锋刃利器!

    在学习Elasticsearch的过程中,必不可少需要通过一些工具查看es的运行状态以及数据.如果都是通过rest请求,未免太过麻烦,而且也不够人性化. 此时,head可以完美的帮助你快速学习和使用e ...

  2. 使用KeleyiSQLHelper类进行分页查询

    本文适用于sql server单主键表或者视图进行分页查询,支持多字段排序. KeleyiSQLHelper类的最新代码请到http://hovertree.com/down/下载整个解决方案源代码查 ...

  3. C#系统缓存全解析(转载)

    C#系统缓存全解析 对各种缓存的应用场景和方法做了很详尽的解读,这里推荐一下 转载地址:http://blog.csdn.net/wyxhd2008/article/details/8076105

  4. T-SQL 查询出某个列总值大于X的数据

    原文: https://www.lesg.cn/netdaima/sqlservert-sql/2016-459.html 今天操作查询的时候遇见一个这样的要求: 有一张表 用户ID 购买日期 购买金 ...

  5. archive for required library...

    最近把移动硬盘上的一个Android项目复制到笔记本上面,import后项目文件夹始终有一个红色叹号,console里面提示“archive for required library...”,原来是l ...

  6. 获取PC或移动设备的所有IP地址

    不论是PC还是移动设备,都有可能同时存在几个IP地址(如具有多块网卡),本文介绍怎样获得PC或移动设备的所有IP地址. // 获得所有IP地址 public static void get_ip(){ ...

  7. ZooKeeper----Java实例文档

    **************************************************************************************************** ...

  8. FNV哈希算法

    由来:FNV哈希算法全名为Fowler-Noll-Vo算法,是以三位发明人Glenn Fowler,Landon Curt Noll,Phong Vo的名字来命名的,最早在1991年提出. 特点和用途 ...

  9. 制作rpm包步骤

    由于项目需要,需要自行制作rpm包.比较全面的可以参考如下链接: http://blog.chinaunix.net/uid-23069658-id-3944462.html 大致框架如下: 1,安装 ...

  10. linux_shell_5_shell特性_正则_1

    前面我们了解了部分linux shell的相关特性,下面的链接是第4篇文章:linux_shell_4_shell特性 这里我们来继续讨论linux shell中至关重要的一个特性: 正则表达式 (r ...