使用 Flow 时 Android 房间查询为空

标签 android android-room android-livedata

我对使用 Flow 感到困惑与 Room用于数据库访问。我希望能够观察表格的变化,但也可以直接访问它。
但是,当使用返回 Flow 的查询时,结果似乎总是 null虽然 table 不是空的。返回 List 的查询直接,似乎工作。
有人可以解释差异或告诉我我可能错过了文档的哪一部分吗?

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        db_button.setOnClickListener {
            val user_dao = UserDatabase.getInstance(this).userDatabaseDao

            lifecycleScope.launch {
                user_dao.insertState(State(step=4))

                val states = user_dao.getAllState().asLiveData().value
                if (states == null || states.isEmpty()) {
                    println("null")
                } else {
                    val s = states.first().step
                    println("step $s")
                }

                val direct = user_dao.getStatesDirect().first().step
                println("direct step $direct")
            }
        }
    }
}
@Entity(tableName = "state")
data class State(
    @PrimaryKey(autoGenerate = true)
    var id: Int = 0,

    @ColumnInfo(name = "step")
    var step: Int = 0
)

@Dao
interface UserDatabaseDao {
    @Insert
    suspend fun insertState(state: State)

    @Query("SELECT * FROM state")
    fun getAllState(): Flow<List<State>>

    @Query("SELECT * FROM state")
    suspend fun getStatesDirect(): List<State>
}
输出:
I/System.out: null
I/System.out: direct step 1

最佳答案

Room , 我们使用 FlowLiveData观察查询结果的变化。所以Room查询db异步,当您尝试立即检索该值时,很可能会得到 null .
因此,如果您想立即获取值,则不应使用 Flow作为房间查询函数的返回类型,就像你在 getStatesDirect(): List<State> 上所做的一样.另一方面,如果你想观察数据变化,你应该使用 collect Flow 上的终端功能接收其排放:

lifecycleScope.launch {
    user_dao.insertState(State(step=4))

    val direct = user_dao.getStatesDirect().first().step
    println("direct step $direct")
}

lifecycleScope.launch {
    user_dao.getAllState().collect { states ->
        if (states == null || states.isEmpty()) {
            println("null")
        } else {
            val s = states.first().step
            println("step $s")
        }
    }
}

关于使用 Flow 时 Android 房间查询为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65539009/

相关文章:

android - 当 dao 设置为返回 Single<List<DummyObject>> 时,找不到符号返回 RxRoom.createSingle

java - Android:将房间数据库链接和同步到在线服务器数据库

android - 使用 LiveData 在 ImageView 上使用 DataBinding 时出现 IllegalArgumentException

android - 为什么我应该使用实时数据而不是 Observable?

android - 生成签名 APK 成功,但谷歌播放说它没有签名

android - 使用 mapbox 从地址获取经纬度

android - Android Room Persistence Library:处理错误

android - ViewModel中的LiveData类型不匹配

Android:使用 onCreateOptionsMenu 时出错,在父类(super class)中不可用?

Android ListView 在不滚动 ListView 的情况下将项目添加到顶部