You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 15:06:16