Android MediatorLiveData源订阅不会触发

时间:2019-06-21 17:12:15

标签: android android-livedata mutablelivedata

在我的项目中,我使用的是经过稍微修改的存储库模式:

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

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

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

几乎是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.
    }
}

在实现此示例的情况下,updateCurrentUser()不会被调用,即使发生了对其他LiveData字段的订阅,并且在currentUser对象上调试时也可以看到。

通过addSource进行的相同订阅在其他存储库中也可以正常工作,并且它们的构建方式与上述相同。

这里可能出什么问题了?

1 个答案:

答案 0 :(得分:2)

MediatorLiveData如果没有订阅源,则不会观察源LiveData。订阅updateCurrentUser()会立即调用currentUser