EventBus原理分析

EventBus 是一个流行的事件发布/订阅框架,主要用于简化 Android 应用中不同组件之间的通信。它的设计基于观察者模式,可以有效地减少组件间的耦合性,使得代码更加模块化和可维护。

下面是 EventBus 的实现原理,结合其源码进行说明:

1. 注册订阅者 (Registering Subscribers)

EventBus 中,一个订阅者通常是一个 Android 组件(如 ActivityFragment),它通过调用 EventBus.getDefault().register(this) 方法来注册自身。在注册时,EventBus 会通过反射机制扫描订阅者的类,查找带有 @Subscribe 注解的方法。这些方法就是事件处理方法。

源码中相关的关键部分包括 EventBusregister 方法:

Java

1public void register(Object subscriber) {
2    Util.ensureBackgroundThread();
3    Set<Class<?>> subscriberTypes = subscriberTypes(subscriber);
4    for (Class<?> subscriberType : subscriberTypes) {
5        SubscriberMethod[] methods = findSubscriberMethods(subscriberType);
6        for (SubscriberMethod method : methods) {
7            method.subscriber = subscriber;
8            method.eventType = method.rawEventType;
9            method.threadMode = method.rawThreadMode;
10            method.priority = method.rawPriority;
11            method.sticky = method.rawSticky;
12            registerSubscriber(subscriber, method);
13        }
14    }
15}

findSubscriberMethods 方法会找到所有带有 @Subscribe 注解的方法,并封装成 SubscriberMethod 对象。

2. 发布事件 (Posting Events)

发布事件是通过调用 EventBus.getDefault().post(event) 方法完成的。这个方法会将事件放入一个事件队列中,并且根据事件类型和线程模式,调用相应的处理方法。

源码中的关键部分是 EventBuspost 方法:

Java

1public void post(Object event) {
2    Util.ensureBackgroundThread();
3    if (event == null) throw new NullPointerException("Event must not be null");
4    Class<?> eventClass = event.getClass();
5    synchronized (this) {
6        deliver(eventClass, event);
7    }
8}

deliver 方法会查找与事件类型相匹配的所有订阅者方法,并按照优先级排序,然后调用 postToSubscription 方法来处理事件。

3. 处理事件 (Handling Events)

事件处理是在 postToSubscription 方法中完成的,它会根据 SubscriberMethod 的线程模式来决定在哪个线程中调用事件处理方法。常见的线程模式有 POSTING, MAIN, ASYNC, BACKGROUND

源码中处理事件的部分涉及到 EventBuspostToSubscription 方法:

Java

1void postToSubscription(Event event, Subscription subscription) {
2    SubscriberMethod method = subscription.method;
3    if (method.threadMode == ThreadMode.POSTING) {
4        postToPostingThread(event, subscription);
5    } else if (method.threadMode == ThreadMode.MAIN) {
6        postToMainThread(event, subscription);
7    } else if (method.threadMode == ThreadMode.ASYNC) {
8        postToAsyncThread(event, subscription);
9    } else if (method.threadMode == ThreadMode.BACKGROUND) {
10        postToBackgroundThread(event, subscription);
11    }
12}

每个线程模式都有对应的 postToXXXThread 方法,它们负责在正确的线程上下文中执行事件处理方法。

4. 取消注册 (Unregistering Subscribers)

当一个订阅者不再需要接收事件时,它应该调用 EventBus.getDefault().unregister(this) 方法来取消注册。这样可以避免内存泄漏和不必要的事件处理。

以上就是 EventBus 的基本工作原理。通过上述机制,EventBus 提供了一种简洁高效的方式来处理组件间通信,减少了组件之间的直接依赖,提高了代码的可测试性和可维护性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/44446.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

快到不可思议!Internet Download Manager下载器,让你的网速飞起来!

&#x1f31f; 快到不可思议&#xff01;Internet Download Manager下载器&#xff0c;让你的网速飞起来&#xff01;&#x1f680; 嗨喽&#xff0c;各位csdn的朋友们&#xff01;&#x1f44b;今天我要跟大家分享一个我超爱的下载神器——Internet Download Manager&#xff…

