Android多线程,阿里Android面试必问

public final class Message implements Parcelable{

Handler target;//target处理

Runnable callback;//Runnable类型的callback

Message next;//下一条消息,消息队列是链式存储的

//代码省略

}

Looper


至于Handler是如何关联消息队列以及线程的呢,我们可以从下面的代码中获悉,Handler在内部通过Looper.myLooper()来获取Looper对象,并且与之关联,获取消息队列。

public Handler(Callback callback, boolean async) {

// 仅贴出关键代码

mLooper = Looper.myLooper();

if (mLooper == null) {

throw new RuntimeException(

“Can’t create handler inside thread that has not called Looper.prepare()”);

}

mQueue = mLooper.mQueue;

mCallback=null;

}

再看下面的代码,myLooper()方法返回的是sThreadLocal.get(),sThreadLocal是当前的线程,在prepareMainLooper()方法中prepare()将Looper对象放进了sThreadLocal中。

public static void prepare() {

prepare(true);

}

private static void prepare(boolean quitAllowed) {

if (sThreadLocal.get() != null) {//每个线程只能有一个looper

throw new RuntimeException(“Only one Looper may be created per thread”);

}

//设置本线程的looper。

sThreadLocal.set(new Looper(quitAllowed));

}

所以最终,创建Handler的同时则自动在当前线程sThreadLocal中设置Looper对象,并获取该对象,进而获取消息队列。这样一来,Handler自然和消息队列以及线程关联起来了。

消息处理


Looper通过loop()方法建立消息循环:

public static void loop() {

//里面调用了sThreadLocal.get()获得刚才创建的Looper对象

final Looper me = myLooper();

if (me == null) {//如果Looper为空则会抛出异常

throw new RuntimeException(“No Looper; Looper.prepare() wasn’t called on this thread.”);

}

final MessageQueue queue = me.mQueue;

for (;😉 {

//这是一个死循环,从消息队列不断的取消息

Message msg = queue.next(); // might block

if (msg == null) {

//由于刚创建MessageQueue就开始轮询,队列里是没有消息的,等到Handler sendMessage enqueueMessage 后队列里才有消息

return;

}

msg.target.dispatchMessage(msg);

}

}

在上面的loop方法中,我们看到通过dispatchMessage方法来处理消息,根据适才看过的Message代码,target是Handler类型,所以说,Handler将消息投递到消息队列后,消息队列有将消息分发给Handler来处理。我们来看看消息处理函数的具体实现:

public void dispatchMessage(Message msg) {

if (msg.callback != null) {

//callback在message的构造方法中初始化或者使用handler.post(Runnable)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值