Android源码之Handler(三)

public Handler(Looper looper, Callback callback, boolean async) {
mLooper = looper;
mQueue = looper.mQueue;
[// mQueue = looper.mQueue
这里可以看出,Handler类的MessageQueue成员变量mQueue其实就是Looper内部的MessageQueue变量。
]// mQueue = looper.mQueue
mCallback = callback;
mAsynchronous = async;
}
[// public Handler(Looper looper, Callback callback, boolean async)
这个重载版本的构造函数的实现就是初始化Handler的几个成员变量。这几个成员变量的定义如下:
final MessageQueue mQueue;
    final Looper mLooper;
    final Callback mCallback;
[// final Callback mCallback
mCallback是Handler的Callback. 其实Message中会有一个Runnable类型的成员变量callback,这里为什么又要给Handler来定义一个Callback的成员变量呢?
Callback接口定义在Handler内部:
public interface Callback {
                public boolean handleMessage(Message msg);
               }
]// final Callback mCallback
    final boolean mAsynchronous;
    [// final boolean mAsynchronous
    mAsynchronous表示Hanlder是否是异步的?在我们的认识中,Handler就是按照顺序来处理消息的, 这难道不是Handler的作用么?难道还可以异步的处理消息么?
    ]// final boolean mAsynchronous
由此可见,每一个Handler内部维护了一个Looper,而每一个Looper中又维护了一个MessageQueue.
这里我们就来看一下Looper的实现:

]// public Handler(Looper looper, Callback callback, boolean async)
Handler的一系列的构造函数中,其实最重要的就是两个:Handler(Callback callback, boolean async)和Handler(Looper looper, Callback callback, boolean async).
]// Handler的构造函数

