一、前言:

  1. 简介:

1、LiveData的简介

LiveData是一种类,持有可被观察的数据。
LiveData是一种可感知生命周期的组件,意味着该组件重视其他app组件的生命周期,如Activity、Fragment、Service
该组件能确保,仅仅在Activity\Fragment\Service等组件都处于活跃的生命周期状态的时候,才去更新app组件。

2、LiveData只有当观察者的生命周期处于活跃状态时才会去通知观察者。

实现了Observer类的观察者,可以注册监听LiveData
活跃状态就是指处于STARTED或者RESUMED状态
处于非活跃的观察者,LiveData不会去通知这些观察者

3、可以注册一种观察者, 该观察者与LifecycleOwner对象(如:Activity、Fragment)相关联。

在对应的Lifecycle Object处于DESTORYED状态时,会自动解除LiveData和该观察者的注册关系

4、在Activity、Fragment中这种自动解除注册的特性非常有用

Activity、Fragment不用担心会出现内存泄露
在Activity、Fragment销毁时,LiveData会自动解除其注册关系
  1. 优势:

5、LiveData能确保UI和数据状态相符

因为是观察者模式,LiveData会在生命周期状态改变时,通知观察者
可以在观察者对象中进行UI的更新操作

6、LiveData没有内存泄露

观察者和Lifecycle对象绑定,能在销毁时自动解除注册

7、LiveData不会给已经停止的Activity发送事件

如果观察者处于非活跃状态,LiveData不会再发送任何事件给这些Observer对象

8、LiveData能确保不再需要手工对生命周期进行处理

UI组件仅仅需要对相关数据进行观察
LiveData自动处理生命周期状态改变后,需要处理的代码。

9、LiveData能保证数据最新

一个非活跃的组件进入到活跃状态后,会立即获取到最新的数据
不用担心数据问题

10、LiveData在横竖屏切换等Configuration改变时,也能保证获取到最新数据

例如Acitivty、Fragment因为屏幕选装导致重建, 能立即接收到最新的数据

11、LiveData能资源共享

如果将LiveData对象扩充,用单例模式将系统服务进行包裹。这些服务就可以在app中共享。
只需要LiveData和系统服务connect,其他观察者只需要监视LiveData就能获取到这些资源

二、使用LiveData
1、LiveData与MutableLiveData区别

LiveData与MutableLiveData的其实在概念上是一模一样的.唯一几个的区别如下:MutableLiveData的父类是LiveDataLiveData在实体类里可以通知指定某个字段的数据更新.MutableLiveData则是完全是整个实体类或者数据类型变化后才通知.不会细节到某个字段

2、LiveData有几种使用方式:

    使用LiveData对象继承LiveData类

3、为什么将LiveData放置到ViewModel中,而不放到activity或者fragment中?

    避免fragment和activity的代码臃肿将LiveData和特定的activity/fragment解耦,能够在configuration改变的时候,LiveData依然存活。

4、在App组件的哪个生命周期适合观察LiveData对象?为什么?

    app组件的onCreate()方法不适合在onResume()等方法中,可能会调用多次能确保组件能尽可能快的展示出数据。只要app组件处于启动状态(STARTED)就会立即接收到LiveData对象中的数据—前提是已经监听了LiveData

5、ViewModelProviders为什么找不到?

引用的版本太老了,需要新的Lifecyle扩展库(目前可以用的最新版)
//viewMouble使用
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'

6、创建LiveData实例

Android文档中建议LiveData配合ViewModel使用更加哦,其实呢,你也可以不使用ViewModel,但是一定要做到LiveData中保存的数据和组件分离,至于原因,前面我们已经提到过了。下面是在ViewModel中创建LiveData实例的例子:

