一种全局数据变化而且是多个的通知实现

有个需求:
从activityA,打开activityB, activityC 或者还存在viewpager上的其他Fragment。甚至activityB,又打开了activityBA。
在这些界面上,大家都有相同的数据Bean(name, info, isFavourite)去展示成卡片列表。
这种情况下,当操作了某个界面的Bean数据,更新当前自己是很容易的;但是当想更新其他界面,其他activity就比较麻烦了。

这里给出一个实现方案。

interface ICrossNotify<T> {@MainThreadfun onCrossNotify(data:List<T>?)
}
 
/*** @date :2024/7/18 19:34* @description: 跨activity通知。* 必须把它变成一个单例(或存储在单例里面,唯一。但可以多个实例。)** 用法在Activity或者Fragment* 1. onCreate()里面调用callOnCreate(this)* 2. 然后,给它实现ICrossNotify接口。一切就已经完成。** 更新数据,调用changeData,必须保证是主线程。** 内部会针对,监听的前后,分别通知不同的时机的数据。*/
class CrossActivityNotifyListObserver<T : Any>(private val mainHandler:Handler) : DefaultLifecycleObserver{//value的左边代表是否监听后,有更新过。右边代表更新后的值。private data class CrossActivityNotifyListInfo<T>(var isResumed:Boolean,val data: ArrayList<T> = ArrayList(4))private val TAG = "crossNotify"private val callbackList = HashMap<LifecycleOwner, CrossActivityNotifyListInfo<T>>(8)/*** 如果你希望数据进行去重,比如Info(a, b, c),其中以a字段如果相同就认为是同一份数据,* 本类中将会进行去重。避免多次操作同一个对象。*/var distinct:((a:T, b:T)->Boolean)? = null/*** 每次resume都调用本函数。内部做了处理。*/fun callOnCreate(owner: LifecycleOwner) {//如果不存在,就将入监听列表if (owner !is ICrossNotify<*>) {throw IllegalArgumentException("Do not call callOnCreate() because owner is not ICrossNotify!")}owner.lifecycle.addObserver(this)callbackList[owner] = CrossActivityNotifyListInfo(isResumed = true)if (BuildConfig.DEBUG) Log.d(TAG, "callOnCreate add owner $owner")}/*** 暂定必须,不得为空。* 会帮你运行在主线程。*/fun notify(d:T) {if (BuildConfig.DEBUG) {Log.d(TAG, "changeData $d")}if (!isMainThread) {mainHandler.post {changeDataMainThread(d)}} else {changeDataMainThread(d)}}private fun changeDataMainThread(d: T) {callbackList.forEach { (owner, info) ->addWithDistinct(info, d)if (info.isResumed) {if (BuildConfig.DEBUG) Log.d(TAG, "changeData owner $owner isResumed onDateChanged")owner.asOrNull<ICrossNotify<T>>()?.onCrossNotify(fetchAndClear(info))} else {if (BuildConfig.DEBUG) Log.d(TAG, "changeData owner $owner isNotResumed just save")}}}override fun onResume(owner: LifecycleOwner) {super.onResume(owner)//如果已经存在,就把当前的通知出来。val info = callbackList[owner]!!info.isResumed = trueif (info.data.isNotEmpty()) {if (BuildConfig.DEBUG) Log.d(TAG, "onResumeCall exist $owner onDataChanged ${info.data}")val outList = fetchAndClear(info)owner.asOrNull<ICrossNotify<T>>()?.onCrossNotify(outList)} else {if (BuildConfig.DEBUG) Log.d(TAG, "onResumeCall exist $owner no change.")}}private fun addWithDistinct(info: CrossActivityNotifyListInfo<T>, data:T) {distinct?.let { dist->var size = info.data.sizewhile (size > 0) { //倒序遍历移除size--if (dist(info.data[size], data)) {info.data.removeAt(size)}}}info.data.add(data)}private fun fetchAndClear(info: CrossActivityNotifyListInfo<T>): List<T>? {if (info.data.isEmpty()) {return null}val outList = ArrayList<T>(info.data)info.data.clear()return outList}override fun onPause(owner: LifecycleOwner) {super.onPause(owner)callbackList[owner]?.isResumed = falseif (BuildConfig.DEBUG) Log.d(TAG, "onPause owner $owner")}override fun onDestroy(owner: LifecycleOwner) {super.onDestroy(owner)callbackList.remove(owner)if (BuildConfig.DEBUG) Log.d(TAG, "onDestroy owner remove $owner")}
}

