首页 > 解决方案 > 将 LiveData 转换为 MutableLiveData

问题描述

显然,Room 无法处理 MutableLiveData,我们必须坚持使用 LiveData,因为它返回以下错误:

error: Not sure how to convert a Cursor to this method's return type

我以这种方式在我的数据库助手中创建了一个“自定义”MutableLiveData:

class ProfileRepository @Inject internal constructor(private val profileDao: ProfileDao): ProfileRepo{

    override fun insertProfile(profile: Profile){
        profileDao.insertProfile(profile)
    }

    val mutableLiveData by lazy { MutableProfileLiveData() }
    override fun loadMutableProfileLiveData(): MutableLiveData<Profile> = mutableLiveData

    inner class MutableProfileLiveData: MutableLiveData<Profile>(){

        override fun postValue(value: Profile?) {
            value?.let { insertProfile(it) }
            super.postValue(value)
        }

        override fun setValue(value: Profile?) {
            value?.let { insertProfile(it) }
            super.setValue(value)
        }

        override fun getValue(): Profile? {
            return profileDao.loadProfileLiveData().getValue()
        }
    }
}

这样,我从数据库获取更新并可以保存Profile对象,但我不能修改属性。

例如: mutableLiveData.value = Profile()会工作。 mutableLiveData.value.userName = "name"会打电话getValue()postValue()不是工作。

有没有人找到解决方案?

标签: androidkotlinandroid-roomandroid-architecture-componentsandroid-livedata

解决方案


叫我疯了,但 AFAIK 没有理由为您从 DAO 收到的对象使用 MutableLiveData。

这个想法是您可以通过LiveData<List<T>>

@Dao
public interface ProfileDao {
    @Query("SELECT * FROM PROFILE")
    LiveData<List<Profile>> getProfiles();
}

现在您可以观察它们:

profilesLiveData.observe(this, (profiles) -> {
    if(profiles == null) return;

    // you now have access to profiles, can even save them to the side and stuff
    this.profiles = profiles;
});

因此,如果您想让这些实时数据“发出新数据并对其进行修改”,则需要将配置文件插入数据库。写入将重新评估此查询,一旦新的配置文件值写入 db,它将被发出。

dao.insert(profile); // this will make LiveData emit again

所以没有理由使用getValue/ setValue,只需写入您的数据库。


推荐阅读