屏幕重建时崩溃:HomeViewModel无无参构造函数依赖注入问题
问题解决步骤
核心原因
屏幕重建时,系统默认的ViewModelProvider会尝试通过无参构造创建HomeViewModel,但你的类只有带参构造,导致崩溃。如果随便换获取方式(比如直接实例化),又会因为每次重建都生成新实例,丢失原有的observeParentViewModel逻辑关联。
具体解决方案
1. 自定义ViewModel工厂类(结合Dagger)
创建一个HomeViewModelFactory,实现ViewModelProvider.Factory,让Dagger注入ViewModel所需的依赖,确保每次创建实例时都能正确传入参数:
class HomeViewModelFactory @Inject constructor( private val homeRepository: HomeRepository, // 这里添加HomeViewModel构造需要的其他依赖 ) : ViewModelProvider.Factory { override fun <T : ViewModel> create(modelClass: Class<T>): T { require(modelClass.isAssignableFrom(HomeViewModel::class.java)) { "不支持创建${modelClass.name}类型的ViewModel" } @Suppress("UNCHECKED_CAST") return HomeViewModel(homeRepository) as T } }
2. 在Dagger组件中暴露工厂类
修改你的AppComponent(或者对应Scope的组件),添加工厂类的提供方法:
@Component(modules = [/*你的Dagger模块*/]) interface AppComponent { fun homeViewModelFactory(): HomeViewModelFactory // 其他已有的注入方法 }
3. 在页面中正确获取ViewModel实例
在HomeActivity或HomeFragment中,使用viewModels()委托结合自定义工厂获取ViewModel,这样配置变更时系统会自动复用原有实例:
// 以Activity为例 class HomeActivity : AppCompatActivity() { private val viewModel: HomeViewModel by viewModels { // 从Application中获取Dagger组件,再拿到工厂 (application as YourApp).appComponent.homeViewModelFactory() } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 这里正常初始化页面,ViewModel是复用的,observeParentViewModel逻辑会保持生效 viewModel.observeParentViewModel() } }
4. 确保observe逻辑的稳定性
检查HomeViewModel中的observeParentViewModel方法,确保它是在ViewModel的init块中执行,或者在页面初始化时主动调用,避免依赖页面的临时状态。如果该逻辑依赖LiveData/Flow,确保这些可观察对象是ViewModel的成员变量,这样重建后依然能保持订阅关系。
内容的提问来源于stack exchange,提问作者Elano Vasconcelos
相关产品推荐
相关产品推荐

