kotlin 如何使用房间Db的暂停功能?

ovfsdjhp  于 2023-01-17  发布在  Kotlin
关注(0)|答案(5)|浏览(192)

我在Kotlin中使用的是使用协程的Room Db。这是我的Dao接口:

@Dao
interface CheckListNameDao {

    @Insert
    suspend fun insertName(name: CheckListName)

    @Query("SELECT * FROM CheckListNamesTable")
    fun getAllNames(): LiveData<List<CheckListName>>
}

getAllNames()方法工作正常,问题出在insertName()方法上,当我从insertName()方法中删除suspend关键字时,它抛出了这个异常: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()

为什么会显示此错误?我的代码是基于这个Android房间查看-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)
        }
    }

这是视图模型:

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

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

这是CheckListName数据类:

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

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

        var name: String
)
vmpqdwk3

vmpqdwk31#

根据Room Declaring Dependencies文档,您需要对room-ktx有一个依赖关系,才能使用协程,并使用suspend方法:

implementation "androidx.room:room-ktx:2.2.3"
5cnsuln7

5cnsuln72#

编辑:您的代码是正确的,它可以用于具有挂起功能的房间数据库。只需编辑您的Gradle依赖项(如下图所示)即可修复该错误。
如果您使用的是Kotlin版本(1.7.0),则应使用最新的alpha版本(2.5.0-alpha 02

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"

如果你想在稳定版本(2.4.2)中使用空间,应该使用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"

我都试过了,他们的工作。这是参考:issue tracker

h9a6wy2h

h9a6wy2h3#

下面的代码片段包含一个带有一个实体和一个DAO的示例数据库配置:

@Entity
data class User(
    @PrimaryKey val uid: Int,
    @ColumnInfo(name = "first_name") val CheckListName: String?,
)
eufgjt7s

eufgjt7s4#

如果查询返回LiveData并且Kotlin版本高于以下版本,则在Room DAO中挂起不起作用:1.4.32
更多信息请参见此处:Link

wf82jlnq

wf82jlnq5#

只有改变你的乐趣到这一点:

@Insert(onConflict = OnConflictStrategy.REPLACE)

suspend fun insertName(name: CheckListName) : Long

相关问题