一般情况下LiveData都是搭配这ViewModel使用,这里先介绍一下LiveData,再结合ViewModel使用
 

1、什么是LiveData

  1. LiveData是一个观察者模式的数据实体类,它可以在所有注册观察者回调里查看数据是否有更新。
  2. LiveData它能感知绑定者的生命周期(如Activity,Fragment),不会发生内存泄露,因为它只会给活跃状态的activity回调,我们在使用的时候通常都会在回调里去更新UI。
  3. 从非活跃状态变为活跃状态时,回调方法会立即接收到最新的数据
  4. 当设备切横竖屏,会重建Activity生命周期,它也会立即接收最新的可用数据。
  5. 不可变,setValue和postValue不支持外部使用(protected修饰)。下面代码讲解
  6. 抽象类,无法直接new
 

2、什么是MutableLiveData

  1. MutableLiveData的父类是LiveData
  2. 用法和LiveData类似,也是在注册观察者回调里查看更新数据
  3. 可变,setValue和postValue支持外部使用(public修饰)
  4. 普通类,可以直接new
 

3、LiveData与MutableLiveData区别

  1. LiveData在实体类里可以通知指定某个字段的数据更新.(下面会贴代码)
  2. MutableLiveData则是完全是整个实体类或者数据类型变化后才通知.不会细节到某个字段
 

4、LiveData的使用

public class UserBean extends LiveData<UserBean> {
String name;
int age; public String getName() {
return name;
} public void setName(String name) {
this.name = name;
postValue(this);
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
postValue(this); }
}
postValue(this);这个方法是用于触发回调数据更新的方法. 你可以在你需要被观察的数据里添加.
 
小注意点:如果不使用postValue(this)会怎么样?
    public void setAge(int age) {
this.age = age;
// postValue(this);
// 如果不写的话,单独调用setAge后,在外getAge获取不到值,因为回调没有被触发,
// 如果name写了postValue(this),更新了name也会连着age更新,因为传的是this
}
你也可以集成LiveData<String>,那么postValue(string),回调中只会接收postValue最后的赋值。
 

4.1ViewModel新建

public class MyViewModel extends ViewModel {

    public UserBean mUserBean = new UserBean();

    public UserBean getUserBean() {
return mUserBean;
} }
 

4.2Activity中添加回调方法

//通过ViewModeProvider 把activity和ViewModel绑定起来。
myViewModel = new ViewModelProvider(this, new ViewModelProvider.NewInstanceFactory()).get(MyViewModel.class);
observer = new Observer<UserBean>() {
@Override
public void onChanged(UserBean userBean) {
Log.e("activity",userBean.getName());
mBinding.textShow.setText("name="+userBean.getName()+" ,, age="+userBean.getAge()+"");
}
};
//绑定观察者
myViewModel.getUserBean().observe(this, observer); a = 0;
mBinding.btnUpdata.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
myViewModel.getUserBean().setName("大王"+a);
myViewModel.getUserBean().setAge(a++);
}
});
注意:这里的myViewModel.getUserBean().observe() 是LiveData的方法。
我们上面创建了一个Observer,并且和activity关联,然后通过一个按钮去动态设置值,果然回调里就会有数据更新。
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
 

4.3有绑定就会有解绑

myViewModel.getUserBean().removeObserver(observer);
 

5、MutableLiveData的使用

它是直接作用在变量上,mStr.setValue(s);触发观察者的回调。
public class MyViewModel extends ViewModel {
private MutableLiveData<String> mStr; public MutableLiveData<String> getmStr() {
return mStr;
} public void setmStr(String s) {
if(mStr==null){
mStr = new MutableLiveData<>();
}
mStr.setValue(s);
} }

5.1在activity中使用

myViewModel.getmStr().observe(this, new Observer<String>() {
@Override
public void onChanged(String s) { }
});
 

6、LiveData和MutableLiveData的可变与不可变

