Android-初识Handler,Looper,Message(-) 源码
Android-初识Handler,Looper,Message(-) 源码
本文只是表面的带大家浏览下Handler,Looper,Message的源码
Android的消息处理有三个核心类:Looper,Handler和Message。其实还有一个Message Queue(消息队列),
异步处理大师 Handler:
什么是handler?handler扮演了往MQ上添加消息和处理消息的角色(只处理由自己发出的消息),即通知MQ它要执行一个任务(sendMessage),并在loop到自己的时候执行该任务(handleMessage),整个过程是异步的。handler创建时会关联一个looper,默认的构造方法将关联当前线程的looper,不过这也是可以set的。默认的构造方法:
- public class handler {
- final MessageQueue mQueue; // 关联的MQ
- final Looper mLooper; // 关联的looper
- final Callback mCallback;
- // 其他属性
- public Handler() {
- if (FIND_POTENTIAL_LEAKS) { // 没看懂,直接略过,,,
- final Class<? extends Handler> klass = getClass();
- if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
- (klass.getModifiers() & Modifier.STATIC) == 0) {
- Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
- klass.getCanonicalName());
- }
- }
- // 默认将关联当前线程的looper
- mLooper = Looper.myLooper();
- // looper不能为空,即该默认的构造方法只能在looper线程中使用
- //UI主线程中默认带有一个Looper
- if (mLooper == null) {
- throw new RuntimeException(//不能在没有Looper的线程上创建Handler,
- "Can't create handler inside thread that has not called Looper.prepare()");
- }
- // 重要!!!直接把关联looper的MQ作为自己的MQ,因此它的消息将发送到关联looper的MQ上
- mQueue = mLooper.mQueue;
- mCallback = null;
- }
- // 其他方法
- }
当然这只是Handler的一个构造方法。Handler本身有四个构造函数,其他其他的三个你可以通过查看源码来解析,大致雷同。
Handler发送消息
有了handler之后,我们就可以使用 post(Runnabl),sendMessage(Message)
这些方法向MQ上发送消息了。光看这些API你可能会觉得handler能发两种消息,一种是Runnable对象,一种是message对象,这是直观的理解,但其实post发出的Runnable对象最后都被封装成message对象了,见源码:
Post发送的形式
- public final boolean post(Runnable r){//使用Post发送消息
- return sendMessageDelayed(getPostMessage(r), 0);
- }
- private final Message getPostMessage(Runnable r) {//把一个Runnable包转成一个Message
- Message m = Message.obtain();
- m.callback = r;
- return m;
- }
- public final boolean sendMessageDelayed(Message msg, long delayMillis){
- if (delayMillis < 0) {
- delayMillis = 0;
- }
- return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
- }
- <pre class="java" name="code"><pre class="java" name="code">public boolean sendMessageAtTime(Message msg, long uptimeMillis){
- boolean sent = false;
- MessageQueue queue = mQueue;
- if (queue != null) {
- /*该handler对象,这确保了looper执行到该message时能找到处理它的handler,直白点就是ABC三个Handler发送消息,最终执行的时候Message消息
- 也是由他们本身来执行,而不会发生A接受到B发送的Message之类的情况*/
- msg.target = this;//
- sent = queue.enqueueMessage(msg, uptimeMillis);//压入消息队列
- }else {
- RuntimeException e = new RuntimeException(
- this + " sendMessageAtTime() called with no mQueue");
- Log.w("Looper", e.getMessage(), e);
- }
- return sent;
sendMessage(Message)形式
- public final boolean sendMessage(Message msg){
- return sendMessageDelayed(msg, 0);
- }
- public final boolean sendMessageDelayed(Message msg, long delayMillis){
- if (delayMillis < 0) {
- delayMillis = 0;
- }
- return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
- }
从源码中我们中我们可以很清晰的看到无论是用psot(Runnable)还是使用sendMessage(Message)方法,最后他们都会调用到同一个方法压入都一个队列中去。
|
评论暂时关闭