티스토리 뷰
Scope
CoroutineBuilder(launch, async)를 생성하는 범위이다. CoroutineBuilder를 통해 만들어진 Coroutine들은 기본적으로 해당 Scope의 Context를 전달받는다. 즉 Scope는 Coroutine을 만들 수 있는 범위이며, cancel같은 함수로 해당 Scope의 Coroutine을 관리할 수 있다.
val scope = CoroutineScope(Dispatchers.IO)
val job = scope.launch {
// 기본적으로 스코프의 Context 영향을 받는다. (IO)
launch {
// 상위 스코프의 Context를 가져온다. (IO)
}
launch(Dispatchers.Main) {
// Context를 재정의 할 수 있다. (Main)
}
}
// 해당 스코프의 Coroutine을 종료한다.
scope.cancel()
CoroutineScope
기본적으로 CoroutineScope는 Interface로 선언됐다. CoroutineScope라는 public function을 호출하여 CoroutineScope를 만들 수 있으며 매개변수로 CoroutineContext를 제공하여 만들 수 있다. 기본적으로 Scope내의 Coroutine이 모두 완료되기 전까지 완료되지 않습니다.
public interface CoroutineScope {
/**
* The context of this scope.
* Context is encapsulated by the scope and used for implementation of coroutine builders that are extensions on the scope.
* Accessing this property in general code is not recommended for any purposes except accessing the [Job] instance for advanced usages.
*
* By convention, should contain an instance of a [job][Job] to enforce structured concurrency.
*/
public val coroutineContext: CoroutineContext
}
@Suppress("FunctionName")
public fun CoroutineScope(context: CoroutineContext): CoroutineScope =
ContextScope(if (context[Job] != null) context else context + Job())
MainScope
CoroutineScope에서 Dispatchers.Main이 추가된 함수이다. UI Thread에서 처리할 작업을 실행할 때 적합하다.
@Suppress("FunctionName")
public fun MainScope(): CoroutineScope = ContextScope(SupervisorJob() + Dispatchers.Main)
GlobalScope
CoroutineScope를 상속받고 있습니다. GlobalScope는 앱이 동작하는 동안 계속 살아있습니다. 실제로 public object로 Singleton 패턴으로 만들어졌으며 잘못된 사용은 메모리 누수로 이어질 수 있습니다. Android에서는 CoroutineScope와 MainScope의 사용을 권장하고 있습니다.
@DelicateCoroutinesApi
public object GlobalScope : CoroutineScope {
/**
* Returns [EmptyCoroutineContext].
*/
override val coroutineContext: CoroutineContext
get() = EmptyCoroutineContext
}
LifecycleScope
생명주기가 중요한 Android에서 제공하는 Scope입니다. CoroutineContext를 설정할 수 있으며 기본으로 Dispatchers.Main이 제공됩니다. Lifecycle이 destroy되는 경우 해당 Scope의 모든 Coroutine은 취소됩니다.
Activity, Fragment에서 사용할 수 있습니다. Fragment경우 View의 LifeCycle에 맞춘 ViewLifecycleScope도 제공합니다.
public val Lifecycle.coroutineScope: LifecycleCoroutineScope
get() {
while (true) {
val existing = mInternalScopeRef.get() as LifecycleCoroutineScopeImpl?
if (existing != null) {
return existing
}
val newScope = LifecycleCoroutineScopeImpl(
this,
SupervisorJob() + Dispatchers.Main.immediate
)
if (mInternalScopeRef.compareAndSet(null, newScope)) {
newScope.register()
return newScope
}
}
}
lifecycleScope.launchWhenCreated {
Log.d("PASS", "Create : ${Thread.currentThread()}")
}
lifecycleScope.launchWhenStarted {
Log.d("PASS", "Start : ${Thread.currentThread()}")
}
lifecycleScope.launchWhenResumed {
Log.d("PASS", "Resume : ${Thread.currentThread()}")
}
lifecycleScope.launch {
Log.d("PASS", "Launch : ${Thread.currentThread()}")
}
2022-01-07 21:00:47.457 17304-17304/? D/PASS: Create : Thread[main,5,main]
2022-01-07 21:00:47.465 17304-17304/? D/PASS: Start : Thread[main,5,main]
2022-01-07 21:00:47.475 17304-17304/? D/PASS: Resume : Thread[main,5,main]
2022-01-07 21:00:47.455 17304-17304/? D/PASS: Launch : Thread[main,5,main]
ViewModelScope
ViewModel의 생명주기에 맞는 ViewModelScope도 지원합니다. LifeCycleScope와 마찬가지로 Dispatchers를 지정할 수 있으며 지정하지 않는 경우 Dispatchers.Main이 제공됩니다.
public val ViewModel.viewModelScope: CoroutineScope
get() {
val scope: CoroutineScope? = this.getTag(JOB_KEY)
if (scope != null) {
return scope
}
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()
}
}
viewModelScope.launch {
}'Android > Coroutine' 카테고리의 다른 글
| Android Coroutine - Job Lifecycle (0) | 2022.01.15 |
|---|---|
| Android Coroutine - Cancel (0) | 2022.01.08 |
| Android Coroutine - Coroutine Builder (0) | 2022.01.07 |
| Android Coroutine - CoroutineContext (0) | 2022.01.07 |
| Android Coroutine - 개념 (0) | 2022.01.04 |
- Total
- Today
- Yesterday
- rxjava
- Flutter
- 코루틴
- 클린 코드
- TDD
- git
- viewmodel
- Exception
- Widget
- 클린코드
- CancellationException
- ViewModelStoreOwner
- 함수
- DSL
- clean code
- Coroutine
- DART
- observable
- ConcatAdapter
- ConcatAdapter.Config
- gradle
- ViewModelProvider
- Flowable
- 연산자
- 보이스카우트 규칙
- isActive
- commit
- Kotlin
- null
- Android
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 8 | 9 | 10 | 11 | 12 | 13 | 14 |
| 15 | 16 | 17 | 18 | 19 | 20 | 21 |
| 22 | 23 | 24 | 25 | 26 | 27 | 28 |
