无法使用共享首选项存储库的柄/匕首解析应用程序上下文

问题描述 投票:0回答:0

尝试将共享首选项实现为单例,以将用户首选项存储在我的应用程序中。我已经在应用程序的各个地方实现了匕首和刀柄,但我对它的理解仍然很不稳定。

这是我的键值存储类


class KeyValueStore @Inject constructor(
    private val sharedPreferences: SharedPreferences
) {

    fun getString(key: SharedPreferenceKey) = sharedPreferences.getString(key.name, "")

    fun getBoolean(key: SharedPreferenceKey) = sharedPreferences.getBoolean((key.name), false)

    fun setString(vararg values: Pair <SharedPreferenceKey, String>) = sharedPreferences.edit{
        values.forEach { (key, value)  ->
            putString(key.name, value)
        }
    }

    fun setBoolean(vararg values: Pair <SharedPreferenceKey, Boolean>) = sharedPreferences.edit{
        values.forEach { (key, value)  ->
            putBoolean(key.name, value)
        }
    }

    fun clearValue(key: SharedPreferenceKey) = sharedPreferences.edit{
        remove(key.name)
    }

    fun clear() = sharedPreferences.edit{
        clear()
    }
}

然后在我的 appModule 中我尝试初始化单例

@Module
@InstallIn(SingletonComponent::class)
object AppModule {

    @Provides
    @Singleton
    fun sharedPreferences(@ApplicationContext context: Context): SharedPreferences{
        return sharedPreferences(context)
    }
}

这里还初始化了其他存储库,也用于我的数据访问(通过对象框),并且已经工作了一段时间,但我只是复制了与共享首选项相关的内容。

我尝试在我的主要活动中使用键值存储

@ExperimentalAnimationApi
@ExperimentalPagerApi
@AndroidEntryPoint
class MainActivity : ComponentActivity() {

    @Inject lateinit var splashViewModel: SplashViewModel
    @Inject lateinit var keyValueStore: KeyValueStore


    @RequiresApi(Build.VERSION_CODES.TIRAMISU)
    override fun onCreate(savedInstanceState: Bundle?) {

        var keepSplashOnScreen = true
        val delay = 1000L

        installSplashScreen().setKeepOnScreenCondition { keepSplashOnScreen }
        Handler(Looper.getMainLooper()).postDelayed({ keepSplashOnScreen = false }, delay)

        super.onCreate(savedInstanceState)

        initialiseApp()

        setContent {
            FL_DatatrackerTheme {
                val screen by splashViewModel.startDestination
                SetupNavGraph(startDestination = screen)
            }
        }
    }

    private fun initialiseApp(){
        if(!keyValueStore.getBoolean(SettingsKeys.ONBOARDING_COMPLETE)){
            keyValueStore.setBoolean(Pair(SettingsKeys.ONBOARDING_COMPLETE, false))
            keyValueStore.setString(Pair(SettingsKeys.CURRENT_PRESET, "Default"))
        }
    }
}

并尝试在视图模型的 SplashScreen 中使用 keyValueStore。此类处理我在第一个屏幕之前显示的入门部分。

class SplashViewModel @Inject constructor(
    private val keyValueStore: KeyValueStore
) : ViewModel() {

    private val _isLoading: MutableState<Boolean> = mutableStateOf(true)

    private val _startDestination: MutableState<String> = mutableStateOf(Screen.Welcome.route)
    val startDestination: State<String> = _startDestination

    init {
        viewModelScope.launch {
            if (keyValueStore.getBoolean(SettingsKeys.ONBOARDING_COMPLETE)) {
                _startDestination.value = Screen.HomeScreen.route
            } else {
                _startDestination.value = Screen.Welcome.route
            }
        }
        _isLoading.value = false
    }
}

一切看起来都不错并且可以构建,但随后我收到堆栈溢出错误

 E  FATAL EXCEPTION: main
Process: com.jorotayo.fl_datatracker, PID: 5186 java.lang.StackOverflowError: stack size 8188KB
at com.jorotayo.fl_datatracker.dependencyInjection.AppModule.sharedPreferences(Unknown Source:2)
at com.jorotayo.fl_datatracker.dependencyInjection.AppModule.sharedPreferences(AppModule.kt:131)

任何帮助将不胜感激

尝试过各种类型的共享首选项初始化,甚至尝试以不同的方式在应用程序上下文中检索。这是我得到的最远的结果,因为该应用程序实际上已构建。其他东西甚至无法构建

kotlin singleton sharedpreferences dagger-hilt
© www.soinside.com 2019 - 2024. All rights reserved.