背景需求

在Android中,当遇到子线程需要刷新UI时,最常的做法就是handler,当然还有其他方便的方法如Android给我们提供的runOnUiThread(runnable)方法,但归根结底都是使用handler来刷新UI的。

Android消息传递原理

简单的讲:handler发送(post或send)一条消息;MessageQueue(队,实际上是一个用单链表实现的队列)接受并存储该消息;looper无限循环的从MessageQueue中取出一条消息,例如msg,然后调用msg.target.dispatchMessage(msg)方法对msg进行处理。其中msg.target为发送该msg的handler。

源码解读

Handler

Handler在Android消息传递过程中,主要负责发送消息和处理事件。

当handler发送一条消息时,无论是使用handler.postXX()还是使用handler.sendXXX()最终调用的都是:

 public boolean sendMessageAtTime(Message msg, long uptimeMillis) {        MessageQueue queue = mQueue;        if (queue == null) {            RuntimeException e = new RuntimeException(                    this + " sendMessageAtTime() called with no mQueue");            Log.w("Looper", e.getMessage(), e);            return false;        }        return enqueueMessage(queue, msg, uptimeMillis);    }

其中enqueueMessage()方法是执行单链表在队尾的插入操作,该方法主要完成的是想messagequeue中插入一条消息。

dispatchMessage(Message msg)方法:

 public void dispatchMessage(Message msg) {        if (msg.callback != null) {            handleCallback(msg);        } else {            if (mCallback != null) {                if (mCallback.handleMessage(msg)) {                    return;                }            }            handleMessage(msg);        }    }

在looper.loop()方法中,调用该方法对消息msg进行处理。

几点说明:

  1. msg.callback中的callback实际上是handler.post(runable r)中的r。handleCallback代码:
private static void handleCallback(Message message) {        message.callback.run();    }

从这可以看出,handleCallback实际操作是调用r.run()方法,即调用post过来的线程的run方法执行该线程的逻辑。

 2. mCallback :当我们创建一个handler对象时,handler有一个构造方法: 
public Handler(Callback callback){        this(callback, false);    }

其中Callback是一个接口,即:

public interface Callback {        public boolean handleMessage(Message msg);    }

mCallback.handleMessage(msg)实际调用的就是构造handler时传入的callback对象的handlermessage方法。
3. 最后调用的 handleMessage(msg)方法实际上是我们自己构造一个handler时 @Override 的handleMessage(Message msg)方法。

需要特别指明的是:

handler.post(runnable r)实际执行在handler所在的线程中。
官方说明为:
*Causes the Runnable r to be added to the message queue.
* The runnable will be run on the thread to which this handler is
* attached. *

在view中也有类似的post(runnable r)方法,但该方法执行在UI线程中。
官方说明为:
Causes the Runnable to be added to the message queue.The runnable will be run on the user interface thread.

Looper

在一个线程中,只有一个Looper对象。Looper在实现上使用的是单例模式。

Looper.prepare()代码:

private static void prepare(boolean quitAllowed) {        if (sThreadLocal.get() != null) {            throw new RuntimeException("Only one Looper may be created per thread");        }        sThreadLocal.set(new Looper(quitAllowed));    }

new Looper(quitAllowed)代码:

private Looper(boolean quitAllowed) {        mQueue = new MessageQueue(quitAllowed);        mThread = Thread.currentThread();//当前looper所在线程    }

在这里可以看出,looper的构造方法是私有的,表明当前Looper使用的是单例模式,只有在myLooper()方法中才返回,代码 :return sThreadLocal.get()

总结

Handler:发送和处理message
Looper:为一个线程创建以messagequeue,使得在该线程中可以使用Handler。

更多相关文章

  1. Android Native 绘图方法
  2. Android源码解析Handler系列第(三)篇---深入了解Android的消息机制
  3. Android Handle,Looper,Message消息机制
  4. 《Android开发艺术探索》第十章Android的消息机制+第十一章Andro
  5. 《Android Dev Guide》系列教程5:Android进程和线程
  6. Android 消息处理机制(Looper、Handler、MessageQueue,Message)
  7. Android 消息机制

随机推荐

  1. Android(安卓)中进程、Activity、Boradca
  2. 【专家专栏】Android中的防缓冲区溢出技
  3. Android(安卓)动态设置TextView的drawabl
  4. 如何修改Android5.1系统音量大小
  5. Android中 Lottie库初步实践与应用场景分
  6. Android之——使用Android(安卓)studio创
  7. 这是一篇描述 Broadcasts 的文章
  8. Android(安卓)Application Digital Signa
  9. Android(安卓)SpannableString 设置文字
  10. ArraySet 添加和删除元素分析