Android中的MessageQueue,Handler,Looper和Thread
来源:互联网 发布:ips屏幕 知乎 编辑:程序博客网 时间:2024/04/28 12:35
MessageQueue
消息队列MessageQueue是一个以执行时间为序的优先级队列:
o 普通消息的执行为当前时间,先发送的前面,后发送在后面,这是典型的FIFO。
o 最高优先级的消息执行时间为0,所以直接插在队列的最前面,通常会立即执行。
o 而在将来执行的Message相当于timer,执行时间为当前时间+delay的时间。
MessageQueue的函数boolean enqueueMessage(Message msg, long when)用来向队列中插入消息。
Message和GTK+ idle不同之处在于,Message只是一段数据,里面说明了要做什么,但不并知道如何做。而idle带有自己的数据和处理函数,它知道如何做。Message放入队列中后,在处理这些消息时到底要做些什么呢?这就引入了Handler:
Handler
Handler 对消息队列的enqueueMessage做了包装,这其实并不重要,因为完全可以直接调用enqueueMessage来实现。重要的Handler把在包装enqueueMessage的同时,把Message的target设成了自己,即为Message指定执行的行为:
if (queue != null) { msg.target = this; sent = queue.enqueueMessage(msg, uptimeMillis); }
这样一来,当前Message被处理的时候就会调用Handler的dispatchMessage,而这个函数就会调用你要实现的虚函数handleMessage了。经过消息队列转了一圈,还是调用了你自己的实现函数,但是同步操作变成了异步操作。
public void dispatchMessage(Message msg) { if (msg.callback != null) { handleCallback(msg); } else { if (mCallback != null) { if (mCallback.handleMessage(msg)) { return; } } handleMessage(msg); } }
Looper
Message放在消息队列里了,谁来一个一个的取出来处理呢?这时轮到Looper上场了,它的函数loop会一直循环处理队列中的消息,直到遇上一个没有target的Message:
public static final void loop() { Looper me = myLooper(); MessageQueue queue = me.mQueue; while (true) { Message msg = queue.next(); // might block //if (!me.mRun) { // break; //} if (msg != null) { if (msg.target == null) { // No target is a magic identifier for the quit message. return; } if (me.mLogging!= null) me.mLogging.println( ">>>>> Dispatching to " + msg.target + " " + msg.callback + ": " + msg.what ); msg.target.dispatchMessage(msg); if (me.mLogging!= null) me.mLogging.println( "<<<<< Finished to " + msg.target + " " + msg.callback); msg.recycle(); } } }
由此可见:一个Looper总是和一个MessageQueue关联起来的。
Thread
loop只是一个函数,它也需要别人来执行它。由于它一执行就会阻塞在那里,所以一定需要一个线程来调用:
* class LooperThread extends Thread { * public Handler mHandler; * * public void run() { * Looper.prepare(); * * mHandler = new Handler() { * public void handleMessage(Message msg) { * // process incoming messages here * } * }; * * Looper.loop(); * } * }
一个Looper也总是和一个Thread关联起来的,不过不一定要创建新线程,可以是主线程的。Handler和Thread不是一一对应的,理论上,在一个LooperThread中,可以有任何多个Handler,每个消息都可以指定不同的Handler,因为每个消息都可以有不同的行为。
在创建Handler时并不会创建Thread,它只是取当前线程的Looper的MessageQueue:
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(); if (mLooper == null) { throw new RuntimeException( "Can't create handler inside thread that has not called Looper.prepare()"); } mQueue = mLooper.mQueue; mCallback = null; }
通过myLooper取出当前线程的Looper:
public static final Looper myLooper() { return (Looper)sThreadLocal.get(); }
这个Looper是在Looper.prepare里创建的:
public static final void prepare() { if (sThreadLocal.get() != null) { throw new RuntimeException("Only one Looper may be created per thread"); } sThreadLocal.set(new Looper()); }
- Android中的MessageQueue,Handler,Looper和Thread
- Android中的MessageQueue,Handler,Looper和Thread
- Android中的MessageQueue,Handler,Looper和Thread
- Android中的MessageQueue,Handler,Looper和Thread
- Android中的MessageQueue,Handler,Looper和Thread
- Android中的MessageQueue,Handler,Looper和Thread
- Android中的MessageQueue,Handler,Looper和Thread
- Android中的MessageQueue,Handler,Looper和Thread
- Android中的Handler, Looper, MessageQueue和Thread
- Android中的Handler, Looper, MessageQueue和Thread
- Android中的Handler, Looper, MessageQueue和Thread
- Android中的Handler, Looper, MessageQueue和Thread
- Android中的Handler, Looper, MessageQueue和Thread
- Android中的Handler, Looper, MessageQueue和Thread
- Android中的MessageQueue,Handler,Looper和Thread
- Android中的MessageQueue,Handler,Looper和Thread
- Android中的Handler, Looper, MessageQueue和Thread
- Android中的Handler, Looper, MessageQueue和Thread
- Thread和Looper以及Handler和Message详解
- bash 学习
- tcpdump 学习笔记
- 几种文件操作类
- 我要克服的
- Android中的MessageQueue,Handler,Looper和Thread
- WPF学习
- [NPWP笔记]Write a FTP client with two-process model
- __FILE__,__LINE__,FUNCTION__实现代码跟踪调试(linux下c语言编程 )(转)
- 贷款流程
- 深入理解Android消息处理系统——Looper、Handler、Thread
- sprintf trap
- Java常识
- 闲聊linux中的input设备(5) 她那含情脉脉的眼神