
协程取消 :
创建 协程作用域 CoroutineScope 实例对象 , 传入 调度器 :
// 创建协程作用域
val coroutineScope = CoroutineScope(Dispatchers.Default)调用 协程作用域的 CoroutineScope#launch 方法 , 可以创建一个子协程 ;
val job0 = coroutineScope.launch {
Log.i(TAG, "job0 子协程执行开始")
delay(2000)
Log.i(TAG, "job0 子协程执行完毕")
}完整代码示例 :
package kim.hsl.coroutine
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import kotlinx.coroutines.*
class MainActivity : AppCompatActivity(){
val TAG = "MainActivity"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
runBlocking {
// 创建协程作用域
val coroutineScope = CoroutineScope(Dispatchers.Default)
val job0 = coroutineScope.launch {
Log.i(TAG, "job0 子协程执行开始")
delay(2000)
Log.i(TAG, "job0 子协程执行完毕")
}
val job1 = coroutineScope.launch {
Log.i(TAG, "job1 子协程执行开始")
delay(2000)
Log.i(TAG, "job1 子协程执行完毕")
}
// 100ms 后取消协程作用域
delay(100)
// 取消协程作用域
coroutineScope.cancel()
}
}
}执行结果 : 取消 coroutineScope 协程作用域之后 , 该作用域下的 job0 和 job1 子协程都被取消了 , 两个子协程都没有执行完毕 ;
10:33:33.468 I job0 子协程执行开始
10:33:33.471 I job1 子协程执行开始
如果不取消协程作用域 , 应该打印如下内容 :
10:31:49.880 I job0 子协程执行开始
10:31:49.886 I job1 子协程执行开始
10:31:51.937 I job1 子协程执行完毕
10:31:51.938 I job0 子协程执行完毕单独取消 协程作用域 中的 子协程 , 协程作用域 中的其它 兄弟协程不受影响 ;
package kim.hsl.coroutine
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import kotlinx.coroutines.*
class MainActivity : AppCompatActivity(){
val TAG = "MainActivity"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
runBlocking {
// 创建协程作用域
val coroutineScope = CoroutineScope(Dispatchers.Default)
val job0 = coroutineScope.launch {
Log.i(TAG, "job0 子协程执行开始")
delay(2000)
Log.i(TAG, "job0 子协程执行完毕")
}
val job1 = coroutineScope.launch {
Log.i(TAG, "job1 子协程执行开始")
delay(2000)
Log.i(TAG, "job1 子协程执行完毕")
}
// 100ms 后取消协程作用域
delay(100)
// 取消协程作用域中的子协程
job1.cancel()
}
}
}执行结果 : 在 协程作用域 coroutineScope 中 启动了 job0 和 job1 两个协程 , 取消了 job1 协程 , job1 协程没有执行完毕 , job0 协程执行完毕 ;

