android - 使用 Kotlin 协程时 Room dao 类出错

标签 android kotlin coroutine android-room

我正在尝试使用 kotlin 协程通过 here 描述的方法访问房间数据库,添加了插件和依赖,并在gradle中启用了kotlin协程。

gradle 文件中:

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

所以我添加了 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{}方法,但使用 suspend关键字,因为代码中有很多地方可以查询db。

我该如何解决这个问题?

最佳答案

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

Room 等待特定的方法签名生成代码。所以,在 Room 不直接支持协程之前,你不能对 DAO 使用挂起函数。

目前,您有这样的解决方法:

  1. 如果 DAO 方法返回值,使用 RxJava 或 LiveData 获取它并 使用 coroutine adapter for RxJava或为 LiveData 编写自己的 (不知道现有的)
  2. 将同步 DAO 方法调用包装到 具有自己的线程池的协程(因为这样的调用会阻塞)。

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

Room 2.1.0-alpha03 开始,DAO 方法现在可以是 suspend 函数。被特别注解为@Insert、@Update 或@Delete 的Dao 方法可以是挂起函数。注释为@Query 的插入、更新和删除是not yet supported虽然正常查询是。更多详情请见:Architecture Components Release NotesFeature Request .

关于android - 使用 Kotlin 协程时 Room dao 类出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48694449/

相关文章:

android - 可使用自定义可打包对象进行打包

error-handling - Lua : pcall() doesn't work with coroutine as expected

python - Twisted、genvent、asyncoro——它们是我可能需要的吗?

java - 几种口味的 Kotlin 配置

Android proguard 错误 com.google.ads.util.i : and setMediaPlaybackRequiresUserGesture(boolean)

android - 添加注解处理器时,Android Studio会引发重复的类错误

java - Kotlin(null 不能转换为非 null 类型)自定义日历实现

python-3.x - 在 python 中使用协程。如何链接两个协程

java - 使用改造过帐值

java - 计算手机实际行驶距离