首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用Hilt提供首选项数据存储

使用Hilt提供首选项数据存储
EN

Stack Overflow用户
提问于 2020-12-11 13:47:16
回答 3查看 7.8K关注 0票数 22

我试图提供一个通用的DataStore<Preferences>,以便可以在多个地方使用相同的首选项文件,但是我得到了有用的错误消息:

找不到符号: DaggerMyApplication_HiltComponents_SingletonC.builder()

代码语言:javascript
运行
复制
@Module
@InstallIn(ApplicationComponent::class)
object DataStoreModule {
    
    @Provides
    fun provideDataStore(@ApplicationContext context: Context): DataStore<Preferences> = context.createDataStore("settings")
}

不过,我可以执行以下操作,并在@Inject构造函数中使用它。

代码语言:javascript
运行
复制
@Singleton
class DataStoreProvider @Inject constructor(@ApplicationContext context: Context) {

    val dataStore: DataStore<Preferences> = context.createDataStore("settings")
}

我假设扩展createDataStore正在做一些希尔特不喜欢的事情,但我希望能解释一下发生了什么,即使问题无法解决。

EN

Stack Overflow用户

发布于 2021-06-11 08:48:59

我在Hilt中使用了DataStore<Preferences>,如下所示。

PersistenceModule.kt

代码语言:javascript
运行
复制
@Module
@InstallIn(SingletonComponent::class)
object PersistenceModule {

    @Provides
    @Singleton
    fun provideDataStoreManager(@ApplicationContext context: Context): DataStoreManager {
        return DataStoreManager(context)
    }
}

DataStoreManager.kt

代码语言:javascript
运行
复制
class DataStoreManager @Inject constructor(@ApplicationContext private val context: Context) {

    private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(STORE_NAME)

    private suspend fun <T> DataStore<Preferences>.getFromLocalStorage(
        PreferencesKey: Preferences.Key<T>, func: T.() -> Unit) {
        data.catch {
            if (it is IOException) {
                emit(emptyPreferences())
            } else {
                throw it
            }
        }.map {
            it[PreferencesKey]
        }.collect {
            it?.let { func.invoke(it as T) }
        }
    }

    suspend fun <T> storeValue(key: Preferences.Key<T>, value: T) {
        context.dataStore.edit {
            it[key] = value
        }
    }

    suspend fun <T> readValue(key: Preferences.Key<T>, responseFunc: T.() -> Unit) {
        context.dataStore.getFromLocalStorage(key) {
            responseFunc.invoke(this)
        }
    }
}

ViewModel.kt

代码语言:javascript
运行
复制
@HiltViewModel
class HomeViewModel @Inject constructor(
    private val dataStore: DataStoreManager
) : LiveCoroutinesViewModel() {

    fun readNextReviewTime() {
        viewModelScope.launch {
            dataStore.readValue(nextReviewTime) {
                // Here you can do something with value.
            }
        }
    }
}

更新

代码语言:javascript
运行
复制
@HiltViewModel
class TranslateViewModel @Inject constructor(
    definitionRepository: DefinitionRepository,
    translateRepository: TranslateRepository,
    val dataStoreManager: DataStoreManager
) : LiveCoroutinesViewModel() {

    init {
        readValueInViewModelScope(sourceLanguage, "ta") { // use value here }
        readValueInViewModelScope(targetLanguage, "si") { // use value here }
    }

    private fun <T> readValueInViewModelScope(key: Preferences.Key<T>, defaultValue: T, onCompleted: T.() -> Unit) {
        viewModelScope.launch {
            dataStoreManager.readValue(key) {
                if (this == null) {
                    storeValueInViewModelScope(key, defaultValue)
                } else {
                    onCompleted.invoke(this)
                }
            }
        }
    }

    fun <T> storeValueInViewModelScope(key: Preferences.Key<T>, value: T) {
        viewModelScope.launch {
            dataStoreManager.storeValue(key, value)
        }
    }
}
票数 6
EN
查看全部 3 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65252533

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档