主要介绍`CoroutineScope`使用过程涉及的类以及对应的源码;
[TOC]
## MainScope
```kotlin
//CoroutineScope.kt
public fun MainScope(): CoroutineScope = ContextScope(SupervisorJob() + Dispatchers.Main)
```
## LifecycleCoroutineScope
```kotlin
//Lifecycle.kt
public abstract class LifecycleCoroutineScope internal constructor() : CoroutineScope {
internal abstract val lifecycle: Lifecycle
@Suppress("DEPRECATION")
public fun launchWhenCreated(block: suspend CoroutineScope.() -> Unit): Job = launch {
lifecycle.whenCreated(block)
}
@Suppress("DEPRECATION")
public fun launchWhenStarted(block: suspend CoroutineScope.() -> Unit): Job = launch {
lifecycle.whenStarted(block)
}
@Suppress("DEPRECATION")
public fun launchWhenResumed(block: suspend CoroutineScope.() -> Unit): Job = launch {
lifecycle.whenResumed(block)
}
}
```
### Lifecycle获取对应的CoroutineScope
```kotlin
//Lifecycle.kt
public var internalScopeRef: AtomicReference<Any> = AtomicReference<Any>()
public val Lifecycle.coroutineScope: LifecycleCoroutineScope
get() {
while (true) {
val existing = internalScopeRef.get() as LifecycleCoroutineScopeImpl?
if (existing != null) {
return existing
}
// 这里需要注意的是 SupervisorJob() + Dispatchers.Main.immediate
// 和MainScope的CoroutineContext一致
val newScope = LifecycleCoroutineScopeImpl(
this,
SupervisorJob() + Dispatchers.Main.immediate
)
if (internalScopeRef.compareAndSet(null, newScope)) {
newScope.register()
return newScope
}
}
}
```
### LifecycleCoroutineScopeImpl
```kotlin
internal class LifecycleCoroutineScopeImpl(
override val lifecycle: Lifecycle,
override val coroutineContext: CoroutineContext
) : LifecycleCoroutineScope(), LifecycleEventObserver {
init {
// 如果我们是在非主线程上初始化的,那么在返回作用域之前要做一次“尽力检查”。
// 这不是同步,但如果开发人员在非主调度程序上启动,他们无论如何都不能100%确定。
if (lifecycle.currentState == Lifecycle.State.DESTROYED) {
coroutineContext.cancel()
}
}
fun register() {
launch(Dispatchers.Main.immediate) {
// 在主线程中执行,判断当前的声明周期是否已经处于销毁状态;
// 如果是销毁状态,那么直接取消协程;
// 如果不是那么添加生命周期的监听,发生销毁的时候再执行取消协程同步反注册监听
if (lifecycle.currentState >= Lifecycle.State.INITIALIZED) {
lifecycle.addObserver(this@LifecycleCoroutineScopeImpl)
} else {
coroutineContext.cancel()
}
}
}
override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
if (lifecycle.currentState <= Lifecycle.State.DESTROYED) {
lifecycle.removeObserver(this)
coroutineContext.cancel()
}
}
}
```
### LifecycleCoroutineScope使用
```kotlin
// LifecycleOwner.kt
public val LifecycleOwner.lifecycleScope: LifecycleCoroutineScope
get() = lifecycle.coroutineScope
```
- 在页面生命周期中监听`StateFlow`的数据流变化
```kotlin
lifecycleScope.launch {
viewModel.listStateFlow.collect {
workOrderListAdapter.submitData(it)
}
}
```
## viewModelScope
```kotlin
//ViewModel.kt
private const val JOB_KEY = "androidx.lifecycle.ViewModelCoroutineScope.JOB_KEY"
/**
* ViewModel 相关的 CoroutineScope
* 这个协程作用域一直到ViewModel被清理:eg:ViewModel.onCleared方法被调用
*/
public val ViewModel.viewModelScope: CoroutineScope
get() {
// 获取已经创建的CoroutineScope
val scope: CoroutineScope? = this.getTag(JOB_KEY)
if (scope != null) {
return scope
}
// 保存标记和对应的Value,该方法支持多线程并发。且在添加的时候如果发现ViewModel已经cleared,那么会直接调用Closeable关闭协程。
return setTagIfAbsent(
JOB_KEY,
CloseableCoroutineScope(SupervisorJob() + Dispatchers.Main.immediate)
)
}
internal class CloseableCoroutineScope(context: CoroutineContext) : Closeable, CoroutineScope {
override val coroutineContext: CoroutineContext = context
override fun close() {
coroutineContext.cancel()
}
}
```
- 写在前面的话
- Java
- 基础
- Double的比较
- 小数怎么用二进制表示
- 多线程
- 并发和并行
- 线程池
- 线程池背景
- 线程池构造
- 任务阻塞队列
- Flutter
- 基础知识
- Dart基础
- Android
- 项目架构
- View
- 非UI线程更新View
- AlarmManager
- 对比postDelaryed和Timer
- Bitmap
- 加载100M的图片却不撑爆内存
- Bitmap压缩
- Bitmap局部解码
- 计算图片的内存占用
- Android动画
- Android动画类型
- Android动画原理
- 属性动画
- 帧动画
- 补间动画
- 使用动画的注意事项
- Android新特性
- 权限组
- Android23(Marshmallow)-6.0
- Android24(Nougat)-7.0
- Android26(Oreo)-8.0
- Android28(Pie)-9.0
- Android29(Q)-10.0
- AndroidX迁移
- Kotlin
- 关键字
- Kotlin操作符
- CoroutineScope
- Flow
- CoroutineException