Marcelo Hernandez
03/07/2019, 7:05 PMcancelChildren()
while never explicitly cancelling the parent Job
itself? This way when onStart()
is called, you can continue reusing the Job
for launching more coroutines?CompositeDisposable
is used where instead of invoking dispose()
, you can use clear()
so that future Disposables
can be added should the lifecycle begin again for the same instance of the lifecycle-aware component.onDestroy
.withoutclass
03/07/2019, 7:26 PMCoroutineScope
and the examples on github?Marcelo Hernandez
03/07/2019, 7:31 PMViewModel
so it's pretty straightforward to override onCleared()
and cancel the entire parent Job
. But we have a lot of older code that is following MVP with our own definition of Presenters. These presenters only have an onTake
and onDrop
callback which are tied to the onStart()
and onStop()
events of the Activity.coroutineContext
, a new SupervisorJob
instance will be created.onPause()
will cancel a different instance of SupervisorJob
which is not the same instance that is being used in onResume
to launch the coroutine.withoutclass
03/07/2019, 7:35 PMval
property, so it get’s set once, unless the activity is destroyed anywaysby MainScope()
was saying that it is deprecatedcancelChildren
call 😄Marcelo Hernandez
03/07/2019, 7:46 PMfun main(args: Array<String>) {
val person = Person()
println(person.name)
println(person.name)
println(person.name)
}
class Person {
var counter = 0
val name: String get() = "User id ${counter++}"
}
And the results were:
User id 0
User id 1
User id 2
get()
for a val
property causes the expression to be evaluated every time you access the property. It's like having a getter
function that does some work before returning.withoutclass
03/07/2019, 7:48 PMMarcelo Hernandez
03/07/2019, 7:49 PMonPause
is creating a new SupervisorJob
instance and then immediately invoking cancel
on it, essentially leaking the previous one.withoutclass
03/07/2019, 7:50 PMMarcelo Hernandez
03/07/2019, 7:50 PMSupervisorJob
and continue to invoke cancel
, then onResume
will fail to launch the coroutine the second time around.cancelChildren
instead and allow the Activity to be destroyed without ever officially invoking cancel()
on the parent Job
?withoutclass
03/07/2019, 7:57 PMemail_sign_in_button.onClick(coroutineContext) {
// clickEventChannel.send(SignInClickEvent.SignInButton)
val ctx1 = coroutineContext
val ctx2 = coroutineContext
println(ctx1)
println("=======")
println(ctx2)
}
[StandaloneCoroutine{Active}@93c7f7b, Main]
=======
[StandaloneCoroutine{Active}@93c7f7b, Main]
email_sign_in_button.onClick(coroutineContext) {
// clickEventChannel.send(SignInClickEvent.SignInButton)
val ctx1 = coroutineContext
val ctx2 = coroutineContext
println(ctx1[Job])
println("=======")
println(ctx2[Job])
}
Marcelo Hernandez
03/07/2019, 7:59 PMwithoutclass
03/07/2019, 8:00 PMMarcelo Hernandez
03/07/2019, 8:00 PMwithoutclass
03/07/2019, 8:01 PMJob
is fineMarcelo Hernandez
03/07/2019, 8:03 PMJob
is still active
, however all of it's children will be cancelled.withoutclass
03/07/2019, 8:09 PMcoroutineContext
, using the correct property, returns a new contextMarcelo Hernandez
03/07/2019, 8:10 PMwithoutclass
03/07/2019, 9:11 PMcancelChildren
seems a good way to go, I need to update my examples to use itMarcelo Hernandez
03/07/2019, 10:23 PMJob
as active if we never call cancel
on it though. I'd like to think it is okay. 🤔withoutclass
03/08/2019, 12:57 AMMarcelo Hernandez
03/08/2019, 1:01 AMonDestroy
. As mentioned before, with RxJava, we use compositeDisposable.clear()
instead of compositeDisposable.dispose()
and leave the CompositeDisposable
as undisposed.withoutclass
03/08/2019, 1:06 AMMarcelo Hernandez
03/08/2019, 1:21 AMgildor
03/08/2019, 1:23 AMLooking at the structured concurrency example it seems that for each invocation ofNo, it shouldn’t work like that, you should keep Job until scope cancellation and recreate your job if some onStart method may be called a few times, a newcoroutineContext
instance will be created.SupervisorJob
usingNo, it’s not deprecated, it’s experimental, it means that this API might be changed in the future, but it doesn’t mean that it deprecatedwas saying that it is deprecatedby MainScope()
with RxJava, we useYou can do this with coroutines scope, just use cancelChildren()instead ofcompositeDisposable.clear()
and leave thecompositeDisposable.dispose()
as undisposed.CompositeDisposable
Marcelo Hernandez
03/08/2019, 1:30 AMcancelChildren()
, I've been using approach similar to the following:
private var scope by Delegates.notNull<CoroutineScope>()
fun onStart() {
scope = CoroutineScope(SupervisorJob() + Dispatchers.Main)
haveFunAndLaunchSomeCoroutines()
}
fun onStop() {
scope.cancel()
}
gildor
03/08/2019, 1:30 AMMarcelo Hernandez
03/08/2019, 1:31 AMcancelChildren()
approach since you get to use a val
and avoid the initialization in the onStart
.gildor
03/08/2019, 1:33 AMMarcelo Hernandez
03/08/2019, 1:34 AMonStop()
.gildor
03/08/2019, 1:35 AMwithoutclass
03/08/2019, 1:53 PM