Android Jetpack—LiveData和数据倒灌

2023-10-16 06:10

本文主要是介绍Android Jetpack—LiveData和数据倒灌,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.LiveData

LiveData是Jetpack包提供的一种可观察的数据存储器类,它可以通过添加观察者被其他组件观察其变更。不同于普通的观察者,LiveData最重要的特征是它具有生命周期感知能力,它遵循其他应用组件(如Activity、Fragment或Service)的生命周期。这种感知能力可确保LiveData仅更新处于活跃生命周期状态的应用组件观察者。如在Activity中如果数据更新了但Activity已经处于destroy状态,则LiveData就不会通知Activity(observer)了。

回想一下,在项目中是不是经常会碰到这样的问题:当网络请求结果回来的时候,经常需要判断Activity或者Fragment是否已经Destroy, 如果不是destroy才更新UI。而如果使用Livedata的话,因为它是在Activity处于onStart或者onResume的状态时,它才会进行相应的回调,因而可以很好得处理这个问题,不必写一大堆的 activity.isDestroyed()。

注意:当Activity不是处于激活状态的时候,如果想Livedata调用setValue之后立即回调obsever的onChange方法,而不是等到Activity处于激活状态的时候才回调obsever的onChange方法,可以使用observeForever方法,但是必须在onDestroy的时候调用removeObserver()方法来停止对LiveData的观察,否则LiveData会一直处于激活状态,Activity就永远不会被系统自动回收,会造成内存泄露。

LiveData有两个子类:MutableLiveData和MediatorLiveData。MutableLiveData针对单个需要观察的数据进行了封装,而MediatorLiveData则可以观察其它的LiveData。开发过程中通常使用LiveData的子类,而不是去继承LiveData。

LiveData通常会配合ViewModel一起使用,ViewModel负责触发数据的更新,更新会通知到LiveData,然后LiveData再通知活跃状态的观察者。当然,LiveData也可以单独使用,分为三步:

①创建对应数据类型的LiveData

②添加观察者与Lifecycle建立联系

③发送对应的数据进行更新

比如MutableLiveData的使用方法:

private void liveDataTest(){

    MutableLiveData<String> mutableLiveData = new MutableLiveData<>();

    mutableLiveData.observe(this, new Observer<String>() {

        @Override

        public void onChanged(String value) {

           //如果数据有变化的话,这里会接收到通知,可以在这里可以做一些反应,比如更新界面

        }

     });

    mutableLiveData.setValue("我的值变化了");

}

 

2.LiveData使用

①引入依赖

implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'

②布局文件

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout >

    <TextView

        android:id="@+id/tv_text"

        android:layout_width="match_parent"

        android:layout_height="50dp"/>

    <LinearLayout

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:orientation="horizontal">

        <ImageButton

            android:id="@+id/img_button_add"

            android:layout_width="70dp"

            android:layout_height="70dp"/>

        <ImageButton

           android:id="@+id/img_button_subtract"

            android:layout_width="70dp"

            android:layout_height="70dp"   />

    </LinearLayout>

</LinearLayout>

③创建ViewModelWithLiveData类继承于ViewModel,在这个类里面声明LiveData变量

public class ViewModelWithLiveData extends ViewModel {

    private MutableLiveData<Integer> LikedNumber;  

    public MutableLiveData<Integer> getLikedNumber() {

        if (LikedNumber == null) {

            //LikedNumber是对象类型,不是基本数据类型,所以要保证变量不是空的

            LikedNumber = new MutableLiveData<>();       

            LikedNumber.setValue(0);  //初始化为0

        }

        return LikedNumber;

    }

    public void addLikedNumber(int n) {

        LikedNumber.setValue( LikedNumber.getValue() + n);

    }

}

④给viewModelWithLiveData里面的LiveData变量添加一个观察,点击按钮实现+1、-1操作

public class LiveDataTestActivity extends AppCompatActivity {

    private ViewModelWithLiveData viewModelWithLiveData;

    private TextView tv_text;

    private ImageButton button_add;

    private ImageButton button_subtract;

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView( R.layout.activity_live);

        viewModelWithLiveData = new ViewModelProvider(this).get(ViewModelWithLiveData.class);

        //给viewModelWithLiveData里面的LiveData变量添加一个观察,如果它发生变化则会回调下面的onChange函数。observe()的第一个参数要求是具有LifeCycle管理功能的一些对象,比如Activity

        viewModelWithLiveData.getLikedNumb er().observe(this, new Observer<Integer>() {

          @Override

          public void onChanged(Integer integer) { //当LiveData数据发生改变时回调这个函数

              tv_text.setText( String.valueOf(integer));

            }

        });

        button_add.setOnClickListener(new View.OnClickListener() {

            @Override

            public void onClick(View view) {

                viewModelWithLiveData.addLikedN umber(1);

            }

        });

        button_subtract.setOnClickListener( new View.OnClickListener() {

            @Override

            public void onClick(View view) {

                viewModelWithLiveData.addLikedN umber(-1);

            }

        });

    }

}

ac6e22946cbb422a94eec0ed51489137.gif

由于ViewModel的存在,当旋转屏幕、切换系统语言等配置时,数据不会丢失。

 

LiveData的好处:

①监听与其绑定的界面的生命周期。因此,使用LiveData就不需要手动管理它的生命周期了。

