Android Thread Looper MessageQueue HandlerTHread分析

Android Thread Looper MessageQueue HandlerTHread分析

Android Thread Looper MessageQueue 
1,看Android的代码的时候,Thread Looper Handler MessageQueue 傻傻分不清。

2,如何入手?以Looper为中心,Looper是Thread挂钩的Looper,Looper‘维护’着一个MessageQueue,分别进行着“消息队列”和“消息循环”。
Hander是一个辅助类,他是用来操作这个消息队列MessageQueue来加入、删掉消息Message等。
3,如何深入?画两个图,类图和关系图
4,参考:Innost 《深入理解Android第5章Looper部分》
1,先了解下状态图
2,类图
  
3,描述
3.1Android系统中,Looper负责管理线程的消息队列和消息循环。我们可以通过Loop.myLooper()得到当前线程的Looper对象,通过Loop.getMainLooper()可以获得当前进程的主线程的Looper对象。 
3.2一个线程可以存在(当然也可以不存在)一个消息队列和一个消息循环(Looper)。 
Activity是一个UI线程,运行于主线程中,Android系统在启动的时候会为Activity创建一个消息队列和消息循环(Looper)。 
3.3Handler的作用是把消息加入特定的(Looper)消息队列中,并分发和处理该消息队列中的消息。构造Handler的时候可以指定一个Looper对象,如果不指定则利用当前线程的Looper创建。
4,代码示例解读
  1. public class MainActivity extends AppCompatActivity {
  2. @Override
  3. protected void onCreate(Bundle savedInstanceState) {
  4. super.onCreate(savedInstanceState);
  5. setContentView(R.layout.activity_main);
  6. new Thread(new Runnable() {
  7. @Override
  8. public void run() {
  9. Looper.prepare();//4.1,创建一个Looper
  10. final Handler handler = new Handler() { //Handler只是工具类,封装了Message的投递(sendMessage)处理(handleMessage)的接口
  11. @Override
  12. public void handleMessage(Message msg) {
  13. super.handleMessage(msg);
  14. Log.v("handlerdemo", "" + msg.what);
  15. }
  16. };
  17. new Thread(new Runnable() {
  18. @Override
  19. public void run() {
  20. Message msg = Message.obtain();
  21. msg.what = 9;
  22. handler.sendMessage(msg);
  23. }
  24. }).start();
  25. Looper.loop();//4.2,Looper开始工作,进入for(; ;)循环处理
  26. }
  27. }).start();
  28. }
  29. }
4.1,一个线程(Thread)通过Looper.prepare()来new一个Looper,new Looper的同时,会new 一个MessageQueue
  1. private static void prepare(boolean quitAllowed) {
  2. ...
  3. sThreadLocal.set(new Looper(quitAllowed));
  4. }
  5. ...
  6. private Looper(boolean quitAllowed) {
  7. mQueue = new MessageQueue(quitAllowed);
  8. mThread = Thread.currentThread(); //得到当前线程
  9. }
4.2,Looper.loop()来处理Handler发到MessageQueue里面的Message
  1. public static void loop() {
  2. final Looper me = myLooper(); //即prepare()创建的Looper
  3. final MessageQueue queue = me.mQueue;//prepare()创建的MessageQueue
  4. for (;;) {
  5. Message msg = queue.next(); // might block
  6. ...
  7. msg.target.dispatchMessage(msg); //读出MessageQueue中的Message,即将由Message的target成员去处理消息,target也是一个Handler,此Handler即为发送这个消息的Handler
  8. ...
  9. msg.recycleUnchecked();
  10. }
  11. }
在msg.target.dispatchMessage(msg);中的target就是发送这个Message的Handler,跟handler.sendmesager()方法可以看到,msg.target = this;验证此说法。
4.3,Handler可以看作一个工具类(辅助类),与Looper(/MessageQueue)绑定,来简化消息的添加和处理
来看Handler的使用,Handler是在线程a中new Handler()来构造。由代码可以,Handler必须绑定Looper(Looper和MessageQueue是成以出现)来存在。
  1.   public Handler() { this(null, false); }
  2. -》
  3. public Handler(Callback callback, boolean async) {
  4. ...
  5. mLooper = Looper.myLooper(); //就是Looper.prepare()实例化的。
  6. if (mLooper == null) {
  7. throw new RuntimeException(
  8. "Can't create handler inside thread that has not called Looper.prepare()");
  9. }
  10. mQueue = mLooper.mQueue;//即为Looper的MessageQueue
  11. mCallback = callback;//null
  12. mAsynchronous = async;//false
  13. }
发送消息:handler.sendMessager(Msg),是往MessageQueue队列中添加消息
  1. return enqueueMessage(queue, msg, uptimeMillis);
接收消息:handler.handleMessager(),具体实现是由子类实现的
  1. /**
  2. * Subclasses must implement this to receive messages.
  3. */
  4. public void handleMessage(Message msg) {
  5. }
5,HandlerThread类是一个继承自Thread的类,他的设计是为了防止两个线程通讯中myLooper()可能为空的情况。
  1. public Looper getLooper() {
  2. ...
  3. synchronized (this) {
  4. while (isAlive() && mLooper == null) {
  5. try {
  6. wait(); //如果当前线程的mLooper还未创建,就阻塞等待
  7. } catch (InterruptedException e) {
  8. }
  9. }
  10. }
  11. return mLooper;
  12. }
  1. public void run() {
  2. Looper.prepare();
  3. synchronized (this) {
  4. mLooper = Looper.myLooper();
  5. notifyAll(); //mLooper创建完成之后,通知阻塞在些Thread上的请求
  6. }
  7. ...
  8. }
6,总结:
5.1,Looper不是一个Thread,因为没有extends Thread,也没有实现Runnable接口。但Looper在构造的时候,与当前Thread绑定在一起。
sThreadLocal.set(new Looper(quitAllowed));
5.2,一个线程(UITHread除外),一但通过Looper.prepare()构造Looper,那么也就是构造了一个MessagerQueue,同时,在哪个线程构造Handler,这个Handler就绑定在这个Looper上。
5.3,两个线程的消息传递是通过一个共同的Handler实例化handler来操作的,拿到了这个Hander,意味着拿到要与之通信的Looper和MessageQueue,就能准确地把消息给到相关Thread。
7,与Android Broadcast机制的联系
TOBE
TOP