如何在协程中从 Room 获取 Cursor?

问题描述 投票:0回答:1

尝试获取此光标:

@Query("SELECT * FROM category")
fun getCursor() : Cursor

使用此代码:

        lifecycleScope.launch {
            binding.category.adapter = SimpleCursorAdapter(
                context,
                android.R.layout.simple_spinner_dropdown_item,
                RoomDB.getInstance(context).categories().getCursor(),
                arrayOf("label"),
                arrayOf(android.R.id.text1).toIntArray(),
                CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER
            )
        }

这会产生此异常:

java.lang.IllegalStateException:无法在主线程上访问数据库...

显然,我没有从主线程访问数据库(注意

lifecycleScope.launch
)。也许我必须让
getCursor
暂停?

很简单,但这会产生奇怪的编译时错误:

实体和 POJO 必须有一个可用的公共构造函数。您可以有一个空构造函数,也可以有一个参数与字段匹配(按名称和类型)的构造函数。 - android.database.Cursor

错误:不确定如何将 Cursor 转换为此方法的返回类型(android.database.Cursor)。

公共抽象 java.lang.Object getCursor(@org.jetbrains.annotations.NotNull()

这是怎么回事?

android kotlin-coroutines android-cursor simplecursoradapter android-cursoradapter
1个回答
0
投票

lifecycleScope.launch
不会将您置于 IO 线程中,此时您只是处于协程范围内,但位于主线程上

创建一个在 IO 上下文中运行查询的单独方法

suspend fun getData(): Cursor = withContext(Dispatchers.IO){
    return RoomDB.getInstance(context).categories().getCursor()
}

lifecycleScope.launch {
    val cursor = getData()
        binding.category.adapter = SimpleCursorAdapter(
            context,
            android.R.layout.simple_spinner_dropdown_item,
            cursor,
            arrayOf("label"),
            arrayOf(android.R.id.text1).toIntArray(),
            CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER
        )
    }
© www.soinside.com 2019 - 2024. All rights reserved.