当通过Handler构造函数得到了Handler对象之后, 会调用obtainMessage来得到一个Message对象. Android推介使用Handler的obtainMessage函数来得到一个Message对象,而不是直接构造一个Message对象, 为什么呢?
同样Handler类也提供了一系列的obtainMessage函数, 我们看一看obtainMessage函数的实现:
[// obtainMessage函数
public final Message obtainMessage()
       {
      return Message.obtain(this);
      }
      public final Message obtainMessage(int what)
     {
       return Message.obtain(this, what);
      }
    public final Message obtainMessage(int what, Object obj)
        {
            return Message.obtain(this, what, obj);
        }
    public final Message obtainMessage(int what, int arg1, int arg2)
        {
            return Message.obtain(this, what, arg1, arg2);
        }
    public final Message obtainMessage(int what, int arg1, int arg2, Object obj)
        {
            return Message.obtain(this, what, arg1, arg2, obj);
        }
        从以上代码也可以看出, Handler的obtainMessage函数其实是调用Message的obtain函数来实现的. 我们看一下Message类的obtain函数的实现:
        [// Message类的obtain函数
public static Message obtain(Handler h) {
                    Message m = obtain();
                    m.target = h;

                    return m;
            }
            public static Message obtain(Handler h, Runnable callback) {
                    Message m = obtain();
                    m.target = h;
                    m.callback = callback;

                    return m;
           }
           public static Message obtain(Handler h, int what) {
                    Message m = obtain();
                    m.target = h;
                    m.what = what;

                    return m;
           }
           public static Message obtain(Handler h, int what, Object obj) {
                    Message m = obtain();
                    m.target = h;
                    m.what = what;
                    m.obj = obj;

                    return m;
        }
        public static Message obtain(Handler h, int what, int arg1, int arg2) {
                    Message m = obtain();
                    m.target = h;
                    m.what = what;
                    m.arg1 = arg1;
                    m.arg2 = arg2;

                    return m;
           }
           public static Message obtain(Handler h, int what,
                        int arg1, int arg2, Object obj) {
                    Message m = obtain();
                    m.target = h;
                    m.what = what;
                    m.arg1 = arg1;
                    m.arg2 = arg2;
                    m.obj = obj;

                    return m;
           }

           Message类同样提供了一系列的obtain的重载函数, 不过大同小异, 都是先调用obtain()函数得到一个Message对象,然后初始化这个Message对象,并返回该Message对象。
           我们分析一下Message类的obtain函数的实现:
           public static Message obtain() {
            synchronized (sPoolSync) {
               if (sPool != null) {
                    Message m = sPool;
                      sPool = m.next;
                     m.next = null;
                      m.flags = 0; // clear in-use flag
                      sPoolSize--;
                   return m;
                  }
              }
              [// synchronized (sPoolSync)
              上面这段代码就是从缓存中取Message。
              其中定义了几个成员变量,分别为:
              private static final Object sPoolSync = new Object();
                   private static Message sPool;
                   private static int sPoolSize = 0;
                 这些变量的作用都很明确. 注意:这些成员变量都是statics的。
              ]// synchronized (sPoolSync)
              return new Message();
        }
        [// public static Message obtain()
        Message的obtain函数的作用得到一个Message变量. 其实Android为Handler维护了一个Message的缓存, 调用obtain函数会首先尝试从缓存中取Message对象,而不是每次就构造一个Message对象。
        这就是为什么推荐使用obtain函数来得到一个Message对象的原因。
        我们简单来看一下Message的几个重要的成员变量:
        public int what;
        what成员变量是为了区分不同的Message.
                    public int arg1;
                    public int arg2;
                    public Object obj;
                    public Messenger replyTo;
                    public int sendingUid = -1;
                    /*package*/ static final int FLAG_IN_USE = 1 << 0;
                    /*package*/ static final int FLAG_ASYNCHRONOUS = 1 << 1;
                    /*package*/ static final int FLAGS_TO_CLEAR_ON_COPY_FROM = FLAG_IN_USE;

                    /*package*/ int flags;

                    /*package*/ long when;
when指示该消息需要被处理的时间戳
                    /*package*/ Bundle data;

                    /*package*/ Handler target;
                    target是最重要的成员变量. Android系统就是通过target找到这个Message所属于的Handler对象,然会调用这个Handler对象的handleMessage函数来处理该消息的
                    /*package*/ Runnable callback;
                    /*package*/ Message next;
                    private static final Object sPoolSync = new Object();
                    private static Message sPool;
                    private static int sPoolSize = 0;
                    private static final int MAX_POOL_SIZE = 50;
                    private static boolean gCheckRecycle = true;
        ]// public static Message obtain()
       ]// Message类的obtain函数
]// obtainMessage函数
经过上面的源码分析,我们可以明白Handler, Looper, MessageQueue和Message个关系了,也理解了这四者是如何配合从而完成Handler机制的。
下面我们分析一下发消息的过程,这主要是通过调用Handler的sendMessage和post函数完成的. Handler提供了一系列的send和post函数:
public final boolean post(Runnable r)
  {
    return  sendMessageDelayed(getPostMessage(r), 0);
    [// sendMessageDelayed(getPostMessage(r), 0)
    private static Message getPostMessage(Runnable r) {
                Message m = Message.obtain();
                m.callback = r;
                return m;
            }
    ]// sendMessageDelayed(getPostMessage(r), 0)
   }
public final boolean postAtTime(Runnable r, long uptimeMillis)
   {
    return sendMessageAtTime(getPostMessage(r), uptimeMillis);
   }
public final boolean postAtTime(Runnable r, Object token, long uptimeMillis)
    {
        return sendMessageAtTime(getPostMessage(r, token), uptimeMillis);
        [// return sendMessageAtTime(getPostMessage(r, token), uptimeMillis)
        private static Message getPostMessage(Runnable r, Object token) {
                Message m = Message.obtain();
                m.obj = token;
                m.callback = r;
                return m;
            }
        ]// return sendMessageAtTime(getPostMessage(r, token), uptimeMillis)
    }
public final boolean postDelayed(Runnable r, long delayMillis)
    {
        return sendMessageDelayed(getPostMessage(r), delayMillis);
    }
    public final boolean postAtFrontOfQueue(Runnable r)
{
            return sendMessageAtFrontOfQueue(getPostMessage(r));
  }
