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 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Lifecycle与LiveData的珠联璧合 -> 正文阅读

[移动开发]Lifecycle与LiveData的珠联璧合

LifecycleLiveData的讲解

lifecycle

Lifecycle是生命周期感知型组件,什么是生命感知型组件?就是与Activity或者Fragment绑定之后,可执行一些操作来响应Activity和Fragment的生命周期状态的变化。

lifecycle是一个类,用于存储有关组件(如 ActivityFragment)的生命周期状态的信息,并且允许其他对象观察此状态。Lifecycle使用两种主要枚举跟踪其关联组件的生命周期状态:这两个枚举类分别是State和Event。

State:当前生命周期所处状态。有以下状态:CREATEDSTARTEDRESUMEDDESTROYEDINITIALIZED

Event:当前生命周期改变对应的事件。 有以下事件:ON_CREATE,ON_START,ON_RESUME,ON_PAUSE,ON_STOP,ON_DESTROY,ON_ANY;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oCzUr0zA-1641547282895)(https://developer.android.com/images/topic/libraries/architecture/lifecycle-states.svg?hl=zh-cn)]

注意这张事件和状态的转换图,它的意思是,从一开始的INITIALIZED状态,经过了onCreate事件,也就是Activity或者FragmentonCreate函数之后,他就变成了CREATED状态,其他的事件和状态的转换同理。就不一一列举了。

LifecycleObserver接口( Lifecycle观察者):实现该接口的类,通过注解的方式,可以通过被LifecycleOwner类的addObserver(o:LifecycleObserver)方法注册,被注册后,LifecycleObserver便可以观察到LifecycleOwner的生命周期事件。

LifecycleOwner接口(Lifecycle持有者):实现该接口的类持有生命周期(Lifecycle对象),Lifecycle对象的改变会被其注册的观察者LifecycleObserver观察到并触发其对应的事件。

通过以上介绍可以知道:实现 LifecycleObserver的组件可与实现 LifecycleOwner的组件完美配合,因为LifecycleOwner可以提供生命周期,而LifecycleObserver可以注册以便观察组件的生命周期。

LifeCycle的用法:以官网的定位功能为例

//没有使用LifeCycle的情况
class MyActivity : AppCompatActivity() {
    private lateinit var myLocationListener: MyLocationListener

    override fun onCreate(...) {
        myLocationListener = MyLocationListener(this) { location ->
            // update UI
        }
    }

    public override fun onStart() {
        super.onStart()
        Util.checkUserStatus { result ->
            // 如果在活动停止后调用这个回调会怎样?可能会崩溃
            if (result) {
                myLocationListener.start()
            }
        }
    }

    public override fun onStop() {
        super.onStop()
        myLocationListener.stop()
    }

}
//使用lifeCycle的方式
class MyActivity : AppCompatActivity() {
    private lateinit var myLocationListener: MyLocationListener

    override fun onCreate(...) {
        myLocationListener = MyLocationListener(this, lifecycle) { location ->
            // update UI
        }
        Util.checkUserStatus { result ->
            if (result) {
                myLocationListener.enable()
            }
        }
        lifeCycle.addObserver(myLocationListener)

    }
}
internal class MyLocationListener(
        private val context: Context,
        private val lifecycle: Lifecycle,
        private val callback: (Location) -> Unit
): LifecycleObserver {

    private var enabled = false

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    fun start() {
        if (enabled) {
            // connect
        }
    }

    fun enable() {
        enabled = true
        if (lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)) {
            // connect if not connected
        }
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    fun stop() {
        // disconnect if connected
    }
}

来看一下整体的生命周期的调用一个流程,如下图。

ShymanZhu在这里插入图片描述

LifeCycle的作用是让其他组件也可以检测Activity和Fragment生命周期的变化,然后做出相应的响应,并且将Activity的生命周期函数简化。它更大的作用是和其他组件配合使用,比如LiveData。

Livedata

LiveData是一种可观察的数据存储器类。与常规的可观察类不同,LiveData 具有生命周期感知能力,意指它遵循其他应用组件(如 Activity、Fragment 或 Service)的生命周期。这种感知能力可确保 LiveData 仅更新处于活跃生命周期状态的应用组件观察者。

如果观察者(由 Observer类表示)的生命周期处于 STARTED或 RESUMED状态,则 LiveData 会认为该观察者处于活跃状态。LiveData 只会将更新通知给活跃的观察者。为观察 LiveData对象而注册的非活跃观察者不会收到更改通知。

那么怎么使用LiveData呢?

  1. 创建 LiveData 的实例以存储某种类型的数据。这通常在 ViewModel类中完成。
  2. 创建可定义 onChanged()方法的 Observer对象,该方法可以控制当 LiveData 对象存储的数据更改时会发生什么。通常情况下,您可以在界面控制器(如 Activity 或 Fragment)中创建 Observer 对象。
  3. 使用 observe() 方法将 Observer 对象附加到 LiveData 对象。observe() 方法会采用 LifecycleOwner 对象。这样会使 Observer 对象订阅 LiveData 对象,以使其收到有关更改的通知。通常情况下,您可以在界面控制器(如 Activity 或 Fragment)中附加 Observer 对象。这一步一般是在onCreate中去完成。
  4. 使用setValue或者postValue的方法去更新LiveDate里面的值,以便观察者能够感知livedate发生了变化。

下面是一个例子:

class TestViewModel: ViewModel(){
    // 1、创建LiveData的实例以存储某种类型的数据。通常再viewmodel中完成,userName的值改变后,会通知它的观察者
    val userName: MutableLiveData<String> = MutableLiveData()

}
    lateinit var testViewModel: TestViewModel
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ...
        
        //2、通过livedata的observe()方法,设置LifecycleOwner和Observer对象
        testViewModel.userName.observe(this){
            //3、实现Observer 即userName更改后需要执行的操作
        })
        
        ...
    }

