1. Avant de commencer
Cet atelier de programmation présente une nouvelle application appelée Forage, que vous allez créer vous-même. Il explique les différentes étapes à suivre pour mener à bien le projet d'application Forage, y compris sa configuration et ses tests dans Android Studio.
Conditions préalables
- Ce projet est destiné aux élèves qui ont terminé le module 5 du cours "Principes de base d'Android en Kotlin".
Objectifs de l'atelier
- Ajoutez une persistance à une application existante avec Room en implémentant une entité, un DAO, un ViewModel et une classe de base de données.
Ce dont vous avez besoin
- Un ordinateur sur lequel est installé Android Studio
2. Présentation de l'application terminée
L'application Forage, une fois terminée, permet aux utilisateurs de garder une trace des produits (alimentaires, par exemple) qu'ils ont trouvés dans la nature. Ces données sont conservées d'une session à l'autre à l'aide de Room. Vous utiliserez vos connaissances sur Room et sur les opérations de lecture, d'écriture, de mise à jour et de suppression effectuées sur une base de données pour implémenter la notion de persistance dans l'application Forage. L'application terminée et ses fonctionnalités sont décrites ci-dessous.
Lorsque l'application est lancée pour la première fois, l'utilisateur arrive sur un écran vide contenant une vue recycleur qui affiche les éléments rencontrés. En bas à droite de l'écran se trouve un bouton flottant permettant d'ajouter de nouveaux éléments.
Lorsqu'un élément est ajouté, l'utilisateur peut saisir un nom, un emplacement et ajouter des notes supplémentaires. Une case à cocher permet d'indiquer si l'aliment est de saison.
Une fois qu'un élément a été ajouté, il apparaît dans la vue recycleur sur le premier écran.
Lorsque vous appuyez sur un élément, un écran détaillé s'affiche avec son nom, son emplacement et des notes.
Le bouton flottant se transforme, passant du symbole "plus" à une icône d'édition. Appuyez sur ce bouton pour accéder à un écran qui vous permet de modifier le nom, le lieu, les notes et la case "de saison". Appuyez sur le bouton "Supprimer" pour supprimer l'élément de la base de données.
Bien que la partie UI de cette application ait déjà été implémentée, votre tâche consiste à implémenter la persistance en utilisant vos connaissances de Room, afin que l'application lise, écrive, mette à jour et supprime des éléments de la base de données.
3. Premiers pas
Télécharger le code du projet
Notez que le nom du dossier est android-basics-kotlin-forage-app
. Sélectionnez ce dossier lorsque vous ouvrez le projet dans Android Studio.
Pour obtenir le code de cet atelier de programmation et l'ouvrir dans Android Studio, procédez comme suit :
Obtenir le code
- Cliquez sur l'URL indiquée. La page GitHub du projet s'ouvre dans un navigateur.
- Sur la page GitHub du projet, cliquez sur le bouton Code pour afficher une boîte de dialogue.
- Dans la boîte de dialogue, cliquez sur le bouton Download ZIP (Télécharger le fichier ZIP) pour enregistrer le projet sur votre ordinateur. Attendez la fin du téléchargement.
- Recherchez le fichier sur votre ordinateur (il se trouve probablement dans le dossier Téléchargements).
- Double-cliquez sur le fichier ZIP pour le décompresser. Un dossier contenant les fichiers du projet est alors créé.
Ouvrir le projet dans Android Studio
- Lancez Android Studio.
- Dans la fenêtre Welcome to Android Studio (Bienvenue dans Android Studio), cliquez sur Open an existing Android Studio project (Ouvrir un projet Android Studio existant).
Remarque : Si Android Studio est déjà ouvert, sélectionnez l'option de menu File > New > Import Project (Fichier > Nouveau > Importer un projet).
- Dans la boîte de dialogue Import Project (Importer un projet), accédez à l'emplacement du dossier du projet décompressé. Il se trouve probablement dans le dossier Téléchargements.
- Double-cliquez sur le dossier de ce projet.
- Attendez qu'Android Studio ouvre le projet.
- Cliquez sur le bouton Run (Exécuter) pour créer et exécuter l'application. Assurez-vous qu'elle fonctionne correctement.
- Parcourez les fichiers du projet dans la fenêtre de l'outil Projet pour voir comment l'application est configurée.
4. Configurer le projet pour utiliser Room
Définir l'entité "Forageable"
Le projet comporte déjà une classe Forageable
qui définit les données de l'application (model.Forageable.kt). Cette classe possède plusieurs propriétés : id
, name
, address
, inSeason
et notes
.
data class Forageable(
val id: Long = 0,
val name: String,
val address: String,
val inSeason: Boolean,
val notes: String?
)
Toutefois, pour utiliser cette classe afin de stocker des données permanentes, vous devez la convertir en une entité Room.
- Annotez la classe en utilisant
@Entity
avec le nom de la table"forageable_database"
. - Définissez la propriété
id
comme étant la clé primaire. La clé primaire devrait être générée automatiquement. - Définissez le nom de colonne de la propriété
inSeason
sur"in_season"
.
Implémenter le DAO
ForageableDao
(data.ForageableDao.kt), comme vous pouvez l'imaginer, permet de définir les méthodes de lecture et d'écriture depuis la base de données auxquelles vous accéderez à partir du modèle de visualisation. Étant donné que le DAO n'est qu'une interface que vous définissez, vous n'aurez pas à écrire de code pour implémenter ces méthodes. Vous devrez utiliser des annotations Room, en spécifiant la requête SQL si nécessaire.
Dans l'interface ForageableDao
, ajoutez cinq méthodes.
- Une méthode
getForageables()
qui renvoie unFlow<List<Forageable>>
pour toutes les lignes de la base de données. - Une méthode
getForageable(id: Long)
qui renvoie unFlow<Forageable>
correspondant à l'id
spécifié. - Une méthode
insert(forageable: Forageable)
qui introduit un nouveauForageable
dans la base de données. - Une méthode
update(forageable: Forageable)
qui utilise unForageable
existant comme paramètre et qui met à jour la ligne en conséquence. - Une méthode
delete(forageable: Forageable)
qui utilise unForageable
comme paramètre et le supprime de la base de données.
Implémenter le modèle de visualisation
Le ForageableViewModel
(ui.viewmodel.ForageableViewModel.kt) est partiellement implémenté, mais vous devrez ajouter une fonctionnalité qui accède aux méthodes DAO afin d'autoriser la lecture et l'écriture de données. Pour implémenter ForageableViewModel
, procédez comme suit :
- Une instance de
ForageableDao
doit être transmise en tant que paramètre dans le constructeur de la classe. - Créez une variable de type
LiveData<List<Forageable>>
qui récupère la liste complète des entitésForageable
à l'aide du DAO et qui convertit le résultat enLiveData
. - Créez une méthode qui utilise un ID (de type
Long
) comme paramètre et renvoie unLiveData<Forageable>
qui appelle la méthodegetForageable()
sur le DAO, et qui convertit le résultat enLiveData
. - Dans la méthode
addForageable()
, lancez une coroutine à l'aide deviewModelScope
et utilisez le DAO pour insérer l'instanceForageable
dans la base de données. - Dans la méthode
updateForageable()
, utilisez le DAO pour mettre à jour l'entitéForageable
. - Dans la méthode
deleteForageable()
, utilisez le DAO pour mettre à jour l'entitéForageable
. - Implémentez un
ViewModelFactory
pouvant créer une instance deForageableViewModel
avec un paramètre constructeurForageableDao
.
Implémenter la classe Database
La classe ForageDatabase
(data.ForageDatabase.kt
) permet de partager vos entités et votre DAO avec Room. Implémentez la classe ForageDatabase
comme expliqué.
- Entités :
Forageable
- Version :
1
- exportSchema :
false
- Dans la classe
ForageDatabase
, incluez une fonction abstraite pour renvoyer unForageableDao
- Dans la classe
ForageDatabase
, définissez un objet compagnon avec une variable privée appeléeINSTANCE
et une fonctiongetDatabase()
qui renvoie le singletonForageDatabase
.
- Dans la classe
BaseApplication
, créez une propriétédatabase
qui renvoie une instanceForageDatabase
à l'aide de l'initialisation différée.
5. Persister et lire les données des fragments
Une fois que vous avez configuré vos entités, le DAO, le modèle de visualisation et défini la classe de base de données pour les partager avec Room, il vous suffit de modifier les fragments pour accéder au modèle de visualisation. Vous devez modifier trois fichiers, un pour chaque écran de l'application.
Liste des aliments
L'écran de la liste des aliments ne nécessite que deux éléments : une référence au modèle de visualisation et un accès à la liste complète des aliments. Effectuez les tâches suivantes dans ui.ForageableListFragment.kt.
- La classe possède déjà une propriété
viewModel
. Toutefois, la classe "Factory" définie à l'étape précédente n'est pas utilisée. Vous devez d'abord refactoriser cette déclaration pour utiliserForageableViewModelFactory
.
private val viewModel: ForageableViewModel by activityViewModels {
ForageableViewModelFactory(
(activity?.application as BaseApplication).database.foragableDao()
)
}
- Ensuite, dans
onViewCreated()
, observez la propriétéallForageables
deviewModel
et appelezsubmitList()
sur l'adaptateur, le cas échéant, pour remplir la liste.
Écran des détails des aliments
Reproduisez cette procédure pour la liste détaillée dans ui/ForageableDetailFragment.kt.
- Convertissez la propriété
viewModel
pour initialiser correctementForageableViewModelFactory
. - Dans
onViewCreated()
, appelezgetForageable()
sur le modèle de visualisation pour transmettre l'id
et obtenir l'entitéForageable
. Observez les données en direct et définissez le résultat sur la propriétéforageable
, puis appelezbindForageable()
pour mettre à jour l'interface utilisateur.
Écran "Ajouter et modifier des aliments"
Pour finir, vous devez faire la même chose dans ui.AddForageableFragment.kt. Notez que cet écran sert aussi à la mise à jour et à la suppression des entités. Toutefois, ces méthodes du modèle de visualisation sont déjà appelées au bon endroit. Vous ne devrez apporter que deux modifications à ce fichier.
- Là encore, refactorisez la propriété
viewModel
pour utiliserForageableViewModelFactory
. - Dans
onViewCreated()
, dans le bloc "if" avant de définir la visibilité du bouton de suppression, appelezgetForageable()
sur le modèle de visualisation pour transmettre l'id
et définir le résultat sur la propriétéforageable
.
C'est tout ce que vous avez à faire au niveau des fragments. Vous pouvez maintenant exécuter votre application et voir toutes les fonctionnalités de persistance en action.
6. Instructions de test
Exécuter vos tests
Pour exécuter les tests, vous pouvez effectuer l'une des opérations suivantes.
Pour un scénario de test unique, ouvrez une classe de scénario de test PersistenceInstrumentationTests.kt
et cliquez sur la flèche verte à gauche de la déclaration de classe. Vous pouvez ensuite sélectionner l'option "Run" (Exécuter) dans le menu. Tous les tests seront exécutés dans le scénario de test.
Souvent, il suffit d'exécuter un seul test, par exemple lorsqu'un test a échoué et que tous les autres ont réussi. Il est possible d'exécuter un seul test de la même manière que vous le feriez pour un scénario de test complet. Utilisez la flèche verte et sélectionnez l'option Exécuter.
Si vous avez plusieurs scénarios de test, vous pouvez également exécuter l'ensemble de la suite de tests. Comme pour l'exécution de l'application, cette option se trouve dans le menu Exécuter.
Notez qu'Android Studio utilise par défaut la dernière cible que vous avez exécutée (applications, cibles de test, etc.). Par conséquent, si le menu indique toujours Run > Run 'app' (Exécuter > Exécuter 'application'), vous pouvez exécuter la cible de test en sélectionnant Run > Run (Exécuter > Exécuter).
Sélectionnez ensuite la cible de test dans le menu pop-up.