LiveData
是一个可观察的数据持有者类,不过它和其他的可观察对象不同,它会与生命周期相关联,比如Activity的生命周期,LiveData能确保仅在Activity
处于活动状态下才会更新。也就是说当观察者处于活动状态,才会去通知数据更新。
个人觉得这是为了避免内存泄漏,可以说是很实用了,因为要想避免内存泄漏,必须要感知到生命周期,而原本并没有提供额外的方法,像Glide采用了一个透明的Fragment来感知Activity的生命周期,这虽然是一个可行的方法,但总共感觉并不是一个最优的方法。
下面是官方说明的使用LiveData的优点
- 确保UI与数据同步
- 不会产生内存泄漏
- 不会因为Activity停止而Crash
- 不需要手动控制生命周期
下面便是LiveData在MVVM中的角色
LiveData使用
LiveData是配合ViewModel使用的
ViewModelWithData.java
public class ViewModelWithData extends ViewModel {
private MutableLiveData<Integer> number;
//注意这个构造方法需要public,因为他是通过方式来创建实例的
public ViewModelWithData(){
number = new MutableLiveData<>();
number.setValue(0);
}
public MutableLiveData<Integer> getNumber() {
return number;
}
public void setNumber(MutableLiveData<Integer> number) {
this.number = number;
}
public void addNumber(int n){
number.setValue(number.getValue() + n);
}
}
LiveDataActivity.java
public class LiveDataActivity extends AppCompatActivity {
private ViewModelWithData viewModelWithData;
private TextView textView;
private ImageButton imageButton1, imageButton2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_live_data);
textView = findViewById(R.id.tv1);
imageButton1 = findViewById(R.id.ib1);
imageButton2 = findViewById(R.id.ib2);
viewModelWithData = ViewModelProviders.of(this).get(ViewModelWithData.class);
//这里添加对viewModelWithData的对象的观察者
viewModelWithData.getNumber().observe(this, new Observer<Integer>() {
@Override
public void onChanged(Integer integer) {
textView.setText(String.valueOf(integer));//响应数据变化
}
});
imageButton1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
viewModelWithData.addNumber(1);
}
});
imageButton2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
viewModelWithData.addNumber(-1);
}
});
}
}
同时LiveData还支持map的映射转换,其实感觉这个liveData和rxJava大同小异
官方示例代码
LiveData<User> userLiveData = ...;
LiveData<String> userName = Transformations.map(userLiveData, user -> {
user.name + " " + user.lastName
});