web-dev-qa-db-fra.com

Erreur avec la classe Room Dao lors de l'utilisation de coroutines Kotlin

J'essaie d'utiliser les coroutines de kotlin pour accéder à la base de données de la pièce par la méthode décrite ici , ajouté le plugin et la dépendance, et activé les coroutines de kotlin dans gradle.

dans le fichier gradle:

    kotlin {
    experimental {
        coroutines 'enable'
    }
}
dependencies { implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:0.21" ...}

J'ai donc ajouté le mot clé suspend pour toutes les méthodes de la classe dao, comme ceci:

classe de dao

@Query("select * from myevent")
suspend fun all(): List<MyEvent>

@Delete
suspend fun deleteEvent(event: MyEvent)
...

et construire, puis obtenir ces erreurs

Erreur

e: C:\Users\projectpath\app\build\tmp\kapt3\stubs\debug\com\robyn\myapp\data\source\local\EventsDao.Java:39: error: Deletion methods must either return void or return int (the number of deleted rows). public abstract Java.lang.Object deleteEventById(@org.jetbrains.annotations.NotNull() ^ e: C:\Users\projectpath\app\build\tmp\kapt3\stubs\debug\com\robyn\myapp\data\source\local\EventsDao.Java:41: error: Query method parameters should either be a type that can be converted into a database column or a List / Array that contains such type. You can consider adding a Type Adapter for this. kotlin.coroutines.experimental.Continuation<? super kotlin.Unit> p1);

les liens d'erreur accèdent à la classe auto générée dao. Les méthodes générées dans cette classe ont maintenant chacune un paramètre supplémentaire de ce type Continuation, comme ceci:

classe de dao générée automatiquement

@org.jetbrains.annotations.Nullable()
@Android.Arch.persistence.room.Delete()
public abstract Java.lang.Object deleteAllEvents(@org.jetbrains.annotations.NotNull() // error indicates at this line
Java.util.List<com.robyn.myapp.data.MyEvent> events, @org.jetbrains.annotations.NotNull()
kotlin.coroutines.experimental.Continuation<? super kotlin.Unit> p1); // error indicates at this line
...

J'ai essayé de supprimer la classe DAO générée et de la reconstruire pour la renégocier, tout en obtenant ces erreurs. J'envisage de ne pas utiliser la méthode lauch{}, mais d'utiliser le mot clé suspend, car il existe de nombreux emplacements dans le code pour interroger db. 

Comment puis-je réparer cela?

7
Robin

Vous ne pouvez pas utiliser les méthodes suspend pour DAO . La fonction de suspension traitée au moment de la compilation et le compilateur modifie la signature de cette fonction (type de retour différent, argument supplémentaire pour le rappel de la machine à états) pour la rendre non bloquante.

Room attend une signature de méthode particulière pour générer du code. Donc, tant que Room ne supporte pas directement les routines, vous ne pouvez pas utiliser la fonction de suspension pour DAO.

Pour l'instant, vous avez de telles solutions:

  1. Si la méthode DAO retourne une valeur, utilisez RxJava ou LiveData pour l'obtenir et Utilisez coroutine adapter pour RxJava ou écrivez le vôtre pour LiveData (Ne pas connaître ceux qui existent déjà) 
  2. Enveloppe l'appel de méthode DAO synchrone à Coroutine avec son propre pool de threads (car cet appel sera bloquant).

Mais préférez toujours l'option 1 si c'est possible car Room fournit déjà une API non bloquante. Il vous suffit d'utiliser un adaptateur coroutine pour autoriser l'utilisation de cette API avec des coroutines sans rappel.

À partir de Room 2.1.0-alpha03, les méthodes DAO peuvent désormais être des fonctions suspend. Les méthodes Dao spécifiquement annotées comme @Insert, @Update ou @Delete peuvent être des fonctions de suspension. Les insertions, les mises à jour et les suppressions annotées en tant que @Query sont pas encore prises en charge bien que les requêtes normales le soient. Pour plus de détails, voir: Notes de version de Architecture Components et Feature Request .

7
gildor

en fait c'est possible,

vous devez utiliser:

implementation "androidx.room:room-coroutines:${versions.room}"

vous pouvez suivre ce tutoriel: https://medium.com/androiddevelopers/room-coroutines-422b786dc4c5

En outre, la version qui a fonctionné pour moi était la suivante: 2.1.0-alpha04So, mon dépôt de pièce était exactement:

implementation "androidx.room:room-runtime:2.1.0-alpha04"
implementation "androidx.room:room-coroutines:2.1.0-alpha04"
kapt "androidx.room:room-compiler:2.1.0-alpha04"
0
eriknyk