一对多的统一监听 —— 这就是 观察者模式(Observer Pattern) 的经典应用场景。

也就是说:

  • 一个事件源(Subject) → 可以注册多个监听器(Observers);

  • 当事件发生时,一次性通知所有监听器

  • 各监听器通过统一的接口接收回调。


🔧 Java 示例代码

import java.util.ArrayList;
import java.util.List;// 统一监听接口(Observer)
interface EventListener {void onEvent(String event);
}// 事件源(Subject)
class EventSource {private final List<EventListener> listeners = new ArrayList<>();// 添加监听器public void addListener(EventListener listener) {listeners.add(listener);}// 移除监听器public void removeListener(EventListener listener) {listeners.remove(listener);}// 触发事件,通知所有监听器public void triggerEvent(String event) {System.out.println("EventSource: 触发事件 -> " + event);for (EventListener listener : listeners) {listener.onEvent(event);}}
}// 具体监听器 A
class LoggingListener implements EventListener {@Overridepublic void onEvent(String event) {System.out.println("LoggingListener 收到事件: " + event);}
}// 具体监听器 B
class AlertListener implements EventListener {@Overridepublic void onEvent(String event) {System.out.println("AlertListener 收到事件: " + event);}
}// 测试
public class ObserverPatternDemo {public static void main(String[] args) {EventSource source = new EventSource();// 注册多个监听器source.addListener(new LoggingListener());source.addListener(new AlertListener());source.addListener(event -> System.out.println("匿名Listener 收到事件: " + event));// 触发事件source.triggerEvent("用户登录");source.triggerEvent("文件上传");}
}

▶️ 输出结果

EventSource: 触发事件 -> 用户登录
LoggingListener 收到事件: 用户登录
AlertListener 收到事件: 用户登录
匿名Listener 收到事件: 用户登录EventSource: 触发事件 -> 文件上传
LoggingListener 收到事件: 文件上传
AlertListener 收到事件: 文件上传
匿名Listener 收到事件: 文件上传

📌 总结

  • 一对多的统一监听 就是 观察者模式

    • Subject(事件源):维护监听器集合;

    • Observer(监听器):实现统一回调接口;

    • Notify(通知):事件触发时,循环回调所有监听器。

这样做的好处是:

  • 解耦(事件源无需关心监听器的实现细节);

  • 扩展性好(随时新增/删除监听器);

  • 统一接口(所有监听器用一个回调方法 onEvent 处理)。

Android 里到处都是“一对多统一监听”这种观察者模式的实例,几乎是 核心设计思想之一。下面列几个典型的例子给你:


📌 Android 中的一对多统一监听实例

1. View 的点击事件分发

  • 事件源(Subject)View

  • 监听器(Observer)OnClickListener

  • 但这里是 一对一,只能设置一个 OnClickListener
    👉 不过在 事件总线/广播里是一对多。


2. BroadcastReceiver(广播机制)

这是 Android 里 最标准的一对多统一监听

  • 事件源:系统/应用发送的广播(Intent)。

  • 观察者:所有注册的 BroadcastReceiver

  • 当广播触发时,系统会依次通知所有匹配的接收者。

// 注册广播接收器
IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
registerReceiver(new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {int level = intent.getIntExtra("level", 0);System.out.println("收到电量变化广播: level=" + level);}
}, filter);// 任意地方发广播
Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED);
intent.putExtra("level", 90);
sendBroadcast(intent);

👉 所有监听 ACTION_BATTERY_CHANGED 的接收器都会同时收到回调。


3. LiveData / Flow / RxJava

  • 事件源LiveData<T>

  • 观察者Observer<T>

  • 你可以给同一个 LiveData 添加多个观察者,它们会同时收到数据更新。

MutableLiveData<String> liveData = new MutableLiveData<>();// 监听器1
liveData.observe(this, data -> {Log.d("Observer1", "收到数据: " + data);
});// 监听器2
liveData.observe(this, data -> {Log.d("Observer2", "收到数据: " + data);
});// 触发事件
liveData.setValue("新消息来了!");

👉 输出:

Observer1: 收到数据: 新消息来了!
Observer2: 收到数据: 新消息来了!

