一、前言:
- 简介:
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会自动解除其注册关系
- 优势:
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的父类是LiveData
LiveData在实体类里可以通知指定某个字段的数据更新.
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 String
private MutableLiveData mCurrentName;
// Create a LiveData with a String list
private MutableLiveData mNameListData;
public MutableLiveData getCurrentName() {
if (mCurrentName == null) {
mCurrentName = new MutableLiveData();
}
return mCurrentName;
}
public MutableLiveData 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();
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mNameViewModel = ViewModelProviders.of(this).get(NameViewModel.class);
// 订阅LiveData中当前Name数据变化,以lambda形式定义Observer
mNameViewModel.getCurrentName().observe(this, new Observer() {
@Override
public void onChanged(String name) {
mTvName.setText(name);
Log.d(TAG, "currentName: " + name);
}
});
// 订阅LiveData中Name列表数据变化,以lambda形式定义Observer
mNameViewModel.getNameList().observe(this, new Observer() {
@Override
public void onChanged(List nameList) {
for (String item : nameList) {
Log.d(TAG, "name: " + item);
}
}
});
}
@Nullable
@Override
public 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 nameList = new ArrayList();
for (int i = 0; i
关注
打赏
- kotlin使用retrofit请求报错Parameter type must not include a type variable or wildcard
- android 中Handle弱引用使用
- 颜色透明参数
- flutter 手机端抓包设置
- vite 创建项目
- 鸿蒙 加载本地rowfile文件中的 json 数据
- 鸿蒙 加载长图(大图自动适用屏幕的宽度)
- Android 与Vue 页面交互
- 鸿蒙 保存图片到相册
- 鸿蒙 上传图片路径转换dataability:///media/external/images/media/30为/storage/emulated/0/DCIM/YIIoT/5769014/202