学习笔记

Handler、Looper、Message源码分析
Publish: 2018/7/23   

    class LooperThread extends Thread {
      public Handler mHandler;

      public void run() {
          Looper.prepare();

          mHandler = new Handler() {
              public void handleMessage(Message msg) {
                  // process incoming messages here
              }
          };

          Looper.loop();
      }
  }

Looper

用于为线程运行消息轮询的类。线程默认没有与它们相关的消息轮询;在要运行轮询的线程中调用prepare(),然后调用loop()处理消息,直到轮询停止。大多数与消息循环的交互是通过Handler。
Looper.prepare();
创建一个与当前线程唯一关联的Looper,同时创建一个MessageQueue。

    public final class Looper{
        ...
        static final ThreadLocal sThreadLocal = new ThreadLocal();
        final MessageQueue mQueue;
        final Thread mThread;

        //通过prepareMainLooper()获得
        private static Looper sMainLooper; 

        //获得主线程的looper
        //调用new Handler(Looper.getMainLooper)可以创建主线程的Handler
        public static Looper getMainLooper() {
            synchronized (Looper.class) {
                return sMainLooper;
            }
        }

        public static void prepare() {
            prepare(true);
        }

        private static void prepare(boolean quitAllowed) {
            //ThreadLocal将Thread和Looper以键值对的形式存起来,类似用户ID。
            //这里每个线程只可以有一个Looper
            if (sThreadLocal.get() != null) {
                throw new RuntimeException("Only one Looper may be created per thread");
            }
            sThreadLocal.set(new Looper(quitAllowed));
        }

        private Looper(boolean quitAllowed) {
            mQueue = new MessageQueue(quitAllowed);
            mThread = Thread.currentThread();
        }
        ...
    }

退出loop():

MessageQueue

持有由Looper分发消息的列表,通过与Looper关联的Handler对象添加消息。

    public final class MessageQueue {
        ...
        // True if the message queue can be quit.
        private final boolean mQuitAllowed;   

        MessageQueue(boolean quitAllowed) {
            mQuitAllowed = quitAllowed;
            mPtr = nativeInit();
        }
        ...
    }    

Handler

Handler允许您发送和处理与线程的MessageQueue关联的Message和Runnable对象。

有两个主要用途:

    public class Handler {
        ...
        public Handler() {
            this(null, false);
        }
        public Handler(Callback callback, boolean async) {
            ...
            mLooper = Looper.myLooper();
            if (mLooper == null) {
                throw new RuntimeException(
                    "Can't create handler inside thread that has not called Looper.prepare()");
            }
            mQueue = mLooper.mQueue;
            mCallback = callback;
            mAsynchronous = async;
        }
        ...
    }
Looper.myLooper();
  ->public static @Nullable Looper myLooper() {
        //获得当前线程相关联的Looper
        return sThreadLocal.get();
    }

发送消息的方法有:

    //最终都是调用Handler的这个方法
    private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
        msg.target = this;//target即Handler实例
        if (mAsynchronous) {
            msg.setAsynchronous(true);
        }
        //将消息加入队列。
        //如果是延迟消息,直到当前任务时间高于延迟时间,然后将任务插入队列
        //如果调用了quite方法,将调用 msg.recycle();回收消息,可能抛出IllegalStateException消息正在使用异常
        return queue.enqueueMessage(msg, uptimeMillis);
    }        

Looper.loop();

public static void loop() {
        final Looper me = myLooper();
        if (me == null) {
            throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
        }
        ...
        for (;;) {
            Message msg = queue.next(); // might block
            if (msg == null) {
                // No message indicates that the message queue is quitting.
                return;
            }
            ...
            try {
                //target是Handler的实例,所以调用的是Handler的dispatchMessage(msg)方法
                msg.target.dispatchMessage(msg);
                ...
            } finally {
                ...
            }
            ...
            //回收可能正在使用的消息
            msg.recycleUnchecked();
        }
    }

Hander#
  ->public void dispatchMessage(Message msg) {
        //如果是异步任务,就执行异步任务
        if (msg.callback != null) {
            handleCallback(msg);
        //如果不是就交由handleMessage来处理,需要自己实现
        } else {
            if (mCallback != null) {
                if (mCallback.handleMessage(msg)) {
                    return;
                }
            }
            handleMessage(msg);
        }
    }

handleCallback(msg);
  ->private static void handleCallback(Message message) {
        message.callback.run();
    }

Message

    //链表结构
    Message next;

    //从系统启动到现在的时间+要延迟的时间
    long when;

    //通过Handler的实例创建message
    public final Message obtainMessage()
    {
        return Message.obtain(this);
    }

Message.obtain(this);
  ->public static Message obtain(Handler h) {
        //obtain实现Message的复用
        Message m = obtain();
        m.target = h;//将Handler实例赋值给target

        return m;
    }



← Java并发编程实战-5基础知识_小结_并发技巧清单 Java并发编程实战-1基础知识_线程安全 →

Powered by Hexo, Theme designs by @hpcslag.
Style-Framework Tocas-UI designs by @yamioldmel