4. RecyclerView.AdapterDataObserver

  • 事件源RecyclerView.Adapter

  • 观察者AdapterDataObserver

  • 当数据集变化时,会通知所有观察者(例如 RecyclerView 自己 + 其他订阅者)。

RecyclerView.Adapter adapter = ...;
adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {@Overridepublic void onChanged() {Log.d("Observer", "Adapter 数据更新");}
});// 更新数据
adapter.notifyDataSetChanged();

5. ContentObserver

  • 事件源:ContentProvider 数据变化。

  • 观察者:所有注册的 ContentObserver

getContentResolver().registerContentObserver(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,true,new ContentObserver(new Handler()) {@Overridepublic void onChange(boolean selfChange) {Log.d("Observer", "相册数据变化了!");}}
);

✅ 总结

在 Android 里,一对多统一监听(观察者模式)的典型实现有:

  1. BroadcastReceiver(广播机制)

  2. LiveData.observe()

  3. RecyclerView.AdapterDataObserver

  4. ContentObserver

  5. EventBus/Flow/RxJava

这些都属于 统一监听回调的一对多场景


Android 开发里,观察者模式(Observer Pattern)非常常见,主要用于 “一对多”通知的场景:当一个对象(被观察者/Subject)状态变化时,会自动通知所有依赖它的对象(观察者/Observer),从而实现解耦。


🔹 为什么要用观察者模式?

  1. 解耦合:观察者不需要知道被观察者的内部实现,只关心变化。

  2. 灵活扩展:可以随时增加/移除观察者,不需要修改被观察者逻辑。

  3. 统一通知机制:避免手动在多个地方写重复的刷新或回调。


🔹 在 Android 中常见的使用场景

1. UI 更新和数据监听

  • LiveData + Observer(Jetpack):UI 组件(Activity/Fragment)订阅数据,数据变化时自动刷新 UI。

  • EventBus/RxJava:跨组件事件传递,类似全局观察者模式。

2. 自定义组件封装

例如封装一个 网络状态监听组件

  • 被观察者:NetworkManager(内部监听系统广播/ConnectivityManager)。

  • 观察者:Activity/Fragment/自定义 View,需要知道网络是否可用。

这样多个页面只要注册为观察者,就能统一收到网络变化通知。

3. 多模块通信

  • 下载/上传进度监听:下载器作为 Subject,UI 页面作为 Observer。

  • 播放器状态监听:MediaPlayer/ExoPlayer 的状态变化通知给 UI 控件(进度条、播放按钮)。

4. 数据缓存和刷新

比如 Room + LiveData 就是典型观察者模式:数据库数据变更 → LiveData 通知 → UI 自动刷新。


🔹 简单封装示例

假设我们封装一个 全局事件中心,支持任意组件监听和通知。

// 1. 定义观察者接口
public interface Observer<T> {void onUpdate(T data);
}// 2. 被观察者(事件中心)
public class EventBus<T> {private final List<Observer<T>> observers = new ArrayList<>();public void register(Observer<T> observer) {observers.add(observer);}public void unregister(Observer<T> observer) {observers.remove(observer);}public void notifyObservers(T data) {for (Observer<T> observer : observers) {observer.onUpdate(data);}}
}// 3. 使用示例
public class NetworkManager {private static final EventBus<Boolean> eventBus = new EventBus<>();public static void addNetworkObserver(Observer<Boolean> observer) {eventBus.register(observer);}public static void removeNetworkObserver(Observer<Boolean> observer) {eventBus.unregister(observer);}// 系统监听到网络变化时调用public static void onNetworkChanged(boolean available) {eventBus.notifyObservers(available);}
}

在 Activity 中用法:

public class MainActivity extends AppCompatActivity {private final Observer<Boolean> networkObserver = available -> {Toast.makeText(this, available ? "网络可用" : "网络不可用", Toast.LENGTH_SHORT).show();};@Overrideprotected void onStart() {super.onStart();NetworkManager.addNetworkObserver(networkObserver);}@Overrideprotected void onStop() {super.onStop();NetworkManager.removeNetworkObserver(networkObserver);}
}

这样就实现了一个简单的观察者封装:

  • 解耦:NetworkManager 不关心谁在监听。

  • 可复用:任意页面都能监听网络变化。


🔹 总结

