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

Android ViewModel使用Context引发内存泄漏警告的解决咨询

解决方案

1. 改用AndroidViewModel消除Context泄漏

ViewModel禁止持有Activity/Fragment级别的Context,改用AndroidViewModel(继承自ViewModel并持有全局Application Context),无需手动传入Context即可获取缓存目录:

class ImageLoader(private val url: URL?) : AndroidViewModel(Application()) {

    val image = MutableStateFlow<ImageBitmap?>(null)    
    // 通过Application直接获取缓存目录,无需外部传参
    private val imageCacheDir: File get() = getApplication<Application>().cacheDir

    init {
        // 使用ViewModel自带的viewModelScope,ViewModel销毁时自动取消协程
        viewModelScope.launch(Dispatchers.IO) {
            loadImage()
        }
    }

    private suspend fun loadImage() {
        // 这里用imageCacheDir处理缓存读取/写入逻辑
        // ...从缓存读取或网络下载的代码
    }
}

2. 正确获取ViewModel实例

不要用remember创建ViewModel,改用Jetpack提供的viewModel()函数——它会自动管理ViewModel的生命周期(配置变化时不会重建),通过自定义Factory传入URL参数:

@Composable
fun YourComposable(event: YourEvent) {
    val imageLoader = viewModel<ImageLoader>(
        factory = object : ViewModelProvider.Factory {
            override fun <T : ViewModel> create(modelClass: Class<T>): T {
                return ImageLoader(event.imageUrl) as T
            }
        }
    )
    val image = imageLoader.image.collectAsState()

    // 后续使用image.value展示图片
}

关键改进说明

  • 彻底解决泄漏警告:AndroidViewModel持有的是全局Application Context,生命周期与应用一致,不会绑定到Activity/Fragment的生命周期。
  • 协程安全:viewModelScope会在ViewModel销毁时自动取消所有后台协程,避免无效任务占用资源。
  • 符合架构规范:用viewModel()获取实例,遵循Jetpack ViewModel的生命周期规则,旋转屏幕等配置变化时图片加载状态不会丢失。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 07:27:38