android 线程消息深入
在网上有许多资料对这三者关系的分析,但都比较笼统不够细致入微.
以下是自己深入源码分析其结果.
Handler 源码:
public class Handler { private static final boolean FIND_POTENTIAL_LEAKS = false; private static final String TAG = "Handler";
public interface Callback { public boolean handleMessage(Message msg); } final MessageQueue mQueue; final Looper mLooper; final Callback mCallback; IMessenger mMessenger; /** * Subclasses must implement this to receive messages. */ public void handleMessage(Message msg) { } 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; }
/** * 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); } } 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; } public boolean sendMessageAtTime(Message msg, long uptimeMillis) { boolean sent = false; MessageQueue queue = mQueue; if (queue != null) { msg.target = this; sent = queue.enqueueMessage(msg, uptimeMillis); } else { RuntimeException e = new RuntimeException( this + " sendMessageAtTime() called with no mQueue"); Log.w("Looper", e.getMessage(), e); } return sent; }
|
从源码分析可以看出:
handler在无参数的构造方法中调用Looper.myLooper()方法,里面就是从当前线程里面获取一个Looper对象,如果没有则创建.这样对Looper就进行初始化,初始化Looper的同时一并初始化MessageQueue,并且从中得到looper的MessageQueue .可以看出Handler就是Looper和MessageQueue的管理者和调度者.
其中最重要的是:sendMessageAtTime(Message msg, long uptimeMillis)这个方法,当你往Handler中发送Message消息的时候,从代码看出他自己并不去处理Message ,而是交给了MessageQueue.由以下从这段代码来处理:
queue.enqueueMessage(msg, uptimeMillis), 其具体实现要看下面的对
MessageQueue的分析
Looper结构关联的内容:
Looper 源码:
public class Looper { private static final boolean DEBUG = false; private static final boolean localLOGV = DEBUG ? Config.LOGD : Config.LOGV;
// sThreadLocal.get() will return null unless you've called prepare(). private static final ThreadLocal sThreadLocal = new ThreadLocal();
final MessageQueue mQueue; volatile boolean mRun; Thread mThread; private Printer mLogging = null; private static Looper mMainLooper = null;
public static final void prepare() { if (sThreadLocal.get() != null) { throw new RuntimeException("Only one Looper may be created per thread"); } sThreadLocal.set(new Looper()); } public static final void loop() { Looper me = myLooper(); MessageQueue queue = me.mQueue; while (true) { Message msg = queue.next(); // might block if (msg != null) { if (msg.target == null) { 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 封装的信息:
Looper实质上是对当前线程, ThreadLocal,MessageQueue的封装,也就是负责在多线程之间传递消息的一个循环器.
当你往Handler中添加消息的时候则,里面这个方法: public static final void loop()死循环的方法就会被系统调用,之后的功能代码是:
msg.target.dispatchMessage(msg),则从MessageQueue中得到一个
Message(msg),之后调用Handler的dispatchMessage(msg),这个方法内部实际调用的就是 Handler.handleMessage(msg)方法,这个就是我们在
activity要重写的方法,所以我们就能够得到其他子线程传递的Message了.
Message的源码分析:
public final class Message implements Parcelable { public int what; public int arg1; public int arg2; public Object obj; public Messenger replyTo; long when; Bundle data; Handler target; Runnable callback; Message next; private static Object mPoolSync = new Object(); private static Message mPool; private static int mPoolSize = 0; private static final int MAX_POOL_SIZE = 10;
|
When: 向Handler发送Message生成的时间
Data: 在Bundler 对象上绑定要线程中传递的数据
Next: 当前Message 对一下个Message 的引用
Handler: 处理当前Message 的Handler对象.
mPool: 通过字面理解可能叫他Message池,但是通过分析应该叫有下一个Message引用的Message链更加适合.
其中Message.obtain(),通过源码分析就是获取断掉Message链关系的第一个Message.
MessageQueue
public class MessageQueue { Message mMessages; private final ArrayList mIdleHandlers = new ArrayList(); private boolean mQuiting = false; boolean mQuitAllowed = true;
public static interface IdleHandler { boolean queueIdle(); }
public final void addIdleHandler(IdleHandler handler) { if (handler == null) { throw new NullPointerException("Can't add a null IdleHandler"); } synchronized (this) { mIdleHandlers.add(handler); } }
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; } |
mMessages: 为当前序列的第一个Message, 通过源码分析 MessageQueue并不是对许多Message 之间的关系维护,这样也许可以省去很多事把,而Message 之间的关系
则统统丢给了Message自己去维护,这个可以从对Message源码分析可以理解.
mIdleHandler: 保存的是一系列的handler的集合.
其中final boolean enqueueMessage(Message msg, long when),
这个方法就是上面提到Handler 处理消息时调用到的方法,对她理解了就显
的很重要了,功能代码如下:
msg.when = when; 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(); }
|
当向MessageQueue中添加消息的时候,判断当前的Message(mMessage)是否为空,
如果为空或者when=0或者when<p.when: 则把要添加的Message(msg)赋给当
前的Message(mMessage),并且将msg.next属性设为空,
如果不为空: 则循环把当前的Message(mMessage)的下一个Message(next)进行遍历,用prev记住当前的message,直到找到prev的下一个Message为空的时候就退出循环,最后将msg接到prev的屁股后面,
即这段代码: prev.next = msg;