在 Android 里,观察者模式适用于:

  • 数据驱动 UI(LiveData、Flow、RxJava)

  • 组件通信(EventBus、全局状态监听)

  • 自定义控件封装(播放器、下载器、网络监控等)

👉 适合所有 “一个地方变化,多个地方要响应” 的场景。

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

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

相关文章

C#测试调用OpenXml操作word文档的基本用法

OpenXML SDK是微软为高效处理Office文档&#xff08;如Word、Excel&#xff09;而开发的开源.NET库,它直接操作文档内部的XML结构&#xff0c;无需安装Office软件即可实现文档的创建、读取和编辑,常用于服务器端批量生成报表、自动化文档处理等场景&#xff0c;轻量且跨平台。本…

照度传感器考虑笔记

您好&#xff01;很高兴为您解答关于照度计传感器和设计的问题。这是一个非常专业且实际的话题。 一、照度计常用的照度传感器类型 照度计的核心是光电探测器&#xff0c;其工作原理是将光信号转换为电信号。目前主流的照度传感器都属于硅光电二极管&#xff08;Si Photodiode&…

C# Web API Mapster基本使用

安装包&#xff1a;Mapster1.注册MyRegister.Scan(); // 全局配置 //builder.Services.AddMapster(); // 需要安装Mapster.DependencyInjection包 builder.Services.AddScoped<IMapper,Mapper>();2.配置&#xff08;可不进行配置直接使用也行&#xff09;public class My…

<数据集>无人机航拍人员搜救识别数据集<目标检测>

数据集下载链接https://download.csdn.net/download/qq_53332949/91899456数据集格式&#xff1a;VOCYOLO格式 图片数量&#xff1a;5755张 标注数量(xml文件个数)&#xff1a;5755 标注数量(txt文件个数)&#xff1a;5755 标注类别数&#xff1a;1 标注类别名称&#xff…

STM32 开发(三十三)STM32F103 片内资源 —— 直接存储 DMA 实战 编码详解

👈《上一篇》  🏡《主目录》  👉《下一篇》 文章目录 一、基础知识点 二、开发环境 三、STM32CubeMX相关配置 四、Vscode 代码讲解 ADC -DMA 采集温度值 代码解析 DAC -DMA 输出 1KHZ 正弦波 代码解析 五、结果演示 ADC -DMA 采集温度值 结果演示 DAC -DMA 输出 1KHZ 正…

Ip 地址,子网掩码

1. 什么是 IP 地址&#xff1f;IP 地址是互联网上设备的唯一标识&#xff0c;类似于现实中的“门牌号”&#xff0c;用于设备之间的通信。ABC类IP内网地址的范围如下&#xff1a;A类地址&#xff1a;范围是 10.0.0.0 到 10.255.255.255&#xff0c;用于大型网络&#xff0c;网络…

软件工程领域内容运营的翻译策略:打破语言边界

软件工程领域内容运营的翻译策略:打破语言边界 关键词:软件工程、内容运营、翻译策略、技术本地化、术语管理、跨文化沟通、机器翻译 摘要:在全球化协作日益紧密的今天,软件工程领域的内容(如技术文档、API手册、开发者博客、开源社区指南等)早已突破单一语言限制,成为连…

元宇宙与金融创新:虚实融合下的金融服务新形态

1 元宇宙重构金融核心服务场景1.1 零售金融场景&#xff1a;从 “线下网点 线上 APP” 到 “沉浸式虚拟金融空间”传统零售金融服务受限于物理网点或二维 APP&#xff0c;交互性与体验感不足&#xff0c;元宇宙通过 “3D 虚拟金融空间 数字分身交互”&#xff0c;打造 “身临…

信奥赛csp初赛高频考点真题分类解析之:基本运算

信奥赛csp初赛高频考点真题分类解析之:基本运算 题目1: 答案:C 题解:R进制转换为十进制:按权展开 3 \times 8 1 ^1

PyTorch深度学习实战【10】之神经网络的损失函数

文章目录零 回顾&#xff1a;机器学习中的模型训练流程一 神经网络的损失函数1.1 机器学习中的优化思想1.2 回归&#xff1a;误差平方和SSE1.3 二分类交叉熵损失的原理与实现1.3.1 极大似然估计求解二分类交叉熵损失1.3.2 实现二类交叉熵损失1.4 多分类交叉熵损失的原理与实现1…

