带有 Kotlin Flow toList() 的 Android Room 库不起作用

Rus*_*nko 4 android android-room kotlin-coroutines kotlin-flow

我使用 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
}
Run Code Online (Sandbox Code Playgroud)

我想使用toList()上面代码中的函数,但出了点问题,甚至日志也不打印。同时使用collect()效果很好,并给了我所有的记录。

任何人都可以向我解释什么是错的?谢谢。

Dom*_*her 5

这里有一些问题,但我将解决主要问题。

Flow每次修改数据库时, room 返回的 s 都会发出查询结果。(这可能仅限于表更改而不是整个数据库)。

由于数据库可以在未来的任何时候更改,因此Flow(或多或少)永远不会完成,因为更改总是可能发生。

toList()对返回的调用Flow将永远暂停,因为Flow永远不会完成。这在概念上是有道理的,因为 Room 无法在不等待它发生的情况下为您提供将发生的每个更改的列表。有了这个,我相信你知道为什么collect给你记录而toList()没有。

你可能想要的是这个。

@Query("SELECT * FROM currency")
fun getAllCurrencies(): Flow<List<CurrencyLocalEntity>>
Run Code Online (Sandbox Code Playgroud)

有了这个,您可以获得查询的第一个结果Flow<...>.first()