[英]Android Room library with Kotlin Flow toList() doesn't work
我使用 Room 和 Flows 制作了一个简单的示例应用程序:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val build = Room.databaseBuilder(this, FinanceDatabase::class.java, "database.db")
.fallbackToDestructiveMigration()
.build()
GlobalScope.launch {
build.currencyDao().addCurrency(CurrencyLocalEntity(1))
val toList = build.currencyDao().getAllCurrencies().toList()
Log.d("test", "list - $toList")
}
}
}
@Entity(tableName = "currency")
data class CurrencyLocalEntity(
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "currencyId")
var id: Int
) {
constructor() : this(-1)
}
@Dao
interface CurrencyDao {
@Query("SELECT * FROM currency")
fun getAllCurrencies(): Flow<CurrencyLocalEntity>
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun addCurrency(currency: CurrencyLocalEntity)
}
@Database(entities = [CurrencyLocalEntity::class], version = 1)
abstract class FinanceDatabase : RoomDatabase() {
abstract fun currencyDao(): CurrencyDao
}
我想像上面的代码一样使用toList()
function,但是出了点问题,甚至 Log 也不打印。 同时使用collect()
工作正常并给我所有记录。
谁能向我解释哪里出了问题? 谢谢。
这里有一些问题,但我会解决主要问题。
每次修改数据库时,房间返回的Flow
都会发出查询结果。 (这可能仅限于表更改而不是整个数据库)。
由于数据库可以在未来的任何时候更改,因此Flow
将(或多或少)永远不会完成,因为更改总是会发生。
您对返回的Flow
的调用toList()
将永远挂起,因为Flow
永远不会完成。 这在概念上是有道理的,因为 Room 无法在不等待发生的情况下为您提供将要发生的所有更改的列表。 有了这个,我相信你知道为什么collect
给你记录而toList()
没有。
你可能想要的是这个。
@Query("SELECT * FROM currency")
fun getAllCurrencies(): Flow<List<CurrencyLocalEntity>>
有了这个,您可以使用Flow<...>.first()
获得查询的第一个结果。
Flow in Room 用于观察表格的变化。
每当对表进行任何更改时,无论更改了哪一行,都会重新触发查询,并且 Flow 将再次发出。
然而,数据库的这种行为也意味着如果我们更新一个不相关的行,我们的 Flow 将再次发出,结果相同。 因为 SQLite 数据库触发器只允许在表级别而不是在行级别进行通知,所以 Room 无法知道表数据中究竟发生了什么变化
确保您用于检索列表的相同 doa object 用于更新数据库。 除了使用 asLivedata 扩展 function 将流转换为 livedata 之外
对我来说,下面的解决方案适用于使用数据库表更改更新视图。
解决方案:我们向房间数据库中插入详细信息并从数据库中获取信息时,应使用相同的 Dao Object。
如果您使用的是匕首柄,那么
@Singleton 注释将起作用。
我希望这会解决你的问题。
**getAllCurrencies()** function should be suspend.
Please check the syntax to collect List from Flow:
suspend fun <T> Flow<T>.toList(
destination: MutableList<T> = ArrayList()
): List<T> (source)
https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/to-list.html
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.