我正在尝试通过here描述的方法使用kotlin协程访问房间数据库,添加插件和依赖项,并在gradle中启用kotlin协程。
在 gradle 文件中:
kotlin {
experimental {
coroutines 'enable'
}
}
dependencies { implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:0.21" ...}
所以我为 dao 类中的所有方法添加了
suspend
关键字,如下所示:
道类
@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
关键字,因为代码中有很多地方可以查询数据库。
我该如何解决这个问题?
您不能对 DAO 使用
suspend
方法。
在编译时处理的挂起函数,编译器会更改该函数的签名(不同的返回类型,状态机回调的附加参数)以使其非阻塞。
Room 等待特定的方法签名来生成代码。因此,在 Room 不直接支持协程之前,您无法对 DAO 使用挂起功能。
目前,您有这样的解决方法:
从
Room 2.1.0-alpha03
开始,DAO 方法现在可以是
suspend
函数。特别注释为@Insert、@Update 或@Delete 的Dao 方法可以是挂起函数。尽管普通查询支持,但注释为 @Query 的插入、更新和删除尚不支持。有关更多详细信息,请参阅:架构组件发行说明和功能请求。
您需要使用:
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"
一般来说,如果仍然有错误,我建议您对依赖项使用最新的稳定版本。
suspend 关键字:
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertCountry(country: Country) // here
转换为这个解决了我的问题:
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertCountry(country: Country)
val room_version = "2.5.0"
对我有用。我的错误是关于 Dao 和 Entity 类。
// at an Activity:
CoroutineScope(Dispatchers.Main).launch {
rcAdapter.helper = helper
rcAdapter.listData.addAll(helper?.roomDao()?.getAll() ?: listOf())
}
// at Dao:
suspend fun getAll(): List<Room>
在这种情况下,如果 Dao 中没有使用 suspend 方法,这个 Activity 就会崩溃。这意味着不可能摆脱协程或删除 suspend 方法。在这种情况下,如果您从 Dao 中删除 suspend 方法并将 Activity 的协程更改为以下内容,则可以正常工作。
// at an Activity:
lifecycleScope.launch(Dispatchers.IO) {
rcAdapter.helper = helper
rcAdapter.listData.addAll(helper?.roomMemoDao()?.getAll() ?: listOf())
}
// at Dao:
fun getAll(): List<Room>
参见。 kotlin_version = '1.6.0' 和 room_version = "2.3.0"
build.gradle 中的类路径“org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0”
这对我有用
配置:
def room_version = "2.6.1"
implementation "androidx.room:room-runtime:$room_version"
implementation "androidx.room:room-ktx:$room_version"
kapt "androidx.room:room-compiler:$room_version"
延续); ^