《Android Handler分析(一) Handler和Message详解》
《Android Handler分析 (二) MessageQueue详解》
《Android Handler分析 (三) Looper详解和Handler其他知识》
《Android 中的 HandlerThread 类详解》
在上一篇博客《Android Handler分析(一) Handler和Message分析》中我们说到了Android中Handler机制的两个重要类Message和Handler,在这篇博客中,我们继续来看一下另外的一个重要类,MessageQueue(消息队列)类。
MessageQueue源码分析:
1. MessageQueue中的一些成员变量
private final boolean mQuitAllowed; // MessageQueue是否可以退出,如果是主线程的就不能退出
private long mPtr; // used by native code,native方法中使用的,表示native代码中的MessageQueue地址
Message mMessages; // Message是一个链表结构,mMessages表示链表的第一个元素,也就是消息队列的队首
private final ArrayList<IdleHandler> mIdleHandlers = new ArrayList<IdleHandler>();// 用来保存IdleHandler对象的集合
private IdleHandler[] mPendingIdleHandlers;// 用来保存IdleHandler对象的数组,在后面会将集合中的对象复制到数组中
private boolean mQuitting; // 当前消息队列是否处于退出状态
private boolean mBlocked; // 表示在next()方法中是否被阻塞在超时时间非0的native pollOnce()方法上。
private int mNextBarrierToken; // 表示下一个Barrier(障碍物,屏障;界线)的标记(令牌)
2. 看一下IdleHandler接口
/**
* 这个接口是当next()方法没有获取到或者在等待可以执行的消息时,就可以执行这个接口的回调
*/
public static interface IdleHandler {
/**
* 回调方法,返回boolean类型的值,如果返回true表示不移除,返回false表示执行完之后就从集合中移除该对象
*/
boolean queueIdle();
}
// 增加一个IdleHandler接口实现类对象到mIdleHandlers集合中
public void addIdleHandler(@NonNull IdleHandler handler) {
if (handler == null) {
throw new NullPointerException("Can't add a null IdleHandler");
}
synchronized (this) {
mIdleHandlers.add(handler);
}
}
// 从mIdleHandlers集合中移除这个IdleHandler对象
public void removeIdleHandler(@NonNull IdleHandler handler) {
synchronized (this) {
mIdleHandlers.remove(handler);
}
}
下面是系统ActivityThread.java中的一个使用IdleHandler的例子
final GcIdler mGcIdler = new GcIdler();
// 创建内部类实现 IdleHandler 接口
final class GcIdler implements MessageQueue.IdleHandler {
@Override
public final boolean queueIdle() {
// 调用关于gc的方法,即当Handler没有消息可以执行时调用一下doGcIfNeeded()方法进行垃圾回收
doGcIfNeeded();
// 返回false,表示执行完之后就移除
return false;
}
}
void scheduleGcIdler() {
if (!mGcIdlerScheduled) {
mGcIdlerScheduled = true;
// 调用MessageQueue的addIdleHandler()方法将mGcIdler添加到集合
Looper.myQueue().addIdleHandler(mGcIdler);
}
mH.removeMessages(H.GC_WHEN_IDLE);
}
void unscheduleGcIdler() {
if (mGcIdlerScheduled) {
mGcIdlerScheduled = false;
// 从集合中移除mGcIdler对象
Looper.myQueue().removeIdleHandler(mGcIdler);
}
mH.removeMessages(H.GC_WHEN_IDLE);
}
在ActivityThread.java类中还有一些使用了这个接口,大家有兴趣可以去查看一下
3. MessageQueue对象的创建
// 构造方法,默认修饰符,开发者不能创建,是在创建Looper时系统创建的,并和Looper绑定在一起
// 参数quitAllowed 表示该消息队列是否可以退出,主线程的不可以退出,其他线程的可以