半行代碼綁定協程與activity的生命週期

半行代碼綁定協程生命週期

純屬娛樂!

廢話很少說,直接上代碼!git

GlobalScope.launch(Dispatchers.IO){
    
}.lifeRecycle(lifecycle) <<<<在這裏
複製代碼

沒錯就是這麼簡單。就是半行代碼!github

先說一下原理

在AndroidX中Activity的生命週期的監聽可使用lifecycle
lifecycle.addObserver(LifecycleObserver)
複製代碼
使用這個觀察者監聽當前activity的生命週期變化。
lifecycle.addObserver(object : LifecycleEventObserver {
            override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
                if (event == Lifecycle.Event.ON_DESTROY) {
                   //activity destroy
                }
            }
        })
複製代碼

因此我所實現的步驟就是經過觀察activity的生命週期執行協程的cancel函數。async

要使用這種方式不免要封裝一下。ide

我看過網上有一個庫RxLife-Coroutine 我細看了一下,他的方式有一些將協程本來的代碼書寫方式修改了。隨也是一種方式,不過對於一些就項目不是很好的接入。函數

因而我靈雞一動,想到不如用擴展函數。在不破壞源代碼(這裏的指的是現有使用協程的項目)的狀況下,快速接入,一鍵完成生命週期的綁定。this

因此就有了這樣的代碼:spa

launch 使用
GlobalScope.launch(Dispatchers.IO){
    
}.lifeRecycle(lifecycle) <<<<在這裏
複製代碼
async 使用
GlobalScope.async(Dispatchers.IO){

}.lifeRecycle(lifecycle) <<<<在這裏
複製代碼
runBlocking 使用
runBlocking(Dispatchers.IO) {
	lifeRecycle(lifecycle) <<<<在這裏
}
複製代碼
withContext 使用
withContext(Dispatchers.Main){
	lifeRecycle(lifecycle) <<<<在這裏
}
複製代碼

有沒有很簡潔的樣子code

我是這麼作的

1.要先找到給誰擴展

我看了部分源碼找到了這幾個類 Job,Deferred<T>,CoroutineScopecdn

Job就是使用launch函數的時候的返回值它持有cancel函數server

Deferred<T>繼承自Job

public interface Deferred<out T> : Job {
//...
}
複製代碼

CoroutineScope 是協程執行範圍可在執行期間cancel本身這個cancelCoroutineScope 的擴展函數

public fun CoroutineScope.cancel(cause: CancellationException? = null) {
	//。。。。。。
}
複製代碼

而咱們通用的幾個協程函數取消的控制也就這幾個能夠控制,因此我找到了給誰擴展。

2.如何擴展

先給Job擴展一個

fun Job.lifeRecycle(lifecycle: Lifecycle): Job {
    return this
}
複製代碼

就是這麼簡單,但爲何要return回去呢,爲了避免破壞原代碼的結構。減小異常的處理。

咱們要使用activity的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
}
複製代碼

看是否是很簡單!

個人思路很簡單。代碼量也不多。

我也寫了一個相關的demo在GitHub上。有感興趣的小夥伴能夠一塊兒探索,討論。

最後貼兩張所有代碼圖片

相關文章
相關標籤/搜索