android Jetpack数据存储@Inject需要初始化

kiz8lqtg  于 2023-02-14  发布在  Android
关注(0)|答案(1)|浏览(136)

我学习了本教程link
但是我遇到了一个问题,"kotlin.未初始化的属性访问异常:lateinit属性splashViewModel尚未初始化"这是我的代码

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

    @Provides
    @Singleton
    fun provideDataStoreRepository(
        @ApplicationContext context: Context
    ) = DataStoreRepository(context = context)
}
val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "on_boarding_pref")

class DataStoreRepository(context: Context) {

    private object PreferencesKey {
        val onBoardingKey = booleanPreferencesKey(name = "on_boarding_completed")
    }

    private val dataStore = context.dataStore

    suspend fun saveOnBoardingState(completed: Boolean) {
        dataStore.edit { preferences ->
            preferences[PreferencesKey.onBoardingKey] = completed
        }
    }

    fun readOnBoardingState(): Flow<Boolean> {
        return dataStore.data
            .catch { exception ->
                if (exception is IOException) {
                    emit(emptyPreferences())
                } else {
                    throw exception
                }
            }
            .map { preferences ->
                val onBoardingState = preferences[PreferencesKey.onBoardingKey] ?: false
                onBoardingState
            }
    }
}
class SplashViewModel @Inject constructor(
    private val repository: DataStoreRepository
) : ViewModel() {

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

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

    init {
        viewModelScope.launch {
            repository.readOnBoardingState().collect { completed ->
                if (completed) {
                    _startDestination.value = Screen.MainScreen.route
                } else {
                    _startDestination.value = Screen.OnboardingFirstScreen.route
                }
            }
            _isLoading.value = false
        }
    }

}

在我的主要活动中

class MainActivity : ComponentActivity() {

    @Inject
    lateinit var splashViewModel: SplashViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        installSplashScreen().setKeepOnScreenCondition {
            !splashViewModel.isLoading.value
        }

        setContent{
            BottomNavWithBadgesTheme {
                val screen by splashViewModel.startDestination
                ....
            }
        }

原来MainModule对象从来没有被使用过。这是问题吗?我是新的jetpack数据存储,我只是跟着它,所以我不知道问题在哪里,如何解决它。谢谢你提前。

nxowjjhe

nxowjjhe1#

首先,它不是关于数据存储,而是关于依赖注入。您试图在视图模型未初始化时从视图模型中获取数据。要解决这个问题:
1.使用**@HiltViewModel注解标记视图模型类
1.从MainActivity的视图模型中删除lateinit var关键字和@Inject注解
1.您的视图模型必须在
onCreate**函数中初始化,如下所示:

viewModel: SplashViewModel = hiltViewModel()

相关问题