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?Marcelo Hernandez
03/07/2019, 7:07 PMCompositeDisposable 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.Marcelo Hernandez
03/07/2019, 7:09 PMonDestroy.withoutclass
03/07/2019, 7:26 PMwithoutclass
03/07/2019, 7:27 PMCoroutineScope and the examples on github?withoutclass
03/07/2019, 7:30 PMMarcelo 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.Marcelo Hernandez
03/07/2019, 7:31 PMMarcelo Hernandez
03/07/2019, 7:34 PMcoroutineContext, a new SupervisorJob instance will be created.Marcelo Hernandez
03/07/2019, 7:35 PMonPause() 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 anywayswithoutclass
03/07/2019, 7:37 PMby MainScope() was saying that it is deprecatedwithoutclass
03/07/2019, 7:44 PMcancelChildren 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 2Marcelo Hernandez
03/07/2019, 7:47 PMget() 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 PMwithoutclass
03/07/2019, 7:49 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 PMMarcelo Hernandez
03/07/2019, 7:51 PMSupervisorJob and continue to invoke cancel, then onResume will fail to launch the coroutine the second time around.Marcelo Hernandez
03/07/2019, 7:52 PMcancelChildren 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)
}withoutclass
03/07/2019, 7:58 PM[StandaloneCoroutine{Active}@93c7f7b, Main]
=======
[StandaloneCoroutine{Active}@93c7f7b, Main]withoutclass
03/07/2019, 7:59 PMemail_sign_in_button.onClick(coroutineContext) {
// clickEventChannel.send(SignInClickEvent.SignInButton)
val ctx1 = coroutineContext
val ctx2 = coroutineContext
println(ctx1[Job])
println("=======")
println(ctx2[Job])
}withoutclass
03/07/2019, 7:59 PMMarcelo 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 finewithoutclass
03/07/2019, 8:02 PMMarcelo 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 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 newcoroutineContextinstance will be created.SupervisorJob
gildor
03/08/2019, 1:27 AMusingNo, 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()
gildor
03/08/2019, 1:29 AMwith 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 AMgildor
03/08/2019, 1:31 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 AMgildor
03/08/2019, 1:34 AMMarcelo Hernandez
03/08/2019, 1:34 AMonStop().gildor
03/08/2019, 1:35 AMgildor
03/08/2019, 1:36 AMwithoutclass
03/08/2019, 1:53 PM