web-dev-qa-db-ja.com

Kotlinコルーチンを使用する場合のRoomdaoクラスのエラー

Kotlinコルーチンを使用して、説明されている方法で部屋のデータベースにアクセスしようとしています ここ 、プラグインと依存関係を追加し、gradleでkotlinコルーチンを有効にしました。

gradleファイル内:

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

そこで、次のように、daoクラスのすべてのメソッドにsuspendキーワードを追加しました。

daoク​​ラス

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

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

ビルドしてから、これらのエラーを取得します

エラー

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);

エラーリンクは、自動生成daoク​​ラスに移動します。このクラスで生成されたメソッドには、それぞれ次のように、このタイプContinuationの追加のパラメーターがあります。

自動生成されたdaoクラス

_@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
...
_

生成されたdaoクラスを削除し、再構築して再生成しようとしましたが、それでもこれらのエラーが発生します。 _lauch{}_メソッドを使用しないことを検討しますが、dbをクエリするコードには多くの場所があるため、suspendキーワードを使用します。

どうすればこれを修正できますか?

7
Robin

DAOにsuspendメソッドを使用することはできません。コンパイル時に処理されたサスペンド関数とコンパイラーは、この関数のシグニチャー(異なる戻り値の型、ステートマシンコールバックの追加の引数)を変更して、非ブロッキングにします。

Roomは、特定のメソッドシグネチャがコードを生成するのを待ちます。そのため、Roomがコルーチンを直接サポートしない限り、DAOのサスペンド機能を使用することはできません。

今のところ、次のような回避策があります。

  1. DAOメソッドが値を返す場合は、RxJavaまたはLiveDataを使用して取得し、 RxJavaのコルーチンアダプター を使用するか、LiveData用に独自のアダプターを作成します(既存のものはわかりません)
  2. 同期DAOメソッド呼び出しを独自のスレッドプールでコルーチンにラップします(このような呼び出しはブロックされるため)。

ただし、RoomはすでにノンブロッキングAPIを提供しているため、可能であれば常にオプション1を優先します。コルーチンアダプターを使用して、コールバックなしでコルーチンでこのAPIを使用できるようにします。

Room 2.1.0-alpha03の時点で、DAOメソッドをsuspend関数にすることができます。 @ Insert、@ Update、または@Deleteとして特別にアノテーションが付けられたDaoメソッドは、サスペンド関数にすることができます。 @Queryとして注釈が付けられた挿入、更新、および削除は まだサポートされていません ですが、通常のクエリはサポートされています。詳細については、 アーキテクチャコンポーネントリリースノート および 機能リクエスト を参照してください。

10
gildor

実際にそれは可能です、

使用する必要があります:

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

このチュートリアルに従うことができます: https://medium.com/androiddevelopers/room-coroutines-422b786dc4c5

さらに、私のために働いたバージョンは:2.1.0-alpha04です。

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"
3
eriknyk