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
});