Job是Kotlin协程中表示协程任务的核心概念,它提供了对协程生命周期的控制和管理的功能。
Job是协程的句柄,具有以下特点:
val job = GlobalScope.launch {
// 协程体
}
val deferred = GlobalScope.async {
// 协程体,返回结果
}
// Deferred继承自Job,额外提供await()方法获取结果
Job有以下几种状态:
状态转换关系:
New → Active → Completing → Completed
↘ Cancelling → Cancelled
job.cancel() // 取消协程
job.cancel("取消原因", CancellationException()) // 带原因的取消
job.join() // 挂起当前协程,直到目标协程完成
job.cancelAndJoin() // 先取消再等待完成
job.isActive // 是否活跃
job.isCompleted // 是否完成
job.isCancelled // 是否已取消
val parentJob = Job()
val childJob = GlobalScope.launch(parentJob) {
// 子协程
}
fun fetchData() {
val parentJob = Job()
launch(parentJob) { fetchUser() }
launch(parentJob) { fetchPosts() }
// 取消所有相关协程
parentJob.cancel()
}
val job = launch {
try {
withTimeout(3000) {
longRunningTask()
}
} catch (e: TimeoutCancellationException) {
// 处理超时
}
}
val job = launch {
try {
// 执行任务
} finally {
// 确保资源清理
releaseResources()
}
}
job.invokeOnCompletion { cause: Throwable? ->
// 协程完成或取消时的回调
cause?.let { println("协程被取消: $it") }
}
val supervisorJob = SupervisorJob()
launch(supervisorJob) {
// 子协程失败不会影响其他子协程
}
Job是CoroutineContext的一部分:
launch(Dispatchers.IO + CoroutineName("my-coroutine") + job) {
// 协程体
}
fun loadMultipleDataSources() {
val parentJob = Job()
val userJob = launch(parentJob + Dispatchers.IO) { fetchUser() }
val postsJob = launch(parentJob + Dispatchers.IO) { fetchPosts() }
// 等待所有完成
runBlocking {
userJob.join()
postsJob.join()
}
// 或者取消所有
parentJob.cancel()
}
class MyViewModel : ViewModel() {
private val jobs = mutableListOf<Job>()
fun fetchData() {
val job = viewModelScope.launch {
// 执行任务
}
jobs.add(job)
job.invokeOnCompletion {
jobs.remove(job)
}
}
override fun onCleared() {
jobs.forEach { it.cancel() }
}
}
Job是Kotlin协程并发控制的基础,合理使用Job可以实现:
理解并掌握Job的使用是编写健壮协程代码的关键。