IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android JetPack系列---LiveData -> 正文阅读

[移动开发]Android JetPack系列---LiveData

接着上一篇博客ViewModel,这一篇我们就来说一下一般配合ViewModel使用的LiveData

jetpack系列

第一篇:jetpack—Lifecycle的运用
第二篇:jetpack—ViewModel的了解
第三篇:jetpack—LiveData的使用

什么是LiveData?

官方说明:LiveData 是一种可观察的数据存储器类。与常规的可观察类不同,LiveData 具有生命周期感知能力,意指它遵循其他应用组件(如 Activity、Fragment 或 Service)的生命周期。这种感知能力可确保 LiveData 仅更新处于活跃生命周期状态的应用组件观察者。如果观察者(由 Observer 类表示)的生命周期处于 STARTED 或 RESUMED 状态,则 LiveData 会认为该观察者处于活跃状态。LiveData 只会将更新通知给活跃的观察者。为观察 LiveData 对象而注册的非活跃观察者不会收到更改通知。

在这里插入图片描述

使用LiveData写一个示例参照官方文档上的步骤

1、创建 LiveData 的实例以存储某种类型的数据。这通常在 ViewModel 类中完成。那我们就先需要写一个viewModel,然后在创建LiveData实例。

class LiveDataViewModel : ViewModel() {
    private val data = MyData()

    private val liveData: MutableLiveData<MyData> by lazy {
        MutableLiveData<MyData>()
    }
    
    override fun onCleared() {
        super.onCleared()
    }
}

注意:
1、看源码可知LiveData是一个抽象类,我们就不能直接 使用,但是我们可以使用他的子类,MutableLiveData
2、确保更新界面的LiveData对象储存在ViewModel对象中

然后我们需要加入更新数据的一个方法setUserData,和获取数据的方法getUserData,在更新数据的setUserData中给livedata设置数据liveData.value = data

class LiveDataViewModel : ViewModel() {
    private val data = MyData()

    private val liveData: MutableLiveData<MyData> by lazy {
        MutableLiveData<MyData>()
    }
    //获取到myData实例
    fun getUserData(): LiveData<MyData> {
        return liveData
    }
	//更新数据的方法
    fun setUserData(str: String) {
        data.name = str
        liveData.value = data
    }

    override fun onCleared() {
        super.onCleared()
    }
}

注意:
Livedata提供给我们2个更新数据的方法,一个是PostValue 一个是setValue点击去看源码可以知道
postValue适用于非UI线程的异步线程
setValue是在UI线程中

我上面的示例并非异步线程中所以直接使用了setValue
在这里插入图片描述
2、创建可定义 onChanged() 方法的 Observer 对象,该方法可以控制当 LiveData 对象存储的数据更改时会发生什么。通常情况下,您可以在界面控制器(如 activity 或 fragment)中创建 Observer 对象。
就是在Activity中间我们需要创建一个观察者对数据进行观察

class MainActivity : AppCompatActivity() {
    private lateinit var start: TextView
    private lateinit var contentTv: TextView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        start = findViewById(R.id.start)
        contentTv = findViewById(R.id.contentTv)

        //绑定viewModel
        val viewModel = ViewModelProvider(this)[LiveDataViewModel::class.java]
        //获取liveData
        val liveData = viewModel.getUserData()
        //liveData.observer()观察ViewModel中数据的变化
        liveData.observe(this, {
            contentTv.text =it.name
        })

        start.setOnClickListener {
            viewModel.setUserData("改变改变")
        }
    }
}

然后我们点击按钮改变一下viewModel中LiveData的值然后看下是否改变了。
在这里插入图片描述
从上面劣质的Gif可以看出LiveData的例子是已经成功了,并且因为ViewModel的原因,并不会因为屏幕旋转而导致数据丢失,如果对ViewModel有什么疑问的话可以看下我的上一篇,目录在文章的开头已经给出来了

