带参数的AndroidViewModel未用Factory实例化运行正常,是否存在潜在问题?
你的代码能正常运行的原因
你当前的实现本质上没有通过Jetpack组件提供的ViewModelProvider获取ViewModel实例,而是直接调用构造方法实例化了一个普通的Kotlin类对象,只要参数传递正确自然可以正常运行,相当于你只是把业务逻辑封装到了命名为ViewModel的类里,完全没有用到Jetpack ViewModel的生命周期管理能力。
该实现存在的明确弊端
- 完全丢失ViewModel的核心优势:Jetpack ViewModel的核心作用是在配置变更(屏幕旋转、系统语言切换、深色模式切换等)导致页面重建时,保留已存在的ViewModel实例,避免重复加载数据、丢失页面状态。你自己构造的ViewModel实例会在每次Fragment重建时重新生成,已经加载的
itemList数据、存储在_singleItem中的状态都会全部丢失。 - 存在协程泄漏风险:如果你后续需要用到ViewModel自带的
viewModelScope调度协程任务,自行构造的ViewModel实例无法正常关联页面生命周期,页面销毁时协程不会自动取消,会持续占用内存,甚至引发空指针崩溃。 - 后续扩展维护成本极高:如果之后需要新增ViewModel依赖参数,或者适配Hilt、Koin等依赖注入框架,这种硬编码构造的方式完全不符合框架规范,需要全部重构才能适配。
符合规范的实现参考
首先实现自定义ViewModel Factory:
class MyListViewModelFactory( private val application: Application, private val currentItemName: String ) : ViewModelProvider.Factory { @Suppress("UNCHECKED_CAST") override fun <T : ViewModel> create(modelClass: Class<T>): T { if (modelClass.isAssignableFrom(MyListViewModel::class.java)) { return MyListViewModel(application, currentItemName) as T } throw IllegalArgumentException("Unknown ViewModel class") } }
修改Fragment中ViewModel的获取逻辑:
val currentItemName = "some item name" val binding = FragmentItemsListBinding.inflate(inflater) val application = requireNotNull(this.activity).application // 通过ViewModelProvider获取实例,享受生命周期缓存能力 val viewModel = ViewModelProvider( this, MyListViewModelFactory(application, currentItemName) )[MyListViewModel::class.java] binding.lifecycleOwner = this binding.viewModel = viewModel
内容的提问来源于stack exchange,提问作者brandNoob
相关产品推荐
相关产品推荐