public class NameViewModel extends ViewModel{// Create a LiveData with a Stringprivate MutableLiveData<String> mCurrentName;// Create a LiveData with a String listprivate MutableLiveData<List<String>> mNameListData;public MutableLiveData<String> getCurrentName() {if (mCurrentName == null) {mCurrentName = new MutableLiveData<>();}return mCurrentName;}public MutableLiveData<List<String>> getNameList(){if (mNameListData == null) {mNameListData = new MutableLiveData<>();}return mNameListData;}
}

在NameViewModel中创建了两个MutableLiveData(MutableLiveData是LiveData的子类)实例,分别存储当前姓名、姓名列表;两个实例通过NameViewModel中的getter方法得到。

7、创建Observer对象,添加观察者

public class LiveDataFragment extends Fragment {private static final String TAG = "LiveDataFragment";private NameViewModel mNameViewModel;@BindView(R.id.tv_name)TextView mTvName;public static LiveDataFragment getInstance(){return new LiveDataFragment();}@Overridepublic void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);mNameViewModel = ViewModelProviders.of(this).get(NameViewModel.class);// 订阅LiveData中当前Name数据变化,以lambda形式定义ObservermNameViewModel.getCurrentName().observe(this, new Observer<String>() {@Overridepublic void onChanged(String name) {mTvName.setText(name);Log.d(TAG, "currentName: " + name);}});// 订阅LiveData中Name列表数据变化,以lambda形式定义ObservermNameViewModel.getNameList().observe(this, new Observer<List<String>>() {@Overridepublic void onChanged(List<String> nameList) {for (String item : nameList) {Log.d(TAG, "name: " + item);}}});}@Nullable@Overridepublic View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {View view = inflater.inflate(R.layout.layout_livedata, container, false);ButterKnife.bind(this, view);return view;}}

在onCreate()方法中通过LiveData.observe()方法添加观察者,当数据变化时会通过回调方法通知观察者,在lambda表达式中更新当前姓名和打印姓名列表。

8、更新LiveData中的数据
在上面我们已经订阅了LiveData数据变化,现在我们看下如果LiveData数据变化时,上面的lambda表达式中是否会受到更新的通知。我们在LiveDataFragment中增加两个按钮来改变LiveData中的数据。

@OnClick({R.id.btn_change_name, R.id.btn_update_list})
void onClicked(View view){switch (view.getId()){case R.id.btn_change_name:mNameViewModel.getCurrentName().setValue("Jane");break;case R.id.btn_update_list:List<String> nameList = new ArrayList<>();for (int i = 0; i < 10; i++){nameList.add("Jane<" + i + ">");}mNameViewModel.getNameList().setValue(nameList);break;}
}

代码很简单,在两个按钮的点击事件中通过LiveData.setValue()方法来改变LiveData中保存的数据。当点击这两个按钮的时候,我们会发现在onCreate()方法中会收相应到数据改变的回调。

9、继承LiveData类

除了直接使用LiveDatad对象外,我们还可以通过集成LiveData类来定义适合特定需求的LiveData。下面继承LiveData类的例子,验证下LiveData的其中一个优点——资源共享。

