Android中利用Handler实现消息的分发机制(零)

Android Handler消息机制详解 Android应用程序是通过消息驱动实现的,因此,Handler机制对于Android应用程序的运行极其重要。 本文详细的介绍了Handler、Looper、MessageQueue、Message、ThreadLocal,内容较长,可以分部分进行学习。文章未详尽之处,欢迎交流,描述有误之处,欢迎指正。 点关注,不迷路;点收藏,你更强;点点赞,我心欢。 阅读详情

在之前一篇介绍AsyncTask的文章中,我们在最后讲到,AsyncTask是利用Handler的消息异步处理机制,将操作结果,利用Message传回主线程,从而进行UI线程的更新的。

而在我们日常的开发工作中,Handler也是我们经常使用的类之一,那么Handler的主要作用是什么?

Handler 的主要作用就是对消息(消息可以是我们想做的一些UI更新,也可以是其他的一些不可见的操作,如操作数据库等)的异步处理机制,而相信大家都了解异步的概念。

简单地说一下:

1)从程序的角度来看,就是当执行某行代码的时候,发送了一个异步请求(消息),程序不需要在此行代码上继续等待下去,而是能够继续执行之后的代码。

2)从用户的角度来看,用户发送了一个消息,不需要什么事也不做,就在那傻等,而可以去做其他的事情,当对应的消息被处理完之后 ,就会通过回调机制处理对应的结果。

所以,Android中Handler的消息异步处理机制,能够给用户提供一个更加合理及友好的用户体验。当然,Android是用Handler来实现,其他的平台环境,也有着自己的一套异步实现机制,原理一样,名称不同而已。

既然我们是做Android开发的,那么我们肯定就要好好地学习一下Handler的使用,探究一下隐藏在Handler之后的代码架构。

首先,我们还是从简单的例子来入门,学习一下,如何使用Handler。

代码如下:

public class MainActivity extends ActionBarActivity {

    private static final int MSG_ID_1 = 1;
    private static final int MSG_ID_2 = 2;

    private Handler mHandler = new Handler() {

        public void handleMessage(Message msg) {
            switch (msg.what) {
            case MSG_ID_1:
                Log.v("Test", "Toast called from Handler.sendMessage()");
                break;
            case MSG_ID_2:
                break;
            }
            
        }
    };
    
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Message message = mHandler.obtainMessage();
        message.what = MSG_ID_1;
        mHandler.sendMessage(message);
    }
}

当我们启动程序的时候,我们可以看到,在LogCat里面就会看到,已经打印出了如下的信息:

10-27 15:13:21.382: V/Test(9618): Toast called from Handler.sendMessage()

而这正是我们在handler的handleMessage中对msg.what = MSG_ID_1 的情况下进行处理的。

从这个简单的例子,我们可以归纳一下Handler的使用步骤,大概有以下几步:

1)创建一个Handler对象,并且实现其 handleMessage(Message msg) 方法,如代码中:

private Handler mHandler = new Handler() {

而实现handleMessage方法一步,我们可以看到,会获取一个Message对象。

Message对象封装了一些参数,常用的大概有以下几个:

a)what 参数:这是一个 int 值,经常是我们用来区分消息的一个ID,比如例子中,我们将MSG_ID_1在创建消息的时候赋值给msg.what。

b)obj 参数:这是一个Object对象。通过obj参数,可以把任何对象赋给消息,然后在handleMessage中进行处理,而这也是Handler在异步处理中传递数据的方法。

c)arg1, arg2 等参数:上述a),b) 两个参数是我们最常用的Message的参数了,基本上也需要这两个参数就足够了,不过Message还是提供了其他的一些字段供我们使用,如argX等,也就是 arguments的缩写。arg1和arg2是Android提供的所谓low-cost的变量,不过一般也就是用来设置一些int值。

d)data参数,data参数是一个Bundle类型的对象,我们可以通过setData方法来设置bundle,就跟我们在Activity之间利用Intent传递数据一样来使用。

