Apparemment, Room n’est pas capable de gérer MutableLiveData et nous devons nous en tenir à LiveData car il renvoie l’erreur suivante:
error: Not sure how to convert a Cursor to this method's return type
J'ai créé un MutableLiveData "personnalisé" dans mon assistant de base de données de cette manière:
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()
}
}
}
De cette façon, j'obtiens les mises à jour de la base de données et je peux enregistrer l'objet Profile
mais je ne peux pas modifier les attributs.
Par exemple: mutableLiveData.value = Profile()
fonctionnerait .mutableLiveData.value.userName = "name"
appellerait getValue()
à la place de postValue()
et ne fonctionnerait pas.
Quelqu'un a-t-il trouvé une solution à cela?
Appelez-moi fou, mais autant que je sache, il n'y a aucune raison d'utiliser un MutableLiveData pour l'objet que vous avez reçu de la DAO.
L'idée est que vous pouvez exposer un objet via LiveData<List<T>>
@Dao
public interface ProfileDao {
@Query("SELECT * FROM PROFILE")
LiveData<List<Profile>> getProfiles();
}
Maintenant, vous pouvez les observer:
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;
});
Donc, si vous voulez que ces données en direct "émettent de nouvelles données et les modifient", vous devez alors insérer le profil dans la base de données. L'écriture réévaluera cette requête et elle sera émise une fois que la nouvelle valeur de profil aura été écrite dans la base de données.
dao.insert(profile); // this will make LiveData emit again
Il n’ya donc aucune raison d’utiliser getValue
/setValue
, il suffit d’écrire sur votre base de données.
Puisque Room ne prend pas en charge MutableLiveData
et ne prend en charge que LiveData
, votre approche consistant à créer un wrapper est la meilleure approche à laquelle je puisse penser. Il sera compliqué pour Google
de supporter MutableLiveData
car les méthodes setValue
et postValue
sont public
. Où comme pour LiveData
ils sont protected
qui donne plus de contrôle.