Android Handler 消息机制(解惑篇)

551 查看

Android中的消息处理机制概述

大家对于Android中的消息处理机制的用法一定都比较熟悉,至于工作原理估计不少人有研究。就像我们自己写的类我们用起来比较熟悉一样,如果我们熟悉了消息处理机制的具体实现,那么我们用起来肯定也会事半功倍。

博主之前只是稍有涉猎,对其中一些地方也还心存疑虑,比如既然Looper.loop()里是一个死循环,那它会不会很消耗CPU呢?死循环阻塞了线程,那我们其他的事务是如何被处理的呢?Android的UI线程是在哪里被初始化的呢?等等。索性今天就把他们放到一起,说道说道。

Android中线程的分类

  • 带有消息队列,用来执行循环性任务(例如主线程、android.os.HandlerThread)
    • 有消息时就处理
    • 没有消息时就睡眠
  • 没有消息队列,用来执行一次性任务(例如java.lang.Thread)
    • 任务一旦执行完成便退出

带有消息队列线程概述

四要素

  • Message(消息)
  • MessageQueue(消息队列)
  • Looper(消息循环)
  • Handler(消息发送和处理)

四要素的交互过程

具体工作过程

  • 消息队列的创建
  • 消息循环
  • 消息的发送最基本的两个API
    • Handler.sendMessage
      • 带一个Message参数,用来描述消息的内容
    • Handler.post
      • 带一个Runnable参数,会被转换为一个Message参数
  • 消息的处理

基于消息的异步任务接口

  • android.os.HandlerThread
    • 适合用来处于不需要更新UI的后台任务
  • android.os.AyncTask
    • 适合用来处于需要更新UI的后台任务

带有消息队列线程的具体实现

ThreadLocal

ThreadLocal并不是一个Thread,而是Thread的局部变量。当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。

从线程的角度看,目标变量就象是线程的本地变量,这也是类名中“Local”所要表达的意思。

Looper

用于在指定线程中运行一个消息循环,一旦有新任务则执行,执行完继续等待下一个任务,即变成Looper线程。Looper类的注释里有这样一个例子:

其实核心代码就两行,我们先来看下Looper.prepare()方法的具体实现