package com.hao.architecture;import android.arch.lifecycle.LiveData;import java.math.BigDecimal;public class StockLiveData extends LiveData<BigDecimal> {private StockManager stockManager;public StockLiveData(String symbol) {stockManager = new StockManager(symbol);}private SimplePriceListener listener = new SimplePriceListener() {@Overridepublic void onPriceChanged(BigDecimal price) {// 更新LiveData并且通知所有活跃的观察者setValue(price);}};@Overrideprotected void onActive() {// 具有活跃的观察者时调用stockManager.requestPriceUpdates(listener);}@Overrideprotected void onInactive() {// 没有任何活跃的观察者时调用stockManager.removeUpdates(listener);}
}
onActive(),此方法是当处于激活状态的observer个数从0到1时,该方法会被调用。
onInactive() ,此方法是当处于激活状态的observer个数从1变为0时,该方法会被调用。

10、改变LiveData数据

LiveData提供了两种改变数据的方法:setValue()和postValue()。
区别是:

setValue()要在主线程中调用,
postValue()既可在主线程也可在子线程中调用。

我们先看setValue()方法的具体实现:

@MainThread
protected void setValue(T value) {assertMainThread("setValue"); //判断当前线程是否是主线程,不是主线程就抛出异常mVersion++;mData = value;dispatchingValue(null);
}

再看下postValue()方法的具体实现:

protected void postValue(T value) {boolean postTask;synchronized (mDataLock) {postTask = mPendingData == NOT_SET;mPendingData = value;}if (!postTask) {return;}// 会在主线程中执行  mPostValueRunnable中的内容。ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}private final Runnable mPostValueRunnable = new Runnable() {@Overridepublic void run() {Object newValue;synchronized (mDataLock) {newValue = mPendingData;mPendingData = NOT_SET;}// 在主线程中调用setValue()方法setValue((T) newValue); }
};

postValue()方法通过ArchTaskExecutor实现在主线程中执行mPostValueRunnable对象中的内容,而在mPostValueRunnable中最终会调用setValue()方法来实现改变LiveData存储的数据。
11、添加观察者

LiveData提供了两种添加观察者的方法:observeForever()、observe()。

observeForever()
@MainThread
public void observeForever(@NonNull Observer<T> observer) {observe(ALWAYS_ON, observer);
}

从方法的命名,我们也能对它的功能略知一二,通过observeForever()添加观察者,观察者会一直受到数据的变化回到,而不是在组件处于STARTED和RESUMED状态下才会收到,因为这是LifecycleOwner对象就不再是组件了,而是ALWAYS_ON;另外通过该方法添加观察者后,要手动调用removeObserver()方法来停止观察者接收回调通知。observeForever()方法体很简单,调用了observe()方法,传入的一个参数是ALWAYS_ON常量,重点看下ALWAYS_ON常量是个啥东东。

private static final LifecycleOwner ALWAYS_ON = new LifecycleOwner() {private LifecycleRegistry mRegistry = init();private LifecycleRegistry init() {LifecycleRegistry registry = new LifecycleRegistry(this);registry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);registry.handleLifecycleEvent(Lifecycle.Event.ON_START);registry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);return registry;}@Overridepublic Lifecycle getLifecycle() {return mRegistry;}
};

ALWAYS_ON是LifecycleOwner常量,在init方法中会初始化Lifecycle的生命周期状态,完了之后,就没有改变过Lifecycle的生命周期状态了,这也就是为什么通过observeForever()添加观察者是,当数据改变时不管组件处于什么状态都会收到回调的原因,除非手动将观察者移除。

