J'ai une classe distincte dans laquelle j'ai la poignée de la récupération de données (plus précisément Firebase) et j'ai l'habitude de retourner LiveData objets et de les mettre à jour de manière asynchrone. Maintenant, je veux avoir le retour des données stockées dans un ViewModel, mais le problème est que pour obtenir cette valeur, j'ai besoin d'observer la LiveData objet de retour de mon la récupération de données de la classe. Observer la méthode requise d'un LifecycleOwner objet en tant que premier paramètre, mais évidemment je n'ai pas qu'à l'intérieur de mon ViewModel et je sais que je ne suis pas censé le garder en référence à l'Activité/Fragment à l'intérieur de ce Dernier. Que dois-je faire?
Réponses
Trop de publicités?Dans ce billet de blog du développeur Google Jose Alcérreca, il est recommandé d’utiliser une transformation (voir le paragraphe "LiveData dans les référentiels").
Dans le ViewModel de la documentation
Cependant ViewModel objets ne doivent jamais observer les changements de cycle de vie-conscience observables, tels que LiveData objets.
Une autre façon est pour les données à mettre en œuvre RxJava plutôt que LiveData, alors il n'aura pas l'avantage de cycle de vie-conscience.
Dans google échantillon de todo-mvvm-live-kotlin, il utilise une fonction de callback sans LiveData dans le ViewModel.
Je suppose que si vous souhaitez de se conformer à l'ensemble de l'idée de cycle de vie-ware, nous devons aller de l'observation du code de l'Activité/Fragment. Sinon, nous pouvons utiliser le callback ou RxJava dans le ViewModel.
L'autre solution de compromis est de mettre en œuvre MediatorLiveData (ou Transformations) et d'observer (mettez votre logique ici) dans le ViewModel. Avis MediatorLiveData observateur ne se déclenche pas (même en tant que Transformations), sauf si elle est observée dans l'Activité/Fragment. Ce que nous faisons, c'est de mettre un blanc d'observer dans l'Activité/Fragment, où le vrai travail est fait dans le ViewModel.
// ViewModel
fun start(id : Long) : LiveData<User>? {
val liveData = MediatorLiveData<User>()
liveData.addSource(dataSource.getById(id), Observer {
if (it != null) {
// put your logic here
}
})
}
// Activity/Fragment
viewModel.start(id)?.observe(this, Observer {
// blank observe here
})
PS: j'ai lu Viewmodel et LiveData: Modèles + AntiPatterns qui suggère que des Transformations. Je ne pense pas qu'il fonctionne que si les LiveData est observée (qui a probablement besoin d'être faite à l'Activité/Fragment).