MySQL相关函数

SQL函数 聚合函数 定义&#xff1a;聚合函数作用与一组数据&#xff0c;并对一组数据返回一个值。 常用&#xff1a;AVG()、SUM()、MAX()、MIN()、COUNT()。 说明&#xff1a;聚合函数不能嵌套使用。 字符串函数 MYSQL中常用的字符串函数&#xff1a; 函数名作用concat(s1,s…

springboot+vue项目实战2024第三集修改用户信息

1.获取用户信息 GetMapping("/userInfo")// RequestHeader(name "Authorization") String tokenpublic Result<User> userInfo(){// Map<String, Object> map JwtUtil.parseToken(token);Map<String,Object> map ThreadLocalUti…

基于uni-app与图鸟UI的知识付费小程序模板

一、项目概述 在知识经济蓬勃发展的背景下&#xff0c;移动互联网成为知识传播与消费的重要渠道。本项目旨在利用前沿的前端技术栈——uni-app及高效UI框架图鸟UI&#xff0c;打造一款集多功能于一体的、面向广大求知者的知识付费平台移动端模板。该模板旨在简化开发流程&…

Java:分批查询

前言 最近遇到一个场景问题&#xff0c;就是基于SQL server数据库的规范&#xff0c;查询条件in如果个数超过2100个就会报错。由于是ORM映射框架采用的MybatisPlus 起初我想到的是基于 MybatisPlus 的 参数分割&#xff0c;测试还是不行&#xff0c;于是就直接基于 mybatis xm…

自定义业务非受检异常

【受检和非受检异常】 受检异常&#xff1a;当你需要强制调用者对异常异常进行处理时&#xff0c;抛出该类型异常。往往适用于开发通用的底层接口、或者调用第三方出现异常时。 非受检异常&#xff1a;当你不需要调用者关心时&#xff0c;抛出该类型异常。往往适用于普通的业务…

arm64架构下源码编译安装kafka —— 筑梦之路

一般来说&#xff0c;直接使用官方提供的二进制文件即可&#xff0c;没有必要使用源码编译安装的方式&#xff0c;而对于有特殊用途的&#xff0c;选择源码编译安装无疑是更好地选择。比如修改源码实现想要的功能&#xff0c;mirrormaker2保持topic名称不变。 git clone https…

缓存击穿、缓存穿透、缓存雪崩以及应对措施

1.缓存击穿 1.1概念 是指当某一key的缓存时间过期时大量并发量的请求同时访问此key&#xff0c;瞬间击穿服务器的直接访问数据库&#xff0c;让数据库处于负载的情况。 1.2解决措施 1.2.1异步定时更新 在缓存处理上&#xff0c;某一个热点数据的过期时间为一小时&#xff…

线性回归笔记

https://blog.51cto.com/u_16213589/7682076 残差图 多元回归-最小二乘法-残差分析笔记 一.多元线性回归模型的假设 我们需要进行以下六个假设&#xff0c;这些假设是经典的多元线性回归模型有效的前提&#xff1a; 1、因变量Y和自变量X1&#xff0c;X2&#xff0c;…&#…

Vue3.js“非原始值”响应式实现基本原理笔记(三)

如果您觉得这篇文章有帮助的话&#xff01;给个点赞和评论支持下吧&#xff0c;感谢~ 作者&#xff1a;前端小王hs 阿里云社区博客专家/清华大学出版社签约作者/csdn百万访问前端博主/B站千粉前端up主 此篇文章是博主于2022年学习《Vue.js设计与实现》时的笔记整理而来 书籍&a…

BEV 之 LSS概要

1、 Lift 显示估计图像下采样&#xff08;16倍&#xff09;后的特征点深度&#xff0c;将2D图像提升到3D空间&#xff0c;得到图像特征的视锥&#xff08;点云&#xff09;。 根据图像和深度均分得到3D视锥索引 下采样16倍&#xff0c;得到特征图大小为 H x W, 每个特征点深…

