经典软件设计模型 - 事件驱动模型

MBSE建模学习之六:状态机和状态机图 本文介绍了MBSE中使用SysML语言进行状态机建模的基础知识和案例 阅读详情


模型说明

在UI编程中,常常要对鼠标点击进行相应,首先如何获得鼠标点击呢?
方式一:创建一个线程,该线程一直循环检测是否有鼠标点击,那么这个方式有以下几个缺点:
1. CPU资源浪费,可能鼠标点击的频率非常小,但是扫描线程还是会一直循环检测,这会造成很多的CPU资源浪费;如果扫描鼠标点击的接口是阻塞的呢?
2. 如果是堵塞的,又会出现下面这样的问题,如果我们不但要扫描鼠标点击,还要扫描键盘是否按下,由于扫描鼠标时被堵塞了,那么可能永远不会去扫描键盘;
3. 如果一个循环需要扫描的设备非常多,这又会引来响应时间的问题;
所以,该方式是非常不好的。

方式二:就是事件驱动模型
目前大部分的UI编程都是事件驱动模型,如很多UI平台都会提供onClick()事件,这个事件就代表鼠标按下事件。事件驱动模型大体思路如下:
1. 有一个事件(消息)队列;
2. 鼠标按下时,往这个队列中增加一个点击事件(消息);
3. 有个循环,不断从队列取出事件,根据不同的事件,调用不同的函数,如onClick()、onKeyDown()等;
4. 事件(消息)一般都各自保存各自的处理函数指针,这样,每个消息都有独立的处理函数;
如图:



Android的Looper和Handler模型

在Android系统中,一般的事件驱动应用都可以使用Looper和Handler来实现,uml如下

UML



说明

Message是一个个的消息,每个消息代表一个事件,每个Message都有独立的处理者target;
多个消息利用Message里的next属性首尾相接组成一个MessageQueue队列;
MessageQueue提供了插入Message接口enqueueMessage和读取Message接口next;
Looper是一个循环类,它利用MessageQueue的next接口,不断从MessageQueue获得消息;
如果Looper获得了一个消息Message,那么就调用Message的target来处理该消息,这个target其实就是一个Handler;
Handler的HandlerMessage函数就是处理Message的地方,这是一个接口函数,所以使用者根据业务需求重写这个接口;
Handler除了处理Message外,还提供了插入Message的接口sendMessage,从这也可以看出,利用这四个类设计最简单的事件驱动模型只需操作Hanlder一个类即可,因为它既提供了插入消息的接口,也提供了处理消息的接口;

当然这四个类除了MessageQueue之外,其他三个用户都可以根据业务需求操作实现更复杂的模型,我们可以自己创建一个Message而不是使用Message的默认创建方法(如可以为每个Message设计不同的处理函数,不一定使用HandlerMessage),然后通过Handler插入到消息队列中;然后创建自己的Looper线程,自己独自使用一个Looper;之所以MessageQueue不能自行设计,是因为Android的设计问题,因为MessageQueue是在Looper的构造函数自己new的。

重点代码分析

Handler的handleMessage优先级

    /**
     * Subclasses must implement this to receive messages.
     */
    public void handleMessage(Message msg) {
    }
    
    /**
     * Handle system messages here.
     */
    public void dispatchMessage(Message msg) {
        if (msg.callback != null) {
            handleCallback(msg);
        } else {
            if (mCallback != null) {
                if (mCallback.handleMessage(msg)) {
                    return;
                }
            }
            handleMessage(msg);
        }
    }

looper读取一个消息后,首先执行的是dispatchMessage,然后dispatchMessage根据不同条件调用不同的handleMessage;
这里边有好多callback,是因为不一定非要使用Handler提供的handleMessage接口处理消息,也可以有很多其他方式设置回调函数; 
优先级最高的是msg.callback,如果要处理的Message本身有处理回调接口,那么就使用Message本身的;
优先级次之的是mCallback,mCallback是在Handler的构造函数设置的,说明可以为Handler统一设置一个处理回调接口;
优先级最低的是handleMessage,这个才是handleMessage用户重写的接口;

设置这些优先级,主要为了在应用中需要处理的消息有很多种分类,但是它们共用一个Looper,如
1. 如果所有的消息属于一个分类,那么只需要一个Handler即一个handleMessage即可;
2. 如果消息分属于不同的分类,那么每个分类使用一个Handler管理,即每个分类使用一个handleMessage,即mCallback;
3. 如果所有的消息种类都不一样,如果使用一个Handler在逻辑上不伦不类,所以,这个时候不如为每个消息设置一个回调函数更好,即msg.callback;


MessageQueue的时间优先级when
Handler是通过enqueueMessage接口将消息插入到MessageQueue的,在插入的时候就已经将消息按照时间排序了,其中时间0代表最高的优先级,时间越大,优先级越小,越延后处理
所以,Looper通过MessageQueue的next接口获得的消息就是优先级最高的消息,next不需要重新排序消息队列了;


HandlerThread的作用

