看到Handler中的消息处理函数:

  1. public void dispatchMessage(Message msg){...}

这个函数是在Looper的执行消息循环loop()的时候取出Message然后执行:

  1. msg.target.dispatchMessage(msg);

时,msg对象的target就是这个Handler对象,即执行了Handler的dispatchMessage()函数:

函数定义如下:

  1. /**
  2. * Handle system messages here.
  3. */
  4. public void dispatchMessage(Message msg) {
  5. if (msg.callback != null) {
  6. handleCallback(msg);
  7. } else {
  8. if (mCallback != null) {
  9. if (mCallback.handleMessage(msg)) {
  10. return;
  11. }
  12. }
  13. handleMessage(msg);
  14. }
  15. }

从这个函数中可以看到,执行顺序逻辑是这样的:

1.如果Message对象有CallBack回调的话,就只执行这个回调,然后就结束了。

可见如果要使用Message的CallBack的话,就别在用其他的东西了。其实是个Runnable对象。

例如我们可以这样构建Message的CallBack:

  1. Message msgCallback = Message.obtain(myHandler, new Runnable() {
  2. @Override
  3. public void run() {
  4. Log.d(TAG, "msgCallback Runnable run() tid : " + Thread.currentThread().getId());
  5. }
  6. });

2.else分支下,如果Handler的CallBack对象不为空,那么就执行它的handleMessage()函数。

如果这个函数return true,那么就直接推出了,不会执行下面了。如果return false的话,就继续执行3.

例如我们可以这样来构建一个Handler的CallBack对象:

  1. private Handler.Callback callback = new Handler.Callback() {
  2. @Override
  3. public boolean handleMessage(Message msg) {
  4. Log.d(TAG, "Handler.Callback handleMessage msg : " + msg.what);
  5. Log.d(TAG, "Handler.Callback handleMessage tid : " + Thread.currentThread().getId());
  6. return false;
  7. //            return true;
  8. }
  9. };

3.这才调用到了Handler的handleMessage()函数,也就是我们经常要在子类覆写的这个函数,从中我们可以做消息的处理。

附件中是我的测试Demo,也同时解惑了我的一个疑问,那就是Runnable对象到Handler中执行的时候,是不是另启动了新的线程呢?答案是否定的,这个Runnable对象只是被调用了它的run()方法,就像是一个普通的方法被调用了一样,根本就没有start一个线程,所以这个run()方法也是在Handler所在的线程中被执行的。

这个是handleCallback函数:

  1. private static void handleCallback(Message message) {
  2. message.callback.run();
  3. }

可以看到,只是调用了message对象的Runnable对象的run()函数。

当然,还得分析Handler的post(Runnable r)方法的Runnable对象最终是怎么被执行的,才能彻底解决我的疑问。

这个是Handler的post方法:

  1. public final boolean post(Runnable r)
  2. {
  3. );
  4. }

看到把Runnable对象r传到getPostMessage中了。

Handler中的getPostMessage方法:

  1. private static Message getPostMessage(Runnable r) {
  2. Message m = Message.obtain();
  3. m.callback = r;
  4. return m;
  5. }

可以看到,原来是这样啊。使用了Runnable对象r从Message中obtain()分配出一个Message对象出来,然后调用的是sendMessageDelayed来发送消息。

这就对了,我们自己post的Runnable对象,也不过是放到了Message的Runnable对象中了,也就是Message对象的CallBack了。他有优先执行的权利,事实上,我们如果通过post一个Runnable的话,也没办法修改更多的Message对象的参数信息了,所以只执行到这个Runnable也是合理的。

但是我却几乎没使用过Handler的callback对象,看来这个东西还是可以做优先级的消息过滤的,如果return true的话,就不去继续执行了。这个以后还是要研究研究具体怎么应用场景的啦。

