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

相关文章

使用Java解析JSON数据并提取特定字段的实现步骤(以提取mailNo为例)

《使用Java解析JSON数据并提取特定字段的实现步骤(以提取mailNo为例)》在现代软件开发中,处理JSON数据是一项非常常见的任务,无论是从API接口获取数据,还是将数据存储为JSON格式,解析... 目录1. 背景介绍1.1 jsON简介1.2 实际案例2. 准备工作2.1 环境搭建2.1.1 添加

MySQL中删除重复数据SQL的三种写法

《MySQL中删除重复数据SQL的三种写法》:本文主要介绍MySQL中删除重复数据SQL的三种写法,文中通过代码示例讲解的非常详细,对大家的学习或工作有一定的帮助,需要的朋友可以参考下... 目录方法一:使用 left join + 子查询删除重复数据(推荐)方法二:创建临时表(需分多步执行,逻辑清晰,但会

Java实现任务管理器性能网络监控数据的方法详解

《Java实现任务管理器性能网络监控数据的方法详解》在现代操作系统中,任务管理器是一个非常重要的工具,用于监控和管理计算机的运行状态,包括CPU使用率、内存占用等,对于开发者和系统管理员来说,了解这些... 目录引言一、背景知识二、准备工作1. Maven依赖2. Gradle依赖三、代码实现四、代码详解五

详谈redis跟数据库的数据同步问题

《详谈redis跟数据库的数据同步问题》文章讨论了在Redis和数据库数据一致性问题上的解决方案,主要比较了先更新Redis缓存再更新数据库和先更新数据库再更新Redis缓存两种方案,文章指出,删除R... 目录一、Redis 数据库数据一致性的解决方案1.1、更新Redis缓存、删除Redis缓存的区别二

Redis事务与数据持久化方式

《Redis事务与数据持久化方式》该文档主要介绍了Redis事务和持久化机制,事务通过将多个命令打包执行,而持久化则通过快照(RDB)和追加式文件(AOF)两种方式将内存数据保存到磁盘,以防止数据丢失... 目录一、Redis 事务1.1 事务本质1.2 数据库事务与redis事务1.2.1 数据库事务1.

Oracle Expdp按条件导出指定表数据的方法实例

《OracleExpdp按条件导出指定表数据的方法实例》:本文主要介绍Oracle的expdp数据泵方式导出特定机构和时间范围的数据,并通过parfile文件进行条件限制和配置,文中通过代码介绍... 目录1.场景描述 2.方案分析3.实验验证 3.1 parfile文件3.2 expdp命令导出4.总结

更改docker默认数据目录的方法步骤

《更改docker默认数据目录的方法步骤》本文主要介绍了更改docker默认数据目录的方法步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录1.查看docker是否存在并停止该服务2.挂载镜像并安装rsync便于备份3.取消挂载备份和迁

不删数据还能合并磁盘? 让电脑C盘D盘合并并保留数据的技巧

《不删数据还能合并磁盘?让电脑C盘D盘合并并保留数据的技巧》在Windows操作系统中,合并C盘和D盘是一个相对复杂的任务,尤其是当你不希望删除其中的数据时,幸运的是,有几种方法可以实现这一目标且在... 在电脑生产时,制造商常为C盘分配较小的磁盘空间,以确保软件在运行过程中不会出现磁盘空间不足的问题。但在

Android数据库Room的实际使用过程总结

《Android数据库Room的实际使用过程总结》这篇文章主要给大家介绍了关于Android数据库Room的实际使用过程,详细介绍了如何创建实体类、数据访问对象(DAO)和数据库抽象类,需要的朋友可以... 目录前言一、Room的基本使用1.项目配置2.创建实体类(Entity)3.创建数据访问对象(DAO

Java如何接收并解析HL7协议数据

《Java如何接收并解析HL7协议数据》文章主要介绍了HL7协议及其在医疗行业中的应用,详细描述了如何配置环境、接收和解析数据,以及与前端进行交互的实现方法,文章还分享了使用7Edit工具进行调试的经... 目录一、前言二、正文1、环境配置2、数据接收:HL7Monitor3、数据解析:HL7Busines