如果我们需要自己创建Looper,需要将创建的Looper和创建的Handler联系在一起。如果两个对象的创建是在一个线程里,并且先创建Looper后创建Handler是没有问题的;但是如果两个对象是在两个线程里创建,有可能在构造Handler时,Looper并没有真正的创建好,其实这之间只要通过一个同步就可以。HandlerThread就是Android提供给我们用的一个类,它已经做好了同步,所以可以安全使用。

QP: 一种替代前后台和RTOS的程序框架 QP(量子平台)是一个基于活动对象和层次式状态机的开源实时嵌入式框架(real-time embedded frameworks)和运行环境。一种优秀的可以代替前后台和RTOS的实时运行框架 阅读详情

相关推荐

十三、python的事件驱动模型和IO模型

python的事件驱动模型和IO模型

weixin_45460686的博客 1172

事件驱动模型

事件驱动模型的概念、作用、实现思路以及几种不同的实现方式。

米碎师兄 1万+

FID指标实战:如何用Python快速计算生成图像的质量分数(附完整代码)

本文详细介绍了如何使用Python计算Fréchet Inception Distance(FID)指标,以评估生成图像的质量。通过完整的代码示例和优化技巧,帮助开发者快速实现FID计算,并解读分数背后的实际意义,适用于GAN和扩散模型的性能评估。

weixin_28718487的博客 375

事件驱动模型&IO模型

事件驱动模型是一种计算机编程模型,它通过等待事件的触发,在事件被触发时执行对应的处理函数。这种模型下,程序不再按照严格的顺序执行命令,而是以事件为驱动进行执行。事件驱动模型更适合处理大量事件和复杂的业务场景,并且可以提高系统性能和响应速度。熟悉和运用事件驱动模型在某些场景下可以提高代码的效率和稳定性,同时增加代码的可扩展性。可以通过继承ApplicationEvent类来自定义一个事件类,然后在合适的位置使用ApplicationContext发布该事件。

写Bug小能手 2876

我爬取了某非法网贷后台系统数据,终于知道什么叫做利滚利滚利滚利了

我爬取了非法贷款的后台网站!

weixin_44042821的博客 2879

深入剖析STM32F103 I2C总线死锁问题及高效应对策略

本文深入剖析了STM32F103硬件I2C总线在轮询模式下发生死锁的根本原因,即硬件状态机的预取机制与软件响应速度不匹配。文章提供了高效的解决方案,包括在轮询模式下提前发送NACK/STOP信号、降低总线速度,以及治本的中断与DMA应用策略,帮助开发者根据项目需求选择最合适的方案,彻底解决这一经典硬件缺陷问题。

weixin_29184371的博客 206

Python IO model

1、 事件驱动模型传统线性模式编程:开始--->代码块A--->代码块B--->代码块C--->结束 1 每一个代码块里是完成各种各样事情的代码,但编程者知道代码块A,B,C,D...的执行顺序,唯一能够改变这个流程的是数据。输入不同的数据,根据条件语句判断,流程或许就改为A--->C--->E...--->结束。每一次程序运行顺序或许都不同...

318

聚焦112Gb/s SerDes芯片的AN/LT端口自协商和链路学习,评估验证高速链路的信号质量并分析调优(400/800G高速以太网互联接口,AI加速卡网络RDMA性能测试,交换背板接口性能评估)

在112G SerDes高速通道下的400G/800G高速以太网端口下,如何保障通信速率,验证SerDes的数据完整性和链路余量,自动协商(AN)和链路训练(LT)功能显得尤其重要,其在DAC、ACC、AEC铜缆连接或高速背板通信上,自动协商(AN)和链路训练(LT)的工作与否将决定高速链路传输质量的优劣。本文将系统的讨论介绍自动协商(AN)和链路训练(LT)的测试流程,其可以独立使用,也可以与teledynelecroy SierraNet M1288配合使用。

专注有线以太网性能测试--丹麦信雅纳网络(Xena Networks) 9402

深入理解重要的编程模型

背景模型是对事物共性的抽象,编程模型就是对编程的共性的抽象。什么是编程的共性呢?最重要的共性就是:程序设计时,代码的抽象方式、组织方式或复用方式。编程模型主要是方法与思想。编程模型处于方法...

716

(35)远程识别(又称无人机识别)(一)

Ardupilot官网关于《Peripheral Hardware》的翻译 —《(35) 远程识别(又称无人机识别)》。

无人机开发(开源Ardupilot) 4万+

SpringBoot 指标监控——Actuator

1、 访问:localhost:8000/actuator 设置健康监控显示具体情况 metrics http://localhost:8000/actuator/metrics/jvm.gc.live.data.size 定制化health信息 //利用构造器,在注册中心中添加cityService.saveCity.count指标 public CityServiceImpl(MeterRegistry meter...

weixin_44302046的博客 4628

深入分析Spring事件驱动模型

聊一聊从观察者模式到Spring的事件驱动模型

Z先生 4万+

RT-DETR改进前必看 - Ultralytics调参 1:1还原RT-DETR官方版本实验环境,更方便改进