其实就是setValue和postValue是否暴露问题,LiveData中是不支持外部使用,而MutableLiveData特意放开
@SuppressWarnings("WeakerAccess")
public class MutableLiveData<T> extends LiveData<T> {
@Override
public void postValue(T value) {
super.postValue(value);
} @Override
public void setValue(T value) {
super.setValue(value);
}
}
 
可以看到在MutableLiveData包裹的有setValue,postValue方法
当然我们也可以让它不对外暴露setValue,postValue方法,返回值修改为LiveData<String>
public class MyViewModel extends ViewModel {
private MutableLiveData<String> mStr= new MutableLiveData<>(); public LiveData<String> getmStr() {
return mStr;
}
//在外面只能通过这种方式去更新
public void setmStr(String s) {
mStr.setValue(s);
}
}

7、其他方法

postValue()
  postValue的特性如下:
  1.此方法可以在其他线程中调用
  2.如果在主线程执行发布的任务之前多次调用此方法,则仅将分配最后一个值。
  3.如果同时调用 .postValue()和.setValue(),结果是post的值覆盖set值。 setValue()
  setValue()的特性如下:
  1.此方法只能在主线程里调用
getValue()
  返回当前值。 注意,在后台线程上调用此方法并不能保证将接收到最新的值。 removeObserver(@NonNull final Observer<? super T> observer)
移除指定的观察者 removeObservers(@NonNull final LifecycleOwner owner)
  移除当前Activity或者Fragment的全部观察者 hasActiveObservers()
  如果此LiveData具有活动(Activity或者Fragment在前台,当前屏幕显示)的观察者,则返回true。其实如果这个数据的观察者在最前台就返回true,否则false。 hasObservers()
  如果此LiveData具有观察者,则返回true。 observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer)
  设置此LiveData数据当前activity或者Fragment的观察者,会给此activity或者Fragment在前台时回调数据。 observeForever(@NonNull Observer<? super T> observer)
  1.设置永远观察者,永远不会被自动删除。您需要手动调用removeObserver(Observer)以停止观察此LiveData,
  2.设置后此LiveData,一直处于活动状态,不管是否在前台哪里都会获得回调。

总结:

LiveData一般使用在实体类,MutableLiveData作用在变量上,他们通常和ViewModel结合使用,上面例子过于简单,工作当中可按照业务需要进行调整。
 

Android  JetPack~ LiveData (一)   介绍与使用的更多相关文章

  1. Android Jetpack 组建介绍(一)——Lifecycler

    转自带你领略Android Jetpack组件的魅力 Android Jetpack 对于任何一个产品来说,我们开发中都会面对哪些问题?如:产品交互.用户体验.代码结构.数据获取.数据存储.网络优化. ...

  2. Android Jetpack 组建介绍(二)——Lifecycler

    参考Android Jetpack架构组件之 Lifecycle(源码篇) 源码分析 关于Lifecycle的使用考上一篇文章Android Jetpack框架之 Lifecycles(使用篇),从使 ...

  3. Android Jetpack 架构组件最佳实践之“网抑云”APP

    背景 近几年,Android 相关的新技术层出不穷.往往这个技术还没学完,下一个新技术又出来了.很多人都是一脸黑人问号? 不少开发者甚至开始哀嚎:"求求你们别再创造新技术了,我们学不动了!& ...

  4. 学习Android Jetpack? 入门教程和进阶实战这里全都有!

    前言 2018年谷歌I/O,Jetpack横空出世,官方介绍如下: Jetpack 是一套库.工具和指南,可帮助开发者更轻松地编写优质应用.这些组件可帮助您遵循最佳做法.让您摆脱编写样板代码的工作并简 ...

  5. Android官方架构组件介绍之LifeCycle(一)

    Android官方架构组件介绍之LifeCycle 下面是官方提供的Android App开发的架构图: 从上图可以看到一些关键字:ViewModel,LiveData,Room等.其实看了上面视频的 ...

  6. Android Jetpack - 使用 Navigation 管理页面跳转

    在今年的 IO 大会上,发布了一套叫 Android Jetpack 的程序库.Android Jetpack 里的组件大部分我们都接触过了,其中也有一些全新的组件,其中一个就是 Navigation ...

  7. 带你了解Android Jetpack

    1.Jetpack主要特性有以下三点: 1.加速开发组件可单独使用,也可以协同工作,当使用kotlin语言特性时,可以提高效率. 2.消除样板代码Android Jetpack可管理繁琐的Activi ...

  8. Android Jetpack组件

    带你领略Android Jetpack组件的魅力 Android新框架jetpack的内容讲解:Room.WorkManager.LifeCycles.LiveData.ViewModel.DataB ...

  9. Android Jetpack从入门到精通(深度好文,值得收藏)

    前言 即学即用Android Jetpack系列Blog的目的是通过学习Android Jetpack完成一个简单的Demo,本文是即学即用Android Jetpack系列Blog的第一篇. 记得去 ...

  10. 【Android Jetpack高手日志】DataBinding 从入门到精通

    前言 DataBinding 数据绑定库是 Android Jetpack 的一部分,借助该库可以使用声明性格式(而非程序化地)将布局中的界面组件绑定到应用中的数据源.我个人觉得,使用 DataBin ...

