Android 消息机制

  • Handler 绑定在消息上

消息循环主要是不断取出消息,让Handler去处理消息,也就是说,Handler是消息发送端,和处理端。

下面来看一下循环消息部分源代码

private static boolean loopOnce(final Looper me,
        final long ident, final int thresholdOverride) {
    Message msg = me.mQueue.next(); // might block
    if (msg == null) {
        // No message indicates that the message queue is quitting.
        return false;
    }
    //省略掉一些代码
    try {
        msg.target.dispatchMessage(msg);//从消息中,拿到Handler 引用
    } catch (Exception exception) {
        throw exception;
    } finally {
    }
    msg.recycleUnchecked();

    return true;
}

msg.target.dispatchMessage(msg); target 就是消息绑定的handler

  • MessageQueue 一个线程通常只有一个消息队列

prepare()方法是绑定了线程和Looper的关系,也就是存储到线程上

private static void prepare(boolean quitAllowed) {
    sThreadLocal.set(new Looper(quitAllowed));
}

然后在消息循环的时候,根据根据当前线程去取出Looper

public static void loop() {
    final Looper me = myLooper();
    //省略掉一些代码
    for (;;) {
        if (!loopOnce(me, ident, thresholdOverride)) {
            return;
        }
    }
}
public static @Nullable Looper myLooper() {
    return sThreadLocal.get();
}

然后消息队列MessageQueue是在Looper初始化的时候就创建好了

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

所以一个Thread关联上了一个LooperLooper关联上了MessageQueue,循环的时候,通过Looper拿到MessageQueueMessageQueue不断去读取Message,下面是循环方法loopOnce

Message msg = me.mQueue.next();

private static boolean loopOnce(final Looper me,
        final long ident, final int thresholdOverride) {
    Message msg = me.mQueue.next(); // might block
    if (msg == null) {
        // No message indicates that the message queue is quitting.
        return false;
    }
    //省去一堆代码
    msg.recycleUnchecked();

    return true;
}

那是不是所有的线程自动就有这些关系?不是的,需要怎么做才行呢,源码给出了例子。

class LooperThread extends Thread {
        public Handler mHandler;
  
        public void run() {
            Looper.prepare();//1
            //2
            mHandler = new Handler(Looper.myLooper()) {
                public void handleMessage(Message msg) {
                    // process incoming messages here
                }
            };
            //3
            Looper.loop();
        }
}

其实这么做,只是为了建立关系而已。当然Google也给了一个封装好的线程HandlerThread

  • 频繁切换不同线程

当我们在后台线程执行过程中,突然又要切换到主线程执行,这时候就可以借助Handler这套消息机制,它可以帮忙我们在不同的线程之前切换。但是,如果反复在不同线程之间切换,代码实现起来经常会很难看,为了优化这个问题,很多开源工具就出现了,比如EventBus,RxJava.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值