Message implements Parcelable
public int what;//defined message code
public int arg1;
public int arg2;
public Object obj;
/*package*/ Handler target; 相关的外部调用方法 sendToTarget(){target.sendMessage(this);} 还有get/set方法
/*package*/ Bundle data; 相关的外部调用方法 Bundle peekData(); setData(Bundle data);
/*package*/ Runnable callback; 相关的外部调用方法 Runnable getCallback();
/*package*/ Message next;
private static Message sPool;
静态sPool,链表结构:每个对象都有一个next指针
一些重载的obtain():如果池中有对象,从sPool中取一个,并将当前指针指向下一个;如没有,则new Message();
obtain()中必须传一个Handler对象,赋给target
简单的说就是 存放、获取Message的管理类
类本身的构造函数也是 package的访问权限,即外部不能new 一个它的实例对象
/*package*/ Message mMessages; //存储Message
主要方法:
enqueueMessage(Message, long);
新消息加入到mMessages的链尾
Message next();
取出链尾的最新消息,并改变指针指向
removeMessages()、removeCallbacksAndMessages(); 都要传入一个handler对象
消息循环
主要属性与构造方法源码:
static final ThreadLocal sThreadLocal = new ThreadLocal();
private static Looper sMainLooper; // guarded by Looper.class
final MessageQueue mQueue;
final Thread mThread;
private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread(); //关联当前调用者线程
}
主要方法:
private static void prepare();
加锁判断sMainLooper是否设置值:有,抛出异常;无,则 sThreadLocal.set(new Looper(…))
说明该方法仅能执行一次
public static void prepare();
调用私有prepare();
public static void prepareMainLooper();//ui线程,即main线程 使用
调用私有prepare();
加锁判断sMainLooper是否设置值:有,抛出异常;无,则 sMainLooper = myLooper();
public static Looper getMainLooper()
加锁,返回 sMainLooper
public static @Nullable Looper myLooper()
返回 sThreadLocal.get()
public static void loop()
在Looper所属的线程,开启消息循环。
通过myLooper(),拿到Looper对象,再获取它的MessageQueue对象。
启动一个无线循环:queue.next(),获取Message对象,再调用msg.target.dispatchMessage(msg);
即最后,调用Handler对象的dispatchMessage()
一般的使用方式,如下,
UI主线程使用:
prepareMainLooper();静态sMainLooper被赋值,mThread=主线程
子线程使用:
prepare();由于sThreadLocal是一个线程局部变量,即使声明为static,在子线程中也是一个新的对象,可以由它set/get一个new Looper();这时sMainLooper还是主线程赋值的Looper对象,myLooper()才是子线程的Looper对象,mThread=子线程
统一处理前面所有消息相关元素。
主构造方法 :
public Handler(Looper looper, Callback callback, boolean async);
public Handler(Callback callback, boolean async);
这两个构造方法是@hide的,其它构造方法基于这两个方法。
关于Looper对象,没有手动指定时,默认直接从Looper.myLooper()获取;
那就需要在初始化Handler之前,就初始化一个Looper;
Android系统帮我们初始了主线程的Looper,在源码ActivityThread的入口main()中。
Callback定义:
public interface Callback {
public boolean handleMessage(Message msg);
}
async 表示是异步还是同步的处理消息,true为异步
一些操作Message的方法,如obtainMessage()系列、getPostMessage()系列、sendMessage()系列、removeMessages()系列;
一些操作Message#callback的方法,如post()系列、removeCallbacks()系列;
Looper getLooper();
public void handlerMessage(Message);
可以由子类重写,默认空实现
public void dispatchMessage(Message);
该方法是处理消息的总入口,一般不需要手动重写
判断msg的callback是否为空,不为空时执行msg.callback.run();
为空,再判断当前Handler对象的Callback实例属性,是否为空,不为空时执行mCallback.handleMessage(msg);
还为空,执行this.handlerMessage(msg);
由此看出这些元素执行的判断优先级:msg.callback > mCallback.handlerMessage() > this.handlerMessage()
Handler通常我们用的new Handler()默认,是处理同步消息的。如果要处理的是异步消息,需谨慎
HandlerThread extends Thread
主要的方法源码 {
protected void onLooperPrepared() { }
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}
public boolean quit() {//关闭消息循环
Looper looper = getLooper();
if (looper != null) {
looper.quit();
return true;
}
return false;
}
public boolean quitSafely() {//安全的关闭消息循环
Looper looper = getLooper();
if (looper != null) {
looper.quitSafely();
return true;
}
return false;
}
public Looper getLooper() { ... }
}
这是一个Thread的子类;run()中,初始了Looper,并开启了消息循环;还提供了关闭消息循环的方法。
使用场景:如果要在子线程中使用Handler传递消息,可以继HandlerThread。通过getLooper获取Looper,并传递给Handler对象。
如果要在开启消息循环即Looper.loop()之前,处理某些事,可以重写onLooperPrepared(),比如初始化一个Handler:
protected void onLooperPrepared() {
mHandler = new Handler() {
public void handleMessage(Message msg) {
}
};
}