LiveData
-
基本特性
1.没有内存泄漏:因为 Observer被绑定到它们自己的 Lifecycle对象上,所以,当它们的 Lifecycle 被销毁时,它们能自动的被清理。
2.不会因为 Activity 停止而崩溃:如果 Observer 的 Lifecycle 处于闲置状态(例如:activity 在后台时),它们不会收到变更事件。
3.始终保持数据最新:如果 Lifecycle重新启动(例如:activity 从后台返回到启动状态)将会收到最新的位置数据(前提是有新数据更新,或者被重新订阅)。
4.正确处理配置更改:如果 activity 或 fragment 由于配置更改(如:设备旋转)重新创建,将会立即收到最新的有效位置数据。
5.资源共享:可以只保留一个 MyLocationListener 实例,只连接系统服务一次,并且能够正确的支持应用程序中的所有观察者。
6.不再手动管理生命周期你可能已经注意到,fragment 只是在需要的时候观察数据,不用担心被停止或者在停止之后启动观察。由于 fragment 在观察数据时提供了其 Lifecycle,所以 LiveData会自动管理这一切。
-
基本用法
/**
- ViewModel
**/
public class SampleViewModel extends ViewModel {
private MutableLiveData<String> sampleLiveData;
public MutableLiveData<String> getSampleLiveData() {
if (sampleLiveData == null) {
sampleLiveData = new MutableLiveData<String>();
}
return sampleLiveData;
}
//主线程更新数据调用
sampleLiveData.setValue(data);
//子线程更新数据调用
sampleLiveData.postValue(data);
}
/**
- Activity
/
public class SampleActivity extends AppCompatActivity {
private SampleViewModel viewModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
viewModel = ViewModelProviders.of(this).get(SampleViewModel.class);
final Observer<String> observer = new Observer<String>() {
@Override
public void onChanged(@Nullable final String dataStr) {
textView.setText(dataStr);
}
};
viewModel.getSampleLiveData().observe(this, observer);
}
}
/ - Fragment
**/
public class SampleFragment extends Fragment {
private SampleViewModel viewModel;
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
viewModel = ViewModelProviders.of(this).get(SampleViewModel.class);
final Observer<String> observer = new Observer<String>() {
@Override
public void onChanged(@Nullable final String dataStr) {
textView.setText(dataStr);
}
};
viewModel.getSampleLiveData().observe(this, observer);
}
}
Note: 确保 LiveData 是在ViewModel 中更新数据,原因如下:
避免Activity和Fragment变的臃肿。这样UI只需要关心它需要展示的数据,而不需要关系数据的获取和状态。
抽离LiveData到ViewModel 中可以使Activity和Fragment在重建之后数据不会丢失。
observeForever
viewModel.getSampleLiveData().observeForever(observer);
viewModel.getSampleLiveData().removeObserver(observer);
自定义LiveData
public class CustomLiveData extends LiveData<String> {
/**
* 有可被通知的observer
/
@Override
protected void onActive() {
super.onActive();
}
/*
* 没有可被通知的observer
*/
@Override
protected void onInactive() {
super.onInactive();
}
}
MediatorLiveData
private MutableLiveData<String> data1 = new MutableLiveData<>();
private MutableLiveData<String> data2 = new MutableLiveData<>();
private MediatorLiveData<String> mediatorLiveData = new MediatorLiveData<>();
private void sample(@NonNull LifecycleOwner owner) {
mediatorLiveData.addSource(data1, new Observer<String>() {
@Override
public void onChanged(@Nullable String s) {
mediatorLiveData.setValue(s);
}
});
mediatorLiveData.addSource(data2, new Observer<String>() {
@Override
public void onChanged(@Nullable String s) {
mediatorLiveData.setValue(s);
}
});
mediatorLiveData.observe(owner, new Observer<String>() {
@Override
public void onChanged(@Nullable String s) {
}
});
// mediatorLiveData.removeSource();
}
关于更新数据丢失问题
在UI可见时,调用
liveData.postValue("a");
liveData.setValue("b");
会先收到"b",后收到"a"
在UI不可见时,调用
liveData.postValue("a");
liveData.setValue("b");
当UI可见,只会收到"a",因为setValue先执行,之后被postValue更新掉
在UI可见时,调用
liveData.setValue("a");
liveData.setValue("b");
liveData.setValue("c");
liveData.setValue("d");
liveData.setValue("e");
会按顺序收到"a","b","c","d","e"
在UI可见时,调用
liveData.postValue("a");
liveData.postValue("b");
liveData.postValue("c");
liveData.postValue("d");
liveData.postValue("e");
只会收到"e"
在UI可见时,调用
liveData.postValue("a");
liveData.postValue("b");
liveData.postValue("c");
liveData.postValue("d");
liveData.setValue("e");
会先收到"e",后收到"d"
在UI不可见时,调用
liveData.setValue("a");
liveData.setValue("b");
liveData.setValue("c");
liveData.setValue("d");
liveData.setValue("e");
当UI可见之后,只会收到"e"
在UI不可见时,调用
liveData.postValue("a");
liveData.postValue("b");
liveData.postValue("c");
liveData.postValue("d");
liveData.postValue("e");
当UI可见之后,只会收到"e"
在UI不可见时,调用
liveData.setValue("a");
liveData.setValue("b");
liveData.setValue("c");
liveData.setValue("d");
liveData.postValue("e");
当UI可见之后,只会收到"e"
在UI不可见时,调用
liveData.postValue("a");
liveData.postValue("b");
liveData.postValue("c");
liveData.postValue("d");
liveData.setValue("e");
当UI可见之后,只会收到"d"