为什么 Android Datastore 在运行阻塞时总是返回相同的值

Umu*_*kin 3 android kotlin kotlin-coroutines android-jetpack-datastore

我已经使用数据存储很长时间了。今天我必须读取主线程中的值。查看文档后,我决定使用runblocking。我创建了一个长值,其名称为lastInsertedId。

我在片段 A 中读取了lastInsertedId,然后导航到片段B,并且我正在更改lastInsertedId 的值。当我回到片段 A 时,我再次阅读了lastInsertedId。但lastInsertedId的值仍然相同。实际上它的值正在改变,但我无法读取它的最后一个值。

我认为这是因为碎片A没有被破坏。只有 onDestroyView 是从 onCreateView 调用并创建的。我想要的是只要我想在主线程中访问lastInsertedID 的当前值。

当我将其创建为变量时,它总是返回相同的值。但当我将它转换为函数时,它运行良好。但我不认为这是最佳实践。访问此值的最佳方式是什么?谢谢。

private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "main")

@Singleton
class DataStoreManager @Inject constructor(@ApplicationContext appContext: Context) {

    private val mainDataStore = appContext.dataStore

    suspend fun setLastInsertedId(lastId: Long) {
        mainDataStore.edit { main ->
            main[LAST_INSERTED_ID] = lastId
        }
    }

    // Returns always the same value
    val lastInsertedId: Long = runBlocking {
        mainDataStore.data.map { preferences ->
            preferences[LAST_INSERTED_ID] ?: 0
        }.first()
    }

    // Returns as expected
    fun lastInsertedId(): Long = runBlocking {
        mainDataStore.data.map { preferences ->
            preferences[LAST_INSERTED_ID] ?: 0
        }.first()
    }

    // This is also work perfectly but i need to access in main thread.
    val lastInsertedId : Flow<Long> =  mainDataStore.data.map { preferences ->
        preferences[LAST_INSERTED_ID] ?: Constants.DEFAULT_FOOD_ID
    }

    companion object {
        private val LAST_INSERTED_ID = longPreferencesKey("last_inserted_id")
    }
}
Run Code Online (Sandbox Code Playgroud)

小智 6

get()必须像这样添加到您的 val 定义中。

val lastInsertedId: Long get() = runBlocking {
    mainDataStore.data.map { preferences ->
        preferences[LAST_INSERTED_ID] ?: 0
    }.first()
}
Run Code Online (Sandbox Code Playgroud)