@@ -30,7 +30,7 @@ class DispatchersGuideTest {
30
30
* [ Parental responsibilities] ( #parental-responsibilities )
31
31
* [ Naming coroutines for debugging] ( #naming-coroutines-for-debugging )
32
32
* [ Combining context elements] ( #combining-context-elements )
33
- * [ Cancellation via explicit job ] ( #cancellation-via-explicit-job )
33
+ * [ Getting it together ] ( #getting-it-together )
34
34
* [ Thread-local data] ( #thread-local-data )
35
35
36
36
<!-- - END_TOC -->
@@ -487,48 +487,43 @@ I'm working in thread DefaultDispatcher-worker-1 @test#2
487
487
488
488
<!-- - TEST FLEXIBLE_THREAD -->
489
489
490
- ### Cancellation via explicit job
490
+ ### Getting it together
491
491
492
492
Let us put our knowledge about contexts, children and jobs together. Assume that our application has
493
493
an object with a lifecycle, but that object is not a coroutine. For example, we are writing an Android application
494
494
and launch various coroutines in the context of an Android activity to perform asynchronous operations to fetch
495
495
and update data, do animations, etc. All of these coroutines must be cancelled when activity is destroyed
496
- to avoid memory leaks.
497
-
498
- We manage a lifecycle of our coroutines by creating an instance of [ Job] that is tied to
499
- the lifecycle of our activity. A job instance is created using [ Job()] factory function when
500
- activity is created and it is cancelled when an activity is destroyed like this:
496
+ to avoid memory leaks. We, of course, can manipulate contexts and jobs manually to tie activity's
497
+ and coroutines lifecycles, but ` kotlinx.coroutines ` provides an abstraction that encapsulates that: [ CoroutineScope] .
498
+ You should be already familiar with coroutine scope as all coroutine builders are declared as extensions on it.
501
499
500
+ We manage a lifecycle of our coroutines by creating an instance of [ CoroutineScope] that is tied to
501
+ the lifecycle of our activity. ` CoroutineScope ` instance can be created by [ CoroutineScope()] or [ MainScope()]
502
+ factory functions. The former creates a general-purpose scope, while the latter creates scope for UI applications and uses
503
+ [ Dispatchers.Main] as default dispatcher:
502
504
503
505
<div class =" sample " markdown =" 1 " theme =" idea " data-highlight-only >
504
506
505
507
``` kotlin
506
- class Activity : CoroutineScope {
507
- lateinit var job: Job
508
-
509
- fun create () {
510
- job = Job ()
511
- }
512
-
508
+ class Activity {
509
+ private val mainScope = MainScope ()
510
+
513
511
fun destroy () {
514
- job .cancel()
512
+ mainScope .cancel()
515
513
}
516
514
// to be continued ...
517
515
```
518
516
519
517
< / div>
520
518
521
- We also implement [CoroutineScope ] interface in this `Actvity ` class. We only need to provide an override
522
- for its [ CoroutineScope .coroutineContext] property to specify the context for coroutines launched in its
523
- scope. We combine the desired dispatcher (we used [Dispatchers .Default ] in this example) and a job :
519
+ We can implement [CoroutineScope ] interface in this `Actvity ` class. The best way to do it is
520
+ to use delegation with default factory functions.
521
+ We also can combine the desired dispatcher (we used [Dispatchers .Default ] in this example) with the scope :
524
522
525
523
< div class = " sample" markdown= " 1" theme= " idea" data- highlight- only>
526
524
527
525
```kotlin
528
- // class Activity continues
529
- override val coroutineContext: CoroutineContext
530
- get() = Dispatchers .Default + job
531
- // to be continued ...
526
+ class Activity : CoroutineScope by CoroutineScope (Dispatchers .Default )
532
527
```
533
528
534
529
< / div>
@@ -566,23 +561,13 @@ onto the screen anymore if we wait:
566
561
import kotlin.coroutines.*
567
562
import kotlinx.coroutines.*
568
563
569
- class Activity : CoroutineScope {
570
- lateinit var job: Job
571
-
572
- fun create () {
573
- job = Job ()
574
- }
564
+ class Activity : CoroutineScope by CoroutineScope (Dispatchers .Default ) {
575
565
576
566
fun destroy () {
577
- job. cancel()
567
+ cancel() // Extension on CoroutineScope
578
568
}
579
569
// to be continued ...
580
570
581
- // class Activity continues
582
- override val coroutineContext: CoroutineContext
583
- get() = Dispatchers .Default + job
584
- // to be continued ...
585
-
586
571
// class Activity continues
587
572
fun doSomething () {
588
573
// launch ten coroutines for a demo, each working for a different time
@@ -598,7 +583,6 @@ class Activity : CoroutineScope {
598
583
fun main () = runBlocking<Unit > {
599
584
// sampleStart
600
585
val activity = Activity ()
601
- activity.create() // create an activity
602
586
activity.doSomething() // run test function
603
587
println (" Launched coroutines" )
604
588
delay(500L ) // delay for half a second
@@ -712,7 +696,9 @@ that should be implemented.
712
696
[ CoroutineScope.coroutineContext ] : https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-coroutine-scope/coroutine-context.html
713
697
[ Job.join ] : https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-job/join.html
714
698
[ CoroutineName ] : https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-coroutine-name/index.html
715
- [ Job() ] : https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-job.html
699
+ [ CoroutineScope() ] : https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-coroutine-scope.html
700
+ [ MainScope() ] : https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-main-scope.html
701
+ [ Dispatchers.Main ] : https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-dispatchers/-main.html
716
702
[ asContextElement ] : https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/java.lang.-thread-local/as-context-element.html
717
703
[ ThreadContextElement ] : https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-thread-context-element/index.html
718
704
<!-- - END -->
0 commit comments