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

如何确保使用同一ViewModel实例?Hilt与Activity实例冲突问题

解决ViewModel实例不一致的问题

原因分析

你当前代码里,MainActivity用viewModels<MainViewModel>()创建实例,Composable用hiltViewModel(),两者获取ViewModel的逻辑不匹配:

  • viewModels()是系统默认的ViewModel创建方式,未结合Hilt的依赖注入规则
  • hiltViewModel()是Hilt专为Composable提供的方法,会基于Hilt的作用域生成实例

这种差异导致两者拿到的不是同一个ViewModel,状态自然无法同步。

解决方案

方案1:Activity改用Hilt的hiltViewModels()获取实例

将MainActivity里的ViewModel获取逻辑替换为Hilt提供的扩展方法,就能和Composable中的实例保持一致:

class MainActivity : ComponentActivity() {
    // 替换为hiltViewModels()
    private val viewModel by hiltViewModels<MainViewModel>()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            if(viewModel.isActive()) {
                //Do stuff...
            } else {
                //Do other stuff...
            }
        }
    }
}

Composable代码无需修改,此时两者都会基于Activity的ViewModelStoreOwner生成同一个实例。

方案2:Composable中指定Activity作为ViewModelStoreOwner

如果不想修改Activity的代码,可以在Composable调用hiltViewModel()时,明确传入当前Activity作为ViewModel存储容器:

@Composable
fun ActivateScreen(
    // 指定Activity为ViewModelStoreOwner
    viewModel: MainViewModel = hiltViewModel(LocalContext.current as ComponentActivity)
) {
    Scaffold(
        topBar = { /*... */ },
        content = {
            UiContent(
                onClick = {
                    viewModel.activate()
                }
            )
        }
    )
}

这样Composable的ViewModel会和Activity中viewModels()创建的实例共享存储容器,保证是同一个实例。

额外注意事项

  • 确保MainViewModel已正确配置Hilt注解:
@HiltViewModel
class MainViewModel @Inject constructor(
    // 按需添加依赖注入参数
) : ViewModel() {
    fun activate() { /*...*/ }
    fun isActive(): Boolean { /*...*/ }
}
  • 确认App已完成Hilt基础配置:Application添加@HiltAndroidApp注解,Activity添加@AndroidEntryPoint注解

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 22:50:41