在全局的某个单例中定义全局单例变量:


val changeData = CrossActivityNotifyListObserver<Pair<String, Boolean>>(mainHandler).also {it.distinct = { a, b->a.first == b.first}}

在更新数据的时候,changeData.notify(bean)。

想监听的activity、fragment,在onCreate函数中调用callOnCreate,并让它实现ICrossNotify即可。

这个简易的框架的目的是当onResume状态下,就把当前通知的单条变化直接通知到;
非resume状态下,就收集后,等待resume一来就发送。

代码设计为避免了粘性数据,即从某个界面监听开始,后续的变化它才会接受到。而且提供了计算去重distinct 的逻辑,比如Bean(name, info, isFavourite), 你可以判断a.name == b.name 就认为它是相同的,就允许覆盖。

简易好用。

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

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

相关文章

社会科学研究

《社会科学研究》是四川省社会科学院主管主办&#xff0c;国内外公开发行的综合性人文社会科学学术理论刊物&#xff0c;于1979年3月创刊&#xff0c;主要刊登经济学、政治学、法学、社会学、哲学、历史学、文学、新兴交叉等学科的研究论文&#xff0c;是我国人文社科界向海内外…

CentOS 7 yum官方源失效

问题 2024年7月&#xff0c;官方对centos 7停止了维护&#xff0c;yum的源网址mirror.centos.org也已经无法访问。 在此情况下&#xff0c;无法正常使用yum进行安装和更新工具。 在尝试了更换阿里源之后&#xff0c;仍然有部分工具库无法访问。 通用解决方案 1. 打开/etc/y…

AWS Certified Developer Associate备考笔记

AWS Certified Developer Associate备考笔记 缓慢更新中&#xff0c;如果你也正在关注该考试&#xff0c;请点赞后评论感兴趣的章节&#xff0c;可加快我的更新速度 &#x1f603; 文章目录 AWS Certified Developer Associate备考笔记一、IAM二、EC2三、EC2 Instance Storage…

CAPL语言设计(3)——流程控制

CAPL语言设计&#xff08;3&#xff09;——流程控制 if条件语句if一般格式if与else格式 switch语句while循环语句while循环的一般形式为&#xff1a;do-while循环 for循环语句break语句return语句 if条件语句 CAPL中的if语句有以下两种形式 if一般格式 if (表达式) 语句;例…

【WordPress插件】Media folder汉化版-媒体文件夹-v5.1.2

WP媒体文件夹(WP Media folder)是一个真正的节省图片加载时间的插件&#xff0c;你可以管理文件和图片&#xff0c;从本地WordPress媒体管理器。该插件还包括一个增强版的WordPress图库管理器&#xff0c;主题 NextGEN图库导入器。 【WordPress插件】Media folder汉化版-媒…

Jetson-AGX-Xavier gstreamer UDP推拉流

Jetson-AGX-Xavier gstreamer UDP推拉流 安装nvidia-jetpack 使用硬件编解码 sudo apt-get install nvidia-jetpackgstreamer UDP 推流 gst-launch-1.0 v4l2src device"/dev/video4" ! video/x-raw, format(string)UYVY, width(int)1920, height(int)1080 ! nvvid…

C++的STL简介

0.STL简介 C的STL&#xff08;Standard Template Library&#xff0c;标准模板库&#xff09;是C标准库的一部分&#xff0c;它提供了一套通用的类和函数模板&#xff0c;用于处理数据结构和算法。STL的主要组件包括&#xff1a; 容器分配器算法迭代器适配器仿函数 容器 容…

数据库系统概论:事务与并发一致性问题

随着网络应用的普及&#xff0c;数据库并发问题变得越来越重要。数据库并发指的是多个用户或进程同时访问和操作数据库的能力。它是数据库系统性能优化的重要方面&#xff0c;旨在提高系统的吞吐量和响应时间&#xff0c;以满足多用户同时访问数据库的需求。然而&#xff0c;这…

JAVA IO中的缓冲流,PrintStream类和PrintWriter以及System.in获取用户输入流详解

1.缓冲流 在java中&#xff0c;缓x冲流&#xff08;Buffered Streams&#xff09;是非常有用的&#xff0c;它们属于处理流的一种&#xff0c;用于提高原始数据流&#xff08;如文件流&#xff0c;网络流&#xff09;的读取和写入效率。 Java 的缓冲流是对字节流和字符流的一种…

白骑士的PyCharm教学基础篇 1.1 PyCharm简介

