Android LiveData - 第二次更新时未触发 switchMap
Android LiveData - switchMap is not triggered on second update
我有一个 LiveData
对象依赖于另一个 LiveData
。据我了解,Transformations.switchMap
应该允许链接它们。但是 switchMap
处理程序只被触发一次,它不会对进一步的更新做出反应。相反,如果我在第一个对象上使用 observe
,当它准备好时,检索第二个对象,它工作正常,但在这种情况下,我必须在 Activity
而不是 ViewModel
中进行。是否可以链接 LiveData
个对象,如 Transformations.switchMap
,但接收所有更新,而不仅仅是第一个?
这里尝试使用switchMap
:
LiveData<Resource<User>> userLiveData = usersRepository.get();
return Transformations.switchMap(userLiveData, resource -> {
if (resource.status == Status.SUCCESS && resource.data != null) {
return apiService.cartItems("Bearer " + resource.data.token);
} else {
return AbsentLiveData.create();
}
});
这是 activity 中 observe
的一种方法(有效但需要在 activity 中保持逻辑):
viewModel.user().observe(this, x -> {
if (x != null && x.data != null) {
viewModel.items(x.data.token).observe(this, result -> {
// use result
});
}
});
作为解决方法,我使用了 MediatorLiveData
。我将第一次调用的结果添加为源,准备就绪后,将其替换为最终调用:
MediatorLiveData<MyResponse> result = new MediatorLiveData<>();
LiveData<Resource<User>> source = this.get();
result.addSource(source, resource -> {
if (resource.status == Status.SUCCESS && resource.data != null) {
result.removeSource(source);
result.addSource(apiService.cartItems("Bearer " + resource.data.token), result::postValue);
}
});
return result;
我正在尝试做与您类似的事情。我有一个 LiveData something
,当它发生变化时,我想根据 属性 从数据库中查询 somethingElse
。因为 属性 可以为空,如果我用它查询数据库,我会得到一个异常。因此,如果 属性 为空,我将返回一个空的 MutableLiveData。
我注意到,当我返回这个空的 MutableLiveData 时,订阅 somethingElse
的观察者没有得到任何更新。我在你的 上看到你最终使用了 MediatorLiveData。然后我用调试器单步调试我的代码,注意到 switchMap 也使用了 MediatorLiveData。
经过一番试验,我发现在创建空的MutableLiveData时,它的初始值为null,不会触发任何更新。如果我明确设置值,那么它会通知观察者。
somethingElse = Transformations.switchMap(something, somethingObject -> {
if (something.someProperty() != null) {
return repository.getSomethingElseByProperty(something.someProperty());
}else{
MutableLiveData<SomethingElse> empty = new MutableLiveData<>();
empty.setValue(null);//need to set a value, to force update of observers
return empty;
}
这里的代码对我有用。在这个问题中,你使用了一个 AbsentLiveData,我不知道它是如何实现的,所以我不确定它在那种情况下是否能正常工作。
我有一个 LiveData
对象依赖于另一个 LiveData
。据我了解,Transformations.switchMap
应该允许链接它们。但是 switchMap
处理程序只被触发一次,它不会对进一步的更新做出反应。相反,如果我在第一个对象上使用 observe
,当它准备好时,检索第二个对象,它工作正常,但在这种情况下,我必须在 Activity
而不是 ViewModel
中进行。是否可以链接 LiveData
个对象,如 Transformations.switchMap
,但接收所有更新,而不仅仅是第一个?
这里尝试使用switchMap
:
LiveData<Resource<User>> userLiveData = usersRepository.get();
return Transformations.switchMap(userLiveData, resource -> {
if (resource.status == Status.SUCCESS && resource.data != null) {
return apiService.cartItems("Bearer " + resource.data.token);
} else {
return AbsentLiveData.create();
}
});
这是 activity 中 observe
的一种方法(有效但需要在 activity 中保持逻辑):
viewModel.user().observe(this, x -> {
if (x != null && x.data != null) {
viewModel.items(x.data.token).observe(this, result -> {
// use result
});
}
});
作为解决方法,我使用了 MediatorLiveData
。我将第一次调用的结果添加为源,准备就绪后,将其替换为最终调用:
MediatorLiveData<MyResponse> result = new MediatorLiveData<>();
LiveData<Resource<User>> source = this.get();
result.addSource(source, resource -> {
if (resource.status == Status.SUCCESS && resource.data != null) {
result.removeSource(source);
result.addSource(apiService.cartItems("Bearer " + resource.data.token), result::postValue);
}
});
return result;
我正在尝试做与您类似的事情。我有一个 LiveData something
,当它发生变化时,我想根据 属性 从数据库中查询 somethingElse
。因为 属性 可以为空,如果我用它查询数据库,我会得到一个异常。因此,如果 属性 为空,我将返回一个空的 MutableLiveData。
我注意到,当我返回这个空的 MutableLiveData 时,订阅 somethingElse
的观察者没有得到任何更新。我在你的
经过一番试验,我发现在创建空的MutableLiveData时,它的初始值为null,不会触发任何更新。如果我明确设置值,那么它会通知观察者。
somethingElse = Transformations.switchMap(something, somethingObject -> {
if (something.someProperty() != null) {
return repository.getSomethingElseByProperty(something.someProperty());
}else{
MutableLiveData<SomethingElse> empty = new MutableLiveData<>();
empty.setValue(null);//need to set a value, to force update of observers
return empty;
}
这里的代码对我有用。在这个问题中,你使用了一个 AbsentLiveData,我不知道它是如何实现的,所以我不确定它在那种情况下是否能正常工作。