I was trying to provide a common DataStore<Preferences> so that the same preference file could be used in multiple places but I got the helpful error message:

找不到符号:DaggerMyApplication\u HiltComponents\u SingletonC.建筑商()

@Module
@InstallIn(ApplicationComponent::class)
object DataStoreModule {
    
    @Provides
    fun provideDataStore(@ApplicationContext context: Context): DataStore<Preferences> = context.createDataStore("settings")
}

I can however do the following and use it within an @Inject constructor.

@Singleton
class DataStoreProvider @Inject constructor(@ApplicationContext context: Context) {

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

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

推荐答案

This worked for me:

    @Provides
    @Singleton
    fun dataStore(@ApplicationContext appContext: Context): DataStore<Preferences> =
        appContext.createDataStore("settings")

The idea is putting @Singleton behind the provider method.


Update on Feb 9, 2021:
Preferably, create a manager and provide that:

class DataStoreManager(appContext: Context) {

    private val settingsDataStore = appContext.createDataStore("settings")

    suspend fun setThemeMode(mode: Int) {
        settingsDataStore.edit { settings ->
            settings[Settings.NIGHT_MODE] = mode
        }
    }

    val themeMode: Flow<Int> = settingsDataStore.data.map { preferences ->
        preferences[Settings.NIGHT_MODE] ?: AppCompatDelegate.MODE_NIGHT_UNSPECIFIED
    }

}

AppModule:

@InstallIn(SingletonComponent::class)
@Module
class AppModule {
    @Provides
    @Singleton
    fun dataStoreManager(@ApplicationContext appContext: Context): DataStoreManager =
        DataStoreManager(appContext)

Update on March 20, 2021:
Version 1.0.0-alpha07

private val Context.dataStore by preferencesDataStore("settings")

class DataStoreManager(appContext: Context) {

    private val settingsDataStore = appContext.dataStore

    suspend fun setThemeMode(mode: Int) {
        settingsDataStore.edit { settings ->
            settings[Settings.NIGHT_MODE] = mode
        }
    }

    val themeMode: Flow<Int> = settingsDataStore.data.map { preferences ->
        preferences[Settings.NIGHT_MODE] ?: AppCompatDelegate.MODE_NIGHT_UNSPECIFIED
    }
}

Update on May 1, 2021:

移除dataStoreManager个提供者.然后

private val Context.dataStore by preferencesDataStore("settings")

@Singleton //You can ignore this annotation as return `datastore` from `preferencesDataStore` is singletone
class DataStoreManager @Inject constructor(@ApplicationContext appContext: Context) {

    private val settingsDataStore = appContext.dataStore

    suspend fun setThemeMode(mode: Int) {
        settingsDataStore.edit { settings ->
            settings[Settings.NIGHT_MODE] = mode
        }
    }

    val themeMode: Flow<Int> = settingsDataStore.data.map { preferences ->
        preferences[Settings.NIGHT_MODE] ?: AppCompatDelegate.MODE_NIGHT_UNSPECIFIED
    }

}

Kotlin相关问答推荐

在KMP中使用koin将来自Android的上下文注入到SQLDelight Driver中

外键是主键的一部分,但不是索引的一部分.房间

Regex(Kotlin)仅匹配句子末尾的句号,而忽略中间的句号,如缩写

Android Jetpack编写androidx.compose.oundation.lazy.grid.Items

Kotlin stlib中是否有用于将列表<;对<;A,B&>;转换为对<;列表<;A&>,列表<;B&>;的函数

Kotlin 可空泛型

如何将 `throw` 放置在辅助函数中但仍然具有空安全性?

Kotlin 方法重载

如何创建 Kotlin DSL - DSL 语法 Kotlin

对列表中数字的子集求和

如何用 kotlin 打包 List

将 @Component.Builder 与构造函数参数一起使用

在 Kotlin 中实现 (/inherit/~extend) 注解

如何在 Kotlin 中传递有界通配符类型参数?

Android Studio 将 Java 转换为 Kotlin 错误无法推断此参数的类型

Kotlin协程无法处理异常

Android:Exoplayer - ExtractorMediaSource 已弃用

在 kotlin 中,如何将主构造函数中的属性设置器设为私有?

Kotlin flatMap - map

Android room DAO 接口不适用于继承