Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/179.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 将LiveData转换为可变LiveData_Android_Kotlin_Android Room_Android Architecture Components_Android Livedata - Fatal编程技术网

Android 将LiveData转换为可变LiveData

Android 将LiveData转换为可变LiveData,android,kotlin,android-room,android-architecture-components,android-livedata,Android,Kotlin,Android Room,Android Architecture Components,Android Livedata,显然,Room无法处理MutableLiveData,我们必须坚持使用LiveData,因为它返回以下错误: error: Not sure how to convert a Cursor to this method's return type 我在DB helper中创建了一个“自定义”MutableLiveData,方法如下: class ProfileRepository @Inject internal constructor(private val profileDao: Prof

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

error: Not sure how to convert a Cursor to this method's return type
我在DB helper中创建了一个“自定义”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()
        }
    }
}
class ProfileRepository@Inject内部构造函数(private val profileDao:profileDao):ProfileRepo{
覆盖趣味插入配置文件(配置文件:配置文件){
profileDao.insertProfile(profile)
}
val mutableLiveData by lazy{MutableProfileLiveData()}
重写fun loadMutableProfileLiveData():MutableLiveData=MutableLiveData
内部类MutableProfileLiveData:MutableLiveData(){
覆盖趣味postValue(值:Profile?){
值?.let{insertProfile(it)}
super.postValue(值)
}
覆盖乐趣设置值(值:配置文件?){
值?.let{insertProfile(it)}
super.setValue(值)
}
覆盖乐趣getValue():配置文件{
返回profileDao.loadProfileLiveData().getValue()
}
}
}
通过这种方式,我可以从DB获得更新,并可以保存
概要文件
对象,但我无法修改属性

例如:
mutableLiveData.value=Profile()。
mutableLiveData.value.userName=“name”
将调用
getValue()
而不是
postValue()
,并且不起作用


有人找到了解决方案吗?

由于Room不支持
MutableLiveData
,并且只支持
LiveData
,因此您创建包装器的方法是我能想到的最佳方法。由于
setValue
postValue
方法是
public
的,因此
Google
支持
MutableLiveData
将变得复杂。其中,对于
LiveData
,它们受到
保护
,这提供了更多的控制。

称我为疯子,但如果您从DAO收到的对象使用可变LiveData,那么就没有理由了

其思想是您可以通过
LiveData

因此,如果您希望使此实时数据“发出新数据并修改它”,则需要将概要文件插入数据库。写入操作将重新计算此查询,并在将新配置文件值写入db后发出该查询

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

因此,没有理由使用
getValue
/
setValue
,只需写入数据库。

在存储库中,您可以获取
LiveData
并将其转换为
MutableLivedata

var data= dao.getAsLiveData()
return MutableLiveData<T>(data.value)
var data=dao.getAsLiveData()
返回MutableLiveData(data.value)

如果确实需要,那么可以使用中介技巧

在您的ViewModel中

 val sourceProduct: LiveData<Product>() = repository.productFromDao()
 val product = MutableLiveData<Product>()

 val mediator = MediatorLiveData<Unit>()

 init {
      mediator.addSource(sourceProduct, { product.value = it })
 }

我明白你的意思。目前的解决方案与使用LiveData对象并保存在DB中没有区别。这里的想法是能够独立地修改数据库中的某些属性。当您独立于数据库修改对象,然后从网络中提取对象,保存到数据库,现在您有了“来自网络的新状态”时会发生什么而一个被局部修改的对象?@EpicPandaForce面临类似问题,更新到db不会反映在实时数据上。这就是我试图发布到可变实时数据对象的原因。如果您通过DAO插入DB,那么如果
LiveData
从DAO中暴露出来,并且您观察它,那么您将收到新的数据。这是错误的方式,没有人保证此时LiveData中有数据。如果我们之前检查null呢?使用此技术,对源产品的任何更改都将在mediator livedata中自动触发?因此,我只需要观察产品,还是需要同时观察产品和mediator实时数据?
var data= dao.getAsLiveData()
return MutableLiveData<T>(data.value)
 val sourceProduct: LiveData<Product>() = repository.productFromDao()
 val product = MutableLiveData<Product>()

 val mediator = MediatorLiveData<Unit>()

 init {
      mediator.addSource(sourceProduct, { product.value = it })
 }
observe(mediator, {})
observe(product, { //handle product })