Android 使用 Flow 时房间查询为空
Android room query is empty when using Flow
我对使用 Flow
和 Room
进行数据库访问感到困惑。我希望能够观察 table 的变化,但也可以直接访问它。
但是,当使用 returns a Flow
的查询时,结果似乎总是 null
尽管 table 不为空。 returns 直接 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
中,我们使用Flow
或LiveData
来观察查询结果的变化。因此 Room
异步查询 db
并且当您尝试立即检索值时,很可能得到 null
.
因此,如果你想立即得到值,你不应该使用 Flow
作为房间查询函数的 return 类型,就像你在 getStatesDirect(): List<State>
。另一方面,如果你想观察数据变化,你应该使用 Flow
上的 collect 终端函数来接收它的发射:
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
和 Room
进行数据库访问感到困惑。我希望能够观察 table 的变化,但也可以直接访问它。
但是,当使用 returns a Flow
的查询时,结果似乎总是 null
尽管 table 不为空。 returns 直接 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
中,我们使用Flow
或LiveData
来观察查询结果的变化。因此 Room
异步查询 db
并且当您尝试立即检索值时,很可能得到 null
.
因此,如果你想立即得到值,你不应该使用 Flow
作为房间查询函数的 return 类型,就像你在 getStatesDirect(): List<State>
。另一方面,如果你想观察数据变化,你应该使用 Flow
上的 collect 终端函数来接收它的发射:
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")
}
}
}