简体   繁体   English

如何在非挂起状态下从 DataStore 返回值 function

[英]How to return value from DataStore in non-suspend function

I was saving app language in shared preferences and set the app language by overriding attachBaseContext() in activity like the following:我在共享首选项中保存应用程序语言,并通过覆盖活动中的attachBaseContext()来设置应用程序语言,如下所示:

    override fun attachBaseContext(base: Context) {
    
       val language: String = sharedPreferences.language

       super.attachBaseContext(wrapContext(base, language))
    }

where wrapContext() is a function change the language based on its parameter value.其中wrapContext()是 function 根据其参数值更改语言。

after migration to DataStore, I can't return the language in attachBaseContext() since it's not suspend function, and language become a flow (should collect inside a suspend function)迁移到 DataStore 后,我无法返回attachBaseContext()中的语言,因为它没有挂起 function,并且语言成为一个流(应该在挂起函数内收集)

How can I solve this problem?我怎么解决这个问题?

DataStore is asynchronous API for writing and reading small amounts of data. DataStore 是异步的 API 用于写入和读取少量数据。 To read data synchronously you need to use runBlocking coroutine builder. 要同步读取数据,您需要使用runBlocking协程构建器。 This will block the calling thread until DataStore returns that can lead to ANRs :这将阻塞调用线程,直到 DataStore 返回可能导致ANR

val syncData = runBlocking { context.dataStore.data.first() } // or { context.dataStore.data.firstOrNull() }

It is a good chance to think about how you can use DataStore asynchronously without runBlocking , maybe do some refactoring.这是一个很好的机会,可以考虑如何在不使用runBlocking的情况下异步使用 DataStore,或许可以进行一些重构。

If you decide to use runBlocking you need to think about reasonable timeout to not freeze UI forever:如果您决定使用runBlocking ,您需要考虑合理的超时时间,以免永远冻结 UI:

val syncData = runBlocking { 
    withTimeoutOrNull(2000) { // UI can freeze for 2 seconds
        context.dataStore.data.first()
    }
} 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM