使用Kotlin协程时Room dao类出现错误 [英] Error with Room dao class when using Kotlin coroutines

查看:1353
本文介绍了使用Kotlin协程时Room dao类出现错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正尝试通过此处中所述的方法,使用kotlin协程访问会议室数据库,并添加了插件和依赖项,并在gradle中启用了kotlin协程.

I'm trying to use kotlin coroutines to access room database by the method described here, added the plugin and dependency, and enabled kotlin coroutines in gradle.

渐变文件中:

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

所以我为dao类中的所有方法添加了suspend关键字,如下所示:

So I added suspend keyword for all the methods in dao class, like this:

dao类

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

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

进行构建,然后得到这些错误

and build, then get these errors

错误

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

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类型的附加参数,如下所示:

the error links navigate to the auto generated dao class. The generated methods in this class now each has an additional param of this type Continuation , as this:

自动生成的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{}方法,而是使用suspend关键字,因为代码中有很多地方可以查询数据库.

I tried delete the generated dao class and rebuild to renegerate it, still get these errors. I consider not using the lauch{} method but use suspend keyword, becuase there are many places in code to query db.

我该如何解决?

推荐答案

您不能将suspend方法用于DAO. 在编译时处理挂起的函数,然后编译器更改此函数的签名(不同的返回类型,状态机回调的附加参数)以使其不阻塞.

You cannot use suspend methods for DAO. Suspend function processed in compile time and compiler changes the signature of this function (different return type, an additional argument for state machine callback) to make it non-blocking.

房间等待特定的方法签名生成代码.因此,除非Room不直接支持协程,否则您不能对DAO使用暂停功能.

Room waits for particular method signature to generate code. So, until Room doesn't support coroutines directly, you cannot use suspend function for DAO.

目前,您有以下解决方法:

For now, you have such workarounds:

  1. 如果DAO方法返回值,请使用RxJava或LiveData来获取它,并 使用用于RxJava的协程适配器,或为LiveData编写自己的适配器 (不知道现有的)
  2. 将同步DAO方法调用包装到 协程具有自己的线程池(因为这样的调用将被阻塞).
  1. If DAO method returns value, use RxJava or LiveData to get it and use coroutine adapter for RxJava or write your own for LiveData (don't know existing ones)
  2. Wrap synchronous DAO method call to coroutine with own thread pool (because such call will be blocking).

但是如果可能的话,请始终选择选项1,因为Room已经提供了非阻塞API,只需使用协程适配器即可将此API与协程一起使用而无需回调

But always prefer option 1 if it's possible because Room already provides non-blocking API, just use coroutine adapter to allow use this API with coroutines without callbacks

Room 2.1.0-alpha03开始,DAO方法现在可以是suspend函数.专门标记为@ Insert,@ Update或@Delete的Dao方法可以是挂起函数.尽管支持普通查询,但仍尚不支持.有关更多详细信息,请参见:建筑组件发行说明

As of Room 2.1.0-alpha03, DAO methods can now be suspend functions. Dao methods specifically annotated as @Insert, @Update, or @Delete can be suspend functions. Inserts, Updates, and Deletes annotated as @Query are not yet supported although normal queries are. For further details see: Architecture Components Release Notes and Feature Request.

这篇关于使用Kotlin协程时Room dao类出现错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