本文结合其他两个文章对Android系统中的这三个东西做一个整理归纳,让人更好理解、记忆。
第一篇文章: Android 异步消息处理机制 让你深入理解 Looper、Handler、Message三者关系 作者:鸿洋_
讲的很明白,思路清晰,让人马上形成三者的作用的一个直观的认识,也不长,应该先看这一篇。
第二篇文章:Android异步消息处理机制完全解析,带你从源码的角度彻底理解 作者:guolin
第二篇文章在第一篇文章的基础上,引入了更多一些的源码,和稍多一些的思考。不过内容较多,有第一篇文章的基础后再看第二篇,即能重复加深记忆也能对第二篇文章的理解有促进作用。
下面是我的总结:
一句话总结:
Looper的prepare()构造了消息队列,loop()实现了经典的消息循环机制(loop()会使线程进入一个无限循环);Handler出生时,通过Looper::myloop()函数与Looper构造的消息队列发生联系,用于外部投送消息;Message则是那个投送的具体事物,Message也可以是一个Runnable对象,用于Handler的post()方法投送。
下面是一些零散的总结,包含一些自己的思考和疑问,有一些也是十分浅显的知识:
1. Looper的prepare方法重新构造了一个新的Looper对象(在新对象中会创建一个消息队列),并把新创建的Looper对象配置给了这个Looper的sThreadLocal变量。
2. 在new Looper对象时,主要是创建了消息队列。
3. 取得上面新建的Looper对象以及里面的消息队列,使用无限循环来处理里面的消息:
for(;;;) {
Message msg = queue.next();
msg.target.dispatchMessage(msg); // msg.target就是Handler对象。
msg.recycle();
}
Looper.loop()会让当前线程进入无限循环,每次回调Handler的dispatchMessage方法,在dispatchMessage中会区分直接回调回调方法还是handleMessage方法。
4. 在Handler的构造函数里面,与Looper::loop()类似,同样通过myLooper()获得当前线程的Loop中的新建的Loop对象,也就是第一步中完成新建消息队列的那个Looper对象,同时保存了该消息队列的对象。
5.在发送消息的时候,实质上调用的是queue.enqueueMessage(),在该函数中会对msg.target赋值为此Handler对象。如此,就完成了Handler和Looper::loop()中新建的Looper对象中的MessageQueue对象的联系。
6.在调用Handler的dispatchMessage方法时,会回调handleCallback或者handleMessage,分别对应sendMessage发送消息还是通过post(Runnabble())发送请求,post最终也是调用sendMessageDelayed(getPostMessage(runable), 0).
7.在Activity中,启动时系统帮助调用了Looper.prepare()和Looper.loop()方法。具体位置是在ActivityThread的main()方法中。
8.在未调用Loop.prepare()的线程中new Handler会出错。一个常见的现象是可以再Activity中new Handler对象,但不能直接在线程中创建Handler对象。
9.Handler总是依附于创建时所在的线程,在UI线程(主线程)创建Handler,在子线程中用Handler发送消息。
10.Loop.loop()使线程进入无限循环,在ActivityThread的main()函数的Loop.loop()之后,有一行throw new RuntimeException("Main thread loop unexpectedly exited");