Android LiveData关键代码

1、observer方法

public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {assertMainThread("observe");if (owner.getLifecycle().getCurrentState() == DESTROYED) {// ignorereturn;}LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);if (existing != null && !existing.isAttachedTo(owner)) {throw new IllegalArgumentException("Cannot add the same observer"+ " with different lifecycles");}if (existing != null) {return;}owner.getLifecycle().addObserver(wrapper);}
  1. 首先判断LifecycleOwner是否为DESTROYED状态,如果是就直接忽略,不能添加。
  2. 其次用LifecycleOwnerobserver 组装成LifecycleBoundObserver包装实例wrapper
  3. 使用putIfAbsent()方法observer-wrapper作为key-value添加到观察者列表mObservers中。不能添加具有不同生命周期的相同观察者,否则会抛异常,但是同owner可以add多个Observer
  4. 最后用LifecycleOwnerLifecycle添加observer的封装wrapper

2、数据存储位置 

private SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers =
new SafeIterableMap<>();

3、在Lifecycle生命周期结束时移除对应观察者

4、值的更新

protected void setValue(T value) {assertMainThread("setValue");	//检查是否在主线程mVersion++;	//默认值是-1,每次更新数据都会自增mData = value;	//更新的数据赋值给mDatadispatchingValue(null);	//调用 dispatchingValue()方法并传入null,将数据分发给所有观察者。dispatchingValue如果传入null则是所有的观察者,如果是具体的ObserverWrapper对象,则通知到具体的Observer。
}

protected void postValue(T value) {boolean postTask;	//用于判断是否要更新//加锁解决多个子线程同时调用问题synchronized (mDataLock) {postTask = mPendingData == NOT_SET;mPendingData = value;	//将数据存入 mPendingData}if (!postTask) {return;}//通过线程池分发到主线程去处理ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
private final Runnable mPostValueRunnable = new Runnable() {@SuppressWarnings("unchecked")@Overridepublic void run() {Object newValue;synchronized (mDataLock) {newValue = mPendingData;mPendingData = NOT_SET;}setValue((T) newValue);}
};

真正的发送方法是considerNotify()

private void considerNotify(ObserverWrapper observer) {//观察者非活跃,直接returnif (!observer.mActive) {return;}//观察者状态活跃,但是当前变为了不可见状态,再调用activeStateChanged方法,并传入false,其内部会再次判断if (!observer.shouldBeActive()) {observer.activeStateChanged(false);return;}//如果数据版本已经是最新的了,那么直接返回if (observer.mLastVersion >= mVersion) {return;}//修改数据版本observer.mLastVersion = mVersion;observer.mObserver.onChanged((T) mData);//回调真正的mObserver的onChanged方法
}

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

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

相关文章

Docker-高级使用

前言 书接上文Docker-初级安装及使用_用docker安装doccano-CSDN博客&#xff0c;我们讲解了Docker的基本操作&#xff0c;下面我们讲解的是高级使用&#xff0c;请大家做好准备&#xff01; 大家如果是从初级安装使用过来的话&#xff0c;建议把之前镜像和搭载的容器数据卷里面…

Spring Boot常用注解详解:实例与核心概念

Spring Boot常用注解详解&#xff1a;实例与核心概念 前言 Spring Boot作为Java领域最受欢迎的快速开发框架&#xff0c;其核心特性之一是通过注解&#xff08;Annotation&#xff09;简化配置&#xff0c;提高开发效率。注解驱动开发模式让开发者告别繁琐的XML配置&#xff…

TRO再添新案 TME再拿下一热门IP,涉及Paddington多个商标

4月2日和4月8日&#xff0c;TME律所代理Paddington & Company Ltd.对热门IP Paddington Bear帕丁顿熊的多类商标发起维权&#xff0c;覆盖文具、家居用品、毛绒玩具、纺织用品、游戏、电影、咖啡、填充玩具等领域。跨境卖家需立即排查店铺内的相关产品&#xff01; 案件基…

经验分享-上传ios的ipa文件

.ipa格式的二进制文件&#xff0c;是打包后生成的文件&#xff0c;无论我们是放上去testflight测试还是正式上传到app store&#xff0c;都需要先上传到苹果开发者中心的app store connect上的构建版本上。 在app store connect上&#xff0c;上传构建版本的功能&#xff0c;它…

docker(3) -- 图形界面

1. 前言 在wsl(8) – 图形界面文章中介绍了wsl2默认是支持图形界面的&#xff0c;现在我们尝试下在docker中运行gui程序试试看。 2. x11-apps 启动一个docker&#xff0c;安装一些gui小程序&#xff0c;然后运行&#xff0c;发现会失败。ubuntu_base详见文章wsl(6) – 安装d…

Docker容器跑定时任务脚本

最近搞了一个Docker容器跑脚本&#xff0c;想设置一个定时任务&#xff0c;每天8点运行一次&#xff0c;结果死活不成功。排查了一天&#xff0c;有一点当局者迷了&#xff0c;明明时间是对的&#xff0c;明明时区是对的&#xff0c;定时任务也是启动的&#xff0c;它就是不执行…

【Linux】什么是完全限定域名

FQDN 是 “完全限定域名” (Fully Qualified Domain Name) 的缩写。 FQDN 是一个互联网上特定计算机或主机的完整且唯一的域名。它详细说明了该主机在域名系统 (DNS) 层级结构中的确切位置。 一个 FQDN 通常由以下几个部分组成&#xff0c;从左到右依次是&#xff1a; 主机名…

小结:BFD

*BFD&#xff08;双向转发检测&#xff0c;Bidirectional Forwarding Detection&#xff09;是一种快速、轻量级的故障检测机制&#xff0c;用于检测网络中两点之间的连通性。它广泛应用于各种场景 1. 检测 IP 链路 应用场景&#xff1a; BFD 用于检测两台设备之间的 IP 层连…

配置Spark历史服务器,轻松查看任务记录

在大数据处理中&#xff0c;Spark是一个强大的分布式计算框架。但当Spark服务重启后&#xff0c;之前的运行记录就会消失&#xff0c;给我们排查问题和分析任务执行情况带来不便。这时&#xff0c;配置Spark历史服务器就显得尤为重要&#xff0c;它能帮助我们保存和查看历史任务…

(六)RestAPI 毛子(外部导入打卡/游标分页/Refit/Http resilience/批量提交/Quartz后台任务/Hateoas Driven)

文章目录 项目地址一、外部导入打卡功能1.1 创建实体1. Entry实体2. EntryImport实体3. 添加数据库配置4. 创建表 1.2 创建DTOs1.3 创建GetEnties Controller 二、游标分页2.1 创建所需要的DTOs1. 创建游标分页的请求参数2. 创建CollectionResponse3. 添加游标编码和解码的DTO …

Node.js CSRF 保护指南:示例及启用方法

解释 CSRF 跨站请求伪造 (CSRF/XSRF) 是一种利用用户权限劫持会话的攻击。这种攻击策略允许攻击者通过诱骗用户以攻击者的名义提交恶意请求,从而绕过我们的安全措施。 CSRF 攻击之所以可能发生,是因为两个原因。首先,CSRF 攻击利用了用户无法辨别看似合法的 HTML 元素是否…

Flink介绍——实时计算核心论文之Dataflow论文总结

数据流处理的演变与 Dataflow 模型的革新 在大数据处理领域&#xff0c;流式数据处理系统的发展历程充满了创新与变革。从早期的 S4 到 Storm&#xff0c;再到 MillWheel&#xff0c;每一个系统都以其独特的方式推动了技术的进步。S4 以其无中心架构和 PE&#xff08;Processi…

Arduino 入门学习笔记(五):KEY实验

Arduino 入门学习笔记&#xff08;五&#xff09;&#xff1a;KEY实验 开发板&#xff1a;正点原子ESP32S3 例程源码在文章顶部可免费下载&#xff08;审核中…&#xff09; 1. GPIO 输入功能使用 1.1 GPIO 输入模式介绍 在上一文章中提及到 pinMode 函数&#xff0c; 要对…

Centos9安装docker

1. 卸载docker 查看是否安装了docker yum list | grep docker卸载老版本docker&#xff0c;拷贝自官网 sudo yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine卸载新版本…

Pgvector+R2R搭建RAG知识库

背景 R2R是一个采用Python编写的开源AI RAG框架项目&#xff0c;与PostgreSQL技术栈集成度高&#xff0c;运行需求资源少&#xff08;主要是本人的Macbook air m1内存只有8G&#xff09;的特点&#xff0c;对部署本地私有化化AI RAG应用友好。 Resource Recommendations Whe…

go中redis使用的简单介绍

目录 一、Redis 简介 二、Go中Redis的使用 1. 安装Go Redis包 2. 单机模式 连接示例 3. 哨兵模式 依赖 连接示例 三、Redis集群 1. 集群模式 集群部署 部署结构 使用redis-cli创建集群 连接示例 四、常用数据结构与操作 1. 字符串&#xff08;String&#xff0…

北京工业大学25计专上岸经验分享

1.个人情况介绍 本科就读于河北双非&#xff0c;专业为计算机科学与技术&#xff0c;四级三次498&#xff0c;六级两次460&#xff0c;拿过几次校级奖学金&#xff0c;竞赛经历有蓝桥杯国三、数学竞赛省二。本科成绩排名靠前&#xff0c;保研保7排8&#xff0c;遗憾选择考研继…

在 Ubuntu 24.04 系统上安装和管理 Nginx

1、安装Nginx 在Ubuntu 24.04系统上安装Nginx&#xff0c;可以按照下面的步骤进行&#xff1a; 1.1、 更新系统软件包列表 在安装新软件之前&#xff0c;需要先更新系统的软件包列表&#xff0c;确保获取到最新的软件包信息。打开终端&#xff0c;执行以下命令&#xff1a; …

HarmonyOS4+NEXT星河版入门与项目实战(26)-----版本控制与代码托管

引言 随着移动应用开发技术的不断进步,华为推出的鸿蒙操作系统(HarmonyOS)以及其配套的集成开发环境DevEco Studio逐渐成为开发者关注的焦点。对于新手开发者来说,掌握版本控制和代码托管不仅是提高工作效率的关键,也是团队协作的重要基础。本文将介绍如何在使用DevEco S…

利用Arcgis自己绘制shp文件

1.选择自己想要创建的shp文件的位置 我是直接创建在连接文件夹中 2.右键-新建-shp 3.设置名称、要素类型、空间参考 4、点击创建要素 5、右侧选择图层、创建面 6、开始绘制&#xff0c;双击任意位置结束绘制 之后可以改一下shp文件的名字