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

带参数的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 21:36:03