系列目录 上一篇&#xff1a;无内容 什么是PyCharm&#xff1f; PyCharm 是由 JetBrains 开发的一款集成开发环境&#xff08;IDE&#xff09;&#xff0c;专为 Python 编程语言设计。它提供了强大的代码编辑、调试、测试和部署功能&#xff0c;使得 Python 开发更加高效和便…

Linux NFS服务搭建及使用

一、NFS 服务器介绍 nfs &#xff08; Network File System &#xff09;即网络文件系统&#xff0c;其基于 UDP/IP使用 nfs 能够在不同计算机之间通过网络进行文件共享&#xff0c;能使使用者访问网络上其它计算机中的文件就像在访问自己的计算机一样。 二、NFS 服务器的特点 …

阿里云服务器 篇四:404页面模板

文章目录 系列文章tsParticles 404 Templates安装方法效果展示更多系列文章 阿里云服务器 篇一:申请和初始化 阿里云服务器 篇二:搭建静态网站 阿里云服务器 篇三:提交搜索引擎收录 阿里云服务器 篇四:404页面模板 tsParticles 404 Templates 官网:https://github.com/…

Websocket自动消息回复服务端工具

点击下载《Websocket自动消息回复服务端工具》 1. 前言 在进行Websocket开发时&#xff0c;前端小伙伴通常是和后端开发人员同步进行项目开发&#xff0c;经常会遇到后端开发人员接口还没开发完&#xff0c;也没有可以调试的环境&#xff0c;只能按照接口文档进行“脑回路开发…

【源码阅读】osproxy对象存储分布式代理(2)--初始化底层服务和日志器

文章目录 初始化底层服务函数返回类型APPRedis newLangGoConfig()函数initLangGoConfig()函数 初始化日志器 上一章【源码阅读】osproxy对象存储分布式代理&#xff08;1&#xff09;下一章 这部分涉及了对于底层服务的初始化和日志器的初始化两部分 // 初始化底层服务&#x…

d3d12.dll 文件缺失如何解决?五种修复丢失问题的方法

d3d12.dll 文件缺失如何解决&#xff1f;它为什么会不见呢&#xff1f;今天&#xff0c;我们将探讨 d3d12.dll 文件的重要性、原因以及丢失时的解决策略。本文将全面介绍 d3d12.dll 文件&#xff0c;并提供五种修复丢失问题的方法。 d3d12.dll文件是什么的详细介绍 d3d12.dll …

6 回归集成:xgb、lgb、cat

这个代码是从kaggle上拷贝过来的&#xff1a; 如何使用三个树模型模块化训练&#xff1b;文本特征如何做&#xff0c;如何挖掘&#xff1b;时间特征的处理&#xff1b;模型权重集成&#xff1b; import pandas as pd import math import numpy as np import joblib import…

【JS逆向课件:第八课:异常处理】

异常处理 首先我们要理解什么叫做**"异常”**&#xff1f; 在程序运行过程中&#xff0c;总会遇到各种各样的问题和错误。有些错误是我们编写代码时自己造成的&#xff1a; 比如语法错误、调用错误&#xff0c;甚至逻辑错误。 还有一些错误&#xff0c;则是不可预料的错误…

vst 算法R语言手工实现 | Seurat4 筛选高变基因的算法

1. vst算法描述 &#xff08;1&#xff09;为什么需要矫正 image source: https://ouyanglab.com/singlecell/basic.html In this panel, we observe that there is a very strong positive relationship between a gene’s average expression and its observed variance. I…

OpenAI 推出 GPT-4o mini,一种更小、更便宜的人工智能模型

OpenAI 最近推出了新型人工智能模型 GPT-4o mini&#xff0c;以其较小体积和低成本受到关注。这款模型在文本和视觉推理任务上性能优越&#xff0c;且比现有小型模型更快、更经济。GPT-4o mini 已向开发者和消费者发布&#xff0c;企业用户将在下周获得访问权限。 喜好儿网 在…

ubuntu22.04下YOLOv5 TensorRT模型部署

目录 Ubuntu22.04环境配置 1.1 安装工具链和opencv 1.2 安装Nvidia相关库 1.2.1 安装Nvidia显卡驱动 1.2.2 安装 cuda11.7 安装cuDNN 下载下载 tensorrt 下载仓库TensorRT-Alpha并设置 从yolov5源码中导出onnx文件 ​编辑 利用tensorrt编译onnx模型 编译执行yolov5-t…