android消息线程和消息队列
2014-08-30 11:09
330 查看
基于消息队列的线程通信:
消息队列与线程循环
MessageQueue:
利用链表来管理消息。
Message:
通常由Handler的子类的handleMessage()函数来处理该消息。
由android.os.Handler类来处理消息Message:
Handler:
由Handler来处理消息,由其函数dispatchMessage()完成。
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg); //若消息没有指定处理消息的对象,则由Handler的子类来完成。其子类必须实现handleMessage()方法。
}
}
Looper:
Looper与线程关联,一个线程最多有一个Looper。Looper实例保存到宿主线程的线程局部存储中。
指定了Looper就意味着指定了在哪个线程中处理;为消息指定的Handler则决定如何处理消息。
Looper中拥有一个消息队列MessageQueue,该消息队列由Looper创建,属于它所有。
private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);//创建Looper要处理的消息队列,是否运行线程退出,由消息队列决定。
mRun = true;
mThread = Thread.currentThread();//得到当前线程
}
public static void loop() {
final Looper me = myLooper();
if (me == null) {
throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
}
final MessageQueue queue = me.mQueue;
// Make sure the identity of this thread is that of the local process,
// and keep track of what that identity token actually is.
Binder.clearCallingIdentity();
final long ident = Binder.clearCallingIdentity();
for (;;) {
Message msg = queue.next(); // might block//取得一个消息
if (msg == null) {//消息体为空则表示退出
// No message indicates that the message queue is quitting.
return;
}
// This must be in a local variable, in case a UI event sets the logger
Printer logging = me.mLogging;
if (logging != null) {
logging.println(">>>>> Dispatching to " + msg.target + " " +
msg.callback + ": " + msg.what);
}
msg.target.dispatchMessage(msg);//调用消息指定的接收者Handler来处理它
if (logging != null) {
logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
}
final long newIdent = Binder.clearCallingIdentity();
if (ident != newIdent) {
Log.wtf(TAG, "Thread identity changed from 0x"
+ Long.toHexString(ident) + " to 0x"
+ Long.toHexString(newIdent) + " while dispatching to "
+ msg.target.getClass().getName() + " "
+ msg.callback + " what=" + msg.what);
}
msg.recycle();//丢弃消息,循环再利用
}
}
Handler:消息的处理者。一旦为消息指定了某个特定的处理者Handler,也就确定了在哪个线程的上下文中去处理以及如何处理消息。
实际上是根据Handler的变量mLooper所代表的Looper所在的线程,来决定该Handler运行在哪个线程中。
在一个线程中创建的Handler并不一定运行在该线程中,需要判断该Handler的Looper变量在哪个线程中。
public Handler() {
if (FIND_POTENTIAL_LEAKS) {
final Class<? extends Handler> klass = getClass();
if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
(klass.getModifiers() & Modifier.STATIC) == 0) {
Log.w(TAG, "The following Handler class should be static or leaks might occur: " +klass.getCanonicalName());
}
}
mLooper = Looper.myLooper();//通过线程局部存储,获得本线程的Looper:当程序没有另启一个线程时,该Looper就是主线程的Looper。
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread that has not called Looper.prepare()");
}
mQueue = mLooper.mQueue;
mCallback = null;
}
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);//消息所指定的CallBack,实际就是Runnable
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);//Handler的方法
}
}
相关文章推荐
- Android消息队列及线程机制详解
- Android GUI 单线程消息队列机制 —— 多线程GUI工具箱:一个破碎的梦
- Android:线程间通讯、Handler、Looper、IntentService、自定义消息队列
- Android -- 网络图片查看器,网络html查看器, 消息机制, 消息队列,线程间通讯
- Android进程和线程 --消息队列模型--Looper (2)(2015-12-02 19:41)
- Android消息队列及线程机制详解
- Android基础系列-----------Android进程/线程管理应用示例(Android中的消息队列和线程队列机制)
- Android 系列 4.11使用活动线程队列和处理程序在线程之间发送消息
- Android中的消息队列和线程队列机制
- Android进程和线程 --消息队列模型--ThreadLocal (3)(2015-12-02 19:41)
- Android进程和线程 --消息队列模型 (Looper, MessageQueue, Handler) (1)
- Android -- 网络图片查看器,网络html查看器, 消息机制, 消息队列,线程间通讯
- Android消息队列及线程机制详解
- 关于android Handler进行线程处理消息队列与线程队列线程无法停止的问题
- 细说UI线程和Windows消息队列
- 线程和消息队列的详解 【图】
- 图解 Android Handler 线程消息机制
- 【转】细说UI线程和Windows消息队列
- 线程与消息队列
- FAQ12:每个线程一个消息队列?还是线程中的每个窗口各有一个消息队列?