Android Looper、Handler、Message三者关系

1 简介
// 主要涉及到的类
// ThreadLocal 线程私有数据,保证Looper每个线程中只有唯一的Looper对象
// MessageQueue
// Looper
// Handler
// Message
// Looper负责创建一个MessageQueue,然后进入loop循环体不断从该MessageQueue中读取消息,
// 而消息的创建者就是一个或多个Handler,消息的处理者是msg的Callback或者是hanlder
2 Handler的创建,消息发送的流程
// handler 构造函数, 包含两个重要的成员变量mLooper和mQueue(MessageQueue内部采用链表实现)
// 创建新的Handler时, 如果没有提供Looper对象, 则使用当前创建线程中的Looper对象
public Handler(@Nullable Callback callback, boolean async) {
    mLooper = Looper.myLooper();
    if (mLooper == null) {
        throw new RuntimeException(
        "Can't create handler inside thread " + Thread.currentThread()
        + " that has not called Looper.prepare()");
    }
    mQueue = mLooper.mQueue;
    mCallback = callback;
    mAsynchronous = async;
}

public Handler(@NonNull Looper looper, @Nullable Callback callback, boolean async) {
    mLooper = looper;
    mQueue = looper.mQueue;
    mCallback = callback;
    mAsynchronous = async;
}

public final boolean sendMessage(@NonNull Message msg) {
    return sendMessageDelayed(msg, 0);
}

public final boolean sendMessageDelayed(@NonNull Message msg, long delayMillis) {
    if (delayMillis < 0) {
        delayMillis = 0;
    }
    return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}

// 将消息放入MessageQueue handler发送消息函数最终都是调用sendMessageAtTime函数
public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
    MessageQueue queue = mQueue;
    if (queue == null) {
        RuntimeException e = new RuntimeException(
        this + " sendMessageAtTime() called with no mQueue");
        Log.w("Looper", e.getMessage(), e);
        return false;
    }
    return enqueueMessage(queue, msg, uptimeMillis);
}

private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
    // 把 handler 赋值给msg.target
    msg.target = this;
    if (mAsynchronous) {
    msg.setAsynchronous(true);
    }
    // 加入mQueue队列,检测是否需要唤醒mLooper
    return queue.enqueueMessage(msg, uptimeMillis);
}

3 Handler 处理消息
// Looper
public static void prepare() {
    prepare(true);
}

private static void prepare(boolean quitAllowed) {
    if (sThreadLocal.get() != null) {
        throw new RuntimeException("Only one Looper may be created per thread");
    }
    //创建Loop对象 & 每个线程只能创建唯一的Looper对象 
    sThreadLocal.set(new Looper(quitAllowed));
}

// 创建主线程Looper对象
public static void prepareMainLooper() {
    prepare(false);
    synchronized (Looper.class) {
        if (sMainLooper != null) {
            throw new IllegalStateException("The main Looper has already been prepared.");
        }
        sMainLooper = myLooper();
    }
}

public static void loop() {
    // 获取当前线程的Looper对象
    final Looper me = myLooper();
    if (me == null) {
        throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
    }

    final MessageQueue queue = me.mQueue;
    for (;;) {
        // 从MessageQueue中读取Message,没有消息则休眠
        Message msg = queue.next();
        // target == Handler 调用Handler的dispatchMessage函数
        msg.target.dispatchMessage(msg);
        // 将对应的msg对象加入到缓存池
        msg.recycleUnchecked();
    }
}

//处理消息
public void dispatchMessage(Message msg) {
        // 1 通过post提交的消息最终由Handler的handleCallback函数处理
    if (msg.callback != null) {
        handleCallback(msg);
    } else {
        // 2 Callback函数不为空,则调用Callback的handleMessage
        if (mCallback != null) {
            if (mCallback.handleMessage(msg)) {
            return;
            }
        }
        // 3 以上都没有处理,则交给Hanlder的handleMessage处理
        handleMessage(msg);
    }
}

4 总结
// 1. Handler的构造函数,会执行mLooper = Looper.myLooper()。
// 2.
// Handler.sendMessage() 的时候,会设置msg.target = this 然后调用 mLooper.mQueue.enqueueMessage()。
// Handler.post(runnable) 其实是msg.callback=runnable,最终也是跟sendMessage() 一样的流程。
// 3.
// Looper.prepare()的时候会新建一个Looper并存入sThreadLocal。
// 4.
// Looper的构造函数,会执行mQueue = new MessageQueue()。
// 5.
// Looper.loop() 不断循环mQueue.next()取出msg,然后调用msg.target.dispatchMessage(msg)。
// 6.
// MessageQueue 里有很多native方法,MessageQueue.next()没有消息时会阻塞,MessageQueue.enqueueMessage()收到消息时会唤醒阻塞。
// 7.
// 新建Message最好使用Message.obtain(),会优先从缓存池里获取,避免创建对象。
// 8.
// 我们在UI线程无需调用Looper.prepare()是因为系统已经帮我们执行过Looper.prepareMainLooper()。
// 9.
// 子线程不能直接修改UI,是因为UI的很多方法(比如draw)都不是线程安全的,所以引入Handler和Looper,用队列的形式确保操作UI是同步安全的。
// 10 
// Looper的底层实现 epoll_create eventfd 源码位于/system/core/libutils/Looper.cpp 

//子线程中创建handler注意事项
// 1 必须先调用 Looper.prepare();才能创建 Handler对象
// 2子线程创建handler三部曲
// (1)Looper.prepare();
// (2)handler = new Handler();
// (3)Looper.loop();
5 HandlerThread 解析
public class HandlerThread extends Thread {
    @Override
    public void run() {
        mTid = Process.myTid();
        //创建Looper对象
        Looper.prepare();
        synchronized (this) {
            mLooper = Looper.myLooper();
            notifyAll();
        }
        Process.setThreadPriority(mPriority);
        onLooperPrepared();
        //循环处理消息
        Looper.loop();
        mTid = -1;
    }

    @NonNull
    public Handler getThreadHandler() {
        if (mHandler == null) {
            mHandler = new Handler(getLooper());
        }
        return mHandler;
    }
}

鸿洋的Handler博客

猜你喜欢

转载自blog.csdn.net/he980725866/article/details/105748483
今日推荐