一张图看明白 Android Handler 消息机制

Posted Jeanboy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一张图看明白 Android Handler 消息机制相关的知识,希望对你有一定的参考价值。

概述

android 的消息机制主要是指 Handler 的运行机制以及 Handler 所附带的 MessageQueue 和 Looper 的工作过程。 Handler 的主要作用是将某个任务切换到 Handler 所在的线程中去执行。

Handler机制

Handler工作流程

Looper

每个线程中最多只能有一个 Looper 对象,由 Looper 来管理此线程里的 MessageQueue (消息队列)。

可以通过 Looper.myLooper() 获取当前线程的 Looper 实例,通过 Looper.getMainLooper() 获取主(UI)线程的 Looper 实例。

Lopper 会以无限循环的形式去查找是否有新消息,如果有就处理消息,否则就一直等待着。

Handler

你可以构造 Handler 对象来与 Looper 沟通,通过 push 发送新消息到 MessageQueue 里;或者通过 handleMessage 接收 Looper 从 MessageQueue 取出来消息。

MessageQueue

MessageQueue是一个消息队列,内部存储了一组消息,以队列的形式对外提供插入和 删除的工作,内部采用单链表的数据结构来存储消息列表。

ActivityThread

我们经常提到的主线程,也叫UI线程,它就是 ActivityThread,主线程启动会默认初始化一个 Looper 并创建 Handler。

一个线程中只有一个 Looper 实例,一个 MessageQueue 实例,可以有多个 Handler 实例。

ThreadLocal

一个线程内部的数据存储类,通过它可以在指定线程中存储数据,数据存储后,只有在指定线程中可以获取到存储的数据,对于其他线程来说无法获得数据。

对于 Handler 来说,它需要获取当前线程的 Looper ,而 Looper 的作用于就是线程并且不同的线程具有不同的 Looper ,通过 ThreadLocal 可以轻松实现线程中的存取。

ThreadLocal原理:不同线程访问同一个ThreadLoacl的get方法,ThreadLocal的get方法会从各自的线程中取出一个数组,然后再从数组中根据当前ThreadLocal的索引去查找对应的Value值。

源码分析

通过上面分析我们知道使用 Handler 之前必须先调用 Looper.prepare(); 进行初始化,我们先看下 Looper 的源码。

1. Looper 工作原理

先看一下 Looper 工作流程

一张图看明白 Android Handler 消息机制

Looper 源码最上面的注释里有一个使用示例如下,可以清晰的看出 Looper 的使用方法。

 
   
   
 
  1. 一张图看明白 Android Handler 消息机制

接续看一下 Looper 的完整源码,分析下工作过程。

 
   
   
 
  1. 一张图看明白 Android Handler 消息机制


  2. 一张图看明白 Android Handler 消息机制

2. MessageQueue 工作原理

在 Looper 中创建了 MessageQueue,我们接着看下 MessageQueue 是怎么工作的。

MessageQueue 工作流程

一张图看明白 Android Handler 消息机制


MessageQueue的构造方法。

 
   
   
 
  1. 一张图看明白 Android Handler 消息机制

然后我们再看一下 MessageQueue.enqueueMessage() 的源码,分析下是怎么添加消息的。

 
   
   
 
  1. 一张图看明白 Android Handler 消息机制

知道了怎么添加消息,我们再看下 MessageQueue.next() 方法是怎么取出消息的,也就是 Looper.loop() 方法中不断取消息的方法。

 
   
   
 
  1. 一张图看明白 Android Handler 消息机制

我们知道 MessageQueue 是个链表结构,里面保存的是 Message,我们再看下 Message 是什么。

 
   
   
 
  1. 一张图看明白 Android Handler 消息机制

3. Handler 工作原理

在 Message 中我们看到了 target 是一个 Handler,我们看下 Handler 是怎么与 Looper 和 MessageQueue 一起搭配工作的。

看一下 Handler 的源码。

 
   
   
 
  1. 一张图看明白 Android Handler 消息机制


  2. 一张图看明白 Android Handler 消息机制


  3. 一张图看明白 Android Handler 消息机制

4. ActivityThread 创建默认的 Handler

上面说过,ActivityThread 主线程默认是有一个 Handler 的,我们来看一下主线程是怎么创建默认的 Handler 的。

我们看一下 ActivityThread 类中的 main 方法。

 
   
   
 
  1. 一张图看明白 Android Handler 消息机制

在 Activity 可以直接用 runOnUiThread() 来使用默认的 Handler 发送消息,我们来看下它是怎么实现的。

 
   
   
 
  1. 一张图看明白 Android Handler 消息机制

5. HandlerThread 异步消息处理机制

  1. HandlerThread 继承了 Thread,是一种可以使用 Handler 的 Thread;

  2. 在 run 方法中通过 looper.prepare() 来开启消息循环,这样就可以在 HandlerThread 中创 建Handler了;

  3. 外界可以通过一个 Handler 的消息方式来通知 HandlerThread 来执行具体任务;确定不使 用之后,可以通过 quit 或 quitSafely 方法来终止线程执行。

先分析一下 HandlerThread 的源码。

 
   
   
 
  1. 一张图看明白 Android Handler 消息机制


HandlerThread 使用代码示例

 
   
   
 

总结

到此 Handler 消息机制的源码已经分析完了,相信你一定明白了 Handler 消息机制。
一句话,每个线程可以创建一个 Looper ,每个 Looper 轮询着一个 MessageQueue 不断取出消息,有消息则回调给 Handler,Handler 负责向 MessageQueue 中发送消息和处理回调的消息来完成线程之间的转换。


以上是关于一张图看明白 Android Handler 消息机制的主要内容,如果未能解决你的问题,请参考以下文章

一张图看明白云计算架构核心竞争力

Android一张图看懂Activity的启动流程

Android一张图看懂Activity的启动流程

一张图看懂dex

趣图:一张图看懂敏捷开发

一张图看懂项目管理的47个过程(干货)