handler message looper机制(二)
在handler message looper一文中,我们已经大概了解了这三者之间的关系。本篇文章在此基础上详细介绍Looper循环的流程以及post()和sendMessage()之间的区别。
目录
Looper循环之loop()方法
我们知道,对于线程的Looper,需要严格执行prepare()–>looper()流程。
对于主线程,线程执行之初,Looper就已经自己生成了一个Looper。我们可以在ActivityThread.java中的main方法中找到
Looper.prepareMainLooper();
...
Looper.loop();
里面所执行的代码就是
//Initialize the current thread as a looper
public static void prepareMainLooper(){
prepare(false);
synchronized(Looper.class){
if(mMainLooper != null)
...
sMainLooper = myLooper();
}
}
在Looper.java的loop()中就会去不断地读取消息队列。
对于非主线程,就需要我们自己手动地创造looper以及执行loop()方法
//子线程的Handler,Looper
Looper.prepare();
handler.sendMessage();
Looper.loop();
post()以及sendMessage()系列方法的区别
从代码中我们可以看到,两者最终都会调用到sendMessageAtTime(Message msg ,long time);
两者的区别在于,在post方法中,有一个Runnable对象r,而这个对象r就是消息message.callback属性,这在后面的loop中将会用作判断条件。
public final boolean post(Runnble r){
return sendMessageDelayed(getPostMessage(r),0);
}
private static Message getPostMessage(Runnable r){
Message m = Massage.obtain();
m.callback = r;
return m;
}
在loop()中,所有消息最后都会被dispatchMessage(Mesage msg)方法来处理
public void dispatchMesasage(Message msg){
if(msg.callback != null){//post方法发出的消息 第一种情况
handleCallbck(msg);
}else{ //sendMessage发出的消息 第二种情况
if(mCallback != null){
if(mCallback.handeMessage(msg)){
return;
}
}
handleMessage(msg);//我们熟悉的回调方法
}
}
其中,第二种情况又分为两种,mCallback是否为0。mCallback是在Hander构建的时候赋值的。
public Handler(Callback callback,boolean async){
...
mCallback = callback;
mAsynchronous = async;
...
}
public Handler(){
Hander(null,false);
}
明白了吧。我们平时用的无参的构造函数默认没有回调。所以直接走handleMessage。否则走mCallback.handeMessage(msg)。
而对于post发送的message,会走handleCallbck()流程
private static void handleCallback(Message message){
message.callback.run();//这里就会执行最开始我们post(Runnable r)中r的任务。
}
未完待续。。。