- 首先看一下代码
1. Looper.prepare();//这个如果在主线程中则不需要声明的!
2. mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
//处理即将到来msg
}
};
3. Looper.loop();//这个如果在主线程中则也不需要声明的!
4. 但是如果是在子线程中new Handler();则上面那2个都需要声明,顺序也要明确,因为loop()后面的代码是执行不到的,想要执行需要调用handler对象的getLooper().quit(),loop()才会中止,后面的代码才能执行。
首先查看下Looper.prepare()方法:
- 第一件事:生成一个Looper对象,并生成一个对应的MessageQueue对象;
- 第 二 件 事:存入到本地线程中;
//调用重载带参数方法
public static void prepare() {
prepare(true);
}
//如果sThreadLocal.get()为null,则将本地线程的set中生成一个Looper对象;不为null则异常
rivate static void prepare(boolean quitAllowed) {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper(quitAllowed));
}
//这里new Looper(quitAllowed)中生成MessageQueue对象,和对应的线程
private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}
- mHandler = new Handler(){ … .. ..}方法:
- 将存入本地线程变量 来讲Looper和Handler建立起来
----------
//这个是Looper的静态方法,通过 sThreadLocal.get()方法得到前面set()方法中的Looper对象 下面也需要用到
public static @Nullable Looper myLooper() { return sThreadLocal.get(); }
----------
public class Handler {
//这个方法是将存入本地线程的Looper对象取出来,这样就两者就建立的联系
mLooper = Looper.myLooper();
//将Looper对象中的消息队列取出并赋值到Handler对象中的消息队列
mQueue = mLooper.mQueue;
- Looper.loop()方法:
//这是Looper的静态方法;
public static void loop() {
//得到自己Looper的对象
final Looper me = myLooper();
//取出消息队列
final MessageQueue queue = me.mQueue;
//在这循环中不停的去取消息!
for (;;) {
Message msg = queue.next(); // might block 如果没有消息,则可能阻塞
if (msg == null) {
return;
}
msg.target.dispatchMessage(msg);
// msg.target 等于 handler 对象
// 所以是handler.dispatchMessage(msg);
}
//下面就是handler.dispatchMessage(msg)的方法:
public void dispatchMessage(Message msg) {
//这里会调用该方法!!!
//所以继承Handler的类中需要重写handleMessage(msg)方法
handleMessage(msg);
}
- 说明一下为什么会用Message msg = mHandler.obtainMessage()方法
- 主要就是为了节省内存吧…
//Handler的方法中:
public final Message obtainMessage()
{
return Message.obtain(this);
}
//Message的静态方法:主要就是返回一个Message对象!
public static Message obtain(Handler h) {
Message m = obtain();
m.target = h;
return m;
}
//该方法主要意思就是查看消息池中有无消息:有--取出! 无--new出来
public static Message obtain() {
synchronized (sPoolSync) {
if (sPool != null) {
Message m = sPool;
sPool = m.next;
m.next = null;
m.flags = 0; // clear in-use flag
sPoolSize--;
return m;
}
}
return new Message();
}
- 总结
- 一个Handler对象对应一个Looper对象;
- 一个Looper对象对应一个MessageQueue对象;
- 使用Handler生成Message对象;
- 所生成的Message对象的target属性就是该Handler对象
有什么错误的地方大力敲出来,新手总结的不是很到位…