Android Handler 机制

参考文章:
深入理解Handler机制

Android 事件机制详解

Android Handler消息机制的理解

android的消息处理机制(图+源码分析)——Looper,Handler,Message

概述

在开发中,Handler通常用于异步消息处理,相关联的类有:

ThreadLocal、Looper、MessageQueue、Message、Handler.

Handler持有MessageQueue和Looper,而Looper持有持有MessageQueue,Message中包含Handler和Runnable成员变量。

其中

  • ThreadLocal是把新创建的Looper对象设置进线程本地存储区里。
  • Looper在后台不断轮询获取Message,后调用msg.target.dispatchMessage()执行,最终会掉用handler的handleMessage()。
  • MessageQueue是一个连表结构的集合。里面装有多个Runnable、Message对象
  • Message类似一个JavaBean,其中包含了消息ID,消息处理对象CallBack以及处理的数据Message.obj等
  • Handler是一个调度器,发送消息会掉用enqueueMessage方法将消息打入MessageQueue,

在一个线程中通过调用Looper.prepare();初始化即可使线程成为Looper线程,通过Looper.loop() 来循环处理消息队列

ThreadLocal

参考资料:解密ThreadLocal
正确理解ThreadLocal

ThreadLocal提供了线程局部变量,在线程的生命周期内起作用,使得各线程能够保持各自独立的一个对象,在Thread中将new出来的对象通过ThreadLocal.set()来设置独立于其他线程的对象,其他线程不可访问,不是用来解决线程同步问题的。

每个线程中都有一个ThreadLocalMap类对象,而ThreadLocal实例就是key,value是真正需要存储的Object,在Android’Handler机制中就是我们的Looper对象。

public final class Looper {
    private static final String TAG = "Looper";

    // sThreadLocal.get() will return null unless you've called prepare().
    static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
    private static Looper sMainLooper;  // guarded by Looper.class

    final MessageQueue mQueue;
    final Thread mThread;

    private Printer mLogging;
//....

Looper

通过Looper.prepare();来初始化Looper,并将Looper对象存储到本地线程中,而后创建Handler对象,并掉用Looper.loop()方法进行轮询。

注意:一个线程可以有多个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");
    }
    sThreadLocal.set(new Looper(quitAllowed));  // 创建Looper对象,并设置进TLS
}
//.....

Looper.loop()

public static final void loop() {
        Looper me = myLooper();  //得到当前线程Looper
        MessageQueue queue = me.mQueue;  //得到当前looper的MQ

        Binder.clearCallingIdentity();
        final long ident = Binder.clearCallingIdentity();
        // 开始循环
        while (true) {
            Message msg = queue.next(); // 取出message
            if (msg != null) {
                if (msg.target == null) {
                    // message没有target为结束信号,退出循环
                    return;
                }
            //...
                // 将真正的处理工作交给message的target,即发送消息的handler
                msg.target.dispatchMessage(msg);

Handler

首先,来看一下handler 的构造函数,

public Handler(Callback callback, boolean async) {
        if (FIND_POTENTIAL_LEAKS) {
            final Class<? extends Handler> klass = getClass();
            if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
                    (klass.getModifiers() & Modifier.STATIC) == 0) {
                Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
                    klass.getCanonicalName());
            }
        }

        mLooper = Looper.myLooper();// 设置looper
        if (mLooper == null) {
            throw new RuntimeException(
                "Can't create handler inside thread that has not called Looper.prepare()");
        }
        mQueue = mLooper.mQueue; //设置MessageQueue
        mCallback = callback; //设置CallBack
        mAsynchronous = async;
    }

Handler对象在构造时,不但会把Looper对象记录在它内部的mLooper成员变量中,还会把Looper对象的消息队列也一并记录

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

handler中的post 和send方法都会最终调用sendMessageAtTime方法,通过enqueueMessage方法将消息压入MessageQueue中

 public boolean sendMessageAtTime(Message msg, long uptimeMillis)
    {
        boolean sent = false;
        MessageQueue queue = mQueue;
        if (queue != null) {
            msg.target = this;  // message的target必须设为该handler!
            sent = queue.enqueueMessage(msg, uptimeMillis);
        }
        else {
            RuntimeException e = new RuntimeException(
                this + " sendMessageAtTime() called with no mQueue");
            Log.w("Looper", e.getMessage(), e);
        }
        return sent;
    }

Handler.dispatchMessage()

这个方法是有Looper.loop()方法调用。

 public void dispatchMessage(Message msg) {
        if (msg.callback != null) {
            // 如果message设置了callback,即runnable消息,处理callback!
            handleCallback(msg);
        } else {
            // 如果handler本身设置了callback,则执行callback
            if (mCallback != null) {
                 /* 让activity等来实现Handler.Callback接口,避免了自己编写handler重写handleMessage方法。*/
                if (mCallback.handleMessage(msg)) {
                    return;
                }
            }
            // 如果message没有callback,则调用handler的钩子方法handleMessage
            handleMessage(msg);
        }
    }

    // 处理runnable消息
    private final void handleCallback(Message message) {
        message.callback.run();  //回调CallBack中的run方法!
    }
    // new Handler的时候需要实现的方法
    public void handleMessage(Message msg) {
    }

你可能感兴趣的:(handler,looper)