どうやら、RoomはMutableLiveDataを処理できず、次のエラーを返すため、LiveDataに固執する必要があります。
_error: Not sure how to convert a Cursor to this method's return type
_
この方法で、DBヘルパーに「カスタム」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()
}
}
}
_
この方法で、DBから更新を取得し、Profile
オブジェクトを保存できますが、属性を変更できません。
例:mutableLiveData.value = Profile()
は機能します。 _mutableLiveData.value.userName = "name"
_はgetValue()
の代わりにpostValue()
を呼び出し、動作しません。
誰かがこれに対する解決策を見つけましたか?
クレイジーと呼んでくださいが、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
を使用する理由はなく、データベースに書き込むだけです。
リポジトリでLiveData
を取得し、MutableLivedata
に変換できます。
var data= dao.getAsLiveData()
return MutableLiveData<T>(data.value)
RoomはMutableLiveData
をサポートせず、LiveData
のみをサポートしているため、ラッパーを作成するアプローチは、私が考えることができる最良のアプローチです。 Google
メソッドとMutableLiveData
メソッドはsetValue
であるため、postValue
がpublic
をサポートするのは複雑になります。 LiveData
はprotected
であり、より多くの制御が可能です。
本当に必要な場合は、メディエータートリックを使用できます。
ViewModelで
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 })