如何在 Room Db 上使用挂起功能?

Jay*_*abu 4 android kotlin android-room kotlin-coroutines

我在 kotlin 中使用协同程序使用 Room Db。这是我的 Dao 界面:

@Dao
interface CheckListNameDao {

    @Insert
    suspend fun insertName(name: CheckListName)


    @Query("SELECT * FROM CheckListNamesTable")
    fun getAllNames(): LiveData<List<CheckListName>>
}
Run Code Online (Sandbox Code Playgroud)

getAllNames()方法工作正常。问题出在insertName()方法上。当我suspendinsertName()方法中删除关键字时,它会引发此异常:java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time. 但是,当我使用suspend关键字时,我无法再构建项目。它显示以下错误:

error: Methods annotated with @Insert can return either void, long, Long, long[], Long[] or List<Long>.
public abstract java.lang.Object insertName(@org.jetbrains.annotations.NotNull()
Run Code Online (Sandbox Code Playgroud)

为什么会显示这个错误?我的代码基于此Android Room with a View - Kotlin

编辑: 这是我的存储库:

class MainRepository(application: Application) {

        private var nameDao: CheckListNameDao = AppDatabase.getDatabase(application.applicationContext)
                .checkListNameDao()

        fun getAllNames(): LiveData<List<CheckListName>> {
            return nameDao.getAllNames()
        }

        suspend fun setNewListName(checkListName: CheckListName) {
            nameDao.insertName(checkListName)
        }
    }
Run Code Online (Sandbox Code Playgroud)

这是视图模型:

class MainViewModel(application: Application) : AndroidViewModel(application) {

    private var mainRepository = MainRepository(application)

    fun getAllNames(): LiveData<List<CheckListName>> {
        return mainRepository.getAllNames()
    }

    fun setNewListName(name: String) {
        viewModelScope.launch {
            mainRepository.setNewListName(CheckListName(0, name))
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑2:

添加suspend关键字时,我也收到此错误:

error: Type of the parameter must be a class annotated with @Entity or a collection/array of it.
kotlin.coroutines.Continuation<? super kotlin.Unit> p1);
Run Code Online (Sandbox Code Playgroud)

这是CheckListName数据类:

@Entity(tableName = "CheckListNamesTable")
data class CheckListName(

        @PrimaryKey(autoGenerate = true)
        var id: Int,

        var name: String
)
Run Code Online (Sandbox Code Playgroud)

ian*_*ake 5

根据Roomroom-ktx Declaring Dependencies 文档,您需要依赖于使用协程和suspend方法:

implementation "androidx.room:room-ktx:2.2.3"
Run Code Online (Sandbox Code Playgroud)


Kha*_*din 5

编辑:您的代码是正确的,它可用于具有挂起功能的房间数据库。只需像下面这样编辑 Gradle 依赖项即可修复该错误。

如果您使用 kotlin 版本 ( 1.7.0 ) 应使用 room 最新的 alpha 版本 ( 2.5.0-alpha02 )

classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.0"

implementation "androidx.room:room-runtime:2.5.0-alpha02"
implementation "androidx.room:room-ktx:2.5.0-alpha02"
kapt "androidx.room:room-compiler:2.5.0-alpha02"
Run Code Online (Sandbox Code Playgroud)

如果你想在稳定版本(2.4.2)中使用 room 应该与 kotlin 版本(1.6.20)一起使用

classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.20"

implementation "androidx.room:room-runtime:2.4.2"
implementation "androidx.room:room-ktx:2.4.2"
kapt "androidx.room:room-compiler:2.4.2"
Run Code Online (Sandbox Code Playgroud)

我都尝试过并且它们都有效。这是参考:问题跟踪器