当更新存储在 LiveData 对象中的值时,它会触发所有已注册的观察者(只要附加的 LifecycleOwner 处于活跃状态)。LiveData 允许界面控制器观察者订阅更新。当 LiveData 对象存储的数据发生更改时,界面会自动更新以做出响应。

来看一下LiveData的源码,它的源码也非常简单。我们直接从setValue开始看

   // 首先第一步,通过setValue,将value的值赋值给mData,然后调用dispatchingValue

	@MainThread
    protected void setValue(T value) {
        assertMainThread("setValue");
        mVersion++;
        mData = value;
        dispatchingValue(null);
    }
    void dispatchingValue(@Nullable ObserverWrapper initiator) {
        if (mDispatchingValue) {
            mDispatchInvalidated = true;
            return;
        }
        mDispatchingValue = true;
        do {
            mDispatchInvalidated = false;
            if (initiator != null) {
                considerNotify(initiator);
                initiator = null;
            } else {
                //第二部,到了dispatchingValue里面之后,然后循环遍历,开始调用considerNotify
                for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
                        mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                    considerNotify(iterator.next().getValue());
                    if (mDispatchInvalidated) {
                        break;
                    }
                }
            }
        } while (mDispatchInvalidated);
        mDispatchingValue = false;
    }
// 最后一步,调用considerNotify,判断观察者是不是处于一个活跃状态,如果不是,直接返回,也就是如果这个观察者不是活跃状态,那么将收不到livedata这次改变的通知,如果处于观察者,那么就调用观察者的onChanged函数    
private void considerNotify(ObserverWrapper observer) {
        if (!observer.mActive) {
            return;
        }
        // Check latest state b4 dispatch. Maybe it changed state but we didn't get the event yet.
        //
        // we still first check observer.active to keep it as the entrance for events. So even if
        // the observer moved to an active state, if we've not received that event, we better not
        // notify for a more predictable notification order.
        if (!observer.shouldBeActive()) {
            observer.activeStateChanged(false);
            return;
        }
        if (observer.mLastVersion >= mVersion) {
            return;
        }
        observer.mLastVersion = mVersion;
        observer.mObserver.onChanged((T) mData);
    }

以上就是LiveData的讲解,这一篇讲解比较基础,以为lifecycle与livedate无论原来还是使用比较简单的,他们配合起来使用确实也比较方便。原理无非就是使用了观察者模式而已。

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-01-08 14:08:36  更:2022-01-08 14:10:03 
 
开发: 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年11日历 -2024/11/24 10:30:56-

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