机器视觉理论入门

文章目录 前言一、马尔视觉理论二、图形与图像三、图像基础名词总结 前言 Marr的视觉计算理论立足于计算机科学&#xff0c;系统地概括了心理物理学、神经生理学、临床神经病理学等方面已取得的所有重要成果&#xff0c;是迄今为止最为系统的视觉理论。Marr 的视觉计算理论虽然…

LiteOS GPIO操作

在源码工程中&#xff0c; 华为海思在hi_io.h头文件里已定义好表示每个IO口的宏定义&#xff0c;如&#xff1a; typedef enum {HI_IO_NAME_GPIO_0, /**< GPIO0 */HI_IO_NAME_GPIO_1, /**< GPIO1 */HI_IO_NAME_GPIO_2, /**< GPIO2 */... } 并且在此头文…

【论文速读】《面向深度学习的联合消息传递与自编码器》

这篇文章来自华为的渥太华无线先进系统能力中心和无线技术实验室&#xff0c;作者中有大名鼎鼎的童文。 一、自编码架构的全局收发机面临的主要问题 文章对我比较有启发的地方&#xff0c;是提到自编码架构的全局收发机面临的主要问题&#xff1a; 问题一&#xff1a;基于随…

洛杉矶裸机云大宽带服务器的特性和优势

洛杉矶裸机云大宽带服务器是结合了物理服务器性能和云服务灵活性的高性能计算服务&#xff0c;为用户提供高效、安全的计算和存储能力。在了解如何使用洛杉矶裸机云大宽带服务器之前&#xff0c;需要了解其基本特性和优势。以下是对洛杉矶裸机云大宽带服务器的具体分析&#xf…

使用lv虚拟卷扩展磁盘

使用centos演示。 首先创建centos虚拟机。链接&#xff1a;VMWARE安装Centos8,并且使用ssh连接虚拟机-CSDN博客 1. 增加磁盘。 选中要扩容的虚拟机&#xff0c;右键选择设置&#xff0c;然后点击磁盘&#xff0c;选择添加。 这里选择NVM的磁盘。选择这种磁盘是为了保持与之前…

有Daemon字眼的守护线程,和没有的差异是什么?怎么创建有daemon字眼的线程?

在编程中&#xff0c;尤其是在Java等支持多线程的编程语言中&#xff0c;守护线程&#xff08;Daemon Thread&#xff09;与普通线程&#xff08;Non-Daemon Thread&#xff09;之间存在一些关键差异。这些差异主要体现在它们对程序终止行为的影响上。 主要差异 程序终止行为…

SpringBoot新手快速入门系列教程:前述

我自己是一个SpringBoot新手&#xff0c;花了一天时间学了SpringBoot。大家不要惊讶&#xff0c;前提是我自己已经有了10几年的编程经验精通多门语言&#xff0c;并且在人间最强兵器Chat某T的AI助手帮助下&#xff0c;才能创造一天快速学会一个框架的神话。 当然中间遇到了很多…

笔试算法刷题

猿辅导2021校园招聘笔试&#xff08;算法一&#xff09; 牛客网 - 找工作神器|笔试题库|面试经验|实习招聘内推&#xff0c;求职就业一站解决_牛客网 (nowcoder.com) 第一眼看到这个题想到的是蓝桥杯飞机降落&#xff0c;贪心题。但是这样算的是最大不相交区间数量&#xff0…

Test-Time Adaptation via Conjugate Pseudo-labels--论文笔记

论文笔记 资料 1.代码地址 https://github.com/locuslab/tta_conjugate 2.论文地址 https://arxiv.org/abs/2207.09640 3.数据集地址 论文摘要的翻译 测试时间适应(TTA)指的是使神经网络适应分布变化&#xff0c;在测试时间仅访问来自新领域的未标记测试样本。以前的TT…