observe()
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) {if (owner.getLifecycle().getCurrentState() == DESTROYED) {// ignorereturn;}//将LifecycleOwner对象和Observer对象封装成LifecycleBoundObserver对象。LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);// mObservers可以理解成一个类似Map的容器,putIfAbsent()方法是判断容器中的observer(key)// 是否有已经和wrapper(value)关联,如果已经关联则返回关联值,否则关联并返回wrapper。LifecycleBoundObserver existing = mObservers.putIfAbsent(observer, wrapper);if (existing != null && existing.owner != wrapper.owner) {throw new IllegalArgumentException("Cannot add the same observer"+ " with different lifecycles");}if (existing != null) {return;}owner.getLifecycle().addObserver(wrapper); //条件LifecycleOwner的生命周期观察者
}

LiveData的简介相关推荐

  1. Android Jetpack组件之 LiveData使用-源码

    1.前言 最近简单看了下google推出的框架Jetpack,感觉此框架的内容可以对平时的开发有很大的帮助,也可以解决很多开发中的问题,对代码的逻辑和UI界面实现深层解耦,打造数据驱动型UI界面. A ...

  2. android androidx版本,Android AndroidX 简介与迁移

    AndroidX 简介 AndroidX 是 Android 团队用于在 Jetpack 中开发,测试,打包,版本和发布库的开源项目 . AndroidX 是对原始 Android Support L ...

  3. Room是怎样和LiveData结合使用的?(源码分析)

    前言 之前写项目的时候,对于数据库的操作不是特别多,能避免就尽量避免,并且一直想不到比较好的方法去组织网络数据.本地数据的逻辑.所以在最近的面试中时,问及项目中的数据库实现,以及比较好用的数据库的框架 ...

  4. Android LiveData组件详解以及LiveDataBus

    转载请标明出处:https://blog.csdn.net/zhaoyanjun6/article/details/99749323 本文出自[赵彦军的博客] 一.LiveData简介 LiveDat ...

  5. 把 LiveData 用于事件传递那些坑

    0.前言 如果不是很了解 LiveData 和 Lifecycle 的同学可以先看一下我之前的文章 基于 Android Architecture Components 的 MVVM 浅析.同时安利下 ...

  6. LiveData 源码解析(2.4.1 版本)

    文章目录 1.LiveData 简介 2.LiveData 配置与基本用法 2.1 依赖引入与配置 2.2 基本用法 2.2.1 LiveData 简单使用 2.2.2 LiveData 扩展 2.2 ...

  7. Jetpack 架构组件:LiveData

    简介 LiveData 是一种可观察的数据存储器类.与常规的可观察类不同,LiveData具有生命周期感知能力,意指它遵循其他应用组件(如Activity/Fragment)的生命周期.这种感知能力可 ...

  8. 2018 谷歌 Google I/O 简介 总结

    作者:却把清梅嗅  原文:https://blog.csdn.net/mq2553299/article/details/80534124 前言 美国当地时间5月8日,2018年 Google I/O ...

  9. android——databinding中字符串的拼接处理、TextView显示的值随activity的属性值改变同时改变--LiveData、双向绑定过滤器、监听某个值的改变

    简介 使用的技术是观察者与被观察者的模式,在google推荐的案例中也有使用到,现在我把它封装成一个扩展函数,使得使用更加简单明了 注意 1.在build.gradle添加databinding,在a ...

最新文章

  1. struts2和springmvc的区别
  2. (13)python 字典 2 分钟速解
  3. r语言编程基础_这项免费的统计编程课程仅需2个小时即可学习R编程语言基础知识
  4. Shell脚本中循环语句for,while,until用法
  5. Android junit单元测试
  6. @AspectJ中的几种通知方式详解
  7. Web前端现在薪资多少?企业喜欢什么样的Web前端工程师?
  8. sql数据库身份验证登录
  9. solidworks迈迪设计宝_机械入门|那些看起来很牛X的机械结构,是如何设计的?...
  10. 戴尔r410服务器虚拟磁盘,DELL服务器R410原装 SAS 6/IR RAID卡 阵列控制器卡 支持RAID0,1...
  11. 第三章 代码的坏味道
  12. 具象化的代码世界~~Emoji
  13. css中好看常用的中文字体
  14. 这些选择器你都知道吗?
  15. BigDecimal如何保留小数位
  16. uni-app实现小程序沉浸式导航栏/顶部组件占满导航栏
  17. Hololens远程视频通话与AR标注
  18. 价格表制作软件使用方法
  19. 【ZZULIOJ】1056: 幸运数字
  20. 使用C++面向对象思想计算两条直线交点

热门文章

  1. mysql查询使用空间_mysql 如何察看数据库空间及日志空间使用情况
  2. APP-iOS和Android的尺寸规范
  3. 生信文献 | HOXC11作为一种新的致癌基因在人结肠癌和肾透明细胞癌中发挥作用​...
  4. python中import文件夹下面py文件,报错
  5. DPDK 编译安装(meson ninja)
  6. linux下删除u盘分区工具,如何删除U盘中的CDFS分区-
  7. 隔行换色并且鼠标指向行变色的表格
  8. oracle修改数据文件
  9. 兰州大学本科生(学士学位)LaTeX模板-2021版
  10. 《es6标准入门》 阮一峰