接着《Android消息机制之一简介(1)》和《Android消息机制之二简介(2)》,我们现在来单独看看Handler源码。

设计代码的路径:

base\core\java\android\os\Handler.java

Handler的简单使用

在项目中,Handler的声明和初始化一般如下,使用默认的构造函数,当然Handler中也带参数的构造函数。

  1. // 使用默认构造函数
  2. private Handler mHandler = new Handler();
  3. // 使用默认构造函数,并重写handleMessage方法
  4. private Handler myHandler = new Handler() {
  5. public void handleMessage(android.os.Message msg) {
  6. };
  7. };
复制

Handler的构造函数

下面是Handler.java所有的构造函数(好多个呢)。

Handler类在构造方法中,可指定Looper,Callback回调方法以及消息的处理方式(同步或异步),对于无参的handler,默认是当前线程的Looper。

在初始化时就会把当前线程的Looper和MessageQueue赋值到Handler中的对应变量中。然而Looper和MessageQueue的初始化是在Looper.prepare()中进行的。

同时在Handler初始化时有提示“If this thread does not have a looper, this handler won’t be able to receive messages”,因此必须要有一个Looper.loop()进行循环查询消息队列。又因为loop()中是一个死循环,除非异常或者自动退出,才会执行loop后面代码,所以Handler的使用和初始化必须在Looper.loop()之前。(好像扯远了^_^)

继续看代码

  1. /**
  2. * Default constructor associates this handler with the {@link Looper} for the
  3. * current thread.
  4. *
  5. * If this thread does not have a looper, this handler won't be able to receive messages
  6. * so an exception is thrown.
  7. */
  8. public Handler() {
  9. this(null, false);
  10. }
  11. public Handler(Callback callback) {
  12. this(callback, false);
  13. }
  14. public Handler(Looper looper) {
  15. this(looper, null, false);
  16. }
  17. public Handler(Looper looper, Callback callback) {
  18. this(looper, callback, false);
  19. }
  20. public Handler(boolean async) {
  21. this(null, async);
  22. }
  23. public Handler(Callback callback, boolean async) {
  24. //匿名类、内部类或本地类都必须申明为static,否则会警告可能出现内存泄露
  25. if (FIND_POTENTIAL_LEAKS) {
  26. final Class<? extends Handler> klass = getClass();
  27. if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
  28. (klass.getModifiers() & Modifier.STATIC) == 0) {
  29. Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
  30. klass.getCanonicalName());
  31. }
  32. }
  33. //获取当前线程的Looper,所以在Handler使用前Looper.prepare()
  34. mLooper = Looper.myLooper();
  35. if (mLooper == null) {
  36. throw new RuntimeException(
  37. "Can't create handler inside thread that has not called Looper.prepare()");
  38. }
  39. //获取初始化中初始化的消息队列
  40. mQueue = mLooper.mQueue;
  41. mCallback = callback;
  42. mAsynchronous = async;
  43. }
  44. public Handler(Looper looper, Callback callback, boolean async) {
  45. mLooper = looper;
  46. mQueue = looper.mQueue;
  47. mCallback = callback;
  48. mAsynchronous = async;
  49. }
复制

Handler的消息发送

直接看图,Handler可以发送的参数类型有what,Runnable,message,然后一步一步进行封装成message,最终发送的是message的

Android消息机制之三Handler分析
1、发送what

在项目中,发送what时是使用sendEmptyMessage、sendEmptyMessageDelayed, sendEmptyMessageAtTime的,其实这三个的作用差不多,就是延迟时间不同,其他的都是进一步把what封装

  1. //delayMillis延迟时间为0
  2. public final boolean sendEmptyMessage(int what)
  3. {
  4. return sendEmptyMessageDelayed(what, 0);
  5. }
  6. //delayMillis延迟时间,如果为0,和上面sendEmptyMessage的方法一样
  7. public final boolean sendEmptyMessageDelayed(int what, long delayMillis) {
  8. Message msg = Message.obtain();
  9. msg.what = what;
  10. return sendMessageDelayed(msg, delayMillis);
  11. }
  12. //uptimeMillis 是当前系统时间+延迟的时间(SystemClock.uptimeMillis() + delayMillis)
  13. public final boolean sendEmptyMessageAtTime(int what, long uptimeMillis) {
  14. Message msg = Message.obtain();
  15. msg.what = what;
  16. return sendMessageAtTime(msg, uptimeMillis);
  17. }