2)当创建好Handler对象之后,第二步就需要创建一个Message对象了,创建Message对象有两种方法:

2.1)直接创建新对象,代码如下:

Message msg = new Message()

2.2)利用Handler.obtainMessage()方法,也即上面代码中使用的方式,如下:

Message message = mHandler.obtainMessage();

一般情况下,我们建议使用第二种方式,为什么呢?

因为在Message的内部中维护了一个类似消息池的对象,当我们使用Handler来对Message进行分发的时候,处理完之后,Message对象并不一定会被马上销毁,而是有可能放到一个消息池中。

当利用Handler的obtainMessage方法,Handler会去从消息池中获取一个已经存在的对象,并初始化好其信息,这样,我们就不需要再重新去创建一个对象,浪费一些内存,在嵌入式应用,内存不是很大的情况下,这是对性能的一种优化。

在创建Message的时候,我们就可以对msg.what进行赋值,目的就是为了Handler在handleMessage的时候,可以判断这个消息的用途或目的是什么。

当然,不同的需求,肯定有不同的处理,这就具体情况具体分析了。

3)当消息(Message)创建好了之后,我们就可以利用Handler的sendMessage来进行发送消息了,之后,这个消息就会被其handler所捕获,从而进行处理了。


接下来,我们就再扩充一下这个例子,代码如下:

public class MainActivity extends ActionBarActivity {

    private static final int MSG_ID_1 = 1;
    private static final int MSG_ID_2 = 2;

    private Handler mHandler = new Handler() {

        public void handleMessage(Message msg) {
            switch (msg.what) {
            case MSG_ID_1:
                Log.v("Test", "Toast called from Handler.sendMessage()");
                break;
            case MSG_ID_2:
                String str = (String) msg.obj;
                Log.v("Test", str);
                break;
            }
            
        }
    };
    
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Message message = mHandler.obtainMessage();
        message.what = MSG_ID_1;
        mHandler.sendMessage(message);
        
        Message msg2 = mHandler.obtainMessage();
        msg2.obj = "I'm String from Message 2";
        msg2.what = MSG_ID_2;
        mHandler.sendMessage(msg2);
    }
}

而其对应的结果如下:

10-27 15:35:19.168: V/Test(12135): Toast called from Handler.sendMessage()
10-27 15:35:19.168: V/Test(12135): I'm String from Message 2

由此,我们可以看到,利用obj参数,我们将String对象给传到handleMessage中去了。


除了 sendMessage方法,发送消息时, Handler还可使用如下的方法:

public final boolean post(Runnable r)
    {
       return  sendMessageDelayed(getPostMessage(r), 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);
    }

而其实,无论是还是sendMessage还是使用post方法,其实最终都是通过调用sendMessageAtTime方法,将对应的Message对象放入一个MessageQueue中的。

那么其为什么要放到MessageQueue?放到MessageQueue中有如何跑回到Handler的handleMessage中的呢?

接下来的文章,我们再继续来学习。

这一篇我们就简单地介绍了如何使用Handler,简单的例子,简单地入门。

结束。

Android Handler 消息机制 每一个搞 Android 的对 Handler 应该都不陌生,网上大神的文章也是数不尽的。这篇文章是个人在学习 Handler 过程中的一些疑问的记录。 1. 什么是 Handler,有什么作用 Handler 首先是一个 java 类,定义在/frameworks/base/core/java/android/os/Handler.java。但一般提到 Handler 并不专指它自身,常用来代指 Android 中的消息处理机制,或者说线程间通信的工具,典型应用就是在子线程中更新 UI 线程。那么,很显然 阅读详情

相关推荐

Android消息机制源码解析(Handler)

Android消息机制,其实也就是Handler机制,主要用于UI线程和子线程之间交互。众所周知,一般情况下,出于安全的考虑,所有与UI控件的操作都要放在主线程及UI线程,而一些耗时操作应当放在子线程中。当在子线程中完成耗时操作并要对UI控件进行操作时,就要用Handler来控制。另外,Android系统框架内,Activity生命周期的通知等功能也是通过消息机制来实现的。本篇博文主要是想通过Han

