Pour empêcher les requêtes de bloquer l'interface utilisateur, Room n'autorise pas l'accès à la base de données sur le thread principal. Cette restriction signifie que vous devez rendre vos requêtes DAO asynchrones. La bibliothèque Room inclut des intégrations avec différents frameworks pour permettre l'exécution de requêtes asynchrones.
Les requêtes DAO appartiennent à trois catégories :
- Requêtes d'écriture unique qui insèrent, mettent à jour ou suppriment des données dans la base de données.
- Requêtes de lecture unique qui lisent les données de votre base de données une seule fois et renvoient un résultat avec l'instantané de la base de données à ce moment-là.
- Requêtes de lecture observables qui lisent les données de votre base de données chaque fois que les tables de base de données sous-jacentes changent et émettent de nouvelles valeurs reflétant ces modifications.
Options de langage et de framework
Room permet l'interopérabilité avec des bibliothèques et des fonctionnalités de langage spécifiques. Le tableau suivant présente les types renvoyés applicables en fonction du type de requête et du framework :
Type de requête | Fonctionnalités du langage Kotlin | RxJava | Guava | Jetpack Lifecycle |
---|---|---|---|---|
Écriture unique | Coroutines (suspend ) |
Single<T> , Maybe<T> ,
Completable |
ListenableFuture<T> |
N/A |
Lecture unique | Coroutines (suspend ) |
Single<T> , Maybe<T> |
ListenableFuture<T> |
N/A |
Lecture observable | Flow<T> |
Flowable<T> , Publisher<T> ,
Observable<T> |
N/A | LiveData<T> |
Ce guide présente trois façons d'utiliser ces intégrations pour implémenter des requêtes asynchrones dans vos DAO.
Kotlin avec Flow et coroutines
Kotlin fournit des fonctionnalités de langage qui vous permettent d'écrire des requêtes asynchrones sans frameworks tiers :
- Dans Room 2.2 et les versions ultérieures, vous pouvez utiliser la fonctionnalité Flow de Kotlin pour écrire des requêtes observables.
- Dans Room 2.1 et les versions ultérieures, vous pouvez utiliser le mot clé
suspend
pour rendre vos requêtes DAO asynchrones à l'aide de coroutines Kotlin.
Java avec RxJava
Si votre application utilise le langage de programmation Java, vous pouvez utiliser des types renvoyés spécialisés du framework RxJava pour écrire des méthodes DAO asynchrones. Room est compatible avec les types renvoyés RxJava 2 suivants :
- Pour les requêtes uniques, la version 2.1 et les versions ultérieures sont compatibles avec les types de retour
Completable
,Single<T>
etMaybe<T>
. - Pour les requêtes observables, Room est compatible avec les types renvoyés
Publisher<T>
,Flowable<T>
etObservable<T>
.
De plus, la version 2.3 et les versions ultérieures sont compatibles avec RxJava 3.
Java avec LiveData et Guava
Si votre application utilise le langage de programmation Java et que vous ne souhaitez pas utiliser le framework RxJava, vous pouvez utiliser les alternatives suivantes pour écrire des requêtes asynchrones :
- Vous pouvez utiliser la classe wrapper
LiveData
de Jetpack pour écrire des requêtes observables asynchrones. - Vous pouvez utiliser le wrapper
ListenableFuture<T>
de Guava pour écrire des requêtes uniques asynchrones.
Écrire des requêtes uniques asynchrones
Les requêtes uniques sont des opérations de base de données qui ne s'exécutent qu'une seule fois et récupèrent un instantané des données au moment de l'exécution. Voici quelques exemples de requêtes uniques asynchrones :
Kotlin
@Dao interface UserDao { @Insert(onConflict = OnConflictStrategy.REPLACE) suspend fun insertUsers(vararg users: User) @Update suspend fun updateUsers(vararg users: User) @Delete suspend fun deleteUsers(vararg users: User) @Query("SELECT * FROM user WHERE id = :id") suspend fun loadUserById(id: Int): User @Query("SELECT * from user WHERE region IN (:regions)") suspend fun loadUsersByRegion(regions: List<String>): List<User> }
Java
@Dao public interface UserDao { @Insert(onConflict = OnConflictStrategy.REPLACE) public Completable insertUsers(List<User> users); @Update public Completable updateUsers(List<User> users); @Delete public Completable deleteUsers(List<User> users); @Query("SELECT * FROM user WHERE id = :id") public Single<User> loadUserById(int id); @Query("SELECT * from user WHERE region IN (:regions)") public Single<List<User>> loadUsersByRegion(List<String> regions); }
Java
@Dao public interface UserDao { // Returns the number of users inserted. @Insert(onConflict = OnConflictStrategy.REPLACE) public ListenableFuture<Integer> insertUsers(List<User> users); // Returns the number of users updated. @Update public ListenableFuture<Integer> updateUsers(List<User> users); // Returns the number of users deleted. @Delete public ListenableFuture<Integer> deleteUsers(List<User> users); @Query("SELECT * FROM user WHERE id = :id") public ListenableFuture<User> loadUserById(int id); @Query("SELECT * from user WHERE region IN (:regions)") public ListenableFuture<List<User>> loadUsersByRegion(List<String> regions); }
Écrire des requêtes observables
Les requêtes observables sont des opérations de lecture qui émettent de nouvelles valeurs en cas de modification de l'une des tables référencées par la requête. Vous pouvez les utiliser, par exemple, pour maintenir à jour la liste des éléments affichés à mesure que les éléments de la base de données sous-jacentes sont insérés, mis à jour ou supprimés. Voici quelques exemples de requêtes observables :
Kotlin
@Dao interface UserDao { @Query("SELECT * FROM user WHERE id = :id") fun loadUserById(id: Int): Flow<User> @Query("SELECT * from user WHERE region IN (:regions)") fun loadUsersByRegion(regions: List<String>): Flow<List<User>> }
Java
@Dao public interface UserDao { @Query("SELECT * FROM user WHERE id = :id") public Flowable<User> loadUserById(int id); @Query("SELECT * from user WHERE region IN (:regions)") public Flowable<List<User>> loadUsersByRegion(List<String> regions); }
Java
@Dao public interface UserDao { @Query("SELECT * FROM user WHERE id = :id") public LiveData<User> loadUserById(int id); @Query("SELECT * from user WHERE region IN (:regions)") public LiveData<List<User>> loadUsersByRegion(List<String> regions); }
Ressources supplémentaires
Pour en savoir plus sur les requêtes DAO asynchrones, consultez les ressources supplémentaires suivantes :