笔友城堡 - 可定义的个人主页

前言

Kotlin协程是比较常用的,开发中经常会用到CoroutineScopelifecycleScopeviewModelScope,简单记录于此,方便自己查看和回顾。

正文

CoroutineScope

CoroutineScope用来管协程的“生死”,是 Kotlin 实现结构化并发的核心。

它不负责跑代码,只负责两件事:定边界、管取消,防止协程乱跑造成内存泄漏。

  • 本质:是个接口,里面只有一个 coroutineContext。真正创建 Scope 的是 CoroutineScope()这个函数。

  • 结构化并发:Scope 取消了,里面的协程全都会被取消;用 SupervisorJob还能避免一个子协程崩掉,把兄弟协程也带走。

  • 核心组成:必须有 Job(管生命周期),可选 Dispatcher(管线程)。

  • 定位:协程的“容器”,不干活,只负责管理。

定义在Application中
class App : Application() {
    val applicationScope: CoroutineScope by lazy {
        CoroutineScope(SupervisorJob() + Dispatchers.Default)
    }
}

使用:

val app = requireContext().applicationContext as App
app.applicationScope.launch {
    // 执行全局任务
}

说明:

  • lazy保证线程安全且仅初始化一次。

object 单例
object AppScope : CoroutineScope {

    override val coroutineContext =
        SupervisorJob() + Dispatchers.Default

    fun cancel(reason: String = "AppScope cancelled") {
        coroutineContext.cancel(CancellationException(reason))
    }
}

使用:

AppScope.launch {
    delay(1000)
    Log.d(TAG, "onResume 1 : delay 1000  " + Thread.currentThread().name)
}

AppScope.launch(Dispatchers.IO) {
    delay(1000)
    Log.d(TAG, "onResume 2 : delay 1000  " + Thread.currentThread().name)
}

AppScope.launch(Dispatchers.Main) {
    delay(1000)
    Log.d(TAG, "onResume 3 : delay 1000  " + Thread.currentThread().name)
}

日志打印:

onResume 1 : delay 1000  DefaultDispatcher-worker-3
onResume 2 : delay 1000  DefaultDispatcher-worker-2
onResume 3 : delay 1000  main

说明:

  • object在 JVM 中是饿汉式单例,类加载即初始化,适合轻量全局对象。

  • 默认使用 Dispatchers.Default,适合 CPU 密集型任务。

  • 全局唯一,调用简单,适合 SDK 或基础库使用。

object+lazy延迟初始化
object AppScope : CoroutineScope {
    override val coroutineContext by lazy {
        SupervisorJob() + Dispatchers.Default
    }

    fun cancel(reason: String = "AppScope cancelled") {
        coroutineContext.cancel(CancellationException(reason))
    }
}

说明:

  • 使用 lazy延迟创建 CoroutineContext,避免在类加载阶段过早初始化。

  • 重要:lazy默认线程安全。

  • 注意:一旦调用 cancel()coroutineContext将永久处于取消状态,后续再调用 launch会直接抛出异常。该方式适合“一次性”全局 Scope。

lifecycleScope组件级作用域

适用于 ActivityFragment,由 AndroidX 提供,生命周期与组件绑定。

lifecycleScope.launch {
    // 主线程
}

lifecycleScope.launch(Dispatchers.IO) {
    // IO 线程
}

lifecycleScope.launch(Dispatchers.Main) {
    // UI 线程
}

说明:

  • 自动在 onDestroy()时取消协程。

  • 不会产生 Activity / Fragment 内存泄漏。

  • UI 层协程的首选作用域。

viewModelScope

ViewModel中使用,随 ViewModel.clear()自动取消。

viewModelScope.launch {
    // ViewModel 内任务
}

小结

  • 全局任务:优先使用 object AppScope : CoroutineScope

  • UI 层任务:使用 lifecycleScope

  • ViewModel 任务:使用 viewModelScope

  • 避免使用 GlobalScope:生命周期不可控,容易造成泄漏

  • 全局 Scope 务必使用 SupervisorJob():避免单个子协程失败导致整体取消

参考文章

  1. Kotlin 官方文档 – CoroutineScope

  2. Android Developers – Structured Concurrency

  3. AI 辅助整理

相关文章

笔友城堡 - 可定义的个人主页

暂无评论

评论审核已启用。您的评论可能需要一段时间后才能被显示。

none
暂无评论...