【发布时间】:2022-01-18 12:31:33
【问题描述】:
我正在使用 jetpack compose 从共享偏好迁移到数据存储。一切正常(数据已保存并可成功撤回)。但是,每当检索到数据时,可组合项就会不断地重新组合。我正在使用 MVVM 架构,下面是我实现数据存储的方式。
下面是在我的 AppModule.kt 中声明的
SingletonComponent 中的应用模块
@Provides
@Singleton
fun provideUserPreferenceRepository(@ApplicationContext context: Context):
UserPreferencesRepository = UserPreferencesRepositoryImpl(context)
这是我的 ViewModel:
@HiltViewModel
class StoredUserViewModel @Inject constructor(
private val _getUserDataUseCase: GetUserDataUseCase
): ViewModel() {
private val _state = mutableStateOf(UserState())
val state: State<UserState> = _state
fun getUser(){
_getUserDataUseCase().onEach { result ->
val name = result.name
val token = result.api_token
val balance = result.balance
val agentCode = result.agent_code
_state.value = UserState(user = UserPreferences(name, agentCode, token, balance))
}.launchIn(viewModelScope)
}}
最后,这是我的存储库实现:
class UserPreferencesRepositoryImpl @Inject constructor(
private val context: Context
): UserPreferencesRepository {
private val Context.dataStore by preferencesDataStore(name = "user_preferences")
}
private object Keys {
val fullName = stringPreferencesKey("full_name")
val api_token = stringPreferencesKey("api_token")
val balance = intPreferencesKey("balance")
val agentCode = intPreferencesKey("agent_code")
}
private inline val Preferences.fullName get() = this[Keys.fullName] ?: ""
private inline val Preferences.apiToken get() = this[Keys.api_token] ?: ""
private inline val Preferences.balance get() = this[Keys.balance] ?: 0
private inline val Preferences.agentCode get() = this[Keys.agentCode] ?: 0
override val userPreferences: Flow<UserPreferences> = context.dataStore.data.catch{
// throws an IOException when an error is encountered when reading data
if (it is IOException) {
emit(emptyPreferences())
} else {
throw it
}
}.map { preferences ->
UserPreferences(name = preferences.fullName, agent_code = preferences.agentCode, api_token = preferences.apiToken,
balance = preferences.balance)
}.distinctUntilChanged()
我不知道是什么导致可组合物重新组合。下面是可组合的:
@Composable
fun LoginScreen(
navController: NavController,
userViewModel: StoredUserViewModel = hiltViewModel()
) {
Log.v("LOGIN_SCREEN", "CALLED!")
userViewModel.getUser()
}
如果有人能告诉我哪里做错了,请赐教。我试图在 AppModule 中更改 UserPreferencesRepository 的实现,但没有成功。
下面是 UseState.kt,它只是一个数据类
data class UserState(
val user: UserPreferences? = null
)
下面是 UserPreferences.kt
data class UserPreferences(val name: String, val agent_code: Int, val api_token: String, val balance: Int)
【问题讨论】:
-
你从来没有发过
UserState所以我们不知道 -
@EpicPandaForce 我已经为 UserState 添加了代码,这只是一个数据类
-
好的,现在我们需要
UserPreferences:D -
它也是一个数据类,我已经编辑了问题并包含了它。 @EpicPandaForce
-
我猜,也许使用
stateIn来处理您的流程
标签: android dagger-2 android-jetpack-compose android-jetpack dagger-hilt