调用 Job#cancel 函数 , 取消协程操作 , 该函数原型如下 :
/**
* 使用可选的取消[原因]取消此作业。
* 原因可用于指定错误消息或提供关于的其他详细信息
* 为调试目的而取消的原因。
* 有关取消机制的完整解释,请参阅[Job]文档。
*/
public fun cancel(cause: CancellationException? = null)取消协程时 , 可以传入一个 CancellationException 异常实例对象 , 也可以不传 , 默认为 null ;
// 取消协程作用域中的子协程
job1.cancel()也可以传入一个 自定义 CancellationException 类型的异常 , 取消协程 ;
// 取消协程作用域中的子协程
job1.cancel(CancellationException("自定义 CancellationException 异常"))由于报出的 CancellationException 异常是正常情况 , 如果需要查看该异常 , 需要在协程中使用 try catch 代码块捕获该异常 ;
val job1 = coroutineScope.launch {
try {
Log.i(TAG, "job1 子协程执行开始")
delay(2000)
Log.i(TAG, "job1 子协程执行完毕")
}catch (e: Exception) {
Log.i(TAG, "job1 子协程执行捕获到异常 :")
e.printStackTrace()
}
}完整代码示例 :
package kim.hsl.coroutine
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import kotlinx.coroutines.*
class MainActivity : AppCompatActivity(){
val TAG = "MainActivity"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
runBlocking {
// 创建协程作用域
val coroutineScope = CoroutineScope(Dispatchers.Default)
val job1 = coroutineScope.launch {
try {
Log.i(TAG, "job1 子协程执行开始")
delay(2000)
Log.i(TAG, "job1 子协程执行完毕")
}catch (e: Exception) {
Log.i(TAG, "job1 子协程执行捕获到异常 :")
e.printStackTrace()
}
}
// 100ms 后取消协程作用域
delay(100)
// 取消协程作用域中的子协程
job1.cancel()
}
}
}执行结果 :
16:43:17.637 I job1 子协程执行开始
16:43:17.787 I job1 子协程执行捕获到异常 :
16:43:17.790 W kotlinx.coroutines.JobCancellationException: StandaloneCoroutine was cancelled; job=StandaloneCoroutine{Cancelling}@bc6a601
传入自定义异常代码示例 :
package kim.hsl.coroutine
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import kotlinx.coroutines.*
class MainActivity : AppCompatActivity(){
val TAG = "MainActivity"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
runBlocking {
// 创建协程作用域
val coroutineScope = CoroutineScope(Dispatchers.Default)
val job1 = coroutineScope.launch {
try {
Log.i(TAG, "job1 子协程执行开始")
delay(2000)
Log.i(TAG, "job1 子协程执行完毕")
}catch (e: Exception) {
Log.i(TAG, "job1 子协程执行捕获到异常 :")
e.printStackTrace()
}
}
// 100ms 后取消协程作用域
delay(100)
// 取消协程作用域中的子协程
job1.cancel(CancellationException("自定义 CancellationException 异常"))
}
}
}执行结果 :
17:20:56.487 I job1 子协程执行开始
17:20:56.629 I job1 子协程执行捕获到异常 :
17:20:56.630 W java.util.concurrent.CancellationException: 自定义 CancellationException 异常
17:20:56.631 W at kim.hsl.coroutine.MainActivity$onCreate$1.invokeSuspend(MainActivity.kt:33)
17:20:56.631 W at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
17:20:56.631 W at kotlinx.coroutines.DispatchedTaskKt.resume(DispatchedTask.kt:235)
17:20:56.631 W at kotlinx.coroutines.DispatchedTaskKt.dispatch(DispatchedTask.kt:167)
17:20:56.631 W at kotlinx.coroutines.CancellableContinuationImpl.dispatchResume(CancellableContinuationImpl.kt:408)
17:20:56.631 W at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl(CancellableContinuationImpl.kt:442)
17:20:56.632 W at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl$default(CancellableContinuationImpl.kt:431)
17:20:56.632 W at kotlinx.coroutines.CancellableContinuationImpl.resumeUndispatched(CancellableContinuationImpl.kt:529)
17:20:56.632 W at kotlinx.coroutines.EventLoopImplBase$DelayedResumeTask.run(EventLoop.common.kt:497)
17:20:56.632 W at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:277)
17:20:56.632 W at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:87)
17:20:56.632 W at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:61)
17:20:56.633 W at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source:1)
17:20:56.633 W at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:40)
17:20:56.633 W at kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source:1)
17:20:56.633 W at kim.hsl.coroutine.MainActivity.onCreate(MainActivity.kt:15)
17:20:56.633 W at android.app.Activity.performCreate(Activity.java:7144)
17:20:56.633 W at android.app.Activity.performCreate(Activity.java:7135)
17:20:56.634 W at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
17:20:56.634 W at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2931)
17:20:56.634 W at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3086)
17:20:56.634 W at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
17:20:56.634 W at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
17:20:56.634 W at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
17:20:56.635 W at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1816)
17:20:56.635 W at android.os.Handler.dispatchMessage(Handler.java:106)
17:20:56.635 W at android.os.Looper.loop(Looper.java:193)
17:20:56.635 W at android.app.ActivityThread.main(ActivityThread.java:6718)
17:20:56.642 W at java.lang.reflect.Method.invoke(Native Method)
17:20:56.643 W at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
17:20:56.643 W at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
17:20:56.676 D Skia GL Pipeline