Kotlin协程(四)协程CoroutineScope作用域

1. CoroutineScope 是什么?

CoroutineScope 定义了协程的生命周期,它用于管理协程的启动、取消,并确保协程在 Scope 结束时自动取消,避免内存泄漏。

2. CoroutineScope 的使用方式

(1) 直接创建 CoroutineScope

val scope = CoroutineScope(Dispatchers.IO)  // 绑定 IO 线程

fun startTask() {
    scope.launch {
        println("运行在 ${Thread.currentThread().name}")  // IO 线程
        delay(2000)
        println("任务完成")
    }
}

🔹 优点:可以手动控制 scope.cancel() 来管理协程生命周期。

🔹 缺点:如果不手动取消,scope 可能导致内存泄漏。

(2) GlobalScope(全局作用域,不推荐)

fun test() {
    GlobalScope.launch {
        delay(1000)
        println("全局协程完成")
    }
}

 🔹 特性

  • 全局作用域,不会自动取消(除非应用进程终止)。
  • 适用于 App 全局任务(如日志、统计)。
  • ⚠️ 但不推荐用于普通任务,因为它可能导致内存泄漏!

(3) coroutineScope(挂起当前协程,推荐)

suspend fun test() {
    coroutineScope {
        launch {
            delay(1000)
            println("子协程完成")
        }
        println("coroutineScope 结束")  // 先输出
    }
}

🔹 特性

  • 不会阻塞线程,但会等待子协程完成再返回。
  • 适用于 suspend fun,不适用于 main 函数

3. CoroutineScope 的特性

特性CoroutineScope()GlobalScoperunBlockingcoroutineScope
作用域大小scope 限制全局当前线程当前协程
线程阻塞❌ 否❌ 否✅ 是❌ 否
自动取消✅ 是❌ 否✅ 是✅ 是
适用场景组件生命周期管理全局任务(慎用)测试suspend 函数

4. CoroutineScope 的生命周期管理

(1) 在 ViewModel 中使用

  • viewModelScope 自动绑定 ViewModel 生命周期,在 ViewModel 销毁时会自动取消协程。
class MyViewModel : ViewModel() {
    private val viewModelScope = ViewModelScope()  // Android 提供的作用域

    fun fetchData() {
        viewModelScope.launch {
            val data = withContext(Dispatchers.IO) { fetchFromNetwork() }
            println("数据获取完成: $data")
        }
    }
}

(2) 在 ActivityFragment 中使用

  • onDestroy() 时,job.cancel() 自动取消所有协程,避免泄漏。
class MyActivity : AppCompatActivity(), CoroutineScope {
    private val job = Job()
    override val coroutineContext = Dispatchers.Main + job  // 绑定主线程

    override fun onDestroy() {
        super.onDestroy()
        job.cancel()  // 取消所有协程
    }

    fun startTask() {
        launch {
            delay(1000)
            println("任务完成")
        }
    }
}

如果担心自己忘了取消job,推荐使用lifecycleScope

lifecycleScopeAndroidX Lifecycle 提供的 Lifecycle-aware(生命周期感知)协程作用域。它的 特点

  1. 自动取消协程,在 ActivityFragment 销毁 时,lifecycleScope自动取消所有未完成的协程,避免内存泄漏。
  2. 跟随生命周期lifecycleScope 的生命周期绑定到 LifecycleOwner(如 Activity、Fragment),任务会在 onDestroy() 时自动取消。
  3. 简洁,直接使用,不需要手动管理 Job,代码更清晰。
class MyActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }

    fun startTask() {
        lifecycleScope.launch {
            delay(1000)
            println("任务完成")
        }
    }
}

5. CoroutineScopeJob 的关系

  • CoroutineScope 需要 Job 来管理生命周期

  • CoroutineScope(Dispatchers.Main + Job()):可以手动取消所有协程。

  • scope.cancel() 取消所有子协程,防止任务泄漏。

val scope = CoroutineScope(Dispatchers.Main + Job())

fun startWork() {
    scope.launch {
        delay(2000)
        println("任务完成")
    }
}

fun cancelWork() {
    scope.cancel()  // 取消所有任务
}

6.supervisorScope

supervisorScope 函数用于创建一个使用了 SupervisorJob 的 coroutineScope,该作用域的特点就是抛出的异常不会连锁取消同级协程和父协程

fun main() = runBlocking {
    launch {
        delay(100)
        log("Task from runBlocking")
    }
    supervisorScope {
        launch {
            delay(500)
            log("Task throw Exception")
            throw Exception("failed")
        }
        launch {
            delay(600)
            log("Task from nested launch")
        }
    }
    log("Coroutine scope is over")
}


结果打印
[main] Task from runBlocking
[main] Task throw Exception
[main] Task from nested launch
[main] Coroutine scope is over

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

&岁月不待人&

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值