笔沫拾光 2114

QT连接MySQL数据库问题

QT连接MySQL数据库问题 QT连接MySQL数据库问题 提示:这里简述项目相关背景: 例如:项目场景:示例:通过蓝牙芯片(HC-05)与手机 APP 通信,每隔 5s 传输一批传感器数据(不是很大) No QMySQL driver, the driver failed to load https://blog.youkuaiyun.com/qq_21291397/article/details/107690775?spm=1000.2123.3001.4430 https://www.jb51.net/arti

Jason_Chen__的博客 398

深入分析Android Handler消息机制

概述 Handler是Android消息机制的上层接口。通过它可以轻松地将一个任务切换到Handler所在的线程中去执行。通常情况下,Handler的使用场景就是 更新UI。 Handler的使用 在子线程中,进行耗时操作,执行完操作后,发送消息,通知主线程更新UI。 public class Activity extends android.app.Activity { private Handler mHandler = new Handler(){ @Override

nufuli123的博客 1586

Handler sendMessage 与 obtainMessage (sendToTarget)比较

话说在工作中第一次接触android 的Handler 的时候,不知道怎么去关注性能。 记得当时这么写的: Message msg = new Message() msg.what = xxx; msg.arg1 = xxx; msg.arg2 = xxx; handler.sendMessage(msg); 这样写也没有绝得不好,反正当时项目的功能实现了。(性能上还可以

lovewlforever的专栏 1224

Android Handler的机制跟源码分析

不断循环执行 Looper.loop() ,从 MessageQueue 中读取 Message ,按分发机制将消息分发出去给目标处理(将 Message 发到 Handler.dispatchMessage 方法去处理)。上面讲到了新建Message推荐使用 obtain() ,因为可以有效的复用消息,其中里面复用的就是 sPool 变量,它是在Message回收的时候进行赋值的。在应用启动时,会执行 main() 方法, main() 会创建一个 Looper 对象,然后开启一个死循环,目的是不断从。

u011324501的专栏 943

WandB本地部署踩坑指南:从Docker启动到License更新的完整流程(附常见错误解决方案)

本文详细介绍了Weights & Biases(WandB)机器学习实验管理平台的本地化部署全流程,涵盖从Docker环境搭建、许可证管理到常见错误排查的实战经验。针对企业级应用场景,文章还提供了性能优化、高可用架构设计及开源替代方案Trackio的评估与迁移策略,为构建安全、可控的内部实验追踪平台提供完整解决方案。

potato的博客 567

Android学习笔记——Handler消息分发

Handler 消息分发Handler事件分发机制是 基于生产者/消费者模型,使用Linux下的pipe(管道)实现的,读取和写入相互协调实现等待/通知。Handler机制是用于处理线程间消息分发的。主要角色:Handler(事件处理)、MessageQueue(消息队列)、Looper(消息循环)。 一个线程下可以有多个Handle,但只能拥有一个MessageQueue和一个L

David-Kuper的专栏 995

Dify平台+Excel批量分析实战:5分钟搞定大模型数据处理(附完整代码)

本文详细介绍了如何利用Dify平台的数据集功能,结合Excel和Python脚本,快速构建大模型批量数据处理流水线。通过实战案例演示,读者可在5分钟内完成客户反馈情感分析、产品文案生成等任务,实现从原始数据到结构化洞察的高效转化,极大提升工作效率。

3a9bq4r8t2y的博客 316

Android Handler机制

最近没事干又看了看Handler的机制,做一个大概的阐述。 对于初学者来说会用才是他们的当务之急,但是你要拜托菜鸟的帽子就必须深挖底层的东西。 先看看我们一般是咋用的: private Thread mThread; private Handler mHandler = new Handler(){ public void handleMessage(android.os.Mess

SoulOfAndroid的专栏 554

安装了anaconda,pycharm导入numpy时提示没有该包(模块)?

**问题详情:**我安装了anaconda,在利用Pycharm学习numpy这个库的时候,导入numpy这个包的时候提示我没有nummpy这个模块:No module named numpy.如下图所示。 应该说安装了Anaconda,里边就自带了numpy这个库,就应该能够使用。我一个新手怎么搞得懂呢?于是网上查了查找到了一个解决办法,说是我项目的解释器应该设置为Anaconda安装目录下的python.exe,而不应该是系统自带的:https://blog.youkuaiyun.com/aanndd77/art

qq_39820505的博客 1万+

从FPGA/ASIC工程师视角看DDR:手把手拆解Memory Controller、PHY与DRAM芯片的协作流程

本文从FPGA/ASIC工程师视角深入解析DDR内存子系统,详细拆解Memory Controller、PHY与DRAM芯片的协作流程。通过系统架构分解、接口标准解析和实战调试技巧,帮助工程师优化DDR性能并解决常见问题,涵盖地址映射、命令调度、时序校准等关键技术要点。

weixin_42548888的博客 457

Android多线程Handler、Looper、消息队列

Android系统的消息队列和消息循环都是针对具体线程的,一个线程可以存在(当然也可以不存在)一个消息队列(Message Queue)和一个消息循环(Looper)。Android中除了UI线程(主线程),创建的工作线程默认是没有消息循环和消息队列的。如果想让该线程具有消息队列和消息循环,并具有消息处理机制,就需要在线程中首先调用Looper.prepare()来创建消息队列,然后调用Loope

晓阳 的专栏 1117

android osmdroid 加载常用离线地图格式(开源的在线地图)

osmdroid是(几乎)完整/免费更换为Android MapView(v1 API)类。它还包括一个模块化的瓷砖供应商系统支持众多的在线和离线瓷砖来源和覆盖支持内置覆盖绘制图标,跟踪位置和形状。如果想在你项目中使用osmdroid,绝对是灵活度最高,不用申请百度,高德等的key。还有一堆规则要遵循。osmdroid可以支持多图层叠加,绘制自已的图层。离线加载常用地图格式zip,sqlite,.

mmsx990的博客 1万+

Android的消息机制--Handler

Android handler原理解析

weixin_42277946的博客 2972

【ESP32CAM+Android+OpenCV】自定义目标数据集、训练自己的OpenCV模型部署到手机APP并对ESP32CAM无线图传显示并实时检测识别目标_资料编号30

本项目实现自定义目标数据集(想检测什么就检测什么,按照本文教程自己来更换目标)、训练自己的OpenCV模型实时检测识别(pycharm工程)。手机APP(Android studio工程)部署OpenCV模型实现对ESP32CAM(arduino工程)无线WIFI图传过来的图像实时检测识别。 本文以火焰检测识别为例进行演示,通过该过程,结合本文可自定义尝试更换为其它目标的检测,例如更换为车辆、车牌、手势、人脸面部活动、人脸表情、火焰烟雾、行人、口罩、行为、水果、植物、农作物、建筑、损伤等等部署进行检测。

嵌入式阿齐Archie 3478

Android AMS——AMS初始化(二)

Android AMS 也是一个系统服务,属于系统服务中的引导服务,在 startBootstrapServices() 方法中启动。这里我们就来看一下 ActivityManagerService 的启动流程。

小旭的专栏 776

Android中利用Handler实现消息的分发机制(一)

这两个的差别就在于是否有参数Looper,而Looper是一个线程相关的对象。 何谓线程相关的变量?就是线程间不能共享的对象,只在本线程内有作用的对象。 那么Looper对象的作用是什么? 从我个人的理解,Looper类就是对MessageQueue的封装,它主要做的是两件事: 1)构造Looper对象,初始化MessageQueue,我们可以从其构造函数看到: 可以看到,Loop对象被创建之后,会被放到ThreadLocal变量中,而ThreadLocal正是线程局部变量,这说明了关于Looper的一个特

持剑 3169

手把手教你YOLOv8/YOLOv11分割训练自己数据集和推理,并教你使用Labelme工具标注数据(附分割网络结构图)

YOLOv8-seg 和 YOLOv11-seg 都是一种高效实例分割算法,实例分割模型的输出是一组勾勒出图像中每个物体的遮罩或轮廓,以及每个物体的类标签和置信度分数。当你不仅需要知道物体在图像中的位置,还需要知道它们的具体形状时,实例分割就非常有用了,功能非常强大,可以应对各种视觉任务。 YOLOv11-seg 则在 YOLOv8-seg 基础上进一步魔改了模型架构,相对分割速度可能更快,其他指标性能有待测试。实例分割可以用于自动驾驶、医疗图像处理、智能农业监控等领域。

在职AI算法工程师,擅长计算机视觉,YOLO目标检测、分割等,擅长web、pyqt界面可视化,好内容持续更新中,来这里跟大家一起学习,共同进步 4474

【Android 消息机制】Handler

Android专题学习-Handler总结

studyForMokey的博客 983

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Android面试:Handler消息机制

消息的起点是Message对象,它承载了需要传递的消息,可以通过Message.obtain()获取一个Message对象(也可以使用Handler.obtainMessage()直接通过Handler获取一个Message对象);然后Handler通过sendMessage(Message msg)发送一个完整的Message对象到MessageQueue队列中(先进先出的队列,负责存储所有有待处理的消息),其内部会调用MessageQueue.enqueueMessage将消息按时间顺序插入队列;

aldkdb的博客 1331

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

Android Handler 消息循环机制

核心思想:利用 Linux 的epoll机制,在无事可做时让线程进入休眠,在有新消息时能及时唤醒,从而兼顾了响应效率和资源消耗。

w2064004678的博客 1386

Android中利用Handler实现消息的分发机制(三)

说到代码的可读性,有时候,我们更加看重代码之间的层次或者说模块化,耦合度等特点。 不同的业务逻辑,不同的功能,应该实现在不同的模块中,而模块与模块之间就可以通过一个消息来通信,而这种消息通讯方式,我们就可以利用Handler和HandlerThread来实现。 比如,最近做的一个浏览器的小Demo,其类图如下: ... 在不同的模块实现中, 我们可以调用registerHandler方法,将其对象的Handler注册到MessageDispatcher中,然后通过sendMessage方法,指定对应的目标,

持剑 2305

Handler消息机制-Handler

Handler 消息处理机制主要由 Handler、Looper、MessageQueue 和 Message 四部分组成。Handler作用:用于发送消息和处理消息。发送消息到 MessageQueue。处理从 Looper 分发的消息。特点:每个 Handler 绑定到一个 Looper,从而绑定到一个线程。可以发送 Message 或 Runnable。Message作用:消息的载体,封装了需要处理的任务或数据。通过 what 字段标识消息类型。通过 obj 字段传递数据。

只想搞钱 1719

Android消息机制

以上便是消息机制的原理及组件解析,消息机制的运行过程,可以简单地用下图来理解。

weixin_58719774的博客 2055

Android-Handler消息机制

Handler 是 Android 中用于线程间通信的一种机制。在 Android 应用开发中,由于 Android 系统的单线程模型(主要是 UI 线程模型),为了避免在非 UI 线程中直接操作 UI 而导致程序异常(如 “Only the original thread that created a view hierarchy can touch views”),需要通过 Handler 来实现在不同线程之间传递消息,从而安全地更新 UI 或者执行其他跨线程的操作。

weixin_61662736的博客 1965

【Android基础回顾】二:handler消息机制

Android 的 Handler 机制 是 Android 应用中实现线程间通信、任务调度、消息分发的核心机制之一,它基于 消息队列(MessageQueue)+ 消息循环(Looper)+ 消息处理器(Handler) 组成。

Shujie 1632
上一篇: 关于数字证书和数字签名的一些认识
下一篇: Android中利用Handler实现消息的分发机制(一)
linmiansheng
博客等级 码龄20年 507粉丝 111原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值