美文网首页android
LiveData的使用介绍

LiveData的使用介绍

作者: dashingqi | 来源:发表于2020-06-21 00:51 被阅读0次
Android_Banner.jpg

简介

  • LiveData是JetPack提供的一种响应式编程组件,它可以包含任何数据类型的数据(String,Int,Boolean等)。
  • LiveData在数据发生变化的时候,会通知给观察者。
  • 一般情况下,LiveData与ViewModel配合使用的,在这个前提下,LiveData都是在ViewModel中声明的。但是也是可以单独进行声明使用的。
    • LiveData是具有生命感知的,它的数据源一般都是ViewModel提供的,这样当数据源发生变化我们通过LiveData可以通知给观察者。(通常我们的观察者是组册在Activity或者Fragment中的)
    • 当然也不能忽略生命周期感知这个提点,可以这样理解,当观察者处于Active状态的时候,LiveData发生变化观察者可以收到,但是观察者处于Paused或者Destoryed状态,那么观察者就不能收到LiveData的通知了
  • 在MVVM中,我们可以使用LiveData帮助ViewModel向Activity或者Fragment进行通信
    • 因为ViewModel的生命周期都要比Activity要长的,所以我们不能让ViewModel持有Activity的引用,如果这时我们能在Activity中观察ViewModel中的LiveData,那么就不回因为ViewModel持有activity而造成的内存泄漏问题。
  • LiveData是一个抽象类,其中我们常用的是它的实现子类 MutableLiveData,它是一个可变的LievData,主要有如下几个操作api
    • getValue():用于从LiveData中获取到包装的数据
    • setValue():用于给LiveData设置数据
    • postValue():同样也是给LiveData设置数据
  • postValue与setValuede 区别
    • setValue():只能作用于UI线程中,如果在工作线程中使用,会发生crash
    • postValue:可以用于工作线程中(非UI线程 ),当然在UI线程中也是可用的。

使用

基本使用

我们知道在MVVM中ViewModel是作为数据的持有者,而Activity或者Fragment是作为UI的载体(PhoneWindwo),在MVVM中我们一般是使用DataBinding,将XML文件自动编译成一个XXXDataBinding的文件,通过在Activity中,用这个XXDataBinding去绑定我们的数据持有者ViewModel,然后在xml引入这个ViewModel,并且去动态绑定我们ViewModel中的LiveData或者Observable。达到一个数据监听的作用。

  • 场景设定:我们有一个ViewModel,内部有一个LiveData包装着String类型,同时在Activity中获取到这个ViewModel,注册一个观察者去监听ViewModel中的LiveData,当我们点击按钮设置一个数据源给LiveData,然后在观察者中去更新xml文件中的一个text。

  • 代码实现如下

    class LiveDataMainActivity : AppCompatActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_live_data_main)
            //获取到ViewModel(此种方式获取ViewModel要在Lifecycle2.2.0之后哟!)
            var viewModelDemo2 = ViewModelProvider(this)[ViewModelDemo2::class.java]
            //注册一个观察者,用于观察LiveData,当LiveData的数据源发生改变会通知到观察者中
            viewModelDemo2.liveData.observe(this, Observer {
                it?.let { value ->
                    tvText.text = value
                }
    
            })
    
            btnChange.setOnClickListener {
                viewModelDemo2.liveData.postValue("i am coming ")
    
            }
    
    
        }
    }
    
    class ViewModelDemo2 : ViewModel() {
    
        var liveData = MutableLiveData<String>()
    }
    
map

这里说的map实则是调用了Transformations#map()方法,通过该方法可以将我们的LiveData进行数据类型转换成新类型的LiveData,然后在Activity中注册新LiveData的观察者就能拿到数据源了,

说的可能比较抽象,以列子来说明吧

  • 场景设定:有一个Person,包含姓名和性别,但是我们的UI控件上只用来显示姓名的,这时我们可以通过map这种方式来做处理

  • 代码实现如下

    class MapLiveDataMainActivity : AppCompatActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_map_live_data_main)
            var viewModel = ViewModelProvider(this)[MapLiveDataViewModel::class.java]
            var person = Person()
            person.name = "DashingQi"
            person.sex = "man"
    
            viewModel.transformLiveData.observe(this, Observer {
                it?.let { value ->
                    tvText.text = value
                }
    
            })
            setUser.setOnClickListener {
                viewModel.userLiveData.postValue(person)
            }
    
    
        }
    }
    
    class MapLiveDataViewModel : ViewModel() {
    
        var userLiveData = MutableLiveData<Person>()
    
        /**
         * 使用Transformations#map转换成一个新的LiveData
         * 第一个参数是我们要进行转化的LiveData。里面包装了我们需要的数据
         * 第二个参数是我们要进行转化的函数
         * 这样当userLiveData的数据源发生变化的时候,我们transformLiveData的观察者就能收到转化后的数据源了
         */
        var transformLiveData = Transformations.map(userLiveData) {
            it.name
        }
    }
    
switchMap

switchMap同样是Transformations中的,该方法同样有两个参数 参数一:LiveData 参数二:函数转换体

与map不同,switchMap的函数转化中必须要返回一个LiveData对象,