②组件能及时响应LiveData的数据变化,组件总能拿到LiveData的最新数据。当然被绑定的组件响应LiveData是有一定的前提的,那就是LiveData数据发生变化,且组件处于活跃状态。也就是说,LiveData数据即使发生了变化,也不一定会响应onChanged函数,因为它必须要求LiveData数据所在的界面处于活跃状态,才会响应onChanged函数。

③生命周期自动解绑,它能够在组件销毁的时候自动解绑,大大降低了产生内存泄露的概率。

注:LiveData确实能解决内存泄漏问题,但是如果使用不当,还是会出现内存泄漏的。例如,有一个Activity,Activity包含了一个Fragment,Fragment中有一个LiveData,因此Fragment引用了LiveData。然后LiveData通过observe方法把Activity当作owner进行了绑定,那么这时候,LiveData的生命周期将和Activity一样。如果这时Fragment被销毁了,那LiveData将不会被销毁,因为它被Activity引用着。LiveData本该回收却无法被回收,那么LiveData就发生内存泄漏了。

 

3.LiveData源码

①observe方法

LiveData使用observe()方法监听与其绑定的界面的生命周期。

LiveData.java:

@MainThread

public void observe(LifecycleOwner owner, Observer<? super T> observer) {

    assertMainThread("observe"); //只能在主线程调用这个方法

    if (owner.getLifecycle().getCurrentState() == DESTROYED) {

        return; //如果owner的生命周期已经是DESTROYED状态,则不再往下执行

    }

    //将外部传进的observer对象封装成一个LifecycleBoundObserver对象

    LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);

    //将observer和wrapper分别作为key和value存放到map中

    ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);

    if (existing != null &

这篇关于Android Jetpack—LiveData和数据倒灌的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/219582

相关文章

大模型研发全揭秘:客服工单数据标注的完整攻略

在人工智能(AI)领域,数据标注是模型训练过程中至关重要的一步。无论你是新手还是有经验的从业者,掌握数据标注的技术细节和常见问题的解决方案都能为你的AI项目增添不少价值。在电信运营商的客服系统中,工单数据是客户问题和解决方案的重要记录。通过对这些工单数据进行有效标注,不仅能够帮助提升客服自动化系统的智能化水平,还能优化客户服务流程,提高客户满意度。本文将详细介绍如何在电信运营商客服工单的背景下进行

基于MySQL Binlog的Elasticsearch数据同步实践

一、为什么要做 随着马蜂窝的逐渐发展,我们的业务数据越来越多,单纯使用 MySQL 已经不能满足我们的数据查询需求,例如对于商品、订单等数据的多维度检索。 使用 Elasticsearch 存储业务数据可以很好的解决我们业务中的搜索需求。而数据进行异构存储后,随之而来的就是数据同步的问题。 二、现有方法及问题 对于数据同步,我们目前的解决方案是建立数据中间表。把需要检索的业务数据,统一放到一张M

关于数据埋点,你需要了解这些基本知识

产品汪每天都在和数据打交道,你知道数据来自哪里吗? 移动app端内的用户行为数据大多来自埋点,了解一些埋点知识,能和数据分析师、技术侃大山,参与到前期的数据采集,更重要是让最终的埋点数据能为我所用,否则可怜巴巴等上几个月是常有的事。   埋点类型 根据埋点方式,可以区分为: 手动埋点半自动埋点全自动埋点 秉承“任何事物都有两面性”的道理:自动程度高的,能解决通用统计,便于统一化管理,但个性化定

使用SecondaryNameNode恢复NameNode的数据

1)需求: NameNode进程挂了并且存储的数据也丢失了,如何恢复NameNode 此种方式恢复的数据可能存在小部分数据的丢失。 2)故障模拟 (1)kill -9 NameNode进程 [lytfly@hadoop102 current]$ kill -9 19886 (2)删除NameNode存储的数据(/opt/module/hadoop-3.1.4/data/tmp/dfs/na

异构存储(冷热数据分离)

异构存储主要解决不同的数据,存储在不同类型的硬盘中,达到最佳性能的问题。 异构存储Shell操作 (1)查看当前有哪些存储策略可以用 [lytfly@hadoop102 hadoop-3.1.4]$ hdfs storagepolicies -listPolicies (2)为指定路径(数据存储目录)设置指定的存储策略 hdfs storagepolicies -setStoragePo

Hadoop集群数据均衡之磁盘间数据均衡

生产环境,由于硬盘空间不足,往往需要增加一块硬盘。刚加载的硬盘没有数据时,可以执行磁盘数据均衡命令。(Hadoop3.x新特性) plan后面带的节点的名字必须是已经存在的,并且是需要均衡的节点。 如果节点不存在,会报如下错误: 如果节点只有一个硬盘的话,不会创建均衡计划: (1)生成均衡计划 hdfs diskbalancer -plan hadoop102 (2)执行均衡计划 hd

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)

技术背景 好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明: 1. 使用VLC for Android VLC Media Player(VLC多媒体播放器),最初命名为VideoLAN客户端,是VideoLAN品牌产品,是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影

烟火目标检测数据集 7800张 烟火检测 带标注 voc yolo

一个包含7800张带标注图像的数据集,专门用于烟火目标检测,是一个非常有价值的资源,尤其对于那些致力于公共安全、事件管理和烟花表演监控等领域的人士而言。下面是对此数据集的一个详细介绍: 数据集名称:烟火目标检测数据集 数据集规模: 图片数量:7800张类别:主要包含烟火类目标,可能还包括其他相关类别,如烟火发射装置、背景等。格式:图像文件通常为JPEG或PNG格式;标注文件可能为X