【技术分享】Livedata粘性事件实现源码解析,让你彻底掌握数据更新机制

news2024/11/14 21:43:43

概述

Livedata粘性事件是Android中常用的一种观察者模式,它可以让数据在发生改变时通知观察者并更新UI。在实际开发中,我们可能会遇到粘性事件的情况,即先发送了一个数据,后来才有观察者来监听,这时候我们需要保证观察者能够接收到最新的数据。本文将对Livedata粘性事件的原理以及Framework源码进行分析。

一、Livedata粘性事件的原理

在使用Livedata时,我们可以通过调用setValue方法来设置数据的值,并且可以通过observe方法来添加观察者。如果在观察者添加之前已经调用了setValue方法,那么这个数据就成为了粘性事件。

当观察者被添加到Livedata中时,如果Livedata已经有数据了,那么会立即将这个数据发送给观察者。而如果没有数据,那么就不会发送数据,等到Livedata的数据发生变化时才会发送。

粘性事件的原理

在LiveData中,如果您使用了setValue方法,那么当Observer订阅LiveData时,Observer将收到最新的更新,但是,如果在setValue调用之前已经有一个Observer订阅了LiveData,那么它将不会收到更新,这就是所谓的“粘性事件”。

LiveData的粘性事件是通过内部mLastVersion计数器来实现的。每当LiveData的setValue方法被调用时,mVersion会自增1,并将当前版本号与mLastVersion进行比较,如果当前版本号大于mLastVersion,则LiveData将通知所有的观察者,如果当前版本号小于或等于mLastVersion,则LiveData不会通知观察者。当观察者订阅LiveData时,LiveData将当前版本号分配给观察者的版本号,这样就可以确定观察者是否应该接收最新更新的数据。

粘性事件的代码示例

以下是Livedata粘性事件的代码示例:

kotlinCopy codeclass StickyLiveData<T> : MutableLiveData<T>() {
​
    private var stickyData: T? = null
​
    override fun setValue(value: T?) {
        stickyData = value
        super.setValue(value)
    }
​
    override fun postValue(value: T?) {
        stickyData = value
        super.postValue(value)
    }
​
    override fun observe(owner: LifecycleOwner, observer: Observer<in T>) {
        // 如果已经有粘性数据了,直接将它分发给观察者
        if (stickyData != null) {
            observer.onChanged(stickyData)
        }
        super.observe(owner, object : Observer<T> {
            override fun onChanged(t: T) {
                observer.onChanged(t)
            }
        })
    }
}

在这个示例中,我们创建了一个StickyLiveData类,它是MutableLiveData的子类。我们重写了setValue和postValue方法来处理粘性数据。我们还重写了observe方法,以便在有观察者订阅LiveData时能够分发粘性数据。

在observe方法中,如果有粘性数据存在,我们将粘性数据分发给新的观察者。然后,我们将观察者传递给super.observe方法,以便它可以在LiveData上进行常规观察。

最后,使用StickyLiveData类时,您只需要像这样订阅它:

kotlinCopy codestickyLiveData.observe(this, Observer {
    // 处理更新数据
})

这样就可以处理粘性数据并分发最新的数据。

二、Framework源码分析

LiveData是一个Android Architecture Component,用于支持可观察的数据,它可以使观察者(如Activity、Fragment等)自动更新UI,以反映底层数据的更改。在LiveData中,有一个重要的概念是粘性事件(Sticky Event),它允许观察者在订阅LiveData时立即接收到最新的数据。

下面是LiveData源码的简要分析:

LiveData是一个具有生命周期感知能力的可观察的数据持有者类,当数据发生变化时,它可以通知所有的观察者进行更新操作。LiveData具有以下特点:

  1. 数据持有者:LiveData持有数据,并对外提供对数据的访问,LiveData支持泛型,可以包含任何类型的数据。
  2. 观察者模式:LiveData使用观察者模式,允许多个观察者观察同一个LiveData对象。
  3. 生命周期感知:LiveData可以感知Activity和Fragment等组件的生命周期,以此来确保数据更新仅在组件处于激活状态时进行。
  4. 粘性事件:LiveData可以存储最新的数据,并在新的观察者订阅LiveData时,立即向观察者发送最新的数据。

下面是LiveData源码中粘性事件的实现原理示例:

lessCopy codepublic class StickyLiveData<T> extends LiveData<T> {
    private T mStickyData;
​
    /**
     * 在setValue之前先把粘性事件的数据赋值给mStickyData
     */
    @Override
    public void setValue(T value) {
        mStickyData = value;
        super.setValue(value);
    }
​
    /**
     * 在observe时先判断mStickyData是否有值
     */
    @Override
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
        if (mStickyData != null) {
            observer.onChanged(mStickyData);
        }
        super.observe(owner, observer);
    }
}

