1、LiveData到底是个啥?
LiveData是可以在给定生命周期内观察到的数据持有者类。
它是一个类,这个类可以干嘛呢?
可以在给定的生命周期内观察数据变化。
给定的生命周期是什么意思?
指的是AppCompatActivity的onStart() 和 onResume()方法。
为什么要是AppCompatActivity 这个类而不是单纯的Activity类呢?
很简单当我们查看AppCompatActivity类的源码时发现它实现了LifecycleOwner 这个接口。
LifecycleOwner 这个接口有什么用?
为了实现数据变化的感知,需要实现观察者模式。
所以单靠区区一个类LiveData类还不能实现观察者模式,需要结合LifecycleOwner 接口实现类。为啥我们不需要直接去实现它,因为AppCompatActivity 的这个【ComponentActivity】父类已经实现了LifecycleOwner 这个接口,所以我们可以直接使用LiveData进行数据变更,就会有对应的生命周期响应。
接下来我们看看应该怎么样在实际案例中使用它。
使用之前我们需要在app的build.gradle文件中配置:
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
2、具体案例
布局activity_live_data.xml:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="dataBean"
type="com.hb.mvvm.livedata.DataBeanViewModel" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@={dataBean.data}" />
</LinearLayout>
</layout>
实体类DataBeanViewModel.class:
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
/**
* Created by Administrator
* on 2020/3/31
*/
public class DataBeanViewModel extends ViewModel {
//<String> 可以换成对应的实体类型 eg:<User>
MutableLiveData<String> dbLiveData = new MutableLiveData<>();
//获取LiveData对象实例
public MutableLiveData<String> getData() {
return dbLiveData;
}
}
类LiveDataActivity.class :
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;
import androidx.lifecycle.ViewModelProvider;
import com.hb.mvvm.R;
import com.hb.mvvm.databinding.ActivityLiveDataBinding;
import org.w3c.dom.Text;
public class LiveDataActivity extends AppCompatActivity {
ActivityLiveDataBinding liveDataBinding;
final String TAG = LiveDataActivity.class.getSimpleName();
DataBeanViewModel dbViewModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
liveDataBinding = DataBindingUtil.setContentView(this, R.layout.activity_live_data);
//设置观察
liveDataBinding.setLifecycleOwner(this);
//创建DataBeanViewModel 的实例
dbViewModel = new ViewModelProvider(this).get(DataBeanViewModel.class);
//使用实例
liveDataBinding.setDataBean(dbViewModel);
liveDataBinding.tv.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
Log.i(TAG, "观察TextView数据变化: " + s);
}
});
}
@Override
protected void onStart() {
super.onStart();
Log.i(TAG, "onStart()");
}
@Override
protected void onResume() {
super.onResume();
Log.i(TAG, "onResume()");
}
@Override
protected void onPause() {
super.onPause();
Log.i(TAG, "onPause()");
//为了查看数据是否能够恢复,切换到后台的时候将数据置空
liveDataBinding.tv.setText("");
}
@Override
protected void onStop() {
super.onStop();
Log.i(TAG, "onStop()");
//停止的时候设置数据,看看在OnResume之后能否在显示出数据
dbViewModel.getData().postValue("ViewModel配合LiveData使用");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.i(TAG, "onDestroy()");
}
}
输出:
onStart()
onResume()
onPause()
观察TextView数据变化:
onStop()
onStart()
onResume()
观察TextView数据变化: ViewModel配合LiveData使用
onPause()
观察TextView数据变化:
onStop()
onStart()
onResume()
观察TextView数据变化: ViewModel配合LiveData使用
onPause()
观察TextView数据变化:
onStop()
onStart()
onResume()
观察TextView数据变化: ViewModel配合LiveData使用
onPause()
观察TextView数据变化:
onStop()
onDestroy()
onStart()
onResume()
onPause()
观察TextView数据变化:
onStop()
onDestroy()
输出中可以看到TextView数据恢复时都是在onResume()之后,但是onStart() 貌似没有体现出来。
当我们没调用onDestroy()方法时,每次切换显示界面都会恢复之前设置的数据,否则数据将会不在恢复。
这个过程保证了数据能完整的伴随生命周期的过程,相对而言数据恢复这块比之前的方式savedInstanceState更加方便。
同时通过查阅资料,当生命周期处于onDestory时,观察者会自动删除,防止内存溢出。
3、总结
LiveData 会自己管理自己的生命周期,防止内存溢出。
LiveData 能更好的帮助我们数据恢复,贯穿到整个Activity生命周期。
案例中发现当在onResume的时候看到才会恢复数据。而onStart()的时候没有做具体的实验,希望留给后面进行尝试。