Cet atelier de programmation fait partie du cours Principes de base d'Android en Kotlin. Vous tirerez pleinement parti de ce cours en suivant les ateliers de programmation dans l'ordre. Tous les ateliers de programmation du cours sont listés sur la page de destination des ateliers de programmation Principes de base d'Android en Kotlin.
Introduction
La plupart des applications reposent sur des données qui doivent être conservées, même après que l'utilisateur a fermé l'application. Par exemple, l'application peut stocker une playlist, un inventaire d'éléments de jeu, des tickets de caisse ou des notes de frais, un catalogue de constellations ou des données de sommeil au fil du temps. En général, vous utilisez une base de données pour stocker les données persistantes.
Room est une bibliothèque de base de données qui fait partie d'Android Jetpack. Room se charge de nombreuses tâches liées à la configuration d'une base de données et permet à votre application d'interagir avec en utilisant des appels de fonctions ordinaires. En interne, Room est une couche d'abstraction qui s'ajoute à une base de données SQLite. La terminologie de Room et la syntaxe des requêtes plus complexes suivent le modèle SQLite.
L'image ci-dessous montre comment la base de données Room s'intègre à l'architecture globale recommandée dans ce cours.

Ce que vous devez déjà savoir
Vous devez maîtriser les éléments suivants :
- Créer une interface utilisateur de base pour une application Android
- Utiliser des activités, des fragments et des vues.
- Naviguer entre les fragments et utiliser Safe Args (un plug-in Gradle) pour transmettre des données entre les fragments.
- Afficher les modèles, les fabriques de modèles et
LiveDataainsi que ses observateurs. Ces thèmes liés aux composants d'architecture ont été abordés dans un atelier de programmation précédent de ce cours. - Vous disposez de connaissances fondamentales sur les bases de données SQL et le langage SQLite. Pour obtenir un aperçu rapide ou une piqûre de rappel, consultez Principes de base de SQLite.
Points abordés
- Création d'une base de données
Roomet interaction avec celle-ci pour conserver les données - Comment créer une classe de données qui définit une table dans la base de données.
- Utilisation d'un objet d'accès aux données (DAO, Data Access Object) pour mapper des fonctions Kotlin à des requêtes SQL
- Tester le fonctionnement de votre base de données
Objectifs de l'atelier
- Créez une base de données
Roomavec une interface pour les données de sommeil nocturnes. - Testez la base de données à l'aide des tests fournis.
Dans cet atelier de programmation, vous allez créer la partie base de données d'une application qui suit la qualité du sommeil. L'application utilise une base de données pour stocker les données de sommeil au fil du temps.
L'application comporte deux écrans, représentés par des fragments, comme illustré dans la figure ci-dessous.
Le premier écran, affiché à gauche, comporte des boutons permettant de démarrer et d'arrêter le suivi. L'écran affiche toutes les données de sommeil de l'utilisateur. Le bouton Effacer supprime définitivement toutes les données que l'application a collectées pour l'utilisateur.
Le deuxième écran, à droite, permet de sélectionner une note de qualité du sommeil. Dans l'application, la note est représentée sous forme numérique. À des fins de développement, l'application affiche à la fois les icônes de visages et leurs équivalents numériques.
Voici le parcours de l'utilisateur :
- L'utilisateur ouvre l'application et l'écran de suivi du sommeil s'affiche.
- L'utilisateur appuie sur le bouton Démarrer. L'heure de début est enregistrée et affichée. Le bouton Start (Démarrer) est désactivé, et le bouton Stop (Arrêter) est activé.
- L'utilisateur appuie sur le bouton Arrêter. L'heure de fin est enregistrée et l'écran de qualité du sommeil s'ouvre.
- L'utilisateur sélectionne une icône de qualité du sommeil. L'écran se ferme et l'écran de suivi affiche l'heure de fin du sommeil et la qualité du sommeil. Le bouton Arrêter est désactivé et le bouton Démarrer est activé. L'application est prête pour une nouvelle nuit.
- Le bouton Effacer est activé chaque fois que la base de données contient des données. Lorsque l'utilisateur appuie sur le bouton Effacer, toutes ses données sont effacées sans possibilité de retour en arrière. Aucun message de confirmation n'est affiché.
Cette application utilise une architecture simplifiée, comme indiqué ci-dessous dans le contexte de l'architecture complète. L'application n'utilise que les composants suivants :
- Contrôleur d'interface utilisateur
- Afficher le modèle et
LiveData - Une base de données Room
Étape 1 : Téléchargez et exécutez l'application de démarrage
- Téléchargez l'application TrackMySleepQuality-Starter depuis GitHub.
- Créez et exécutez l'application. L'application affiche l'UI du fragment
SleepTrackerFragment, mais aucune donnée. Les boutons ne répondent pas aux commandes tactiles.
Étape 2 : Inspecter l'application de démarrage
- Examinez les fichiers Gradle :
- Le fichier Gradle du projet
: dans le fichierbuild.gradleau niveau du projet, notez les variables qui spécifient les versions des bibliothèques. Les versions utilisées dans l'application de démarrage fonctionnent bien ensemble et avec cette application. Lorsque vous aurez terminé cet atelier de programmation, Android Studio pourra vous inviter à mettre à jour certaines versions. C'est à vous de décider si vous souhaitez mettre à jour les versions ou conserver celles qui se trouvent dans l'application. Si vous rencontrez des erreurs de compilation "étranges", essayez d'utiliser la combinaison de versions de bibliothèque utilisée par l'application de solution finale. - Fichier Gradle du module. Notez les dépendances fournies pour toutes les bibliothèques Android Jetpack, y compris
Room, et les dépendances pour les coroutines.
- Examinez les packages et l'UI. L'application est structurée par fonctionnalité. Le package contient des fichiers d'espace réservé dans lesquels vous ajouterez du code tout au long de cette série d'ateliers de programmation.
- Le package
databasepour tout le code lié à la base de donnéesRoom. - Les packages
sleepqualityetsleeptrackercontiennent le fragment, le ViewModel et la fabrique de ViewModel pour chaque écran.
- Consultez le fichier
Util.kt, qui contient des fonctions permettant d'afficher les données sur la qualité du sommeil. Certains codes sont mis en commentaire, car ils font référence à un ViewModel que vous créerez ultérieurement. - Consultez le dossier androidTest (
SleepDatabaseTest.kt). Vous utiliserez ce test pour vérifier que la base de données fonctionne comme prévu.
Dans Android, les données sont représentées dans des classes de données, et elles sont accessibles et modifiées à l'aide d'appels de fonction. Toutefois, dans l'univers des bases de données, vous avez besoin d'entités et de requêtes.
- Une entité représente un objet ou un concept et ses propriétés, à stocker dans la base de données. Une classe d'entité définit une table, et chaque instance de cette classe représente une ligne de la table. Chaque propriété définit une colonne. Dans votre application, l'entité va contenir des informations sur une nuit de sommeil.
- Une requête est une demande de données ou d'informations à partir d'une table de base de données ou d'une combinaison de tables, ou une demande d'effectuer une action sur les données. Les requêtes courantes permettent d'obtenir, d'insérer et de mettre à jour des entités. Par exemple, vous pouvez interroger toutes les nuits de sommeil enregistrées, triées par heure de début.
Room fait tout le travail difficile pour vous, des classes de données Kotlin aux entités pouvant être stockées dans des tables SQLite, et des déclarations de fonctions aux requêtes SQL.
Vous devez définir chaque entité comme une classe de données annotée et les interactions comme une interface annotée, un objet d'accès aux données (DAO). Room utilise ces classes annotées pour créer des tables dans la base de données et des requêtes qui agissent sur la base de données.

