`
zzu_007
  • 浏览: 23769 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

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);
    }
分享到:
评论

相关推荐

    Android应用源码之HandlerMessage1_HandlerMessage.zip

    总结来说,`Android应用源码之HandlerMessage1_HandlerMessage.zip`中的内容可能展示了如何利用`Handler`、`Message`和`Looper`进行多线程间的通信,以确保UI线程的流畅运行。理解和掌握这一机制对于Android开发者来...

    Android应用源码之HandlerLooper2_Android.zip

    本压缩包"Android应用源码之HandlerLooper2_Android.zip"可能包含了关于这个主题的详细示例代码,让我们深入探讨这些关键组件的工作原理。 首先,`Handler`类是Android中处理消息和调度任务的核心组件。它允许...

    安卓Android源码——HandlerLooper2.rar

    这个压缩包“安卓Android源码——HandlerLooper2.rar”可能包含了关于这些组件的深入分析和示例代码。以下是关于`Handler`、`Looper`和`MessageQueue`的详细解释: 1. **Handler**: - `Handler`是Android中的一个...

    安卓Android源码——HandlerMessage3.rar

    这个压缩包"安卓Android源码——HandlerMessage3.rar"很可能包含了关于这三者如何协同工作的示例代码或者详细分析。现在,我们将深入探讨这些概念及其在Android系统中的作用。 `Handler` 是一个用于发送和处理消息...

    安卓Android源码——HandlerMessage2.rar

    本资源"安卓Android源码——HandlerMessage2.rar"可能包含了关于`Handler`和`Message`的深入实践和示例代码,下面我们将详细探讨这些核心组件。 `Handler` 是 Android 中用于在线程间传递消息的对象。它通常用于将...

    Android应用源码之HandlerMessage3.zip项目安卓应用源码下载

    Android应用源码之HandlerMessage3.zip项目安卓应用源码下载Android应用源码之HandlerMessage3.zip项目安卓应用源码下载 1.适合学生毕业设计研究参考 2.适合个人学习研究参考 3.适合公司开发项目技术参考

    Android应用源码之HandlerMessage2.zip项目安卓应用源码下载

    Android应用源码之HandlerMessage2.zip项目安卓应用源码下载Android应用源码之HandlerMessage2.zip项目安卓应用源码下载 1.适合学生毕业设计研究参考 2.适合个人学习研究参考 3.适合公司开发项目技术参考

    Android应用源码之HandlerMessage1.zip项目安卓应用源码下载

    Android应用源码之HandlerMessage1.zip项目安卓应用源码下载Android应用源码之HandlerMessage1.zip项目安卓应用源码下载 1.适合学生毕业设计研究参考 2.适合个人学习研究参考 3.适合公司开发项目技术参考

    Android应用源码之HandlerLooper2.zip项目安卓应用源码下载

    Android应用源码之HandlerLooper2.zip项目安卓应用源码下载Android应用源码之HandlerLooper2.zip项目安卓应用源码下载 1.适合学生毕业设计研究参考 2.适合个人学习研究参考 3.适合公司开发项目技术参考

    Android应用源码之HandlerLooper1.zip项目安卓应用源码下载

    Android应用源码之HandlerLooper1.zip项目安卓应用源码下载Android应用源码之HandlerLooper1.zip项目安卓应用源码下载 1.适合学生毕业设计研究参考 2.适合个人学习研究参考 3.适合公司开发项目技术参考

    Android应用源码之HandlerMessage3_Android.zip

    这个压缩包“Android应用源码之HandlerMessage3_Android.zip”显然包含了一个示例,演示了如何在Android应用中有效地使用这些组件。 首先,我们来深入理解Handler。Handler是Android中处理消息和异步任务的类,它...

    Android应用源码之HandlerMessage3.zip

    这个"Android应用源码之HandlerMessage3.zip"压缩包很可能是包含了一个示例项目,详细展示了HandlerMessage的用法。现在我们来深入探讨一下Handler、Message以及它们在Android中的作用。 **1. Handler(处理器)** ...

    Android应用源码之HandlerLooper1_Android.zip

    这个压缩包“Android应用源码之HandlerLooper1_Android.zip”可能包含了一个示例项目,详细展示了如何在Android应用程序中使用这些组件。 首先,我们来深入理解`Handler`。`Handler`是Android中的一个关键类,主要...

    Android应用源码之HandlerMessage2_应用.zip

    本压缩包"Android应用源码之HandlerMessage2_应用.zip"包含了关于如何在Android应用中使用Handler和Message来处理异步任务和更新UI的示例源代码。下面我们将深入探讨这两个核心组件以及它们在Android中的工作原理。 ...

    Android应用源码之HandlerLooper2.zip

    `Android应用源码之HandlerLooper2.zip`可能包含了一个示例项目,用于演示如何有效使用这些组件。以下是对这些核心概念的详细说明: 1. **Handler**: `Handler` 是一个用于在特定线程(通常是UI线程)中发送和...

    Android应用源码之HandlerLooper1.zip

    本资料“Android应用源码之HandlerLooper1.zip”应该是包含了一个关于这些组件的详细示例或分析,让我们来深入探讨它们的工作原理。 首先,`Handler`是Android中的一个类,它用于在UI线程中发送和处理消息。当你...

    安卓Android源码——HandlerLooper1.rar

    在Android系统中,`Handler`、`Looper`和`MessageQueue`是三个核心组件,它们共同构成了Android消息处理机制,使得应用程序能够实现线程间的通信和异步任务执行。这个`HandlerLooper1.rar`文件可能包含了对这些概念...

    Android应用源码之HandlerMessage1.zip

    【Android应用源码之HandlerMessage1.zip】是一个与Android应用程序开发相关的压缩包,重点在于讲解Handler和Message在Android系统中的使用。在这个项目中,我们可能会看到一个简单的Android应用实例,该实例展示了...

    android handler 机制 源码

    在这里,我们将深入探讨Android Handler机制的源码,了解其工作原理。 首先,`Handler`类是处理消息的核心组件。它通过`post()`或`sendMessage()`方法接收并分发Message对象。当创建一个Handler实例时,通常会与...

    android mars视频代码 Handler 源码 ProgressBarHandler

    www.mars-droid.com/Android开发视频教程 代码 源码 mars老师讲课 android 视频源码 Handler ProgressBarHandler(在此特别感谢mars的无私奉献,此代码为跟随视频边学边做的)

Global site tag (gtag.js) - Google Analytics