线程Thread的线程变量ThreadLocal中,存放着这个线程的Looper;Looper在初始化时,会新建一个消息队列MessageQueue,之后Looper进入一个死循环,等待从消息队列MessageQueue取得消息Message(Looper是消费者),没有消息时会阻塞;

我们程序中的Handler,会通过sendMessage或post方法,往MessageQueue中添加消息时,添加的这个Message,会记录他是属于哪个Handler发出的,同时根据message.when,决定新添加的这个Message在Queue中的位置,MessageQueue中只有一个当前的Message,队列关系是通过Message中的prev,next维护的,Message是一个链表的节点;

添加消息后,消费者Looper取得Message,并调用建立Message的Hander的dispatchMessage方法。

咋一看好像Handler即sendMessage,又handlerMessage,事情还是只有一个线程在做事情。

但是后来想想,明白了这样设计的必要性。

因为这个唯一的线程一般而言,都是mainUI线程,如果你有个可以分成多个小任务的任务要处理,你没有使用Handler,直接执行,也许系统忙于处理你这个任务,而无法及时响应用户事件,从而导致ANR的抛出。

如果你把你的任务拆成几个小任务,用Handler来实现,那么系统就可以把你的小任务推到后面来处理,抽出时间来响应用户操作。

如果真的有大任务,一般式需要另外线程去处理,或者开启Service。


Android处理程序:Handler Looper Message源码研究_消息队列

一个在新线程中使用handler例子,我们来分析下源码



1. new Thread(new Runnable() { 
2. @Override public void run() {
3. Handler handler;
4. //1、初始化Looper
5. Looper.prepare();
6. //2、绑定handler到CustomThread实例的Looper对象、定义处理消息的方法
7. handler= new Handler() {
8. @Override public void handleMessage(Message msg) {
9. }
10. };
11. // 3、发送消息
12. handler.sendMessage(new Message());
13. handler.post(new Runnable())
14. handler.obtainMessage(1, "hello").sendToTarget();
15. //4、启动消息循环
16. Looper.loop();
17. }
18. }).start();




    1. public static final void prepare() { 
    2. if (sThreadLocal.get() != null) { // 每个线程,只能有一个Looper对象
    3. throw new RuntimeException("Only one Looper may be created per thread");
    4. }
    5. // 如果当前线程没有Looper,新建一个,构造函数是private的
    6. sThreadLocal.set(new Looper());
    7. }
    8. private Looper() {
    9. mQueue = new MessageQueue(); // 建立消息队列
    10. mRun = true;
    11. mThread = Thread.currentThread();
    12. }



    1. public Handler(){ 
    2. mLooper = Looper.myLooper(); // 取得当前线程的Looper,如果抛异常
    3. if (mLooper == null) {
    4. throw new RuntimeException(
    5. "Can't create handler inside thread that has not called Looper.prepare()");
    6. }
    7. mQueue = mLooper.mQueue; // 取得消息队列
    8. mCallback = null;
    9. }


    1. //不管调用哪个方法,最终执行的是 
    2. public boolean sendMessageAtTime(Message msg, long uptimeMillis){
    3. boolean sent = false;
    4. // 取得消息队列
    5. MessageQueue queue = mQueue;
    6. if (queue != null) {
    7. msg.target = this; // 消息发出着是自己
    8. sent = queue.enqueueMessage(msg, uptimeMillis); // 添加到消息队列中
    9. }
    10. else {
    11. RuntimeException e = new RuntimeException(
    12. this + " sendMessageAtTime() called with no mQueue");
    13. Log.w("Looper", e.getMessage(), e);
    14. }
    15. return sent;
    16. }
    17. final boolean enqueueMessage(Message msg, long when) {
    18. if (msg.when != 0) {
    19. throw new AndroidRuntimeException(msg
    20. + " This message is already in use.");
    21. }
    22. if (msg.target == null && !mQuitAllowed) {
    23. throw new RuntimeException("Main thread not allowed to quit");
    24. }
    25. synchronized (this) {
    26. if (mQuiting) {
    27. RuntimeException e = new RuntimeException(
    28. msg.target + " sending message to a Handler on a dead thread");
    29. Log.w("MessageQueue", e.getMessage(), e);
    30. return false;
    31. } else if (msg.target == null) {
    32. mQuiting = true;
    33. }
    34. msg.when = when;
    35. Message p = mMessages;
    36. // 之前没有其他消息了,MessageQueue中当前消息mMessages 就是传递进来的msg
    37. if (p == null || when == 0 || when < p.when) {
    38. msg.next = p;
    39. mMessages = msg;
    40. this.notify(); // 唤醒
    41. } else {
    42. // 之前有其他消息了,将传递的msg放到适合的位置,根据when
    43. Message prev = null;
    44. while (p != null && p.when <= when) {
    45. prev = p;
    46. p = p.next;
    47. }
    48. msg.next = prev.next;
    49. prev.next = msg;
    50. this.notify(); // 唤醒
    51. }
    52. }
    53. return true;
    54. }



      1. public static final void loop() { 
      2. Looper me = myLooper();
      3. MessageQueue queue = me.mQueue;
      4. while (true) { // 死循环
      5. Message msg = queue.next(); // 当队列中没有消息时会阻塞
      6. if (msg != null) {
      7. if (msg.target == null) { // 消息没有发送者时,退出消息循环
      8. // No target is a magic identifier for the quit message.
      9. return;
      10. }
      11. if (me.mLogging!= null) me.mLogging.println(
      12. ">>>>> Dispatching to " + msg.target + " "
      13. + msg.callback + ": " + msg.what
      14. );
      15. // 调用消息发出者的dispatchMessage,这里msg.target是我们sendMessage的handler
      16. msg.target.dispatchMessage(msg);
      17. if (me.mLogging!= null) me.mLogging.println(
      18. "<<<<< Finished to " + msg.target + " "
      19. + msg.callback);
      20. msg.recycle();
      21. }
      22. }
      23. }
      24. final Message next() {
      25. boolean tryIdle = true;
      26. while (true) {
      27. synchronized (this) {
      28. // 没有消息的或,会阻塞
      29. try {
      30. if (mMessages != null) {
      31. if (mMessages.when-now > 0) {
      32. Binder.flushPendingCommands();
      33. this.wait(mMessages.when-now);
      34. }
      35. } else {
      36. Binder.flushPendingCommands();
      37. this.wait();
      38. }
      39. }
      40. catch (InterruptedException e) {
      41. }
      42. }
      43. }
      44. }


      总结

      Handler作用:

      1. 执行计划任务

      2. 线程间通信

      一个handler,只能接收到自己发出的message。handler实例与消息Message处理是关联的,发送和接受要匹配

      Handler操作队列,主要是在子线程操作主线程的消息队列

      Handler是实现异步的一种方式,用法是在主线程中建立Handler,(主线程中的Handler不用掉Looper.prepare);

      在子线程(耗时操作)任务完成后sendMessage,这个Message会发送到主线程的消息队列中,主线程Handler的重写dispatchMessage方法,做新线程任务完成后的事情,大部分是更新UI。