一张图秒懂Android消息机制(图+源码):Handler、Looper、MessageQueue

概念


  • 什么是Android消息机制?
    刚开始用时都会以为Android消息机制就是指Handler,因为在UI线程使用时都只需要Handler。其实,消息机制的组成不仅包括Handler,还包括Looper、MessegeQueue等。
  • Android消息机制的作用?
    2个作用
    1、代码逻辑转移。
    可以是在线程内部也可以是在线程间转移。
    用post(Runnable task)时,若task创建时所在的线程a和该Handler绑定的线程b不是同一个的话代码逻辑就线程a被转移到线程b中执行,若a、b是同一个线程的话代码逻辑的转移就只是在该线程内部。
    用send方法时,若Handler创建时所在的线程a和该Handler绑定的线程b不是同一个的话代码逻辑就线程a被转移到线程b中执行,若a、b是同一个线程的话代码逻辑的转移就只是在该线程内部。
    例子:IntentService中Handler将代码逻辑(即onHandleIntent()中的代码)从IntentService所在的线程即UI线程转移到IntentService中的HandlerThread这一线程中执行。
    2、发送消息。
    可以是在线程内部也可以在线程间发送消息。实际上也是代码逻辑的转移。
    例子:子线程发送消息通知UI线程更改UI(即调用Handler的handleMesseage()方法,这是代码逻辑在线程内部转移)。
    先上个图看下消息机制的大概原理:(是这篇文章的总结,很重要!!!,图比较小的可用浏览器新的标签页打开或下载下来)
    Android消息机制原理图

看懂上图的你就已经掌握消息机制的一大半了,接下来我们结合源码逐个认识消息机制的组成成员,对每个类的介绍基本都是按照Field、Field的初始化、成员方法这一顺序来介绍的,嘻嘻。。。

Handler


作用:通过Handler的post、send方法发送一个Message(持有该Handler对象)到Handler关联的Looper的MessageQueue中。
关键:post、send方法。

1、 Handler中持有的Field(持有Loopper、MesseageQueue的对象)

final MessageQueue mQueue;
final Looper mLooper;//关联Looper,其实就是关联Looper所在的线程。

它们在构造方法中被赋值,看下面Handler的初始化。

2、 Handler的初始化

  • 不指定Looper 的:handler = new Handler();
public Handler() {
        this(null, false);
}

public Handler(Callback callback, boolean async) {
        mLooper = Looper.myLooper();//默认使用当前线程的Looper。
        if (mLooper == null) {
  //Handler必须创建在有Looper的线程中。
            throw new RuntimeException(
                "Can't create handler inside thread that has not called Looper.prepare()");
        }
        mQueue = mLooper.mQueue;
        mCallback = callback;
        mAsynchronous = async;
}

UI线程中创建Handler一般就是用这种不用指定Looper,直接默认用当前UI线程的Looper。

  • 指定Looper 的:handler = new Handler(looper);
public Handler(Looper looper) {
        this(looper, null, false);
}
public Handler(Looper looper, Callback callback, boolean async) {
        mLooper = looper;
        mQueue = looper.mQueue;
        mCallback = callback;
        mAsynchronous = async;
}

3、 Handler的使用

  • post(Runnable r)
public final boolean post(Runnable r)
{
       return  sendMessageDelayed(getPostMessage(r), 0);
}

//将Runnable对象封装为Message对象
private static Message getPostMessage(Runnable r) {
    Message m = Message.obtain();
    m.callback = r;
    return m;
}

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

public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
    MessageQueue queue = mQueue;//Handler持有的MQ
    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);
}

//调用MessageQueue的enqueueMessage()方法将message添加到它的队列中。
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
    msg.target = this;
    if (mAsynchronous) {
        msg.setAsynchronous(
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值