随机推荐

  1. 使用CRD扩展Kubernetes API

    本文是如何创建 CRD 来扩展 Kubernetes API 的教程.CRD 是用来扩展 Kubernetes 最常用的方式,在 Service Mesh 和 Operator 中也被大量使用.因此读 ...

  2. 深度学习之深L层神经网络

    声明 本文参考(8条消息) [中文][吴恩达课后编程作业]Course 1 - 神经网络和深度学习 - 第四周作业(1&2)_何宽的博客-CSDN博客 力求自己理解,刚刚走进深度学习希望可以一 ...

  3. SpringBoot2.5.1+Mybatis-Plus3.4.3:(Property ‘sqlSessionFactory‘ or ‘sqlSessionTemplate‘ are required)

    项目引发这个问题: Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required <parent> <group ...

  4. docker给已存在的容器添加或修改端口映射

    简述: 这几天研究了一下docker, 发现建立完一个容器后不能增加端口映射了,因为 docker run -p 有 -p 参数,但是 docker start 没有 -p 参数,让我很苦恼,无奈谷歌 ...

  5. go-carbon 1.5.3 版本发布, 修复已知 bug 和新增俄罗斯语翻译文件

    carbon 是一个轻量级.语义化.对开发者友好的golang时间处理库,支持链式调用. 目前已被 awesome-go 收录,如果您觉得不错,请给个star吧 github.com/golang-m ...

  6. P3Depth: Monocular Depth Estimation with a Piecewise Planarity Prior

    1. 论文简介 论文题目:P3Depth: Monocular Depth Estimation with a Piecewise Planarity Prior Paper地址:paper Code ...

  7. @Data加在子类上,子类无法获取父类的属性

    1.问题描述 我的子类继承父类,并在子类上加了@Data注解.但在程序运行时,输出的结果只有我在子类中定义的属性,父类的属性没有输出. 这是我定义的子类: 这个是子类继承的父类: 这个是输出结果: 可 ...

  8. Redis学习整理

    目录 1.Redis基本概念 2.Redis的5种基本类型 3.Jedis整合redis操作 4.Springboot整合redis 5.Redis主从复制 5.1.概念 5.2.原理 6.开启主从复 ...

  9. drf快速使用 CBV源码分析 drf之APIView分析 drf之Request对象分析

    目录 序列化和反序列化 drf介绍和安装 使用原生django写接口 django DRF安装 drf快速使用 模型 序列化类 视图 路由 datagrip 使用postman测试接口 CBV源码分析 ...

  10. Echarts自适应屏幕,无需刷新网页,可根据屏幕大小完美展现,内有详细代码注释,我可真是个小机灵~~O(∩_∩)O哈哈~

    Echarts自适应屏幕,无需刷新网页,可根据屏幕大小完美展现 效果如图 随意拖拉,无惧检验 ~ ~ ~ ~ 下面上代码 里边有详细解释 <template> <div class= ...