的项目文件中集成了YOLOv3v5v6v8v9v10rt-detr11以及其中不同大小的模型结构,更方便我们学习和使用。的参数配置在路径下,其中中设置了模型在训练Train验证Val/Test预测Predict可视化Visualize导出Export超参数Hyperparameters、以及跟踪Tracker的相关参数。在调参过程中主要涉及训练Train和超参数Hyperparameters。下面主要介绍一下初始超参数Hyperparameters。

Limiiiing的博客 7959

Nginx 事件驱动模型

事件驱动模型是一种基于事件和回调机制的设计模式,在该模式中,程序并不会按传统的流程逐步执行,而是等待外部事件的发生,一旦事件发生,程序会触发对应的回调函数进行处理。这种模型的关键特征是非阻塞式的操作和高并发处理能力。Nginx 的事件驱动模型主要体现在它对并发请求的处理上。不同于传统的多进程或多线程模型,事件驱动模型通过一个或少数几个进程/线程来监听和处理大量的连接请求。事件模型通过事件循环机制将 I/O 操作与应用程序逻辑分离,从而提高了处理效率。

Flying_Fish_roe的博客 875

【DEIM创新改进】独家下采样创新改进篇 | ECCV 2026 | DEIM 引入FSD-Down频域-空间动态下采样,在下采样过程中保留小目标的高频信息、助力小目标检测、遥感小目标检测有效涨点

🔥本文提出了一种名为FSD-Down的频域-空间动态下采样模块,用于改进DEIM网络模型在小目标检测中的性能。FSD-Down通过小波分解显式保留低频语义和高频细节,结合分组卷积、动态通道权重和可学习缩放因子,自适应强化目标边缘与纹理特征。该模块能有效减轻传统下采样造成的频率混叠和细节丢失,提升对小目标、密集目标和低对比度目标的检测能力。实验表明,FSD-Down计算开销可控,在保持实时性的同时显著提升检测精度,特别是在VisDrone和AITODv2数据集上对小目标的检测性能提升显著。

Ai缝合怪、助力小伙伴高效发论文 82

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

事件驱动架构:新时代的软件设计范式

事件驱动架构是一种软件设计模式,其中系统的行为由事件驱动。事件(Event)是指系统内发生的显著的状态变化或动作。事件驱动架构通过事件的产生、传递和处理,构建松散耦合、异步通信的系统。在事件驱动架构中,事件的产生和处理是相互独立的,即事件生产者(Producer)生成事件后,不需要等待事件处理者(Consumer)的响应,而是通过事件总线或消息队列将事件发送出去,由消费者在适当的时间进行处理。

fudaihb的博客 2349

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

【Netty 什么是事件驱动模型?】

首先来简单的看一下netty的简介: Netty 是一个 Java 开源通讯框架,是一个异步的,基于事件驱动的网络应用框架,用以快速开发高性能、高可靠性的网络 IO 程序。 这里主要和大家分享的就是事件驱动模型。 首先我们看下百度百科是如何描述“事件驱动模型”的:鼠标的一个点击,移动,键盘的按键按下等等操作,都是对应操作系统的一个事件,然后应用程序接受你的操作进行处理。 em...好像没有什么不对的地方,但是基本上我们看完后也还是不懂什么是事件驱动模型。只能说百度百科凝结的都是精华(敷衍~)。 1

W664160450的博客 2200

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Nginx 的事件驱动模型

事件驱动模型是一种异步处理模型,它基于事件的发生来触发相应的操作,而不是等待操作的完成。与传统的多进程和多线程模型不同,Nginx 的事件驱动模型能够在单个或少量的工作进程中处理大量的并发连接,极大地提高了系统的性能和资源利用率。Nginx 的事件驱动模型依赖于操作系统的 I/O 多路复用机制,这些机制允许一个进程同时处理多个 I/O 操作,而不需要创建多个线程或进程。在 Web 服务器的上下文中,事件驱动模型能够帮助服务器以非阻塞的方式处理多个并发请求,而不需要为每个请求创建新的进程或线程。

江左散人的专栏 1441

Python中的事件驱动编程模型

事件驱动编程是现代软件开发中不可或缺的编程范式,它通过响应事件的方式来组织和控制程序流程。本文将深入探讨Python中事件驱动编程的核心概念、实现方式和最佳实践。

2301_78217634的博客 1007

详解Spring事件驱动模型

事件驱动模型简介 事件驱动模型也就是我们常说的观察者,或者发布-订阅模型;理解它的几个关键点: 首先是一种对象间的一对多的关系;最简单的如交通信号灯,信号灯是目标(一方),行人注视着信号灯(多方); 当目标发送改变(发布),观察者(订阅者)就可以接收到改变; 观察者如何处理(如行人如何走,是快走/慢走/不走,目标不会管的),目标无需干涉;所以就松散耦合了它们之间的关系。 接下来...

jiangbb8686的博客 256
上一篇: 多线程 - 你知道线程栈吗
下一篇: YUV格式
G机器猫
博客等级 码龄16年 106粉丝 74原创
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值