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和数据倒灌的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:https://blog.csdn.net/zenmela2011/article/details/130068181
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/219582

相关文章

C#监听txt文档获取新数据方式

《C#监听txt文档获取新数据方式》文章介绍通过监听txt文件获取最新数据,并实现开机自启动、禁用窗口关闭按钮、阻止Ctrl+C中断及防止程序退出等功能,代码整合于主函数中,供参考学习... 目录前言一、监听txt文档增加数据二、其他功能1. 设置开机自启动2. 禁止控制台窗口关闭按钮3. 阻止Ctrl +

java如何实现高并发场景下三级缓存的数据一致性

《java如何实现高并发场景下三级缓存的数据一致性》这篇文章主要为大家详细介绍了java如何实现高并发场景下三级缓存的数据一致性,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 下面代码是一个使用Java和Redisson实现的三级缓存服务,主要功能包括:1.缓存结构:本地缓存:使

在MySQL中实现冷热数据分离的方法及使用场景底层原理解析

《在MySQL中实现冷热数据分离的方法及使用场景底层原理解析》MySQL冷热数据分离通过分表/分区策略、数据归档和索引优化,将频繁访问的热数据与冷数据分开存储,提升查询效率并降低存储成本,适用于高并发... 目录实现冷热数据分离1. 分表策略2. 使用分区表3. 数据归档与迁移在mysql中实现冷热数据分

C#解析JSON数据全攻略指南

《C#解析JSON数据全攻略指南》这篇文章主要为大家详细介绍了使用C#解析JSON数据全攻略指南,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、为什么jsON是C#开发必修课?二、四步搞定网络JSON数据1. 获取数据 - HttpClient最佳实践2. 动态解析 - 快速

MyBatis-Plus通用中等、大量数据分批查询和处理方法

《MyBatis-Plus通用中等、大量数据分批查询和处理方法》文章介绍MyBatis-Plus分页查询处理,通过函数式接口与Lambda表达式实现通用逻辑,方法抽象但功能强大,建议扩展分批处理及流式... 目录函数式接口获取分页数据接口数据处理接口通用逻辑工具类使用方法简单查询自定义查询方法总结函数式接口

Android kotlin中 Channel 和 Flow 的区别和选择使用场景分析

《Androidkotlin中Channel和Flow的区别和选择使用场景分析》Kotlin协程中,Flow是冷数据流,按需触发,适合响应式数据处理;Channel是热数据流,持续发送,支持... 目录一、基本概念界定FlowChannel二、核心特性对比数据生产触发条件生产与消费的关系背压处理机制生命周期

Android ClassLoader加载机制详解

《AndroidClassLoader加载机制详解》Android的ClassLoader负责加载.dex文件,基于双亲委派模型,支持热修复和插件化,需注意类冲突、内存泄漏和兼容性问题,本文给大家介... 目录一、ClassLoader概述1.1 类加载的基本概念1.2 android与Java Class

SQL中如何添加数据(常见方法及示例)

《SQL中如何添加数据(常见方法及示例)》SQL全称为StructuredQueryLanguage,是一种用于管理关系数据库的标准编程语言,下面给大家介绍SQL中如何添加数据,感兴趣的朋友一起看看吧... 目录在mysql中,有多种方法可以添加数据。以下是一些常见的方法及其示例。1. 使用INSERT I

Python使用vllm处理多模态数据的预处理技巧

《Python使用vllm处理多模态数据的预处理技巧》本文深入探讨了在Python环境下使用vLLM处理多模态数据的预处理技巧,我们将从基础概念出发,详细讲解文本、图像、音频等多模态数据的预处理方法,... 目录1. 背景介绍1.1 目的和范围1.2 预期读者1.3 文档结构概述1.4 术语表1.4.1 核

MySQL 删除数据详解(最新整理)

《MySQL删除数据详解(最新整理)》:本文主要介绍MySQL删除数据的相关知识,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录一、前言二、mysql 中的三种删除方式1.DELETE语句✅ 基本语法: 示例:2.TRUNCATE语句✅ 基本语