Kotlin协程上下文安全

Quinn942 +0/-0 0 0 正常 2025-12-24T07:01:19 Android开发 · Jetpack组件 · Kotlin协程

Kotlin协程上下文安全踩坑记录

最近在开发一个Android应用时,遇到了一个令人头疼的协程上下文安全问题。项目使用了Jetpack组件,包括ViewModel和LiveData,一切都看起来很完美。

问题复现

在ViewModel中定义了一个协程作用域:

class MyViewModel : ViewModel() {
    private val viewModelScope = CoroutineScope(Dispatchers.Main)
    
    fun fetchData() {
        viewModelScope.launch {
            // 模拟网络请求
            val data = withContext(Dispatchers.IO) { 
                fetchFromNetwork() 
            }
            // 更新UI
            updateUI(data)
        }
    }
}

看似正常的代码,但在某些情况下出现了内存泄漏。经过排查发现,当Activity被销毁后,协程仍在后台执行,试图更新已经销毁的UI组件。

根本原因

问题出在我们手动创建了CoroutineScope而没有正确管理其生命周期。虽然使用了Dispatchers.Main,但当ViewModel被回收时,协程并不会自动取消。

解决方案

正确的做法是使用viewModelScope

class MyViewModel : ViewModel() {
    fun fetchData() {
        viewModelScope.launch {
            val data = withContext(Dispatchers.IO) { 
                fetchFromNetwork() 
            }
            updateUI(data)
        }
    }
}

viewModelScope会自动与ViewModel的生命周期绑定,在ViewModel销毁时自动取消所有协程。

重要提醒

  1. 永远不要手动创建CoroutineScope,除非你明确知道如何管理其生命周期
  2. 使用Jetpack组件提供的作用域viewModelScopelifecycleScope
  3. 注意Context切换:在IO线程执行耗时操作后,记得切回主线程更新UI

这个坑踩得真是血泪史,希望大家引以为戒!

推广
广告位招租

讨论

0/2000