问题:
switchMap转换在其结果必须具有活动的观察者之前不会触发。我正在尝试触发switchMap转换,即使没有观察者也是如此。谁能建议我如何实现此功能?下面有一些代码描述了当前情况。
如何复制:
在ProfileViewModel中,UI可以观察两个不同的LiveData
ProfileViewModel.java
protected String sendTemplate() {
return Objects.requireNonNull(getTemplate(), "message");
}
现在,UI可以观察配置文件数据和Http呼叫状态的变化。 因此,如果用户界面要下载并在用户界面上显示配置文件,则用户界面负责观察 profileLiveData 和 profileApiStateLiveData ,然后调用ViewModel的方法 loadProfile(true);
public class ProfileViewModel extends AndroidViewModel {
private MutableLiveData<Boolean> getProfileCommand = new MutableLiveData<>();
public ProfileViewModel(@NonNull Application application) {
super(application);
profileLiveData = Transformations.switchMap(getProfileCommand, forceUpdate -> UserRepository.getInstance().getProfile(forceUpdate));
profileApiStateLiveData = UserRepository.getInstance().getProfileApiRequestStatus();
}
public void loadProfile(boolean forceUpdate) {
getProfileCommand.postValue(forceUpdate);
}
// Profile Data : Observable Field
private LiveData<Profile> profileLiveData;
public LiveData<Profile> getProfileLiveData() {
if(profileLiveData == null) profileLiveData = new MutableLiveData<>();
return profileLiveData;
}
// Profile Http Call's State : Observable Field
private LiveData<ApiRequest> profileApiStateLiveData;
public LiveData<ApiRequest> getProfileApiStateLiveData() {
if(profileApiStateLiveData == null) profileApiStateLiveData = new MutableLiveData<>();
return profileApiStateLiveData;
}
}
我们在这里可以看到方法 loadProfile 将触发switchMap转换并启动Http调用。请注意,由于用户界面正在观察结果LiveData,即 profileLiveData 。
这种情况下工作正常。但是,如果某个Activity只想发起Http调用并且只想观察 profileApiStateLiveData 而不是 profileLiveData ,则switchMap触发器将永远不会发生,这是因为没有活动LiveData profileLiveData 的活跃观察者。
// Observes Profile Data
mProfileViewModel.getProfileLiveData().observe(this, profileData -> {
// Use profile data here
});
// Observes State of Profile Http Call
mProfileViewModel.getProfileApiStateLiveData().observe(this, profileHttpCallState -> {
// show/hide progress based on http call state
});
// start downloading profile data
mProfileViewModel.loadProfile(true);
我有一个丑陋的解决方案,必须在UI中为 profileLiveData 添加不必要的空白观察器。但这很容易出错,因为其他开发人员可能会忘记为 profileLiveData 添加此不必要的空白观察者,并且即使他们调用方法< strong> loadProfile(true) 。
在此非常感谢Rx专家的帮助:-)
答案 0 :(得分:0)
这个问题已经得到很好的回答,感谢@ arka-prava-basu。 profileLiveData 已从Transformation中分离出来,现在可以直接从Room Database中获取。动作
此转换执行的(UserRepository.getInstance()。getProfile(forceUpdate))
现在已转移到 loadProfile 方法。下面是重构的代码。
ProfileViewModel.java
public class ProfileViewModel extends AndroidViewModel {
public ProfileViewModel(@NonNull Application application) {
super(application);
profileLiveData = UserRepository.getInstance().getMemberInfo();
profileApiStateLiveData = UserRepository.getInstance().getProfileApiRequestStatus();
}
public void loadProfile(boolean forceDownload) {
if(forceDownload) {
UserRepository.getInstance().initiateProfileDownloading();
}
}
// Profile Data : Observable Field
private LiveData<Profile> profileLiveData;
public LiveData<Profile> getProfileLiveData() {
return profileLiveData;
}
// Profile Http Call's State : Observable Field
private LiveData<ApiRequest> profileApiStateLiveData;
public LiveData<ApiRequest> getProfileApiStateLiveData() {
return profileApiStateLiveData;
}
}