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,我不知道它是如何实现的,所以我不确定它在那种情况下是否能正常工作。