Aller au contenu

Créer le ViewModel

7.1 Qu'est-ce qu'un ViewModel ?

Le rôle de la ViewModel est de fournir des données à l'interface utilisateur et de survivre aux changements de configuration. Une ViewModel agit comme un centre de communication entre le Repository et l'interface utilisateur. Vous pouvez également utiliser une ViewModel pour partager des données entre des fragments. La ViewModel est une partie de la bibliothèque Lifecycle.

ViewModel diagram 1

ViewModel diagram 2

Pour une introduction à ce sujet, consultez ViewModel Overview ou le billet de blog ViewModels: A Simple Example.

7.2 Pourquoi utiliser un ViewModel ?

Un ViewModel conserve les données de l'interface utilisateur de votre application de manière consciente du cycle de vie, ce qui leur permet de survivre aux changements de configuration. Séparer les données de l'interface utilisateur de votre application de vos classes Activity et Fragment vous permet de mieux suivre le principe de responsabilité unique : vos activités et fragments sont responsables de l'affichage des données à l'écran, tandis que votre ViewModel peut s'occuper de conserver et de traiter toutes les données nécessaires à l'interface utilisateur.

Dans le ViewModel, utilisez LiveData pour les données modifiables que l'interface utilisateur utilisera ou affichera. L'utilisation de LiveData présente plusieurs avantages :

  • Vous pouvez utiliser un observateur sur les données (au lieu de les interroger régulièrement) et mettre à jour l'interface utilisateur uniquement lorsque les données changent réellement.
  • Le référentiel (Repository) et l'interface utilisateur sont complètement séparés par le ViewModel.
  • Il n'y a pas d'appels à la base de données depuis le ViewModel (tout cela est géré dans le référentiel), ce qui rend le code plus testable.

7.3 Implémenter le ViewModel

Créez un fichier de classe pour WordViewModel sous la racine du package de votre application et ajoutez-y ce code :

WordViewModel.java
public class WordViewModel extends AndroidViewModel {

    private final WordRepository mRepository;

    private final LiveData<List<Word>> mAllWords;

    public WordViewModel (Application application) {
        super(application);
        mRepository = new WordRepository(application);
        mAllWords = mRepository.getAllWords();
    }

    LiveData<List<Word>> getAllWords() { return mAllWords; }

    public void insert(Word word) { mRepository.insert(word); }
}

Explications :

  • Créé une classe appelée WordViewModel qui prend l'application comme paramètre et étend AndroidViewModel.
  • Ajouté une variable membre privée pour conserver une référence au dépôt.
  • Ajouté une méthode getAllWords() pour renvoyer une liste de mots en cache.
  • Implémenté un constructeur qui crée le WordRepository.
  • Dans le constructeur, initialisé le LiveData mAllWords en utilisant le dépôt.
  • Créé une méthode wrapper insert() qui appelle la méthode insert() du dépôt. De cette façon, l'implémentation de insert() est encapsulée de l'interface utilisateur.

Attention aux fuites de mémoire

Ne conservez pas de référence à un contexte dont le cycle de vie est plus court que celui de votre ViewModel ! Des exemples sont :

  • Activité
  • Fragment
  • Vue

Conserver une référence peut provoquer une fuite de mémoire, par exemple si le ViewModel a une référence à une Activity détruite. Tous ces objets peuvent être détruits par le système d'exploitation et recréés lors d'un changement de configuration, ce qui peut se produire plusieurs fois pendant le cycle de vie d'un ViewModel.

Si vous avez besoin du contexte de l'application (qui a un cycle de vie aussi long que celui de l'application), utilisez AndroidViewModel, comme indiqué dans ce codelab.

Persistance des données

Les **ViewModel**s ne survivent pas à l'arrêt du processus de l'application en arrière-plan lorsque le système d'exploitation a besoin de plus de ressources. Pour les données de l'interface utilisateur qui doivent survivre à la mort du processus due à un manque de ressources, vous pouvez utiliser le module Saved State pour les ViewModels. En savoir plus ici.

Ressources complémentaires

Pour en savoir plus sur les classes ViewModel, regardez la vidéo Architecture Components: ViewModel.