public final boolean sendEmptyMessage(int what)
    {
        return sendEmptyMessageDelayed(what, 0);
    }
    public final boolean sendEmptyMessageDelayed(int what, long delayMillis) {
        Message msg = Message.obtain();
        msg.what = what;
        return sendMessageDelayed(msg, delayMillis);
    }
    public final boolean sendEmptyMessageAtTime(int what, long uptimeMillis) {
        Message msg = Message.obtain();
        msg.what = what;
        return sendMessageAtTime(msg, uptimeMillis);
    }
    public final boolean sendMessageDelayed(Message msg, long delayMillis)
    {
        if (delayMillis < 0) {
            delayMillis = 0;
        }
        return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
    }
    public final boolean sendMessageAtFrontOfQueue(Message msg) {
        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, 0);
    }
    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);
    }
    上面这么多的函数(post用于发送Runnable, send用于发送Message),其实都是很相似的。大致过程都成先得到一个Message, 然后调用enqueueMessage函数插入到消息队列中。
    我们分析一下enqueueMessage函数的实现:
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
        msg.target = this;
        if (mAsynchronous) {
            msg.setAsynchronous(true);
        }
        return queue.enqueueMessage(msg, uptimeMillis);
        [// return queue.enqueueMessage(msg, uptimeMillis);
        这里会调用MessageQueue的enqueueMessage函数来将Message插入到队列中,MessageQueue的enqueueMessage函数的实现如下:
        boolean enqueueMessage(Message msg, long when) {
                if (msg.target == null) {
                    throw new IllegalArgumentException("Message must have a target.");
                }
                if (msg.isInUse()) {
                    throw new IllegalStateException(msg + " This message is already in use.");
                }

                synchronized (this) {
                    if (mQuitting) {
                        IllegalStateException e = new IllegalStateException(
                                msg.target + " sending message to a Handler on a dead thread");
                        Log.w("MessageQueue", e.getMessage(), e);
                        msg.recycle();
                        return false;
                    }

                    msg.markInUse();
                    [// msg.markInUse()
                将消息标记为正在使用
                    void markInUse() {
                            flags |= FLAG_IN_USE;
                        }
                    ]// msg.markInUse()
                    msg.when = when;
                    Message p = mMessages;
                    boolean needWake;
                    if (p == null || when == 0 || when < p.when) {
                    [// if (p == null || when == 0 || when < p.when)
                    将消息插入到头部,这时候要唤醒Looper
                    ]// if (p == null || when == 0 || when < p.when)
                        msg.next = p;
                        mMessages = msg;
                        needWake = mBlocked;
                    } else {
                    [// else
                    将消息插入到队列的中间
                    ]// else
                        needWake = mBlocked && p.target == null && msg.isAsynchronous();
                        Message prev;
                        for (;;) {
                            prev = p;
                            p = p.next;
                            if (p == null || when < p.when) {
                                break;
                            }
                            if (needWake && p.isAsynchronous()) {
                                needWake = false;
                            }
                        }
                        msg.next = p; // invariant: p == prev.next
                        prev.next = msg;
                    }

                    // We can assume mPtr != 0 because mQuitting is false.
                    if (needWake) {
                        nativeWake(mPtr);
                        [// nativeWake(mPtr)
                        这里调用nativeWake函数来唤醒Looper, 这也是个native函数,实际上调用的是android_os_MessageQueue.cpp中定义的android_os_MessageQueue_nativeWake函数。
                        android_os_MessageQueue_nativeWake的定义如下:
                        static void android_os_MessageQueue_nativeWake(JNIEnv* env, jclass clazz, jlong ptr) {
                                NativeMessageQueue* nativeMessageQueue = reinterpret_cast<NativeMessageQueue*>(ptr);
                                return nativeMessageQueue->wake();
                               [// return nativeMessageQueue->wake()
                               这里调用的是NativeMessageQueue的wake函数.
                               void NativeMessageQueue::wake() {
                                        mLooper->wake();
                                        [// mLooper->wake()
                                        这里又调用了C++层的wake函数,
                                        void Looper::wake() {
                                            #if DEBUG_POLL_AND_WAKE
                                                ALOGD("%p ~ wake", this);
                                            #endif

                                                ssize_t nWrite;
                                                do {
                                                    nWrite = write(mWakeWritePipeFd, "W", 1);
                                                } while (nWrite == -1 && errno == EINTR);

                                                if (nWrite != 1) {
                                                    if (errno != EAGAIN) {
                                                        ALOGW("Could not write wake signal, errno=%d", errno);
                                                    }
                                                }
                                            }
                                            可以看到C++层的wake函数就是用mWakeWritePipeFd向管道里发送一个"w"字符,这样就会将epoll_wait函数来唤醒。
                                        ]// mLooper->wake()
                                    }
                               ]// return nativeMessageQueue->wake()
                            }
                        ]// nativeWake(mPtr)
                    }
                }
                return true;
            }
        ]// return queue.enqueueMessage(msg, uptimeMillis);
    }

猜你喜欢

转载自zzu-007.iteye.com/blog/2261550
今日推荐