1.关于Message,MessageQueue,Handler和Looper的关系:Looper不断的从MessageQueue中取出消息,交给Handler去处理,looper和线程绑定
来看一下这几个类的源码
参考Message 源码,其主要成员变量如下:
public final class Message implements Parcelable { public int what;
public int arg1;
public int arg2;
public Object obj;
public Messenger replyTo;
public int sendingUid = -1;
private static final Object sPoolSync = new Object();
private static Message sPool;
private static int sPoolSize = 0;
private static final int MAX_POOL_SIZE = 50;
private static boolean gCheckRecycle = true;
.......
}
这些成员变量中what用来保存消息标识,arg1和arg2是用来存放整型数据的,obj存储人员类型变量,replyTo是消息管理器,会关联到一个handler。通常使用Message.obtain获取message,避免创建多余对象节约内存,从源码看sPool为null时会自动new Message出来。
MessageQueue
public final class MessageQueue {
// True if the message queue can be quit.
private final boolean mQuitAllowed;
MessageQueue(boolean quitAllowed) {
mQuitAllowed = quitAllowed;
//构造方法,调用了native方法
mPtr = nativeInit();
}
//队列操作
boolean enqueueMessage(Message msg, long when) //入队
Message next() //出队
void removeMessages(Handler h, Runnable r, Object object) //根据Runable删除队列元素
void removeMessages(Handler h, int what, Object object) //根据Message.what删除队列元素
private void dispose() //销毁队列
.....
}
Handler的构造函数如下:
public Handler()
public Handler(Callbackcallback)
public Handler(Looperlooper)
public Handler(Looperlooper, Callbackcallback)
其主要成员变量如下
public class Handler {
final MessageQueue mQueue;
final Looper mLooper;
final Callback mCallback;
final boolean mAsynchronous;
IMessenger mMessenger;
......
}
第1个和第2个构造函数都没有传递Looper,这两个构造函数都将通过调用Looper.myLooper()获取当前线程绑定的Looper对象,然后将该Looper对象保存到名为mLooper的成员字段中。
第3个和第4个构造函数传递了Looper对象,这两个构造函数会将该Looper保存到名为mLooper的成员字段中。
第2个和第4个构造函数还传递了Callback对象,Callback是Handler中的内部接口,需要实现其内部的handleMessage方法,其中Callback接口如下,该接口处理Message消息。因此处理Message消息有重写Handler的handleMessage方法或者在初始化Handler的时候传入一个Handler.CallBack接口,源码中优先判断Handler.CallBack是否为空
public interface Callback {
/**
* @param msg A {@link android.os.Message Message} object
* @return True if no further handling is desired
*/
public boolean handleMessage(Message msg);
}
把Message消息放入队列的方法如下:
public final boolean post(Runnable r)
public final boolean postDelayed(Runnable r, long delayMillis)
public final boolean sendMessage(Message msg)
public final boolean sendEmptyMessage(int what)
Looper
public final class Looper {
static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
private static Looper sMainLooper; // guarded by Looper.class
final MessageQueue mQueue;
final Thread mThread;
......
}
注释中给出了looper的典型用法:
* <pre>
* 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();
* }
* }</pre>
*/
看一下Looper.prepare()和Looper.loop()具体做了什么
public static void prepare() {
prepare(true);
}
private static void prepare(boolean quitAllowed) {
//通过sThreadLocal.get()判断保证一个Thread只能有一个Looper实例
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
//new一个looper来初始化looper
sThreadLocal.set(new Looper(quitAllowed));
}
private Looper(boolean quitAllowed) {
//在looper的构造函数中创建MessageQueue
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}
再来看一下Handler是如何跟looper关联的:Handler中就持有一个Looper,Looper类提供myLooper()方法提供looper
//Looper中的myLooper()
public static @Nullable Looper myLooper() {
return sThreadLocal.get();
}
//Handler构造函数
public Handler(Callback callback, boolean async) {
......
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;
}
//Looper类同时提供了获取UI线程looper的方法 getMainLooper()
/**
* Returns the application's main looper, which lives in the main thread of the application.
*/
public static Looper getMainLooper() {
synchronized (Looper.class) {
return sMainLooper;
}
}
Looper.loop()创建处理消息的环境,循环处理消息。
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);
if (logging != null) {
logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
}
// Make sure that during the course of dispatching the
// identity of the thread wasn't corrupted.
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.recycleUnchecked();
}
}
进入for循环后,开始从MessageQueue中取出一个消息(可能会阻塞),如果当前消息队列中没有Message,线程退出;否则分发消息。msg.target.dispatchMessage(msg)中的target就是一个Handler。最后消息处理完毕,进行回收。
为何主线程不需要调用Looper.looper和Looper.prepare
普通线程只要prepare就可以了,而主线程使用的是prepareMainLooper;普通线程生成一个与Looper绑定的Handler对象就行,而主线程是从当前线程中获取Handler(thread.getHandler())
我们看一下ActivityThread(UI线程)的源码,ActivityThread在应用程序启动的时候由系统创建出来
public static void main(String[] args) {
......
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
//主线程获取Handler
sMainThreadHandler = thread.getHandler();
}
......
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
//初始化主线程的looper
public static void prepareMainLooper() {
prepare(false);
synchronized (Looper.class) {
if (sMainLooper != null) {
throw new IllegalStateException("The main Looper has already been prepared.");
}
sMainLooper = myLooper();
}
}
//给主线程提供looper
public static Looper getMainLooper() {
synchronized (Looper.class) {
return sMainLooper;
}
}
对于主线程,thread.getHandler()返回的就是mH
如上,一个thread通过sThreadLocal.get来保证只有一个looper,主线程在ActivityThread创建了一个Handler(mH),子线程通过Looper.myLooper获取looper。每个looper只对应一个MessageQueue,每个Message最多指定一个Handler来处理.Thread和Handle是一对多的关系.