Android Handler消息处理顺序分析的更多相关文章

  1. Android Handler 消息处理使用

    本文内容 环境 演示 Handler 消息处理 参考资料 Handler 有两个主要作用或者说是步骤:发送消息和处理消息.在新启动的线程中发送消息,在主线程中获取.并处理消息.Android 平台只允 ...

  2. Android handler 内存泄露分析及解决方法

    1. 什么是内存泄露? Java使用有向图机制,通过GC自动检查内存中的对象(什么时候检查由虚拟机决定),如果GC发现一个或一组对象为不可到达状态,则将该对象从内存中回收.也就是说,一个对象不被任何引 ...

  3. 转 Android的消息处理机制(图+源码分析)——Looper,Handler,Message

    作为一个大三的预备程序员,我学习android的一大乐趣是可以通过源码学习google大牛们的设计思想.android源码中包含了大量的设计模式,除此以外,android sdk还精心为我们设计了各种 ...

  4. 【转】android的消息处理机制(图+源码分析)——Looper,Handler,Message

    原文地址:http://www.cnblogs.com/codingmyworld/archive/2011/09/12/2174255.html#!comments 作为一个大三的预备程序员,我学习 ...

  5. android的消息处理机制(图+源码分析)——Looper,Handler,Message

    android源码中包含了大量的设计模式,除此以外,android sdk还精心为我们设计了各种helper类,对于和我一样渴望水平得到进阶的人来说,都太值得一读了.这不,前几天为了了解android ...

  6. android的消息处理机制(图文+源码分析)—Looper/Handler/Message[转]

    from:http://www.jb51.net/article/33514.htm 作为一个大三的预备程序员,我学习android的一大乐趣是可以通过源码学习google大牛们的设计思想.andro ...

  7. Android 消息处理源代码分析(1)

    Android 消息处理源代码分析(1) 在Android中,通常被使用的消息队列的代码在文件夹\sources\android-22\android\os下,涉及到下面几个类文件 Handler.j ...

  8. Android Handler 异步消息处理机制的妙用 创建强大的图片加载类(转)

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38476887 ,本文出自[张鸿洋的博客] 最近创建了一个群,方便大家交流,群号: ...

  9. Android Handler 异步消息处理机制的妙用 创建强大的图片载入类

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38476887 ,本文出自[张鸿洋的博客] 近期创建了一个群.方便大家交流,群号: ...

随机推荐

  1. 数据备份 及 Python 操作 Mysql

    一 MySQL数据备份 #1. 物理备份: 直接复制数据库文件,适用于大型数据库环境.但不能恢复到异构系统中如Windows. #2. 逻辑备份: 备份的是建表.建库.插入等操作所执行SQL语句,适用 ...

  2. ReactNative报错null is not an object (evaluating '_rngesturehandlermodule.default.direction')

    程序报错: null is not an object (evaluating 'rngesturehandlermodule.default.direction') 解决: react-native ...

  3. springboot 日志配置

    maven依赖中添加了 spring-boot-starter-logging : <dependency> <groupId>org.springframework.boot ...

  4. Dubbo服务发布、引用

    DUBBO原理.应用与面经总结 Dubbo原理和源码解析之服务暴露 Dubbo原理和源码解析之服务引用 服务发布 服务的发布总共做了以下几件事,这个也可以从日志log上看出来: 暴露本地服务 暴露远程 ...

  5. 【Zookeeper】基础学习概览【汇总】

    一.概述 1.1 简介 1.2 Zookeeper集群机制 1.3 Zookeeper特性 二.Zookeeper应用场景 三.Zookeeper数据结构 四.Zookeeper安装 五.Java操作 ...

  6. Android笔记(十九) Android中的Fragment

    通常我们使用Activity来展示界面,但是在手机上界面可能显示的很好看,但在平板上,因为平板的屏幕非常大,手机的界面放在平板上可能会出现控件被拉长.控件之间间距变大等问题.为了更好的体验效果,在Ac ...

  7. 【转载】内联函数 —— C 中关键字 inline 用法解析

    转载地址:https://blog.csdn.net/zqixiao_09/article/details/50877383 一.什么是内联函数 在C语言中,如果一些函数被频繁调用,不断地有函数入栈, ...

  8. 解析Linux中LVM与磁盘配额

    LVM 逻辑卷管理 LVM 概述 LVM 是 Linux 操作系统中对磁盘分区进行管理的一种逻辑机制,它是建立在硬盘和分区之上.文件系统之下的一个逻辑层,在建立文件系统时屏蔽了下层的磁盘分区布局,因此 ...

  9. JavaScript函数封装调用

    举个列子:我们在写前端页面,经常会使用到Jquery文本框内容,来判断一下输入值是否符合,常见的写法: <script> function test(){ $("#ID" ...

  10. 读书笔记——《redis入门指南(第2版)》第七章 持久化

    7 持久化 在一些情况下,我们会希望Redis 在重启后能够保证数据不丢失,例如: 1·将Redis 作为数据库使用时. 2·将Redis 作为缓存服务器,有可能出现的缓存雪崩会使服务无法响应. 这时 ...