1. 什么是LiveData ?
- 数据本身可以被观察者订阅
- 能够感知组件(Fragment,Activity,Service)的生命周期(基于Lifecycle)
- 只有在组件处于激活状态(STARTED,RESUMED)才会通知观察者更新数据
- 当数据变化的时候就会接受到通知(即使观察者是在setValue/postValue之后设置)
2. LiveData 优点
- 保证数据和UI统一:LiveData作为被观察者,当数据变化通知观察者(UI)
- 减少内存泄漏:感知到组件的生命周期,当组件处于DESTROYED状态是,
观察者对象会被清除掉 - 组件和数据相关的内容能实时更新:当组件从后台到前台来时,LiveData能够将最新的数据通知组件
- 针对configuration change时,不需要额外的处理来保存数据:当configuration change(比如语言、屏幕方向变化)时,组件会被recreate,然而系统并不能保证你的数据能够被恢复的。当我们采用LiveData保存数据时,因为数据和组件分离了。当组件被recreate,数据还是存在LiveData中,并不会被销毁
- 资源共享:通过继承LiveData类,然后将该类定义成单例模式,在该类封装监听一些系统属性变化,然后通知LiveData的观察者
3. LiveData基本使用
方法一:关联ViewModel实现
1. 继承ViewModel,内部定义LiveData
2. 创建ViewModel实例
3. 通过ViewModel获取LiveData实例,通过LiveData.Observe实例并且设置观察者
4. 在观察者(Observe)内部重写onChanged事件,决定数据变化时候的动作
方法二:直接创建LiveData实例
1.MutableLiveData<Interger> obj = new MutableLiveData<Integer>() {};
2.obj.Observe()
LiveData能用来包裹所有数据,包括实现了Collections的对象,例如List
LiveData常用方法:
1.LiveData.observe 设置观察者
2.LiveData.observeForever,如果使用此模式那么数据变化的时候,观察者则始终会收到通知,
即使组件处于非激活状态
3.LiveData.removeObserver 删除观察者
4.LiveData.setValue/LiveData.postValue 更新LiveData的值
方法一:demo
public class UserViewModel extends ViewModel {
private MutableLiveData<Integer> mProgress;
public MutableLiveData<Integer> getProgress() {
if(mProgress == null){
mProgress = new MutableLiveData<>();
}
return mProgress;
}
}
//Activity OnCreate的方法中实现
//创建UserViewModel实例
ViewModelProvider viewModelProvider = new ViewModelProvider(this);
mUserViewModal = viewModelProvider.get(UserViewModel.class);
//设置观察者
mUserViewModal.getProgress().observe(this, new Observer<Integer>() {
//当数据变化的时候更新UI
@Override
public void onChanged(Integer integer) {
mProgressBar1.setProgress(integer);
}
});
方法二:demo
mLiveData = new MutableLiveData<Integer>() {
@Override
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super Integer> observer) {
super.observe(owner, observer);
}
};
mLiveData.observe(this, new Observer<Integer>() {
@Override
public void onChanged(Integer integer) {
mProgressBar1.setProgress(integer);
}
});
4. LiveData实现数据共享(Activity,Fragment,Service)
ViewModel只能实现同一个Activity之间的Fragment数据共享,因为不同的Activity之间获取的ViewModel实例不同
public class ShareLiveData extends MutableLiveData<Integer> {
private static final String TAG=ShareLiveData.class.getName();
private static ShareLiveData sInstance;
//使用唯一实例实现数据共享
static public ShareLiveData Instance(){
if(sInstance == null)
sInstance = new ShareLiveData();
return sInstance;
}
//构造函数私有化
private ShareLiveData(Integer val){
super(val);
}
private ShareLiveData(){
super();
}
}
SecoundActivity.java
//OnCreate 方法中实现,设置初始值为10
mLiveData = mLiveData.Instance();
mLiveData.observe(this, new Observer<Integer>() {
@Override
public void onChanged(Integer integer) {
Log.i(TAG, "onChanged: Livedata,val" + integer);
}
});
//设置默认值
mLiveData.postValue(10);
ThirdActivity.java
mShare1 = mShare1.Instance();
mShare1.observe(this, new Observer<Integer>() {
@Override
public void onChanged(Integer integer) {
mProgressBar1.setProgress(integer);
}
});
此时在SecoundActivity通过点击按钮跳转到ThirdActivity,此时进度条默认会被设置为10。当在ThirdActivity改变进度条值之后返回SecoundActivity,SecoundActivity此时变为活动状态,将收到观察者的onChanged通知,数据修改到了30
I/com.example.qwe.SecoundActivity: onChanged: Livedata,val:10
D/LifecycleDeno: onCreate:
D/LifecycleDeno: onStart:
I/ThirdActivity: onChanged: Livedata,val:10
D/LifecycleDeno: onResume:
I/ThirdActivity: onChanged: Livedata,val:20
I/ThirdActivity: onChanged: Livedata,val:30
D/LifecycleDeno: onPause:
I/com.example.qwe.SecoundActivity: onChanged: Livedata,val:30
I/SecoundActivity: MAIN_ORDERED : Subscribe Recv String Event ,thread id: 2,event message:sticky0
D/EGL_emulation: eglMakeCurrent: 0xa9105120: ver 3 1 (tinfo 0xa9103280)
D/LifecycleDeno: onStop:
D/LifecycleDeno: onDestroy:
参考文章:
https://blog.csdn.net/feather_wch/article/details/88648559