看过冷冰的Android核心分析第十一篇:Android GWES之消息系统,我得到了一张重要的图:
对照源码看这张图之后,我发现冷冰已经总结的很清晰。我补充我认识到的另外几点看法和疑问:
1.MessageQueue对外来说基本是不可见的,我们要为自己的程序添加消息处理机制时无需关心的(当然无需关心,这一点好勉强,^_^)
2.在Looper中有这么一段
private static final ThreadLocal sThreadLocal = new ThreadLocal();
因此,即便在一个VM实例中存在多个消息处理框架,线程相关的资源依旧是共享的。(不过ThreadLocal等概念我还得普及一下)
3. 阅读Handler代码发现一个很有趣的地方,先看代码:
在Message中有这么一段:
/*package*/ Runnable callback;
在Handler中有这么一个方法:
private final void handleCallback(Message message) {
message.callback.run();
}
而这个handleCallback方法是在handleMessage时调用的:
/**
* Subclasses must implement this to receive messages.
*/
public void handleMessage(Message msg) {
}
/**
* Handle system messages here.
*/
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
哈,这让我想起了以前写js代码时那种回调风格。。我以前看到的或者用到的回调大多是自己定义一个接口,折腾了一圈才发现,原来有现成的啊,竟然不懂得用。。
4. 从Message类中的next变量和obtain方法看出,Message从结构上来看,就像一个链表,没有方向,没有优先级概念(那如果消息存在优先级的话,这个框架还能搞定吗?当然是不能)。试想一下,在GWES模型中,会不会出现一种情况,某些事件的优先级要高于其它而要优先处理的呢?如果碰到这种情况该怎么处理?
今天看相关源码发现,Android消息处理框架,没有优先级这一说。我们在sendMessage的时候最多能加上一个delay time作为参数,所以框架的使用者如果需要达到某些消息优先处理,那么可以通过这个delay time来实现。(是不是有点别扭,没事,习惯了就好……但,还是有点别扭)
考虑一下Android手机的系统特性,每个手机都会一个菜单键、Home键和back键,那么在什么情况下会存在一些优先级较高的消息呢,我目前还没想出来,因为在一个Activity里面,所有view component的地位都应该是相等的,所以每个component的消息处理也应该是同级的,如果某个应用中需要处理一些特别的(例如定时、延迟)消息,可以采用Task来处理定时任务,延迟也只要加上delay time参数即可。对于back键的处理Activity是单独开来的,开发者需要在onBackPresssed中自行处理,menu键和这是一样的,Home键开发者根本没法控制的,系统会自动处理(onPause --> onStop)。其实这几个键事件也是我目前能想到的需要特别处理的地方。
5. 首先来看一段代码:
final boolean enqueueMessage(Message msg, long when) {
if (msg.when != 0) {
throw new AndroidRuntimeException(msg
+ " This message is already in use.");
}
if (msg.target == null && !mQuitAllowed) {
throw new RuntimeException("Main thread not allowed to quit");
}
synchronized (this) {
if (mQuiting) {
RuntimeException e = new RuntimeException(
msg.target + " sending message to a Handler on a dead thread");
Log.w("MessageQueue", e.getMessage(), e);
return false;
} else if (msg.target == null) {
mQuiting = true;
}
msg.when = when;
//Log.d("MessageQueue", "Enqueing: " + msg);
Message p = mMessages;
if (p == null || when == 0 || when < p.when) {
msg.next = p;
mMessages = msg;
this.notify();
} else {
Message prev = null;
while (p != null && p.when <= when) {
prev = p;
p = p.next;
}
msg.next = prev.next;
prev.next = msg;
this.notify();
}
}
return true;
}
这段代码是MessageQueue中将某个message加入消息队列的方法,这里我注意到两点:
1. 没有使用容器类来充当一个message pool,而是每个message对象都会有一个next字段用以引用它的下一个,所以message是以对象间链式的引用来存储的(message会被Looper处理,所以不用担心对象会释放掉造成数据丢失;没有用到集合类,简化了数据结构和操作)
2.那个while循环是进行排序的,它会对每个新进来的message对象按照when(就是delay time)进行排序,因为是链式数据结构,所以效率相当高(不过我没测试过有多高)
引申:这个算法让我对数据结构又有一点新的认识。以前我总是条件反射的以为,任何数据都会以某种容器来存储(我惯用ArrayList、Map等什么的),但是我却忽视了一点,什么是容器,我曾经看过ArrayList或者其它的代码,它们内部都会有一个数组结构来存储数据,如果数据超出数组边界,那么就新创建一个数组把原来的数据拷贝进去(System.arrayCopy)再把旧数组替换掉(Map什么的我具体忘记了,但是我估计也不出这左右),所以,数组是最基本结构;除此之外,任何new出来的对象都应该是某种数据结构,它们用字段存储数据,只是它们没有名字而已(像List,Map等这样的数据结构领域的名字)。到这,就不难理解为什么googler可以用对象之间的相互引用来实现某种数据存储,因为,任何这种那样的方式的本质是没有改变的:一种映射,语言标记到计算机存储之间的映射,通过使用标记就能明确访问这个标记所对应的计算机上存储的数据。
分享到:
相关推荐
这就是 Android 的异步处理机制,其中 Handler、Looper 和 MessageQueue 是关键组件,它们共同构成了 Android 线程间通信的基础。 1. **Handler**: Handler 是一个接口,用于发送和处理消息。它与 Looper 关联,...
本篇文章将深入探讨Android中消息处理的核心组件——Looper、MessageQueue、Handler以及消息循环的工作原理。理解这些概念对于构建响应迅速、用户友好的应用程序至关重要。 #### 二、核心概念 ##### 1. Looper ...
Message对象包含了消息的内容、目标Handler等信息,通过`MessageQueue.enqueueMessage()`方法添加到队列中。 Handler、Looper和MessageQueue之间的协作流程如下: 1. 在工作线程中,创建一个Handler对象,并关联到...
Handler、Looper和MessageQueue是Android异步处理机制中的核心组件,它们共同构建了一个消息传递系统,使得在不同线程间进行数据交换变得可能。下面我们将深入探讨这三个组件的工作原理及其在实际开发中的应用。 ...
在Android操作系统中,MessageQueue是实现线程间通信和异步处理的核心组件。...通过分析`android_os_MessageQueue.cpp`源代码,开发者可以更深入地了解这个过程,从而优化性能或解决与消息处理相关的复杂问题。
在Android开发中,Handler、Looper和MessageQueue是用于实现线程间通信的关键组件,它们共同构建了一个消息处理机制。理解这三个概念以及它们之间的关系对于优化应用程序的性能和响应性至关重要。 Handler(处理器...
Handler获取当前线程中的looper对象,looper用来从存放Message的MessageQueue中取出Message,再有Handler进行Message的分发和处理. 简单定义: 1、Message Queue(消息队列): 用来存放通过Handler发布的消息,通常...
综上所述,Message、MessageQueue、Looper和Handler这四个组件共同构成了Android应用程序中处理消息的基本机制。通过它们之间的相互协作,使得应用程序能够在不同的线程间高效地传递和处理消息,从而实现了复杂的...
在安卓开发中,`Handler`、`Looper`和`MessageQueue`是三个核心组件,它们共同构成了Android消息处理机制,用于实现线程间的通信。这个压缩包“安卓Android源码——HandlerLooper2.rar”可能包含了关于这些组件的...
在Android系统中,线程(Thread)、Looper、Handler、Message以及MessageQueue和MessagePool是实现异步消息处理机制的关键组件,它们共同构建了一个高效的事件驱动模型。这些组件的关系紧密,协同工作,使得Android...
在Android应用开发中,`Handler`、`Looper`和`MessageQueue`是处理应用程序线程间通信的关键组件,尤其在实现UI更新和异步任务调度时。`Android应用源码之HandlerLooper2.zip`可能包含了一个示例项目,用于演示如何...
在Android开发中,`Handler`、`Looper`和`MessageQueue`是三个核心组件,它们共同构成了Android消息处理机制,用于实现线程间的通信。这个压缩包“Android应用源码之HandlerLooper1_Android.zip”可能包含了一个示例...
4. **Looper**:充当MessageQueue和Handler之间的桥梁角色,负责循环取出MessageQueue中的消息,并交给对应的Handler处理。 #### 四、消息处理流程 1. **创建Handler**:每个需要处理消息的线程都需要一个Handler...
- Handler配合MessageQueue和Looper形成的是一种轻量级的异步消息处理机制,它是Android系统中实现异步任务的一种方式,但不是唯一的方式。其他还包括IntentService、AsyncTask、Loader等。 - Android中的Handler还...
MessageQueue与Looper紧密配合,当MessageQueue中有新消息时,Looper会取出并分发给对应的Handler进行处理。主线程默认已经创建了MessageQueue和Looper,而在其他非主线程中,开发者需要手动调用`Looper.prepare()`...
在Android系统中,`Handler`、`Looper`和`MessageQueue`是三个核心组件,它们共同构成了Android消息处理机制,使得应用程序能够实现线程间的通信和异步任务执行。这个`HandlerLooper1.rar`文件可能包含了对这些概念...
在安卓(Android)开发中,`Handler`、`Message` 和 `Looper` 是三个非常重要的组件,它们共同构成了安卓的异步消息处理机制。这个机制是安卓系统中处理UI线程与后台线程通信的核心方式。`HandlerMessage1.rar` 文件...
5. **分发消息**:Looper从MessageQueue中取出消息,并找到对应Handler的`handleMessage()`方法进行处理。 6. **处理消息**:Handler的`handleMessage()`方法被调用,执行UI更新或其他操作。 注意,Looper一旦启动...
首先,`Looper`是Android系统中一个用于处理消息循环的类,它在后台线程中不断检查消息队列`MessageQueue`,并将新消息分发给相应的`Handler`进行处理。通常,主线程(UI线程)已经有一个默认的`Looper`在运行,因此...
Looper,MessageQueue,Handler分析之ActivityThread.java