如何在ViewModel中实现DataStore读写及Retrofit请求处理?
在ViewModel中实现DataStore偏好设置的读写功能
1. 抽离全局DataStore配置与偏好键
先把通用的DataStore扩展和偏好键单独抽出来,方便多处复用:
// 可放在单独的文件比如DataStoreConfig.kt中 val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "settings") object PreferenceKeys { val ACCOUNT_TYPE = stringPreferencesKey("account_type") }
2. 编写包含DataStore逻辑的ViewModel
使用AndroidViewModel(而非普通ViewModel)来安全获取Application上下文,避免内存泄漏,同时实现读写方法:
class SettingsViewModel(application: Application) : AndroidViewModel(application) { private val dataStore = application.dataStore // 暴露供UI观察的账户类型Flow val accountTypeFlow: Flow<String> = dataStore.data .map { preferences -> preferences[PreferenceKeys.ACCOUNT_TYPE] ?: "" } // 写入账户类型的挂起函数 suspend fun saveAccountType(accountType: String) { dataStore.edit { preferences -> preferences[PreferenceKeys.ACCOUNT_TYPE] = accountType } } }
3. 在Composable中访问ViewModel数据
通过viewModel()获取实例,用collectAsState()将Flow转换为Composable可感知的状态:
@Composable fun SettingsScreen() { val settingsViewModel: SettingsViewModel = viewModel() val accountType by settingsViewModel.accountTypeFlow.collectAsState(initial = "") Column(modifier = Modifier.padding(16.dp)) { Text(text = "当前账户类型:$accountType") Button( onClick = { LaunchedEffect(Unit) { settingsViewModel.saveAccountType("VIP") } } ) { Text("设置为VIP账户") } } }
核心注意事项
- 必须用
AndroidViewModel获取Application上下文,防止Activity/Fragment销毁时引发内存泄漏 - DataStore的读写都是挂起函数,UI层需通过
LaunchedEffect或rememberCoroutineScope调用,不能直接在主线程执行 collectAsState()会自动监听Flow变化,数据更新时UI会自动重组
内容的提问来源于stack exchange,提问作者mfusco
相关产品推荐
相关产品推荐

