Android Handler类的源码详解

handler机制的架构设计

Handler机制主要分为两部分:发送消息和处理消息;
发送消息:可以在任意的子线程中进行操作;
处理消息:在主线程中进行操作,主要是通过Looper类轮询MessageQueue队列来处理消息的;

在这里插入图片描述

handler中的发送消息的方法有很多种;但是这些方法经过处理最终会调用到Handler.enqueueMessage();
发送消息:
1.调用sendMessage方法,将消息传递到MessageQueue队列中
2.使用handler.post(new Runnable(){.....})  //作为message.callback的值,传递给MessageQueue队列
处理消息:
在主线程ActivityThread类中,调用Looper.loop()方法,在该方法中轮询消息队列MessageQueue,然后执行这些消息;

Handler类的源码详解

Handler机制在源码层可以分为4层:

Looper机制:sThreadLocal,Looper.loop();
Message:消息的数据结构,消息缓存池;
MessageQueue:enqueueMessage,next,消息等待,同步消息隔离,idleHandler;
Handler:send/post,dispatchMessage消息处理优先级;

1.Looper机制:

sThreadLocal:静态常量,保证一个线程只有一个 Looper;
sMainLooper:静态变量,在 prepareMainLooper 中赋值当前线程 Looper;
mQueue:变量,Looper 构造函数中初始化,因为一个线程只有一个 Looper,所以也同样只有一个 mQueue。

通过以上分析,我们可以总结出一下特性:
Looper、MessageQueue 是线程唯一的;
一个进程只有一个 sMainLooper;
根据 ThreadLocal 的特性,可通过 myLooper 方法获取当前线程的 Looper。

Looper.loop()public static void loop() {
    final Looper me = myLooper();
    final MessageQueue queue = me.mQueue;
    for (;;) { 
        Message msg = queue.next();
        ...
        msg.target.dispatchMessage(msg);
        ...
        msg.recycleUnchecked();
    }
}
Looper.loop() 方法虽然看起来很多,其实他主要就做了三件事:
从消息队列中获取下一个消息;
msg.target 就是 handler,通过 dispatchMessage 方法把消息分发下去,这个方法下面会有说到;
消息回收,放到消息缓存池里。这里需要注意的是 Message 对象并没有释放,会缓存起来。

2.Message数据结构:

public int what, arg1, arg2;
public Object obj;
public Messenger replyTo;
int flags;
long when;      // 消息发送时间
Bundle data;
Handler target;
Runnable callback;

Message next;

private static final Object sPoolSync = new Object();
private static Message sPool;
private static int sPoolSize = 0;

private static final int MAX_POOL_SIZE = 50;

看到 next 变量,我们会想到单链表,其实 Message 就相当于单链表的 node,MessageQueue 就是一个单链表了,会持有表头的引用;
what、arg1、arg2、obj、data 就是我们发送的一些信息;
值得注意的是 target,他是 Handler 类型,就是本消息的 Handler,会在 Handler 发送消息的时候赋值;
后面的四个对象,都是和消息缓存池有关的。

3.MessageQueue消息队列:

主要作为插入队列的方法,有下列几个特性:
把消息加入消息队列,如果当前表头为空,则把消息作为表头引用;如果不为空,则会根据时间的顺序,插入到对应的时间中;
nativeWake 是调用底层在管道中写操作以唤醒,在队列不是阻塞的状态下是不需要唤醒的;
另外注意其中用了 synchronized 关键字,说明消息队列的插入是线性安全的,删除也是线性安全的,之后我们会说到。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值