Android Handler机制浅析

1. Looper

在讲Handler之前,首先要讲讲Looper和MessageQueue。

Looper类源码的说明:Looper是用来给线程发送消息的,线程没有默认的message loop,可以通过Looper.prepare()创建线程的looper。

看下prepare的代码吧

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中有两个关键的属性:

  1. MessageQueue mQueue:消息队列,用来处理消息
  2. Looper sMainLooper:主线程的looper,也就是Android的UI线程本身就是有looper的,不需要手动去prepare

Looper类中的loop函数则用于具体的消息处理(只选取部分代码)

public static void loop() {
    final Looper me = myLooper(); // 首先要有looper
    final MessageQueue queue = me.mQueue;
    // 死循环
    for(;;) {
        Message msg = queue.next(); // 没有要处理的信息时是阻塞的
        if (msg == null) {
            return; // 返回
        }
        // ... 计算消息的优先级,发送时间的代码
        try {
            msg.target.dispatchMessage(msg);
        } finally {
            if (traceTag != 0) {
                Trace.traceEnd(traceTag);
            }
        }
        msg.recycleUnchecked(); // 回收消息
    }
}

MessageQueue处理消息的代码暂时没能力看懂orz,自作聪明以为里面持有一个Message的队列,结果发现里面只有一个Message对象,每个Message对象都有next属性指向下一个Message

2. Handler

Looper也好,MessageQueue也好,怎么和Handler联系起来呢?

首先看看构造函数:

2.1 构造函数

public Handler(Looper looper, Callback callback) {
	this(looper, callback, false);
}

也可以什么都不传参数或者只传其中一个,在调用链上都会使用到这个构造函数

2.2 sendMessage

sendMessage+后缀的一系列方法,最后都是调用sendMessageAtTime这个方法

public boolean sendMessageAtTime(Message msg, long uptimeMills) {
    MessageQueue queue = mQueue;
    if (queue == null) {
        // ...报错
        return false;
    }
    return enqueueMessage(queue, msg, uptimeMills);
}

可以看到这里出现了上面提到的MessageQueue,而mQueue则是通过looper.mQueue拿到的,也就是说如果自定义线程的Handler,必须传入Looper,否则会报错,而UI线程因为本来就持有looper对象可以直接创建。

enqueueMessage最终调用的是queue.enqueueMessage,也就是把消息委派给MessageQueue去处理了

2.3 handleMessage

使用过Handler的人一定都知道handleMessage这个方法,它是用来处理我们自定义的消息。

Handler中两个handlerMessage方法,一个定义在内类接口Callback中,另一个是个空方法(匿名Handler类重写的就是这个方法)

public interface Callback {
    
    public boolean handleMessage(Message msg);
}
public void handleMessage(Message msg) {
    
}

将这两者联系起来的是**dispatchMessage(Message msg)**这个方法

public void dispatchMessage(Message msg) {
	if (msg.callback != null) {
    	handleCallback(msg);
    } else {
    	if (mCallback != null) {
        	if (mCallback.handleMessage(msg)) {
            	return;
            }
         }
         handleMessage(msg);
    }
}

可以看到,调用的优先级:Message实现的Callback > Handler内的Callback > 自己实现Handler子类重写的handleMessage方法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值