主要介紹`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