android消息队列模型,Android 消息队列机制

本文深入探讨了Android中的消息队列机制,重点介绍了如何使用Handler、Looper和MessageQueue进行线程间通信。通过Looper.prepare()、Looper.loop()和Handler的创建,建立了一个线程的消息循环。当Handler发送Message到MessageQueue后,Looper会在其循环中取出并分发到对应的Handler进行处理。这种机制确保了主线程不被阻塞,提升了应用的响应速度和用户体验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在非UI线程使用Handler进行线程通信时,一般都需要进行3个步骤:

创建Looper Looper.prepar()

创建Handler

启动消息循环Looper.loop()

通过这3步,基本就建立好了 Android 的多线程消息通信机制:

Handler

MessageQueue

Looper

Message

这几者可谓是你中有我,我中有你的存在。通过 Handler 发送 Message 到 Looper 的 MessageQueue 中,待 Looper 的循环执行到 Message 后,就会根据 Message 的 target handler,回调对应 Handler 的 handlerMessage 方法。

例如: Thread-A 拥有一个 Looper,Thread-B 持有一个在 Thread-A 中构造的 Handler,Thread-B 就可以通过这个 Handler 将 Message 发送到 Thread-A 的 Looper 的 MessageQueue 中,然后消息会走到 Thread-A 的 Handler 的 handleMessage 方法。

Looper 原理图

f612393cf207aaba37b8d353d034dba7.png

在 Looper 类加载时就会创建一个 ThreadLocal 类型的类变量 sThreadLocal

public final class Looper {

private static final String TAG = "Looper";

// sThreadLocal.get() will return null unless you've called prepare().

static final ThreadLocal sThreadLocal = new ThreadLocal();

Looper.prepar()

public static void prepare() {

prepare(true);

}

private static void prepare(boolean quitAllowed) {

if (sThreadLocal.get() != null) {

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

}

// 将构造的 looper 存到类变量 sThreadLocal 中

sThreadLocal.set(new Looper(quitAllowed));

}

private Looper(boolean quitAllowed) {

// 构建一个 messageQueue 成员

mQueue = new MessageQueue(quitAllowed);

// 将当前线程存入 mThread 中

mThread = Thread.currentThread();

}

在这里面主要执行了 3 步:

构建一个 looper

构建一个 messageQueue 成员

将当前线程存入 mThread 中

将构造的 looper 存到类变量 sThreadLocal 中

至此,执行 Looper.praper 的当前线程就会拥有一个 looper 成员了,存放在 Looper 的 sThreadLocal 中。

创建Handler

public Handler(Callback callback, boolean async) {

...

// 通过`Looper.myLooper()` 类方法获取 sThreadLocal 中储存的当前线程的 looper,将这个 looper 绑定到 handler 的成员变量 mLooper 中

mLooper = Looper.myLooper();

if (mLooper == null) {

throw new RuntimeException("Can't create handler inside thread that has not called Looper.prepare()");

}

// 将 mLooper 中的 messageQueue 绑定到 handler 的成员变量 mQueue 中

mQueue = mLooper.mQueue;

...

}

public static @Nullable Looper myLooper() {

return sThreadLocal.get();

}

Looper.loop()

声明一个局部常量final Loop me = myLoop()

myLoop()将返回当前线程的looper成员

声明一个局部常量final MessageQueue queue

将me.mQueue赋值给queue

进入无限循环

//进入无限循环

for (;;) {

//取出一条消息

Message msg = queue.next();

//没有消息就阻塞

if (msg == null) {

return;

}

...

//分发消息

try {

msg.target.dispatchMessage(msg);

//msg.target是一个Handler对象

} finally {

if (traceTag != 0) {

Trace.traceEnd(traceTag);

}

}

...

//回收消息

msg.recycleUnchecked();

通过Message.obtain()获取的消息,需要使用Handler.sendMessage()插入到消息队列。

通过Handler.obtainMessage()获取的消息,可以使用message.sendToTaget()插入到消息队列。

ZWave 中的消息队列机制

文章主题   在我们的日常编程中,对消息队列的需求非常常见,使用一个简洁.高效的消息队列编程模型,对于代码逻辑的清晰性,对于事件处理的高效率来说,是非常重要的.这篇文章就来看看 ZWave 中是通过什 ...

Android消息队列和Looper

1. 什么是消息队列 消息队列在android中对应MessageQueue这个类,顾名思义,消息队列中存放了大量的消息(Message) 2.什么是消息 消息(Message)代表一个行为(what ...

Android 消息分发机制

Android 中针对耗时的操作,放在主线程操作,轻者会造成 UI 卡顿,重则会直接无响应,造成 Force Close.同时在 Android 3.0 以后,禁止在主线程进行网络请求. 针对耗时或者 ...

Android开发学习—— 消息队列

###主线程不能被阻塞* 在Android中,主线程被阻塞会导致应用不能刷新ui界面,不能响应用户操作,用户体验将非常差* 主线程阻塞时间过长,系统会抛出ANR异常* ANR:Application ...

Android 开发笔记 “Android 的消息队列模型”

Android是参考Windows的消息循环机制来实现Android自身的消息循环的. Android通过Looper.Handler来实现消息循环机制,Android消息循环是针对线程的(每个线程都 ...

Android 的消息队列模型

Android 的消息队列模型 Android是参考Windows的消息循环机制来实现Android自身的消息循环的.    Android通过Looper.Handler来实现消息循环机制,Andr ...

Android HandlerThread 消息循环机制之源代码解析

关于 HandlerThread 这个类.可能有些人眼睛一瞟,手指放在键盘上,然后就是一阵狂敲.立即就能敲出一段段华丽的代码: HandlerThread handlerThread = new Ha ...

Window Azure ServiceBus Messaging消息队列技术系列1-基本概念和架构

前段时间研究了Window Azure ServiceBus Messaging消息队列技术,搞了很多技术研究和代码验证,最近准备总结一下,分享给大家. 首先,Windows Azure提供了两种类型 ...

跟我一起学WCF(1)——MSMQ消息队列

一.引言 Windows Communication Foundation(WCF)是Microsoft为构建面向服务的应用程序而提供的统一编程模型,该服务模型提供了支持松散耦合和版本管理的序列化功能 ...

随机推荐

【夯实PHP基础】UML序列图总结

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值