Handle的传递机制,Handle Looper MessageQueue的工作原理

因为只有主线程能修改UI组件,所以主线程又被称作UI线程;但是若只由主线程来修改UI的话,这样会导致新启动的线程无法动态改变UI的属性值或者是进行耗时操作,主线程会被阻塞(ANR异常,系统无法响应输入事件和BroadCast),而子线程又不能修改UI组件,只能在新进程里发出一通消息,这时就需要采用handle的传递机制;

Handle的作用有两个:在新启动的线程发送消息(一般采用sendEmptyMessage);在主线程接受,处理消息(重写handleMessage);

 

 

MessageQueue采用先进先出的方式管理消息,Looper会在其中构造一个Looper对象,MessageQueue是由Looper来管理的,初始化Looper时会创建一个与之相关联的MessageQueue,所以必须保证每个线程都有一个Looper;为了保证当前线程有一个Looper对象,分两种情况:

  1.新创建的线程就是在主线程中,这样就无需创建Looper对象,系统已经自动创建了;

2.新创建的线程是自创的子线程(Thread),这样就需要自己获取Looper对象并启动它;通过调用Looper的prepare()方法即可获取Looper对象,然后在调用Looper的静态方法loop()来启动它;

 

 

子线程创建Handler之前:保证调用了Looper.prepare创建Looper对象

 

 Handle的传递机制,Handle Looper MessageQueue的工作原理

 如果在子线程中不调用的话,就会报出   “无法在未调用Looper.prepare()的线程中创建handler”,创建handler之前一定要保证调用了prepare;

 Handle的传递机制,Handle Looper MessageQueue的工作原理

ThreadLocal是一个线程内部的数据存储(这里存放的就是Looper对象)类,通过它可以在指定的线程中存储数据,数据存储以后,只有在指定线程中可以获取到存储的数据,对于其它线程来说无法获取到数据 

Handle的传递机制,Handle Looper MessageQueue的工作原理

Handle的传递机制,Handle Looper MessageQueue的工作原理

 

MessageQueue构造:

Handle的传递机制,Handle Looper MessageQueue的工作原理

 

sendMessage()是handle把消息传给MessageQueue的一种方式,还有一种就是post方式;

 

第一种sendmessage()方法:

Handle的sendmessage()过程:

Handle的传递机制,Handle Looper MessageQueue的工作原理

 那Handle将message送到MessageQueue中,发生了什么?

Handle的传递机制,Handle Looper MessageQueue的工作原理

Handle的传递机制,Handle Looper MessageQueue的工作原理

那在MessageQueue中是如何处理Message的呢?

Handle的传递机制,Handle Looper MessageQueue的工作原理

 Handle的传递机制,Handle Looper MessageQueue的工作原理

Handle的传递机制,Handle Looper MessageQueue的工作原理

Handle的传递机制,Handle Looper MessageQueue的工作原理

第二种:

也要先构造Looper和MessageQueue;

post方法:

Handle的传递机制,Handle Looper MessageQueue的工作原理

 后面和sendmessage()方法是一样的;

 

 

一个常问问题:

Handle的传递机制,Handle Looper MessageQueue的工作原理

 

总结:

Handle的传递机制,Handle Looper MessageQueue的工作原理

Handle的传递机制,Handle Looper MessageQueue的工作原理

 

Message的复用过程:

https://www.jianshu.com/p/8ecacbb97af4