上面的代码展示了如何在LiveData中实现粘性事件的功能。在setValue方法中,将最新的数据存储在mStickyData变量中,同时通过调用super.setValue(value)将数据更新给所有的观察者。在observe方法中,先判断mStickyData是否有值,如果有值则立即将其发送给新的观察者,这样就可以确保观察者可以立即接收到最新的数据。

以上是对LiveData源码中粘性事件的实现原理的简要分析。在实际的开发中,粘性事件可以帮助我们更好地处理数据更新的问题,提高应用的性能和用户体验。更多Android framework的学习进阶;可以参考《Android framework全家桶》文档资料里面包含framework中的底层、通信等等覆盖95%的技术。点击查看详细类目。

image.png

三、总结

Livedata粘性事件是一种非常实用的观察者模式,它可以保证观察者能够接收到最新的数据。在实际开发中,我们经常会遇到粘性事件的情况,因此了解其原理以及源码实现是非常重要的。

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

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

相关文章

集合Map高频面试题

1、介绍下 HashMap 的底层数据结构吧。 在 JDK 1.8&#xff0c;HashMap 底层是由 “数组链表红黑树” 组成&#xff0c;如下图所示&#xff0c;而在 JDK 1.8 之前是由 “数组链表” 组成&#xff0c;就是下图去掉红黑树。 2、为什么使用“数组链表”&#xff1f; 使用 “数组…

如何用 ModelScope 实现 “AI 换脸” 视频

前言 当下&#xff0c;视频内容火爆&#xff0c;带有争议性或反差大的换脸视频总能吸引人视线。虽然 AI 换脸在市面上已经流行了许久&#xff0c;相关制作工具或移动应用也是数不胜数。但是多数制作工具多数情况下不是会员就是收费&#xff0c;而且替换模板有限。以下在实战的角…

三电技术之电机电驱技术

三电技术之电机电驱技术 1 基本功能 电动汽车驱动电机及其控制系统是电动汽车的心脏&#xff0c;是把电能转化为机械能来驱动车辆的部件。它的任务是在驾驶人的控制下&#xff0c;高效率地将动力电池的能量转化为车轮的动能&#xff0c;或者将车轮上的动能反馈到动力电池中。 …

16 个优秀的 Vue 开源项目

为什么我们要关注Vue Vue是一个用于构建用户界面的JavaScript框架。值得关注的是&#xff0c;它在没有谷歌和Facebook的支持下获得了大量的人气。 Vue是结合react和angular的最好的方法&#xff0c;并且拥有一个有凝聚力的&#xff0c;活跃的&#xff0c;能够应对开发问题的大型…

消息队列如何保证消息的幂等性

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 文章目录 什么是幂等性什么是消息的幂等性为什么会出现消息幂等性问题该如何解决消息幂等性问题总结 在分布式系统中&#xff0c;消息队列…

【C++入门必备知识:命名空间与关键字】

【C入门必备知识&#xff1a;命名空间与关键字】 【命名空间】①.命名空间定义Ⅰ.正常定义命名空间Ⅱ.嵌套定义命名空间Ⅲ.合并命名空间 ②.命名空间的使用Ⅰ.命名空间名称及域作用限定符Ⅱ.using成员引入Ⅲ.using namespace名称全部引入 ③.注意事项 【C关键字(C98)】 【命名空…

Ubuntu系统安装docker、docker-compse

环境&#xff1a;Ubuntu 20.04.4 LTS (GNU/Linux 5.4.0-100-generic x86_64) 一、安装docker 1.卸载旧版本 ubuntu下自带了docker的库&#xff0c;不需要添加新的源。 但是ubuntu自带的docker版本太低&#xff0c;需要先卸载旧的再安装新的 sudo apt-get remove docker docke…

免费的语音转文字软件有哪些?推荐一款好用的

随着人工智能技术的不断发展&#xff0c;语音识别技术已经得到了广泛的应用。语音转文字软件是其中的一种应用&#xff0c;它能够将人们说出的话语自动转化为文字&#xff0c;从而方便人们进行文本处理、记录、存档等操作。在现实生活中&#xff0c;有很多人需要使用语音转文字…

Redis的哈希表是如何扩容的?

文章目录 一般面试回答哈希表结构字典数据结构解决哈希冲突扩容/缩容对字典的哈希表rehash步骤 渐进式rehash渐进式rehash步骤 相关问题 一般面试回答 redis 解决冲突的方法是使用链地址法&#xff0c;另外当容量不足的时候&#xff0c;则使用Rehash 进行扩容。 Rehash&#x…

