Android Jetpack之LiveData 使用及源码

推荐链接: 

Android Jetpack之ViewModel、LiveData

Android Jetpack之LifeCycle

Android Jetpack之DataBinding+ViewModel+LiveData+Room


Jetpack

是一个由多个技术库组成的套件,可帮助开发者遵循最佳做法,减少样板代码并编写可在各种Android版本和设备中一致运行的代码,让开发者精力集中编写重要的代码。

LiveData 已经是必不可少的一环了,例如 MVVM 以及 MVI 开发模式中都用到。

LiveData

LiveData 是一种持有可被观察的数据存储类,通常存储在 ViewModel 对象中。可以在 Activity ,fragment 或者 service 生命周期发生改变时、数据发生变化时通知UI更新。

特点

  • 数据发生变化时,就会通知观察者;
  • 没有内存泄漏,关联了页面生命周期,销毁后会进行自我清理;
  • 屏幕翻转数据状态保留;
  • 不再需要手动处理生命周期;
  • 数据始终保持最新状态;

代码示例

class detailViewModel : ViewModel() {
    private val _state by lazy { 
            MutableLiveData<T>() 
        }
    val state : LiveData<T> = _state
    private fun loadImage(page: Int) {
        viewModelScope.launch {
               val result = testApi.getImage("url")
               _state.value = result
        }
     }
}    
//添加观察者
viewModel.state.observe(this, Observer { //UI })

注意:当具有活跃的观察者时,就会调用 onActive 方法。当没有任何活跃的观察者时,就会调用 onInactive 方法。 

LiveData 实现原理

观察者入口observe(this,Observer{})

@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
    if (owner.getLifecycle().getCurrentState() == DESTROYED) {
       return; //如果已经销毁,直接退出
    }
    LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
    ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
    if (existing != null && !existing.isAttachedTo(owner)) { //...添加}
    if (existing != null) {
       return;  //添加过返回
    }
    owner.getLifecycle().addObserver(wrapper); //注册lifecycle
}

更新状态:根据活跃状态mActive变量boolean的值,活跃+1或不活跃-1。

void activeStateChanged(boolean newActive) {
  if (newActive == mActive) {
    return;//如果等于之前状态
  }
  mActive = newActive;
  changeActiveCounter(mActive ? 1 : -1);//活跃 +1,不活跃 -1 
  if (mActive) { //如果状态变成了活跃状态,传入当前的观察者
    dispatchingValue(this); 
  }
}

数据进行派发,通知观察者。观察者会判断版本是否低于当前的版本决定是否回调。

初始值 mLastVersion 默认为 -1,mVersion 默认为 0。

private void considerNotify(ObserverWrapper observer) {
    if (!observer.mActive) { return;}
    if (!observer.shouldBeActive()) { //判断,如果不活跃,则会更新状态,然后退出
        observer.activeStateChanged(false);
        return;
    }
    if (observer.mLastVersion >= mVersion) { //小于等于表示没有需要更新的数据
        return;
    }
    observer.mLastVersion = mVersion;//更新版本
    observer.mObserver.onChanged((T) mData); //通知观察者
}

 梳理流程

  • 通过 observe 添加一个观察者到 Observers集合。最后LifecycleOwner添加observer。
  • 当生命周期发生,LifecycleBoundObserve 调用 onStateChanged 方法。如果生命周期是销毁的,就会移除观察者。否则,会While循环更新当前状态。
  • 更新状态时会判断是否为生命周期是否活跃状态,如果是活跃状态就会进行分发。
  • 最后判断观察者版本是否低于当前版本。
  • 如果都满足,就会调用观察者onChanged方法更新UI。

LiveData缺点

数据粘性事件

        例如,没有观察者的时候发送数据,此时 mVersion +1。等添加了观察者后,生命周期是活跃的,那么就会将这个数据分发到观察者。所以说发送数据这个操作是粘性的。

        如果需要去除粘性事件,可以在添加完 observe 后去通过反射修改 mVersion 和 观察者包装类中的 mLastVersion 的值,将 mVersion 赋值给 mLastVersion 即可去掉粘性事件。

数据倒灌现象

        LiveDatat通常存放在ViewModel中的,当Activity重建的时候,观察者会被 remove 掉。重建后会添加一个新的观察者,版本号mLastVersion 默认为 -1,所以就会出现数据再次被接收到。

        这种解决方式和上面一样,反射修改版本号就可以解决。

        非活跃状态的观察者转为活跃状态后,只能接收到最后一次发送的数据。一般情况下我们都需要的是最新数据,如果非要所有数据,只能重写 LiveData 了。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Android Jetpack是一组用于Android应用程序开发的库集合,旨在帮助开发者简化开发流程、提高生产力和应用性能。它提供了一些常用的组件和工具,可以帮助开发者解决常见的开发问题。 要使用Android Jetpack,您需要在您的项目中添加相关的Jetpack库依赖。您可以通过在项目的build.gradle文件中添加相应的依赖来实现。例如,要使用Navigation组件,您可以添加以下依赖: implementation "androidx.navigation:navigation-fragment-ktx:2.3.5" implementation "androidx.navigation:navigation-ui-ktx:2.3.5" 一旦您添加了所需的依赖,您可以开始使用Jetpack组件了。对于Navigation组件,您可以使用Navigation图形化界面来创建和管理应用程序中的导航结构,并使用NavController来处理导航操作。 另外,为了更好地理解和学习Android Jetpack,您可以借助官方文档和示例代码来深入学习。官方文档提供了详细的介绍和用法示例,而示例代码可以帮助您更好地理解如何在实际项目中应用Jetpack组件。 总结起来,要使用Android Jetpack,您需要添加相关的库依赖,并根据具体的组件使用文档进行配置和使用。通过深入学习官方文档和示例代码,您可以更好地理解和掌握Jetpack使用。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [Android Jetpack架构开发,从入门到实战,看这一篇就够了](https://blog.csdn.net/Eqiqi/article/details/127534594)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [Android JetPack学习](https://blog.csdn.net/weixin_39069034/article/details/100170739)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

艾阳Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值