本文可以和另外一篇文章结合起来看,Android消息机制之——Handler Looper源码分析

在Handler源码开篇,惯例地,有关该类的说明。强烈建议阅读理解10遍+,比任何解说的文章都好用。这里只摘出重要的部分:

     * A Handler allows you to send and process Message and Runnable     * objects associated with a thread's MessageQueue.  Each Handler     * instance is associated with a single thread and that thread's message     * queue.  When you create a new Handler, it is bound to the thread /     * message queue of the thread that is creating it -- from that point on,     * it will deliver messages and runnables to that message queue and execute     * them as they come out of the message queue.

1、Handler通过和一个线程的MessageQueue(俗称消息队列)关联,来进行Message、Runnable的发送和处理;

2、每个Handler实例对应唯一的一个线程以及这个线程对应的MessageQueue;依据Handler实例被创建方式的不同,Handler和创建它一个线程或者一个线程的MessageQueue进行绑定;

3、Handler将消息发送到它绑定的MessageQueue; 同时接收从MessageQueue中派发的消息并进行处理。

这里体现出了Handler的主要作用,即将消息切换到绑定的MessageQueue所在的线程里执行,而不管消息是从哪个线程发送过来的。

一、Handler创建方式:

根据是否指定Looper,分为两种:
(1)我们通常使用的方法,直接new Handler的形式;比如,在某个线程中:

class MyThread extends Thread {    public Handler mHandler;    public void run() {        Looper.prepare(); //当前线程绑定一个MessageQueue        mHandler = new Handler() {            public void handleMessage(Message msg) {                // process incoming messages here            }        };        Looper.loop();    }}

我们知道,Looper.prepare() 是为当前线程绑定一个Looper实例及MessageQueue,在new Handler时,用的就是当前线程的Looper实例和MessageQueue;

Looper的相关细节,可以参见另一篇文章,Android消息机制之——Handler Looper源码分析

调用的构造函数:

public Handler() {    this(null, false);}public Handler(Callback callback, boolean async) {    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());        }    }    mLooper = Looper.myLooper();    if (mLooper == null) {        throw new RuntimeException(            "Can't create handler inside thread that has not called Looper.prepare()");    }    mQueue = mLooper.mQueue;    mCallback = callback;    mAsynchronous = async;}

这里面比较核心的两句:
mLooper = Looper.myLooper(); //和当前线程的Looper实例相关联;mQueue = mLooper.mQueue; //和当前线程的Looper实例的MessageQueue相关联。

同时我们发现,构造函数里面是可以指定callback的,这个callback会在处理消息时,也就是dispatch函数里面用到。

而我们通常的做法,在一个Activity的onCreate()函数里面new Handler(),绑定的是主线程的Looper实例和MessageQueue。具体代码可看ActivityThread源代码。

(2) 指定Looper,这是Handler不太常用的,比较特殊的构造方法,通过这种方法,Handler将和指定的Looper以及Looper的MessageQueue进行绑定;

public Handler(Looper looper, Callback callback, boolean async) {    mLooper = looper;    mQueue = looper.mQueue;    mCallback = callback;    mAsynchronous = async;}

二、Handler两大作用:发送消息 处理消息

发送消息的方法有:
post Runnable方式: post, postAtTime(Runnable, long), postDelayed;
send Message方式: sendEmptyMessage, sendMessage, sendMessageAtTime, sendMessageDelayed;

Runnable对象最终也是被包装成Message对象发送到Handler所绑定的MessageQueue中去:

Runnable 会被包装成设有callback的Message对象:

private static Message getPostMessage(Runnable r) {    Message m = Message.obtain();    m.callback = r;    return m;}

最终发送消息的方法:

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);}

将消息插入到消息队列中去,并且将消息的target设为本Handler实例(this):

private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {    msg.target = this;    if (mAsynchronous) {        msg.setAsynchronous(true);    }    return queue.enqueueMessage(msg, uptimeMillis);}

我们知道,Handler绑定了一个Looper实例,loop方法会不停地从MessageQueue.next()中看是否有消息,如果有消息,就去调用msg.target.dispatchMessage()进行处理,也就是message对应的Handler实例的dispatchMessage()方法进行处理:

public void dispatchMessage(Message msg) {    if (msg.callback != null) {        handleCallback(msg);  // post一个Runnable,Runnable设有callback    } else {        if (mCallback != null) {            if (mCallback.handleMessage(msg)) {  //构造函数传入callback                return;            }        }        handleMessage(msg); // 重写Handler的handleMessage()方法    }}

三、推荐使用obtainMessage方法去获得一个消息对象

我们一般会这样创建一个Message:

    Message msg = new Message();    msg.what = xxx;    msg.arg1 = xxx;    msg.arg2 = xxx;    handler.sendMessage(msg);

然而查看源码会发现, obtainMessage方法是获取一个Message对象效率更高的方式:

/*** Returns a new {@link android.os.Message Message} from the global  message pool. More efficient than* creating and allocating new instances. The retrieved message has its handler set to this instance (Message.target == this).* If you don't want that facility, just call Message.obtain() instead.*/

使用obtainMessage()方法,是从全局的MessagePool中去拿一个Message, 而不是重新创建一个,省去了创建对象申请内存的开销。

因此应尽量使用:

Message msg = handler.obtainMessage();

而不要使用:

Message msg = new Message();

参考:
任玉刚 Android开发艺术探索
http://blog.csdn.net/singwhatiwanna/article/details/48350919

更多相关文章

  1. Android(安卓)ApiDemo学习(三)activity(3)
  2. Android使用Rotate3dAnimation实现3D旋转动画效果的实例代码
  3. Android(安卓)AsyncTask 浅析(源代码取自 API level 23)
  4. Android(安卓)Handler机制5--消息发送
  5. Android(安卓)碎碎记
  6. Android(安卓)异步加载图片-AsyncTask
  7. android 4.0 USB Camera实例(二)应用层
  8. Android(安卓)UI源码解析
  9. android ANR相关问题

随机推荐

  1. Android手机开发 控件 TextView文字居中
  2. Android屏幕保持常亮的三种方法
  3. Android(安卓)招聘
  4. Android 常用对话框Dialog封装
  5. 【ImageView】图片自适应及android:scale
  6. Android传感器的运用之ACCELEROMETER
  7. Androidの自定义对话框AlertDialog(一)
  8. Android快速生成MVP 模式代码
  9. Android(安卓)Drawable Resource学习(二)、
  10. Android : android 9.0 audio 接口分析