96-Linux_UDP实现客户端和服务器端

UDP实现客户端和服务器端 一.udp实现客户端和服务器端的编程流程二.udp实现实现客户端和服务器端所用的接口1.socket2.sendto3.recvfrom 三.udp服务器端代码和客户端的代码1.服务器端2.客户端 一.udp实现客户端和服务器端的编程流程 udp提供无链接的,不可靠的,数据报服务; 二…

burp suite 插件编写-基础

文章目录 前言一、插件的官方文档二、Montoya API jar包结构三、HTTP 处理程序小结 四、代码示例 前言 burp插件入门。入门&#xff0c;我们大概有一个框架&#xff0c;心里不再有怎么做&#xff0c;为什么可以这么做的疑问。现在就要更具体的来回答“怎么做”这个问题。我们通…

基于C#编程建立泛型Vector数据类型及对应处理方法

目录 一、简介 二、方法 2.1 建立Vector类 2.2 Vector成员 2.3 Vector属性 2.4 Vector方法 2.4.1 构造函数 2.4.2 Vector元素操作方法 2.4.3 Vector 运算 三、调用方法 3.1 方法 3.1.1 Append 3.1.2 this[] 3.1.3 Insert 3.1.4 DelLen 3.1.5 FindNumber 3.1.6 …

PHP快速入门04-前后端数据交互与文件上传

文章目录 前言前后端数据交互与文件上传前后端数据交互 $_GET $_POST文件上传 总结 前言 本文已收录于PHP全栈系列专栏&#xff1a;PHP快速入门与实战 前后端数据交互与文件上传 前后端数据交互 $_GET $_POST 他们都是超全局变量。它们用于从HTTP请求中获取数据&#xff0…

除了学历,你更需要有能力

遥想当年&#xff0c;家里培养出一个大学生&#xff0c;是多荣耀的事&#xff01;可现今却处于一个比较尴尬的状态。 为什么大学生贬值得这么厉害&#xff1f;其实大学生之所以会不值钱不外乎三大原因&#xff1a;量大、与企业需求不匹配、质量差。 高校扩招下&#xff0c;大…

OpenAI最新官方ChatGPT聊天插件接口《接入插件快速开始》全网最详细中英文实用指南和教程,助你零基础快速轻松掌握全新技术(二)(附源码)

Getting started 快速开始 前言Introduction 导言Plugin manifest 插件清单OpenAPI definition OpenAPI定义Running a plugin 运行插件Setup a local proxy of your public API 设置公共API的本地代理 Writing descriptions 书写描述Best practices Debugging 排除故障其它资料…

【Android】popup windows 的使用方式 和 遇到不显示的坑

背景 在项目开发过程中有一个需求就是点击一个问号icon 弹出相关提示信息在下面&#xff0c;那么就得对这个做适配了。 计划采用popupWindow 实现&#xff1a; 参考 实现 基本的套路就是写一个xml对应的布局&#xff0c;然后在java 层使用即可。 特别注意的是该xml布局要慎…

ubuntu输入法问题汇总

Xfce4桌面环境输入法 Ubuntu20.04、ubuntu21.04中安装xfce4桌面环境&#xff0c;自带中文输入法&#xff1b; 原生xubuntu20.04中文输入法问题解决办法&#xff1a; 更新语言支持失败的话&#xff0c;终端键入&#xff1a;sudo apt-get install cmake qt5-default qtcreator…

网络安全——传输层安全协议(3)

作者简介&#xff1a;一名云计算网络运维人员、每天分享网络与运维的技术与干货。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 目录 前言 一.SSL密钥更改协议 二.SSL告警协议 关闭报警 错误报警 三.SSL协议安全性…

软件测试测试开发技能

从事软件测试许多年&#xff0c;想必很多人都有感到迷茫不知所措的时候&#xff0c;人生的十字路口有很多&#xff0c;该如何抉择呢&#xff1f;有人成功转型&#xff0c;QA、项目管理、配置管理。当然还有技术型&#xff0c;性能测试、自动化测试、测试开发&#xff0c;而想要…

爬虫JS逆向思路-hook钩子

网络上几千块都学不到的JS逆向思路这里全都有&#x1f44f;&#x1f3fb;&#x1f44f;&#x1f3fb;&#x1f44f;&#x1f3fb; 本系列持续更新中&#xff0c;三连关注不迷路&#x1f44c;&#x1f3fb; 干货满满不看后悔&#x1f44d;&#x1f44d;&#x1f44d; &…