参数一:我们可以作为一个条件决定函数转化中返回什么类型的LiveData,也可以将其包装的数据作为新的LiveData在转化函数中返回

  • 场景设定:同样有一个Person,是一个外国人,有firstName和lastName,不过我们有一个条件就是,UI控件只能显示lastName或者firstName

  • 代码实现如下

    class SwitMapMainActivity : AppCompatActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_swit_map_main)
            var switchMapViewModel = ViewModelProvider(this)[SwitchMapViewModel::class.java]
            switchMapViewModel.transformationsLiveData.observe(this, Observer {
                it.let { value ->
                    nameText.text = value
                }
    
            })
    
            setUser.setOnClickListener {
                var person = Person()
                person.firstName = "zhang"
                person.lastName = "qi"
                //当切换 true或者false观察控件显示是否发生变化了呢
                person.condition = false
                switchMapViewModel.conditionLiveData.postValue(person)
            }
        }
    }
    class SwitchMapViewModel:ViewModel() {
    
        var conditionLiveData = MutableLiveData<Person>()
    
        val transformationsLiveData = Transformations.switchMap(conditionLiveData){
             if (it.condition){
                MutableLiveData(it.firstName)
            }else{
               MutableLiveData(it.lastName)
           }
        }
    }
    class Person {
        var name = ""
        var sex = ""
        var firstName = ""
        var lastName = ""
        var condition = false
    }
    
合并多个LiveData的数据源

该操作使用的是MediatorLiveData,它继承MutableLiveData,在原有功能的基础上,新增了合并多个LiveData的数据源的功能,实则就是一个组件监听多个LiveData,通过addSource方法

  • 场景设定:我们有一个控件,和两个LiveData(L1,L2),当L1的数据源发生变化,我们控件显示L1的,当L2数据源发生变化实现L2的,可能我们的做法就是在ViewModel中声明两个LiveData,然后在Activity中分别注册这两个LiveData的观察者,当数据源发生改变去更新UI,其实我们可以使用MediatorLiveData去简化这个操作,不用在Activity中注册两个LiveData的观察者

  • 代码实现

    class MediatorLiveDataMainActivity : AppCompatActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_mediator_live_data_main)
            var mediatorLiveDataViewModel =
                ViewModelProvider(this)[MediatorLiveDataViewModel::class.java]
            mediatorLiveDataViewModel.mediatorLiveData.observe(this, Observer {
                text.text = it
            })
    
            setLiveData1.setOnClickListener {
                mediatorLiveDataViewModel.liveData1.postValue("liveData1")
            }
    
            setLiveData2.setOnClickListener {
                mediatorLiveDataViewModel.liveData2.postValue("liveData2")
            }
        }
    }
    class MediatorLiveDataViewModel : ViewModel() {
        var liveData1 = MutableLiveData<String>()
        var liveData2 = MutableLiveData<String>()
    
        var mediatorLiveData = MediatorLiveData<String>()
    
    
        init {
            mediatorLiveData.addSource(liveData1) {
                Log.d("perform livedata1", it)
                mediatorLiveData.postValue(it)
            }
    
            mediatorLiveData.addSource(liveData2) {
                Log.d("perform livedata2", it)
                mediatorLiveData.postValue(it)
            }
        }
    }
    

总结

  • 主要介绍了一下LiveData的几种使用场景
  • LiveData作为ViewModel和Activity之间的桥梁,具有生命感知,并且不会存在内存泄漏,其实靠的是Lifecycle组件
  • LiveData在内部使用了Lifecycle组件,来感知生命周期的变化,当Activity销毁的时候也会释放掉引用,防止内存泄漏。
  • LiveData的数据源发生变化只会通知到处于Active状态的Activity中的观察者,当Activty由不可见变为可见的状态,那么此时观察者会收到通知,实则为了减少性能损耗嘛
    • 当Activity处于不可见状态时,LiveData发生了多次改变,当变成可见状态时只能收到最新的变化通知

相关文章

  • LiveData详细分析

    目录介绍 01.LiveData是什么东西 02.使用LiveData的优势 03.使用LiveData的步骤 0...

  • LiveData的使用介绍

    简介 LiveData是JetPack提供的一种响应式编程组件,它可以包含任何数据类型的数据(String,Int...

  • LiveData实现原理

    LiveData使用LiveData LiveData = new LiveData(); liveData.ob...

  • LiveData

    示例应用程序 使用LiveData的优点 使用LiveData对象创建LiveData对象观察LiveData对象...

  • LiveData的工作原理分析

    简介 之前的文章有介绍过LiveData的基本使用,这篇文章主要来讲解一下LiveData的工作原理 在我们使用L...

  • Android MVVM 解读 3. Android MVVM

    2.3 LiveData 官方介绍LiveData Overview 包含 LiveData的设计理念 LiveD...

  • Jetpack组件之LiveData实现原理

    提纲 LiveData是什么 LiveData衍生类及其基本用法 LiveData核心方法介绍 LiveData实...

  • 03 LiveData实战与应用

    前言 上一节内容我们已经充分介绍了LiveData组件,我们可以发现在使用LiveData分发数据的时候,是不会耦...

  • Jetpack学习(三)——LiveData&ViewModel

    jetpack学习(三)——LiveData&ViewModel LiveData 使用 LiveData 的优势...

  • LiveData笔记

    在之前的总结中已经简要介绍了liveData的简单使用,但是咋最近做需求学习前辈的代码的时候发现liveData其...

网友评论

    本文标题:LiveData的使用介绍

    本文链接:https://www.haomeiwen.com/subject/lugnxktx.html