Android的消息机制

##Android的消息机制分析
Android的消息机制分析实际上就是Handler的运行机制,主要包括Handler、MessageQueue和Looper。而在Looper工作原理中使用到了一个重要的类:ThreadLocal。为了更好的理解Looper的工作原理,我们先来了解一下ThreadLocal。

##ThreadLocal
ThreadLocal是线程内部的数据存储类,通过它可以在指定线程中存储数据,而且只能在指定线程中获取到所存储的数据,在其他线程中无法获取到数据。在Android源码中,Looper、ActivityThread以及AMS都用到了ThreadLocal。就拿Hander来举例,Handler需要获取到当前线程的Looper, 很显然Looper的作用域就是当前线程,而且不同线程具有不同的Looper,这时候通过TheardLocal就可以在当前线程中存储Looper,而且还保证了在当前线程中的独享。

原理:在不同线程中访问同一个ThreadLooper的get方法,ThreadLooper内部会从各自线程中取出一个数组,然后再从数组中根据当前的ThreadLoal的索引去查找对应的value值。很显然,不同线程中的数组是不同的,这就是为什么通过ThreadLoal可以在不同线程中维护一套数据的副本并且彼此互不干扰。

##MessageQueue
消息队列MessageQueue主要包含两个操作:插入enqueueMessage和读取next
enqueueMessage的作用: 负责往消息队列中插入一条消息。
next的作用: 负责从消息推列中取出一条消息并将其移除。next 是一个无限循环的方法,如果消息推列中没有消息,那么next方法会一直阻塞。

##Looper
在Android中,消息处理线程启动后会进入一个无限的循环体(Looper)之中,每循环一次,从其内部的消息队列中取出一个消息(先进先出),然后回调相应的消息处理函数,执行完成一个消息后则继续循环。若消息队列为空,线程则会阻塞等待。
Looper负责的就是创建一个MessageQueue,然后进入一个无限循环体不断从该MessageQueue中读取消息,而消息的创建者就是一个或多个Handler 。

首先

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

```Looper.loop()```会让当前线程进入一个无限循环,会调用MessageQueue的```next```方法来获取新消息,而```next```是一个阻塞操作,当没有新消息时,这也导致了```loop```方法也会阻塞。如果MessageQueue的```next```方法返回了新消息,Looper会回调```msg.target.dispatchMessage(msg)```方法,而Hander的```dispatchMessage```方法是执行在创建Hander时所使用的Looper中,这样就成功的将代码逻辑切换到指定线程中执行。
##Handler
Handler的构造方法,会首先得到当前线程中保存的Looper实例,进而与Looper实例中的MessageQueue想关联。

Handler的sendMessage方法,会给msg的target赋值为handler自身,然后加入MessageQueue中。Message的callback是一个Runnable对象,实际上就是Handler的``` post```方法所传递的Runnable参数。

在构造Handler实例时,我们会重写```handleMessage```方法,也就是```msg.target.dispatchMessage(msg)```最终调用的方法。

![2017-12-25 15.07.12.png](http://upload-images.jianshu.io/upload_images/1932104-85ad5bcb1f5d3c85.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
-----------
##注意事项
注意:在实际开发过程中,handler引起的内存泄漏以及解决办法
原因:非静态内部类持有外部类的匿名引用,导致外部activity无法被释放

解决办法
1,handler内部持有外部activity的弱引用,
2,把handler改为静态内部类,
3,在ondestroy方法中调用```mHandler.removeCallback()