一般情况下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. 2022春每日一题:Day 15

    题目:Balanced lineup 题目说的很清楚了,没有修改,直接RMQ,模板题. 代码: #include <cstdio> #include <cstdlib> #in ...

  2. js-day02-综合案例ATM存款书写

     <script>                 // 1. 不断的弹出对话框         // 3. 金额的变量         let money = 100         w ...

  3. SQL注入绕waf思路总结

    1.关键字大小写混合绕过 关键字大小写混合只针对于小写或大写的关键字匹配技术-正则表达式,如果在匹配时大小写不敏感的话,就无法绕过.这是最简单的一个绕过技术. 例如:将union select混写成U ...

  4. 【Shell案例】【awk和循环、NR、格式打印、全局变量、$0、通配符】12、打印每一行出现的数字个数

    写一个 bash脚本以统计一个文本文件 nowcoder.txt中每一行出现的1,2,3,4,5数字个数并且要计算一下整个文档中一共出现了几个1,2,3,4,5数字数字总数. 示例: 假设 nowco ...

  5. Day36:List详解

    List 1.1 概述 List为Collection的子接口,代表的一组任意对象,有序,有下标.元素可以重复. 1.2 方法 方法名 说明 void add(int index,Object o) ...

  6. 【LeetCode】剑指 Offer 30. 包含min函数的栈

    题目描述 定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min.push 及 pop 的时间复杂度都是 O(1). 思路 最初看到O(1)复杂度的时候,就想 ...

  7. Django框架:10、Ajax补充说明、多对多三种创建方法、Django内置序列化组件、批量操作数据方法、分页器思路、form组件

    Django框架 目录 Django框架 一.Ajax补充说明 1.针对前端回调函数接受值的说明 二.多对多三种创建方式 1.自动创建 2.纯手动创建 3.半自动创建 三.Django内置序列化组件 ...

  8. Python如何像awk一样分割字符串

    若你使用过 Shell 中的 awk 工具,会发现用它来分割字符串是非常方便的.特别是多个连续空格会被当做一个处理. [root@localhost ~]# cat demo.txt hello wo ...

  9. 痞子衡嵌入式:对比恩智浦全系列MCU(包含Kinetis/LPC/i.MXRT/MCX)的GPIO电平中断设计差异

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是恩智浦全系列MCU(包含Kinetis, LPC, i.MXRT, MCX)的GPIO电平中断设计差异. 在痞子衡旧文 <以i.M ...

  10. [OpenCV实战]44 使用OpenCV进行图像超分放大

    图像超分辨率(Image Super Resolution)是指从低分辨率图像或图像序列得到高分辨率图像.图像超分辨率是计算机视觉领域中一个非常重要的研究问题,广泛应用于医学图像分析.生物识别.视频监 ...