Half a line of code binds the coroutine life cycle

Pure entertainment!

Without further ado, go straight to the code!

Globalscope.launch (dispatchers.io){}. LifeRecycle (lifecycle) <<<< is hereCopy the code

Yes, it’s that simple. Half a line of code!

Let’s talk about the principle

An Activity lifecycle listener can be used on AndroidXlifecycle.
lifecycle.addObserver(LifecycleObserver)
Copy the code
Use this observer to listen for changes in the lifecycle of the current activity.
lifecycle.addObserver(object : LifecycleEventObserver {
            override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
                if (event == Lifecycle.Event.ON_DESTROY) {
                   //activity destroy}}})Copy the code

So the step I’ve implemented is to execute the coroutine’s Cancel function by observing the activity’s life cycle.

It’s hard to use this approach without encapsulation.

I’ve seen a library on the web called RxLife-Coroutine and I looked at it a little bit, and it’s a little bit of a modification of the way coroutines were written. Random is also a way, but it is not very good access for some existing projects.

I also looked at the official lifecycleScope and saw the same thing. But I still want to do it myself. Do this with the most basic and simple idea.

So I had a brainstorm, and I thought I’d use an extension function. Fast access, one-click life cycle binding without breaking source code (by which I mean existing projects that use coroutines).

So there is code like this:

launchuse
Globalscope.launch (dispatchers.io){}. LifeRecycle (lifecycle) <<<< is hereCopy the code
asyncuse
Globalscope.async (dispatchers.io){}. LifeRecycle (lifecycle) <<<< is hereCopy the code
runBlockinguse
RunBlocking (dispatchers.io) {lifeRecycle(lifecycle) <<<< here}Copy the code
withContextuse
WithContext (dispatchers.main){lifeRecycle(lifecycle) <<<< here}Copy the code

Is there a very simple look

Here’s what I did

1. Figure out who to extend to first

Job,Deferred

, and CoroutineScope classes

Job is the return value when launch is used and it holds the cancel function

Deferred

inherits from the Job

public interface Deferred<out T> : Job {
/ /...
}
Copy the code

CoroutineScope is a coroutine execution scope that can cancel itself during execution. This cancel is an extension of the CoroutineScope function

public fun CoroutineScope.cancel(cause: CancellationException? = null) {
	//...
}
Copy the code

And there’s only so much control over the cancellation of our common coroutine functions, so I figured out who to extend.

2. How to scale

Let’s do an extension for Job

fun Job.lifeRecycle(lifecycle: Lifecycle): Job {
    return this
}
Copy the code

It’s that simple, but why return? So as not to break the structure of the original code. Reduce exception handling.

We will add an observer using the activity’s lifecycle

fun Job.lifeRecycle(lifecycle: Lifecycle): Job {
    lifecycle.addObserver(object : LifecycleEventObserver {
        override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
            if (event == Lifecycle.Event.ON_DESTROY) {
                 cancelChildren()
                 cancel()
            }
        }
    })
    return this
}
Copy the code

See if it’s easy!

My thinking is very simple. Very little code.

I also wrote a related demo on GitHub. Interested partners can explore and discuss together.

Finally, post two pictures of the entire code