Android异步消息处理架构,其实没那么复杂。简单来讲就是looper
对象拥有messagequeue
,而且负责从messagequeue
中取出消息给handler
来处理。同时handler
又负责发送message
给looper
,由looper
把message
添加到messagequeue
尾部。就一个圈儿。下面给出图解:android
因此很明显handler
和looper
是来联系在一块儿的。须要说明的是,多个message
能够指向同一个handler
,多个handler
也能够指向同一个looper
。还有一点很重要,普通的线程是没有looper
的,若是须要looper
对象,那么必需要先调用Looper.prepare()
方法,并且一个线程只能有一个looper
。调用完之后,此线程就成为了所谓的LooperThread
,若在当前LooperThread
中建立Handler
对象,那么此Handler
会自动关联到当前线程的looper
对象,也就是拥有looper
的引用。网络
Looper
就是一个管理messagequeue
的类。下面是这个类的源码。架构
public class Looper { ...... private static final ThreadLocal sThreadLocal = new ThreadLocal(); final MessageQueue mQueue;//拥有的消息队列 ...... /** * Initialize the current thread as a looper. * This gives you a chance to create handlers that then reference * this looper, before actually starting the loop. Be sure to call * {@link #loop()} after calling this method, and end it by calling * {@link #quit()}. */ //建立新的looper对象,并设置到当前线程中 public static final void prepare() { if (sThreadLocal.get() != null) { throw new RuntimeException("Only one Looper may be created per thread"); } sThreadLocal.set(new Looper()); } ····· /** * Return the Looper object associated with the current thread. Returns * null if the calling thread is not associated with a Looper. */ //获取当前线程的looper对象 public static final Looper myLooper() { return (Looper) sThreadLocal.get(); } private Looper() { mQueue = new MessageQueue(); mRun = true; mThread = Thread.currentThread(); } ...... }
调用完Looper.prepare()
以后,在当前的线程建立的Handler
才能拥有当前线程的looper
。而后调用loop()
来开启循环,处理message
。下面是Looper类下的loop方法部分源码:less
public static void loop() { final Looper me = myLooper();//获取looper对象 if (me == null) { //若为空则说明当前线程不是LooperThread,抛出异常 throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread."); } final MessageQueue queue = me.mQueue; 获取消息队列 ..... 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 //打印log,说明开始处理message。msg.target就是Handler对象 Printer logging = me.mLogging; if (logging != null) { logging.println(">>>>> Dispatching to " + msg.target + " " + msg.callback + ": " + msg.what); } //重点!!!开始处理message,msg.target就是Handler对象 msg.target.dispatchMessage(msg);//dispatchMessage:发送消息 //打印log,处理message结束 if (logging != null) { logging.println("<<<<< Finished to " + msg.target + " " + msg.callback); } ..... } }
是一个大的循环,不断从消息队列出取出消息。而后调用一个很关键的方法msg.target.dispatchMessage(msg)
开始处理消息。msg.target
就是message
对应的handler
。looper
对象管理MessageQueue
,从中取出message
分配给对应的handler
来处理。异步
Message
就是一些须要处理的事件,好比访问网络、下载图片、更新ui界面什么的。Message
拥有几个比较重要的属性。async
public int what 标识符,用来识别message
ide
public int arg1,arg2 能够用来传递一些轻量型数据如int之类的函数
public Object obj Message
自带的Object类字段,用来传递对象oop
Handler target 指代此message
对象对应的Handler
post
若是携带比价复杂性的数据,建议用Bundle
封装,值得注意的地方是,虽然Message
的构造方法是公有的,可是不建议使用。最好的方法是使用Message.obtain()
或者Handler.obtainMessage()
能更好的利用循环池中的对象。通常不用手动设置target
,调用Handler.obtainMessage()
方法会自动的设置Message
的target
为当前的Handler
。获得Message
以后能够调用sendToTarget()
,发送消息给Handler
,Handler
再把消息放到messagequeue
的尾部。这个方法的源码以下:
/** * Sends this Message to the Handler specified by {@link #getTarget}. * Throws a null pointer exception if this field has not been set. */ public void sendToTarget() { target.sendMessage(this);//此处的target是message对应的Handler. }
它的构造函数以下:
/** * Default constructor associates this handler with the {@link Looper} for the * current thread. * * If this thread does not have a looper, this handler won't be able to receive messages * so an exception is thrown. */ public Handler() { this(null, false); } /** * Constructor associates this handler with the {@link Looper} for the * current thread and takes a callback interface in which you can handle * messages. * * If this thread does not have a looper, this handler won't be able to receive messages * so an exception is thrown. * * @param callback The callback interface in which to handle messages, or null. */ public Handler(Callback callback) { this(callback, false); } /** * Use the provided {@link Looper} instead of the default one. * * @param looper The looper, must not be null. */ public Handler(Looper looper) { this(looper, null, false); } /** * Use the provided {@link Looper} instead of the default one and take a callback * interface in which to handle messages. * * @param looper The looper, must not be null. * @param callback The callback interface in which to handle messages, or null. */ public Handler(Looper looper, Callback callback) { this(looper, callback, false); } /** * Use the {@link Looper} for the current thread * and set whether the handler should be asynchronous. * * Handlers are synchronous by default unless this constructor is used to make * one that is strictly asynchronous. * * Asynchronous messages represent interrupts or events that do not require global ordering * with respect to synchronous messages. Asynchronous messages are not subject to * the synchronization barriers introduced by {@link MessageQueue#enqueueSyncBarrier(long)}. * * @param async If true, the handler calls {@link Message#setAsynchronous(boolean)} for * each {@link Message} that is sent to it or {@link Runnable} that is posted to it. * * @hide */ public Handler(boolean async) { this(null, async); } /** * Use the {@link Looper} for the current thread with the specified callback interface * and set whether the handler should be asynchronous. * * Handlers are synchronous by default unless this constructor is used to make * one that is strictly asynchronous. * * Asynchronous messages represent interrupts or events that do not require global ordering * with respect to synchronous messages. Asynchronous messages are not subject to * the synchronization barriers introduced by {@link MessageQueue#enqueueSyncBarrier(long)}. * * @param callback The callback interface in which to handle messages, or null. * @param async If true, the handler calls {@link Message#setAsynchronous(boolean)} for * each {@link Message} that is sent to it or {@link Runnable} that is posted to it. * * @hide */ public Handler(Callback callback, boolean async) { 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 = callback; mAsynchronous = async; } /** * Use the provided {@link Looper} instead of the default one and take a callback * interface in which to handle messages. Also set whether the handler * should be asynchronous. * * Handlers are synchronous by default unless this constructor is used to make * one that is strictly asynchronous. * * Asynchronous messages represent interrupts or events that do not require global ordering * with respect to synchronous messages. Asynchronous messages are not subject to * the synchronization barriers introduced by {@link MessageQueue#enqueueSyncBarrier(long)}. * * @param looper The looper, must not be null. * @param callback The callback interface in which to handle messages, or null. * @param async If true, the handler calls {@link Message#setAsynchronous(boolean)} for * each {@link Message} that is sent to it or {@link Runnable} that is posted to it. * * @hide */ public Handler(Looper looper, Callback callback, boolean async) { mLooper = looper; //由此可知,它拥有对象,以及的 mQueue = looper.mQueue; mCallback = callback; mAsynchronous = async; }looperloopermessagequeue
要经过Handler
来处理事件,能够重写handleMessage(Message msg)
,也能够直接经过post(Runnable r)
来处理。这两个方法都会在looper循环中被调用。
loop循环中处理信息的msg.target.dispatchMessage(msg)
方法源码:
public void dispatchMessage(Message msg) { //注意!这里先判断message的callback是否为空,不然就直接处理message的回调函数if (msg.callback!= null) { //这里的callback就是上面的Runnable handleCallback(msg); } else { if (mCallback != null) { //正是在这调用咱们日常重写handleMessage if (mCallback.handleMessage(msg)) { return; } } handleMessage(msg); } }
首先判断是否用的是handler的post方法,若是是就执行r里面run()方法的代码,不然就判断handler的构造函数是否初始化了CallBack,是的话就会执行这个接口里面handleMessage(msg)方法,;若是放回的是false,最后就会调用handleMessage(msg)(创建handler时重写的方法,若是没有重写,就什么都不会执行)。下面是handler的post方法的源码:
/**
* Causes the Runnable r to be added to the message queue.
* The runnable will be run on the thread to which this handler is
* attached.
*
* @param r The Runnable that will be executed.
*
* @return Returns true if the Runnable was successfully placed in to the
* message queue. Returns false on failure, usually because the
* looper processing the message queue is exiting.
*/
public final boolean post(Runnable r)
{
return sendMessageDelayed(getPostMessage(r), 0);//发送消息
}
上面源码中getPostMessage(r)方法的源码:
private static Message getPostMessage(Runnable r) {
Message m = Message.obtain();
m.callback = r; //就是上面的msg.callback,若是调用了handler的post方法,它就会不为空。
return m;
}
上面的 if (msg.callback!= null) { //这里的callback就是上面的Runnable handleCallback(msg); }的handleCallback(msg)源码:(就是运行run方法里面的代码)
private static void handleCallback(Message message) {
message.callback.run();
}
而 if (mCallback.handleMessage(msg)) { return; }中的handleMessage(msg)源码以下:
/**
* Callback interface you can use when instantiating a Handler to avoid
* having to implement your own subclass of Handler.
*
* @param msg A {@link android.os.Message Message} object
* @return True if no further handling is desired
*/
public interface Callback {
public boolean handleMessage(Message msg);
}
因此如今知道loop循环中处理信息的msg.target.dispatchMessage(msg)
方法里面的代码了吧。