Android MediatorLiveData 源订阅不触发

fon*_*232 1 android android-livedata mutablelivedata

在我的项目中,我使用了一个稍微修改的存储库模式:

  • 数据源(例如 API、数据库)。提供实体的 CRUD
  • 处理数据源协调(例如从 API 调用更新数据库)的特定数据的存储库(例如 UserRepository、SettingsRepository)。提供高于 CRUD 的基本功能
  • ViewModel 使用存储库并从存储库调用中创建流(例如,使用 UserRepository 同步用户数据,然后使用 SettingsRepository 同步用户的设置)
  • 视图是数据绑定的

在我的存储库中,我使用公开的 LiveData<*> 字段来传达状态 - 例如,说 UserRepository 将有一个currentUser公共类型 LiveData的字段,私有的 MediatorLiveData,它将链接到一个私有字段,该字段包含要检索的当前用户 ID。

但是,addSource() {}由于某种原因,这些订阅(使用 MediatorLiveData 的方法)不会触发。

一个几乎 1:1 的例子(由于 NDA 替换了模型名称)如下:

abstract class BaseRepository: ViewModel(), KoinComponent {

    val isLoading: LiveData<Boolean> = MutableLiveData<Boolean>().apply { postValue(false) }

}


class UserRepository: BaseRepository() {

    private val client: IClient by inject() // Koin injection of API client
    private val sharedPref: SharedPrefManager by inject() // custom wrapper around SharedPreferences

    private val currentUserId = MutableLiveData()

    val currentUser: LiveData<User> = MediatorLiveData()
    val users: LiveData<List<User>> = MutableLiveData()

    init {
        (currentUser as MediatorLiveData).addSource(currentUserId) { updateCurrentUser() }
        (currentUser as MediatorLiveData).addSource(users) { updateCurrentUser() }

        (currentUserId as MutableLiveData).postValue(sharedPref.getCurrentUserId())
        // sharedPref.getCurrentUserId() will return UUID? - null if 
    }

    fun updateCurrentUser() {
        // Here I have the logic deciding which user to push into `currentUser` based on the list of users, and if there's a `currentUserId` present.
    }
}
Run Code Online (Sandbox Code Playgroud)

实施此示例后updateCurrentUser(),即使对其他 LiveData 字段的订阅发生并且在currentUser对象上调试时可见,也永远不会被调用。

相同的订阅 viaaddSource在其他存储库中也可以正常工作,并且它们的构造方式与上述相同。

这里可能出了什么问题?

San*_*Lee 5

MediatorLiveDataLiveData如果它没有任何订阅自己的观察者,则不会观察源。updateCurrentUser()订阅后将立即调用currentUser