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

如何用Dagger 2为ViewPager中同Fragment实例注入独立ViewModel

问题根源分析

你的问题核心在于Dagger自定义作用域@MainScope和ViewModel的生命周期管理冲突了。

你给ActivityViewModel添加了@MainScope注解,这个作用域绑定在MainActivity的Dagger子组件上——这意味着Dagger会在MainActivity的生命周期内只创建一个ActivityViewModel实例,成为该子组件内的单例。哪怕你在ViewModelProviders.of(this, viewModelFactory).get(key, ActivityViewModel::class.java)里传入了不同的key,Dagger的creator.get()每次都会返回同一个实例,因为它被@MainScope限定成了单例,完全忽略了ViewModelStore的key机制。

这就导致两个Fragment拿到的是同一个ViewModel实例,它们的LiveData观察者自然会同时收到更新。

解决方案

1. 移除ActivityViewModel上的@MainScope注解

修改你的ActivityViewModelModule:

@Module
abstract class ActivityViewModelModule {
    // 移除@MainScope
    @Binds
    @IntoMap
    @ViewModelKey(ActivityViewModel::class)
    abstract fun bindActivityViewModel(viewModel: ActivityViewModel): ViewModel
}

这样一来,Dagger不再强制ActivityViewModel成为单例,每次调用creator.get()都会生成新的ViewModel实例。配合你传入的不同key,ViewModelStore会为每个Fragment维护独立的ViewModel实例,各自的LiveData更新就只会通知对应的观察者。

2. 确认ViewModel的获取方式

确保你在Fragment里是通过ViewModelProviders.of(this, viewModelFactory)获取ViewModel(而不是传入activity),这样ViewModel的生命周期会绑定到Fragment本身,加上不同的key,就能实现完全独立的实例。

为什么working_fine分支正常?

因为那个分支没有添加@MainScope,Dagger没有对ViewModel做单例限制,ViewModelProviders的key机制就能正常工作——每个不同的key对应不同的ViewModel实例,自然不会出现跨Fragment的LiveData同步更新问题。

额外提示

如果你需要在Activity和Fragment之间共享ViewModel,正确的做法是用ViewModelProviders.of(activity, viewModelFactory),利用Android架构组件自带的生命周期作用域,而不是依赖Dagger的自定义作用域。这样既符合Jetpack的设计规范,也能避免作用域冲突的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 13:09:10