人机协同中的层次映射关系研究:从自然语言处理到智能系统设计

一、引言&#xff1a;人机协同的层次化认知基础人机协同作为人工智能领域的核心研究方向&#xff0c;正经历从简单工具使用到深度智能协作的范式转变。在这一演进过程中&#xff0c;如何建立人类意图与机器执行之间的有效映射关系成为关键挑战。自然语言处理(NLP)领域中&#x…

2025主流大模型核心信息

2025主流大模型核心信息国际主流大模型1. GPT-5 (OpenAI)版本特性&#xff1a;多模态能力支持图像、视频、音频的复杂理解与生成&#xff1b;超长上下文处理能力达1M tokens&#xff1b;推理能力接近专家水平优势&#xff1a;综合性能领先&#xff0c;编程能力强(SWE-bench Ver…

将容器连接到默认桥接网络

1.列出当前已有的网络[roothost1 ~]# docker network ls NETWORK ID NAME DRIVER SCOPE db2f3a6af212 bridge bridge local 4251d9be020b host host local ba96ad98e029 none null local2.启动两个 ash &#xff08; Alpine 操作系…

安全审计-Ubuntu防火墙ufw

文章目录 一、为什么运维需要使用防火墙? 二、Ubuntu 上常用的防火墙工具 三、UFW 常用命令及运维使用示例 1. 安装 UFW(如果尚未安装) 2. 查看防火墙状态 3. 设置默认策略(强烈建议) 4. 允许必要服务(常见运维场景) ✅ 允许 SSH(远程管理,最重要!) ✅ 允许 HTTP / …

iPhone 17系列包含哪些版本,各版本又有哪些配置,硬件、功能、性能、价格详细介绍

文章目录版本信息配置信息版本信息 iPhone 17系列提供了四个版本&#xff1a;iPhone 17 (标准版)、iPhone 17 Air、iPhone 17 Pro 和 iPhone 17 Pro Max。它们在设计、性能、影像等方面各有侧重&#xff0c;下面是一个快速概览表格&#xff0c;帮助你直观了解它们的核心区别&a…

Go模块自动导入教学文档

目录 概述核心概念实现原理项目结构代码实现高级特性最佳实践常见问题 概述 Go语言作为一门静态类型语言&#xff0c;没有像Python那样的动态import机制。但是&#xff0c;我们可以通过设计模式和架构设计来实现"自动导入模块"的功能。这种模式特别适合微服务架构…

深入解析Spring AOP核心原理

一 Spring-AOP1.对SpringAOP理解AOP是OOP的延续&#xff0c;是软件开发中的一个热点&#xff0c;也是Spring框架中的一个重要内容&#xff0c;是函数式编程的一种衍生泛型。利用AOP可以对业务逻辑的各个部分进行隔离&#xff0c;从而使得业务逻辑各部分之间的耦合度降低&#x…

大数据与AI:一场“数据盛宴”与“智能大脑”的奇妙邂逅

在当今这个信息爆炸的时代&#xff0c;大数据和AI&#xff08;人工智能&#xff09;就像一对热恋中的情侣&#xff0c;天天黏在一起&#xff0c;形影不离。它们的结合&#xff0c;不仅改变了我们的生活方式&#xff0c;还让这个世界变得更加有趣和奇妙。今天&#xff0c;就让我…

解决window下共享资源报“不允许一个用户使用一个以上用户名与服务器或共享资源的多重连接“问题

问题现象&#xff1a; 使用不同samba共享账号登录同一服务器ip共享文件夹资源时会报错误提示解决办法&#xff1a; 1.使用net use命令查看已保存的网络连接 C:\Users\Administrator>net use 会记录新的网络连接。状态 本地 远程 网络----…

SciKit-Learn 全面分析分类任务 wine 葡萄酒数据集

背景 wine 葡萄酒数据集&#xff0c;提供了对三种不同品种的意大利葡萄酒的化学分析结果 主要特点&#xff1a; 数据集规模&#xff1a;总共有 178 个样本特征数量&#xff1a;每个样本有 13 个化学特征&#xff0c;包括酒精、苹果酸、灰分、镁等类别数量&#xff1a;总共有 3 …