Handler总结多篇博客,吸取之精华!

         一、首先先来上一段Handler的原理:

        当应用程序启动时,Android首先会开启一个主线程 (也就是UI线程) , 主线程为管理界面中的UI控件, 进行事件分发, 比如说, 你要是点击一个 Button ,Android会分发事件到Button上,来响应你的操作。  如果此时需要一个耗时的操作,例如: 联网读取数据,    或者读取本地较大的一个文件的时候,你不能把这些操作放在主线程中,如果你放在主线程中的话,界面会出现假死现象, 如果5秒钟还没有完成的话,会收到Android系统的一个错误提示  "强制关闭"。  这个时候我们需要把这些耗时的操作,放在一个子线程中,因为子线程涉及到UI更新,,Android主线程是线程不安全的, 也就是说,更新UI只能在主线程中更新,子线程中操作是危险的。 这个时候,Handler就出现了。,来解决这个复杂的问题 ,由于Handler运行在主线程中(UI线程中),  它与子线程可以通过Message对象来传递数据, 这个时候,Handler就承担着接受子线程传过来的(子线程用sedMessage()方法传弟)Message对象,(里面包含数据)  , 把这些消息放入主线程队列中,配合主线程进行更新UI。

二、基本概述

       Handler就是解决线程与线程间的通信。
       当我们在子线程处理耗时操作,耗时操作完成后我们需要更新UI的时候,这就是需要使用Handler来处理了,因为子线程不能更  新UI,Handler能让我们容易的把任务切换回来它所在的线程。

消息处理机制本质:一个线程开启循环模式持续监听并依次处理其他线程给它发的消息。
举例说明:

简单的说:一个线程开启一个无限循环模式,不断遍历自己的消息列表,如果有消息就挨个拿出来做处理,如果列表没消息,自己就堵塞(相当于wait,让出cpu资源给其他线程),其他线程如果想让该线程做什么事,就往该线程的消息队列插入消息,该线程会不断从队列里拿出消息做处理。

三、Handler组成部分   

Handler分为五部分组成:

1.Message:message就是用来线程直接的交互数据,可以携带少量数据,它有四个常用的字段 1.what 2.age1 3.age2, 4.obj
what,age1,age2可以携带整行数据,obj呢就可以是任意类型。

2.Handler:handler呢就是用来发送消息和处理消息的,发送消息我们一般使用的都是Send和Post方法这个系列的方法,而这个Post一系列方法是通过Send一系列方法来实现的,而send的这些方法最后都是通过SendMessageAtTime()方法来实现的,Handler发送一条消息,就在消息队列中插一条消息。

3.Message Queue:消息队列的意思,它主要用于存放所有通过Handler发送的消息,这部分消息会一直存储在消息队列中,等待被处理,每个线程里面只能有一个Message Queue对象。
MessageQueue的,它的底层是通过单链表的数据结构来维护消息列表的,它有两个方法 enQueueMessage()和next()
enQueueMessage()主要根据时间的顺序向单链表中插入一条消息,next方法是一个无限循环的方法,如果有消息返回这条消息,并从链表中移除,如果没有消息的话,就一直阻塞在这里

4.Looper:每个线程通过Handler发送的消息都保存在MessageQueue中,Looper通过Loop()的方法就去进入一个无限循环当中,然后每当发现MessageQueue中存在一条消息,就会将它取出来,并传递到Handler的handlermessage()方法中,每个线程只能有一个Looper对象。
Looper在这个循环中不断的从messageQueue的next方法中获取消息,而next方法是一个阻塞操作,没有消息的时候一直处于阻塞状态,当有消息了通过dspatchMessage()发送消息给Handler对象

5.Theradlcal:messageQueue对象和Looper对象在每个线程中都只会有一个对象,怎么来保证它有一个对象,就通过Threadlocal来保存,Threadlocal是一个线程内部的数据存储类,通过它可以在指定的线程中存储数据,数据存储以后只能在指定线程中可以获取到存储的数据,对于其他的线程来说则无法获取到数据。

在主线程使用Handler的过程:
    首先在主线程创建一个Handler对象 ,并重写handleMessage()方法。然后当在子线程中需要进行更新UI的操作,我们就创建一个Message对象,并通过handler发送这条消息出去。之后这条消息被加入到MessageQueue队列中等待被处理,通过Looper对象会一直尝试从Message Queue中取出待处理的消息,最后分发会Handler的handler Message()方法中。