复制

2、发送Message

我们会发现sendMessage()调用sendMessageDelayed()再调用sendMessageAtTime(),再调用enqueueMessage(),最终调用消息队列的enqueueMessage(),也就把message发送到MessageQueue中了。

  1. public final boolean sendMessage(Message msg)
  2. {
  3. return sendMessageDelayed(msg, 0);
  4. }
  5. public final boolean sendMessageDelayed(Message msg, long delayMillis)
  6. {
  7. if (delayMillis < 0) {
  8. delayMillis = 0;
  9. }
  10. return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
  11. }
  12. public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
  13. MessageQueue queue = mQueue;
  14. if (queue == null) {
  15. RuntimeException e = new RuntimeException(
  16. this + " sendMessageAtTime() called with no mQueue");
  17. Log.w("Looper", e.getMessage(), e);
  18. return false;
  19. }
  20. return enqueueMessage(queue, msg, uptimeMillis);
  21. }
  22. private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
  23. msg.target = this;
  24. if (mAsynchronous) {
  25. msg.setAsynchronous(true);
  26. }
  27. return queue.enqueueMessage(msg, uptimeMillis);
  28. }
复制

3、发送Runnable

  1. public final boolean post(Runnable r)
  2. {
  3. return sendMessageDelayed(getPostMessage(r), 0);
  4. }
  5. //uptimeMillis= 是当前系统时间+延迟的时间(SystemClock.uptimeMillis() + delayMillis)
  6. public final boolean postAtTime(Runnable r, Object token, long uptimeMillis)
  7. {
  8. return sendMessageAtTime(getPostMessage(r, token), uptimeMillis);
  9. }
  10. //delayMillis 延迟
  11. public final boolean postDelayed(Runnable r, long delayMillis)
  12. {
  13. return sendMessageDelayed(getPostMessage(r), delayMillis);
  14. }
复制

Handler.sendEmptyMessage()等一系列方法最终调用MessageQueue.enqueueMessage(msg, uptimeMillis),将消息添加到消息队列中,其中uptimeMillis为系统当前的运行时间,不包括休眠时间。

Handler的消息派发

Handler消息的分发是在Looper.loop()查询消息,然后调用msg.target.dispatchMessage(msg);进行派发,最终到了Handler中。

  1. /**
  2. * Callback interface you can use when instantiating a Handler to avoid
  3. * having to implement your own subclass of Handler.
  4. *
  5. * @param msg A {@link android.os.Message Message} object
  6. * @return True if no further handling is desired
  7. */
  8. public interface Callback {
  9. public boolean handleMessage(Message msg);
  10. }
  11. /**
  12. * Subclasses must implement this to receive messages. 子类必须实现此接口
  13. */
  14. public void handleMessage(Message msg) {
  15. }
  16. /**
  17. * Handle system messages here.
  18. */
  19. public void dispatchMessage(Message msg) {
  20. //如果msg中有callback,直接调用message.callback.run()
  21. if (msg.callback != null) {
  22. handleCallback(msg);
  23. } else {
  24. if (mCallback != null) {
  25. //如果有mCallback,就走这里
  26. if (mCallback.handleMessage(msg)) {
  27. return;
  28. }
  29. }
  30. //这个方法要我们实现,然后处理发送来的message
  31. handleMessage(msg);
  32. }
  33. }
复制

分发消息流程:

  1. 当Message的回调方法不为空时,则回调方法msg.callback.run(),其中callBack数据类型为Runnable,否则进入步骤2;
  2. 当Handler的mCallback成员变量不为空时,则回调方法mCallback.handleMessage(msg),否则进入步骤3;
  3. 调用Handler自身的回调方法handleMessage(),该方法默认为空,Handler子类通过覆写该方法来完成具体的逻辑。

其实Handler中还有很多比如移除Message,获取Message,查看是否有这条Message等等,其代码最终还是调用MessageQueue或者Message中的方法.

写了这么多,发现写得一般,算是个流水账似得.不过,自己写写总比只看不思考好多了,写的时候或许可以理理思路吧

写得不好,望见谅!

PS:本文部分内容和图片来自gityuan.com,谢谢

相关文章

暂无评论

none
暂无评论...