Étape 1 : Créer l'entité SleepNight
Dans cette tâche, vous allez définir une nuit de sommeil comme une classe de données annotée.
Pour une nuit de sommeil, vous devez enregistrer l'heure de début, l'heure de fin et une note de qualité.
Vous avez également besoin d'un identifiant pour identifier la nuit de manière unique.
- Dans le package
database, recherchez et ouvrez le fichierSleepNight.kt. - Créez la classe de données
SleepNightavec des paramètres pour un ID, une heure de début (en millisecondes), une heure de fin (en millisecondes) et une note numérique de qualité du sommeil.
- Vous devez initialiser
sleepQualityen le définissant sur-1, ce qui indique qu'aucune donnée de qualité n'a été collectée. - Vous devez également initialiser l'heure de fin. Définissez-le sur l'heure de début pour indiquer qu'aucune heure de fin n'a encore été enregistrée.
data class SleepNight(
var nightId: Long = 0L,
val startTimeMilli: Long = System.currentTimeMillis(),
var endTimeMilli: Long = startTimeMilli,
var sleepQuality: Int = -1
)- Avant la déclaration de la classe, annotez la classe de données avec
@Entity. Nommez la tabledaily_sleep_quality_table. L'argument pourtableNameest facultatif, mais recommandé. Vous pouvez rechercher d'autres arguments dans la documentation.
Si vous y êtes invité, importezEntityet toutes les autres annotations de la bibliothèqueandroidx.
@Entity(tableName = "daily_sleep_quality_table")
data class SleepNight(...)- Pour identifier la propriété
nightIdcomme clé primaire, annotez-la avec@PrimaryKey. Définissez le paramètreautoGeneratesurtruepour queRoomgénère l'ID de chaque entité. L'identifiant de chaque nuit est ainsi forcément unique.
@PrimaryKey(autoGenerate = true)
var nightId: Long = 0L,...- Annotez les propriétés restantes avec
@ColumnInfo. Personnalisez les noms de propriété à l'aide de paramètres, comme indiqué ci-dessous.
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "daily_sleep_quality_table")
data class SleepNight(
@PrimaryKey(autoGenerate = true)
var nightId: Long = 0L,
@ColumnInfo(name = "start_time_milli")
val startTimeMilli: Long = System.currentTimeMillis(),
@ColumnInfo(name = "end_time_milli")
var endTimeMilli: Long = startTimeMilli,
@ColumnInfo(name = "quality_rating")
var sleepQuality: Int = -1
)- Compilez et exécutez votre code pour vous assurer qu'il ne comporte pas d'erreurs.
Dans cette tâche, vous allez définir un objet d'accès aux données (DAO). Sur Android, le DAO propose des méthodes pratiques pour insérer, supprimer et mettre à jour la base de données.
Lorsque vous utilisez une base de données Room, vous l'interrogez en définissant et en appelant des fonctions Kotlin dans votre code. Ces fonctions Kotlin sont mappées à des requêtes SQL. Vous définissez ces mappages dans un DAO à l'aide d'annotations, et Room crée le code nécessaire.
Considérez un DAO comme une interface personnalisée pour accéder à votre base de données.
Pour les opérations de base de données courantes, la bibliothèque Room fournit des annotations pratiques, telles que @Insert, @Delete et @Update. Pour tout le reste, il y a l'annotation @Query. Vous pouvez écrire n'importe quelle requête prise en charge par SQLite.
En outre, lorsque vous créez vos requêtes SQL dans Android Studio, le compilateur vérifie si une erreur de syntaxe est présente.
Pour la base de données du détecteur de sommeil, vous devez être en mesure d'effectuer les opérations suivantes :
- Insérez de nouvelles nuits.
- Modifier une nuit existante : son heure de fin et sa note de qualité
- Obtenir une nuit spécifique en fonction de sa clé.
- Obtenir toutes les nuits afin de pouvoir les afficher.
- Obtenez la nuit la plus récente.
- Supprimer toutes les entrées de la base de données.
Étape 1 : Créer le DAO SleepDatabase
- Dans le package
database, ouvrezSleepDatabaseDao.kt. - Notez que
interfaceSleepDatabaseDaoest annoté avec@Dao. Tous les DAO doivent être annotés avec le mot clé@Dao.
@Dao
interface SleepDatabaseDao {}- Dans le corps de l'interface, ajoutez une annotation
@Insert. Sous@Insert, ajoutez une fonctioninsert()qui reçoit une instance de la classeEntityappeléeSleepNightcomme argument.
Et voilà.Roomva maintenant générer tout le code nécessaire pour insérer l'élémentSleepNightdans la base de données. Lorsque vous appelezinsert()à partir de votre code Kotlin,Roomexécute une requête SQL pour insérer l'entité dans la base de données. (Remarque : Vous pouvez donner le nom de votre choix à la fonction.)
@Insert
fun insert(night: SleepNight)- Ajoutez une annotation
@Updateavec une fonctionupdate()pour un élémentSleepNight. L'entité mise à jour est celle qui a la même clé que celle transmise. Vous pouvez mettre à jour tout ou partie des autres propriétés de l'entité.
@Update
fun update(night: SleepNight)Il n'existe aucune annotation spécifiquement adaptée à la fonctionnalité restante. Vous devez donc utiliser l'annotation @Query et fournir des requêtes SQLite.
- Ajoutez une annotation
@Queryavec une fonctionget()qui accepte un argumentLongkeyet renvoie unSleepNightpouvant être nul. Une erreur s'affiche pour indiquer qu'il manque un paramètre.
@Query
fun get(key: Long): SleepNight?- La requête est fournie en tant que paramètre de chaîne à l'annotation. Ajoutez un paramètre à
@Query. Fais-en uneStringqui est une requête SQLite.
- Sélectionnez toutes les colonnes de
daily_sleep_quality_table. - Avec
WHERE, l'nightIdcorrespond à l'argument :key.
Notez l'élément:key. Utilisez le caractère deux-points, ce qui permet à la requête de faire référence à des arguments dans la fonction.
("SELECT * from daily_sleep_quality_table WHERE nightId = :key")- Ajoutez un autre
@Queryavec une fonctionclear()et une requête SQLite pourDELETEtout à partir dedaily_sleep_quality_table. Cette requête ne supprime pas la table elle-même.
L'annotation@Deletesupprime un élément. Vous pouvez utiliser@Deleteet fournir une liste de nuits à supprimer. L'inconvénient est que vous devez récupérer ou connaître le contenu de la table. L'annotation@Deleteest idéale pour supprimer des entrées spécifiques, mais pas pour effacer toutes les entrées d'une table.
@Query("DELETE FROM daily_sleep_quality_table")
fun clear()- Ajoutez une annotation
@Queryavec une fonctiongetTonight(). Rendez leSleepNightrenvoyé pargetTonight()nullable, afin que la fonction puisse gérer le cas où la table est vide. (La table est vide au début et après l'effacement des données.)
Pour obtenir "ce soir" à partir de la base de données, écrivez une requête SQLite qui renvoie le premier élément d'une liste de résultats triés parnightIddans l'ordre décroissant. UtilisezLIMIT 1pour ne renvoyer qu'un seul élément.
@Query("SELECT * FROM daily_sleep_quality_table ORDER BY nightId DESC LIMIT 1")
fun getTonight(): SleepNight?- Ajoutez une annotation
@Queryavec une fonctiongetAllNights():
- Demandez à la requête SQLite de renvoyer toutes les colonnes de la table
daily_sleep_quality_table, puis d'effectuer un tri par ordre décroissant. - Demandez à
getAllNights()de renvoyer la liste des entitésSleepNighten tant queLiveData.Roomveille automatiquement à ce queLiveDatareste à jour. Vous n'avez donc besoin de générer les données de façon explicite qu'une seule fois. - Il est possible que vous ayez besoin d'importer
LiveDatadepuisandroidx.lifecycle.LiveData.
@Query("SELECT * FROM daily_sleep_quality_table ORDER BY nightId DESC")
fun getAllNights(): LiveData<List<SleepNight>>- Bien qu'aucune modification ne soit visible, exécutez votre application pour vous assurer qu'elle ne comporte pas d'erreurs.
Dans cette tâche, vous allez créer une base de données Room qui utilise les Entity et les DAO créés au cours de la tâche précédente.
Vous devez créer une classe de conteneur de base de données abstraite, annotée avec @Database. Cette classe comporte une méthode qui crée une instance de la base de données si elle n'existe pas ou qui renvoie une référence à une base de données existante.
L'obtention d'une base de données Room est un peu complexe. Voici donc le processus général à suivre avant de commencer à coder :
- Créez une classe
public abstractquiextends RoomDatabase. Cette classe sert de conteneur de base de données. Elle est abstraite, carRoomcrée l'implémentation à votre place. - Annotez la classe avec
@Database. Dans les arguments, déclarez les entités de la base de données et définissez le numéro de version. - Dans un objet
companion, définissez une méthode ou une propriété abstraite qui renvoie unSleepDatabaseDao.Roomgénérera le corps du message pour vous. - Vous n'avez besoin que d'une seule instance de la base de données
Roompour l'ensemble de l'application. Vous devez donc faire en sorte queRoomDatabasesoit un singleton. - Utilisez l'outil de création de base de données de
Roompour créer la base de données uniquement si elle n'existe pas. Sinon, renvoyez la base de données existante.
Étape 1 : Créer la base de données
- Dans le package
database, ouvrezSleepDatabase.kt. - Dans le fichier, créez une classe
abstractappeléeSleepDatabasequi étendRoomDatabase.
Annotez la classe avec@Database.
@Database()
abstract class SleepDatabase : RoomDatabase() {}- Une erreur s'affiche pour indiquer qu'il manque des paramètres d'entités et de version. Pour que
Roompuisse créer la base de données, l'annotation@Databasedoit comporter plusieurs arguments.
- Fournissez
SleepNighten tant que seul élément contenant la liste d'entities. - Définissez
versionsur1. Chaque fois que vous modifiez le schéma, vous devez incrémenter le numéro de version. - Définissez
exportSchemasurfalsepour ne pas conserver les sauvegardes de l'historique des versions de schéma.
entities = [SleepNight::class], version = 1, exportSchema = false- La base de données doit connaître le DAO. Dans le corps de la classe, déclarez une valeur abstraite qui renvoie
SleepDatabaseDao. Vous pouvez avoir plusieurs DAO.
abstract val sleepDatabaseDao: SleepDatabaseDao- En dessous, définissez un objet
companion. L'objet compagnon permet aux clients d'accéder aux méthodes de création ou d'obtention de la base de données sans instancier la classe. Étant donné que le seul objectif de cette classe est de fournir une base de données, il n'y a aucune raison de l'instancier.
companion object {}- Dans l'objet
companion, déclarez uneINSTANCE, une variable privée pouvant être nulle, avant de l'initialiser en lui attribuant la valeurnull. La variableINSTANCEconservera une référence à la base de données, si vous en avez créé une. Cela vous permet d'éviter d'ouvrir plusieurs fois des connexions à la base de données, ce qui est coûteux.
Annotez la variable INSTANCE avec @Volatile. La valeur d'une variable volatile ne sera jamais mise en cache, et toutes les écritures et lectures seront effectuées vers et depuis la mémoire principale. Cela permet de s'assurer que la valeur de la variable INSTANCE est toujours à jour et identique pour tous les threads d'exécution. En d'autres termes, les modifications apportées à INSTANCE par un thread sont immédiatement visibles par tous les autres. Vous évitez ainsi, par exemple, que deux threads mettent à jour la même entité dans un cache, ce qui pourrait poser problème.
@Volatile
private var INSTANCE: SleepDatabase? = null- En dessous de
INSTANCE, tout en restant dans l'objetcompanion, définissez une méthodegetInstance()avec un paramètreContext, dont l'outil de création de base de données aura besoin. Renvoyez un typeSleepDatabase. Une erreur s'affiche, cargetInstance()ne renvoie rien pour le moment.
fun getInstance(context: Context): SleepDatabase {}- Dans
getInstance(), ajoutez un blocsynchronized{}. Transmettezthispour pouvoir accéder au contexte.
Plusieurs threads peuvent demander une instance de base de données en même temps, ce qui génère deux bases de données au lieu d'une seule. Ce problème est peu susceptible de se produire dans cet exemple d'application, mais il peut survenir dans une application plus complexe. En encapsulant le code pour placer la base de données dans un blocsynchronized, vous vous assurez qu'un seul thread d'exécution à la fois peut y accéder. Ainsi, vous avez la certitude que la base de données n'est initialisée qu'une seule fois.
synchronized(this) {}- Dans le bloc synchronisé, copiez la valeur actuelle de
INSTANCEdans une variable localeinstance. Cela permet de profiter du smart cast, qui n'est disponible que pour les variables locales.
var instance = INSTANCE- Dans le bloc
synchronized,return instanceà la fin du blocsynchronized. Ignorez l'erreur de non-concordance du type de retour. Vous ne renverrez jamais la valeur "null" une fois que vous aurez terminé.
return instance- Au-dessus de l'instruction
return, ajoutez une instructionifpour vérifier siinstanceest nul, c'est-à-dire s'il n'y a pas encore de base de données.
if (instance == null) {}- Si
instanceest défini surnull, utilisez l'outil de création de base de données pour obtenir une base de données. Dans le corps de l'instructionif, appelezRoom.databaseBuilderet fournissez le contexte que vous avez transmis, la classe de base de données et un nom pour la base de données,sleep_history_database. Pour supprimer l'erreur, vous devrez ajouter une stratégie de migration etbuild()au cours des étapes suivantes.
instance = Room.databaseBuilder(
context.applicationContext,
SleepDatabase::class.java,
"sleep_history_database")- Ajoutez la stratégie de migration requise au compilateur. Utilisez
.fallbackToDestructiveMigration().
. Normalement, vous devez accompagner toute stratégie de migration d'un objet de migration, au cas où le schéma viendrait à être modifié. Un objet de migration définit la façon dont vous convertissez toutes les lignes de l'ancien schéma pour les rendre compatibles avec le nouveau, de sorte qu'aucune donnée ne soit perdue. La migration dépasse le cadre de cet atelier de programmation. Une solution simple consiste à détruire et à recréer la base de données, ce qui entraîne une perte de données.
.fallbackToDestructiveMigration()- Enfin, appelez
.build().
.build()- Attribuez
INSTANCE = instancecomme dernière étape dans l'instructionif.
INSTANCE = instance- Votre code, une fois fini, doit ressembler à ceci :
@Database(entities = [SleepNight::class], version = 1, exportSchema = false)
abstract class SleepDatabase : RoomDatabase() {
abstract val sleepDatabaseDao: SleepDatabaseDao
companion object {
@Volatile
private var INSTANCE: SleepDatabase? = null
fun getInstance(context: Context): SleepDatabase {
synchronized(this) {
var instance = INSTANCE
if (instance == null) {
instance = Room.databaseBuilder(
context.applicationContext,
SleepDatabase::class.java,
"sleep_history_database"
)
.fallbackToDestructiveMigration()
.build()
INSTANCE = instance
}
return instance
}
}
}
}- Compilez et exécutez votre code.
Vous disposez désormais de tous les éléments nécessaires pour travailler avec votre base de données Room. Ce code peut être compilé et exécuté, mais vous n'avez aucun moyen de savoir s'il fonctionne réellement. C'est donc le moment d'ajouter quelques tests de base.
Étape 2 : Testez SleepDatabase
Au cours de cette étape, vous allez exécuter les tests fournis pour vérifier que votre base de données fonctionne. Cela permet de s'assurer que la base de données fonctionne avant de la développer. Les tests fournis sont basiques. Pour une application de production, vous exécuterez toutes les fonctions et requêtes dans tous les DAO.
L'application de démarrage contient un dossier androidTest. Ce dossier androidTest contient des tests unitaires qui impliquent l'instrumentation Android. En d'autres termes, les tests ont besoin du framework Android. Vous devez donc les exécuter sur un appareil physique ou virtuel. Bien sûr, vous pouvez également créer et exécuter des tests unitaires purs qui n'impliquent pas le framework Android.
- Dans Android Studio, dans le dossier androidTest, ouvrez le fichier SleepDatabaseTest.
- Pour décommenter le code, sélectionnez tout le code commenté et appuyez sur le raccourci clavier
Cmd+/ouControl+/. - Examinez le fichier.
Voici un aperçu rapide du code de test, car il s'agit d'un autre élément de code que vous pouvez réutiliser :
SleepDabaseTestest une classe de test.- L'annotation
@RunWithidentifie le lanceur de test, qui est le programme qui configure et exécute les tests. - Lors de la configuration, la fonction annotée avec
@Beforeest exécutée et crée unSleepDatabaseen mémoire avec leSleepDatabaseDao. "En mémoire" signifie que cette base de données n'est pas enregistrée dans le système de fichiers et qu'elle sera supprimée après l'exécution des tests. - De plus, lors de la création de la base de données en mémoire, le code appelle une autre méthode spécifique aux tests,
allowMainThreadQueries. Par défaut, une erreur s'affiche si vous essayez d'exécuter des requêtes sur le thread principal. Cette méthode vous permet d'exécuter des tests sur le thread principal, ce que vous ne devez faire que pendant les tests. - Dans une méthode de test annotée avec
@Test, vous créez, insérez et récupérez unSleepNight, puis vous affirmez qu'ils sont identiques. En cas de problème, générez une exception. Dans un test réel, vous auriez plusieurs méthodes@Test. - Une fois le test terminé, la fonction annotée avec
@Afters'exécute pour fermer la base de données.
- Effectuez un clic droit sur le fichier de test dans le volet Project (Projet), puis sélectionnez Run 'SleepDatabaseTest' (Exécuter "SleepDatabaseTest").
- Une fois les tests exécutés, vérifiez dans le volet SleepDatabaseTest que tous les tests ont réussi.

Comme tous les tests ont réussi, vous savez maintenant plusieurs choses :
- La base de données est créée correctement.
- Vous pouvez insérer un
SleepNightdans la base de données. - Vous pouvez récupérer le
SleepNight. - La valeur de
SleepNightest correcte pour la qualité.
Projet Android Studio : TrackMySleepQualityRoomAndTesting
Lorsque vous testez une base de données, vous devez exercer toutes les méthodes définies dans le DAO. Pour terminer les tests, ajoutez et exécutez des tests pour exercer les autres méthodes DAO.
- Définissez vos tables en tant que classes de données annotées avec
@Entity. Définissez les propriétés annotées avec@ColumnInfoen tant que colonnes dans les tables. - Définissez un objet d'accès aux données (DAO) en tant qu'interface annotée avec
@Dao. Le DAO mappe les fonctions Kotlin aux requêtes de base de données. - Utilisez les annotations pour définir les fonctions
@Insert,@Deleteet@Update. - Pour toutes les autres requêtes, utilisez l'annotation
@Queryavec une chaîne de requête SQLite comme paramètre. - Créez une classe abstraite qui possède une fonction
getInstance()renvoyant une base de données. - Utilisez des tests instrumentés pour vérifier que votre base de données et votre DAO fonctionnent comme prévu. Vous pouvez utiliser les tests fournis comme modèle.
Cours Udacity :
Documentation pour les développeurs Android :
RoomDatabaseDatabase(annotations)- Vous pouvez utiliser des requêtes brutes avec
Room Roomdatabase.Builder- Entraînement Testing
- Classe
SQLiteDatabase Dao- Bibliothèque de persistance
Room
Autres articles et documentation :
Cette section répertorie les devoirs possibles pour les élèves qui suivent cet atelier de programmation dans le cadre d'un cours animé par un enseignant. Il revient à l'enseignant d'effectuer les opérations suivantes :
- Attribuer des devoirs si nécessaire
- Indiquer aux élèves comment rendre leurs devoirs
- Noter les devoirs
Les enseignants peuvent utiliser ces suggestions autant qu'ils le souhaitent, et ne doivent pas hésiter à attribuer d'autres devoirs aux élèves s'ils le jugent nécessaire.
Si vous suivez cet atelier de programmation par vous-même, n'hésitez pas à utiliser ces devoirs pour tester vos connaissances.
Répondre aux questions suivantes
Question 1
Comment indiquer qu'une classe représente une entité à stocker dans une base de données Room ?
- Configurez la classe pour qu'elle étende
DatabaseEntity. - Annotez la classe avec
@Entity. - Annotez la classe avec
@Database. - Configurez la classe pour qu'elle étende
RoomEntityet annotez-la avec@Room.
Question 2
Le DAO (objet d'accès aux données) est une interface qui permet à Room de mapper les fonctions Kotlin aux requêtes de base de données.
Comment indiquer qu'une interface représente un DAO pour une base de données Room ?
- Configurez l'interface pour qu'elle étende
RoomDAO. - Configurez l'interface pour qu'elle étende
EntityDao, puis implémentez la méthodeDaoConnection(). - Annotez l'interface avec
@Dao. - Annotez l'interface avec
@RoomConnection.
Question 3
Parmi les affirmations suivantes concernant la base de données Room, lesquelles sont vraies ? Plusieurs réponses sont possibles.
- Vous pouvez définir des tables pour une base de données
Roomen tant que classes de données annotées. - Si vous renvoyez
LiveDataà partir d'une requête,RoomgarderaLiveDataà jour pour vous siLiveDatachange. - Chaque base de données
Roomdoit comporter un et un seul DAO. - Pour identifier une classe en tant que base de données
Room, faites-en une sous-classe deRoomDatabaseet annotez-la avec@Database.
Question 4
Quelle annotation pouvez-vous utiliser dans votre interface @Dao ? Plusieurs réponses sont possibles.
@Get@Update@Insert@Query
Question 5
Comment vérifier que votre base de données fonctionne ? Plusieurs réponses possibles.
- En écrivant des tests instrumentés.
- Continuez à écrire et à exécuter l'application jusqu'à ce qu'elle affiche les données.
- En remplaçant les appels vers les méthodes dans l'interface DAO par des appels de méthodes équivalentes dans la classe
Entity. - Exécutez la fonction
verifyDatabase()fournie par la bibliothèqueRoom.
Passer à la leçon suivante :
Pour obtenir des liens vers d'autres ateliers de programmation de ce cours, consultez la page de destination des ateliers de programmation Principes de base d'Android en Kotlin.