1. 一个线程里面只有一个Looper。
2. 子线程也可创建handler。
前后需分别加上Looper.prepare();和Looper.loop();
标准写法:
Looper.prepare();
Handler mHandler = new Handler() {
@Override
publicvoidhandleMessage(Message msg) {
if (msg.what == 10000) {
Log.i(TAG,"在子线程中定义Handler,并接收到消息。。。");
}
}};
Looper.loop();
在prepare 中创建looper。
3. 主线程对应的方法在ActivityThread的main方法中。
4. Looper的构造方法中初始化了一个MessageQueue对象
privateLooper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}
总:Looper.prepare()方法初始话了一个Looper对象并关联在一个MessageQueue对象,并且一个线程中只有一个Looper对象,只有一个MessageQueue对象。而Handler的构造方法则在Handler内部维护了当前线程的Looper对象
5. handler.sendMessage(msg) 会调用queue.enqueueMessage(msg, uptimeMillis);,会发现 MessageQueue并没有使用列表将所有的Message保存起来,而是使用Message.next保存下一个Message,从而按照时间将所有的Message排序;
6. Looper.loop()
可以看到Looper.loop()方法里起了一个死循环,不断的判断MessageQueue中的消息是否为空,如果为空则直接return掉,然后执行queue.next()方法
可以看到其大概的实现逻辑就是Message的出栈操作,里面可能对线程,并发控制做了一些限制等。获取到栈顶的Message对象之后开始执行:
msg.target.dispatchMessage(msg);
Handle的dispatchMessage()
/**
* Handle system messages here. */
publicvoiddispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
}else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
可以看到,如果我们设置了callback(Runnable对象)的话,则会直接调用handleCallback方法:
privatestaticvoidhandleCallback(Message message) {
message.callback.run();
}
msg.callback为空的话,会直接调用我们的mCallback.handleMessage(msg),即handler的handlerMessage方法。由于Handler对象是在主线程中创建的,所以handler的handlerMessage方法的执行也会在主线程中
原作者的总结:
1)主线程中定义Handler,直接执行:
Handler mHandler =new Handler() {
@Override
publicvoidhandleMessage(Message msg) {
super.handleMessage(msg);
}};
而如果想要在子线程中定义Handler,则标准的写法为:
// 初始化该线程Looper,MessageQueue,执行且只能执行一次
Looper.prepare();
// 初始化Handler对象,内部关联Looper对象
Handler mHandler =new Handler() {
@Override
publicvoidhandleMessage(Message msg) {
super.handleMessage(msg);
}
};
// 启动消息队列出栈死循环
Looper.loop();
2)一个线程中只存在一个Looper对象,只存在一个MessageQueue对象,可以存在N个Handler对象,Handler对象内部关联了本线程中唯一的Looper对象,Looper对象内部关联着唯一的一个MessageQueue对象。
3)MessageQueue消息队列不是通过列表保存消息(Message)列表的,而是通过Message对象的next属性关联下一个Message从而实现列表的功能,同时所有的消息都是按时间排序的。
4)android中两个子线程相互交互同样可以通过Handler的异步消息机制实现,可以在线程a中定义Handler对象,而在线程b中获取handler的引用并调用sendMessage方法。
5)activity内部默认存在一个handler的成员变量,android中一些其他的异步消息机制的实现方法:
Handler的post方法:
mHandler.post(new Runnable() {
@Override
publicvoidrun() {
}
});
查看其内部实现:
publicfinalbooleanpost(Runnable r) {
return sendMessageDelayed(getPostMessage(r), 0);
}
可以发现其内部调用就是sendMessage系列方法。。。
view的post方法:
publicbooleanpost(Runnable action) {
final AttachInfo attachInfo = mAttachInfo;
if (attachInfo != null) {
return attachInfo.mHandler.post(action);
}
// Assume that post will succeed later
ViewRootImpl.getRunQueue().post(action);
returntrue;
}
可以发现其调用的就是activity中默认保存的handler对象的post方法。
activity的runOnUiThread方法:
publicfinalvoidrunOnUiThread(Runnable action) {
if (Thread.currentThread() != mUiThread) {
mHandler.post(action);
}else {
action.run();
}
}
判断当前线程是否是UI线程,如果不是,则调用handler的post方法,否则直接执行run方法。
http://blog.csdn.net/qq_23547831/article/details/50751687