接下来就简单的分析一下liveData.observe这个 方法看看他到底是怎么实现的 先看下源码

 @MainThread
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
        assertMainThread("observe");
        if (owner.getLifecycle().getCurrentState() == DESTROYED) {
            // ignore
            return;
        }
        LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
        ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
        if (existing != null && !existing.isAttachedTo(owner)) {
            throw new IllegalArgumentException("Cannot add the same observer"
                    + " with different lifecycles");
        }
        if (existing != null) {
            return;
        }
        owner.getLifecycle().addObserver(wrapper);
    }

1、首先点击observe可以看到这个方法需要一个LifecycleOwner ,我们上面传的是this进去,当前的activity,又因为我们前面再说LifeCycle的时候说过了CompatActivity是已经实现了LifecycleOwner,不是太清楚的话可以看下前面的LifeCycle那一篇,所以说LiveData就拥有了感知生命周期的能力。
2、if (owner.getLifecycle().getCurrentState() == DESTROYED) { return; }这句代码可以看出activity在生命周期结束的时候这个地方就直接return了不会在进行更新数据了。也就解决了有些地方因为activity生命周期结束而产生的内存溢出的问题。

接着往下看LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
看下LifecycleBoundObserver 这个类

class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
        @NonNull
        final LifecycleOwner mOwner;

        LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
            super(observer);
            mOwner = owner;
        }

        @Override
        boolean shouldBeActive() {
            return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
        }

        @Override
        public void onStateChanged(@NonNull LifecycleOwner source,
                @NonNull Lifecycle.Event event) {
            Lifecycle.State currentState = mOwner.getLifecycle().getCurrentState();
            if (currentState == DESTROYED) {
                removeObserver(mObserver);
                return;
            }
            Lifecycle.State prevState = null;
            while (prevState != currentState) {
                prevState = currentState;
                activeStateChanged(shouldBeActive());
                currentState = mOwner.getLifecycle().getCurrentState();
            }
        }

        @Override
        boolean isAttachedTo(LifecycleOwner owner) {
            return mOwner == owner;
        }

        @Override
        void detachObserver() {
            mOwner.getLifecycle().removeObserver(this);
        }
    }

1、可以看到 LifecycleBoundObserver 实现了LifecycleEventObserver 接口重写了onStateChanged这个方法就是说在生命周期状态改变的是时候会去调用。

Lifecycle.State currentState = mOwner.getLifecycle().getCurrentState();
            if (currentState == DESTROYED) {
                removeObserver(mObserver);
                return;
            }

然后获取了当前的生命周期,如果是当前生命周期是Destroyed,就移除掉了这个观察者就不在往下进行了,反之调用activeStateChanged(shouldBeActive());方法保持当前观察者,然后传进去了一个方法shouldBeActive()看下这个方法,返回的就是当前的生命周期的一个状态只有在start,resume,pause的时候才可以进行一个数据的更新

@Override
        boolean shouldBeActive() {
            return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
        }

上面就已经分析了一个LiveData 的一个工作的原理。

我们可以看到除了 liveData.observe,还有一个方法LiveData.observeForever
在这里插入图片描述
方法比对来看,用法都是一样的,但是observe传了一个当前的Activity,当前的Activity又是继承CompatActivity是已经实现了LifecycleOwner,进去相当于绑定了当前Activity的生命周期,从而让LiveData会跟随着Activity的生命周期, LiveData 会认为该观察者处于活跃状态。LiveData 只会将更新通知给活跃的观察者。
但是observeForever 并没有传递一个LifecycleOwner那就是说LiveData的数据发生变化时,无论页面处于什么状态,observeForever()都能收到通知。observeForever也不会随着Activity的销毁而停止对LiveData的观察,所以我们必须在使用完成的时候手动调用removeObserver()来停止对LiveData的观察,否者的话LiveData一直在激活的状态,你的Activity就不会被系统回收。

		liveData.observe(this, {
            contentTv.text =it.name
        })
        liveData.observeForever {
            contentTv.text =it.name
        }

LiveData基本上用到最多的也就是这些如果有什么说的不对的地方,还是麻烦提出来指正

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-12-04 13:33:24  更:2021-12-04 13:34:33 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年10日历 -2024/10/25 14:28:28-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码