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

如何为不同界面状态配置对应ViewModel并传递登录生成的Token?

推荐实现方案(完全符合Hilt和Android架构规范)

1. 实现全局Token存储单例

先创建全局的会话管理类,用Hilt标记为单例,统一管理登录态和Token,所有模块都可以注入调用:

@Singleton
class AuthSession @Inject constructor() {
    // 用StateFlow存储Token,支持全局观察
    private val _token = MutableStateFlow<String?>(null)
    val token: StateFlow<String?> = _token.asStateFlow()

    // 登录成功后调用更新Token
    fun saveToken(newToken: String) {
        _token.value = newToken
        // 可同步写入SharedPreferences实现登录态持久化
    }

    // 退出登录时调用清空Token
    fun clearToken() {
        _token.value = null
        // 同步清空本地存储的登录信息
    }
}

AuthViewModel登录成功后直接调用authSession.saveToken(接口返回的Token)即可,不需要主动向其他业务模块传递Token。

2. 网络层自动注入Token

给OkHttp添加统一的请求拦截器,自动从AuthSession拿Token加到请求头,所有业务请求不需要单独处理Token逻辑:

@Singleton
class AuthInterceptor @Inject constructor(
    private val authSession: AuthSession
) : Interceptor {
    override fun intercept(chain: Interceptor.Chain): Response {
        val originRequest = chain.request()
        val token = authSession.token.value ?: return chain.proceed(originRequest)
        // 自动添加Authorization头
        val authedRequest = originRequest.newBuilder()
            .addHeader("Authorization", "Bearer $token")
            .build()
        return chain.proceed(authedRequest)
    }
}

把这个拦截器加到Hilt提供的OkHttpClient实例中,所有后端请求会自动携带登录态。

3. 路由逻辑优化

你原本的登录态控制路由逻辑可以直接保留,业务ViewModel不需要提前在Activity或者Scaffold中创建,在各自对应的业务页面用hiltViewModel()获取即可,完全符合Compose使用规范:

@ExperimentalComposeUiApi
@Composable
fun LoginState(vm: AuthViewModel = hiltViewModel(), nc: NavController) {
    val token by vm.token.collectAsState()
    when (token) {
        is Resource.Loading -> LoadingScreen()
        is Resource.Success -> {
            // 这里直接放主页面路由容器即可,子页面自行获取对应的ViewModel
            MainNavHost(navController = nc)
        }
        is Resource.Error -> LoginScreen(vm = vm)
    }
}

比如用户页面需要UserViewModel,直接在UserPage Composable内写val userVm: UserViewModel = hiltViewModel()即可,Hilt会自动完成注入。


原方案问题说明

  • 第一个方案的问题是误解了ViewModel的创建规则,不需要在Scaffold中统一创建所有ViewModel,每个业务页面单独获取自身所需的ViewModel就符合规范。
  • 第二个ViewModelManager的方案属于强耦合反模式,后续新增业务ViewModel就要修改MainActivity和ViewModelManager代码,维护成本极高,完全不需要采用。

内容的提问来源于stack exchange,提问作者mama

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 13:54:04