基于kotlin的coroutines的生命周期管理

什么是kotlin

这个都不知道的话,请打开官网

什么是coroutine

说起‘协程’可能有些人会比较熟悉,类似Lua、C#里面的概念。

Coroutines中文名”协程”,简单来说就是使用suspend来代替线程阻塞,可以理解为无阻塞的异步编写方式,基本原理是使用更轻的协程来代替繁重的阻塞操作,并且复用原本阻塞的线程资源。

本文仅简单介绍协程,如果你想知道更多关于协程,请参考这篇文章

Android生命周期

Android有一套基于用户行为的生命周期管理,用于及时释放资源。

问题

Android异步执行耗时任务,然后在主线程回调结果,如果在activity onDestroy之前没有取消掉,那么就会执行已经释放掉的UI资源,导致crash。

官方方案局限

Coroutines虽然返回了Job用于控制协程的取消,对Job的控制粒度非常细,但是每个任务都需要单独写控制代码,代码比较冗余。

另外官方还提供了另一种解决办法,这种办法可以减少一点冗余的代码,但是并没有达到简洁优雅的目的。

自己扩展

官方的不行,就自己来。其实,我们需要的是一个类似AutoDispose的扩展方法,只需要声明是需要生命周期管理的,就自动帮我们取消UI任务。

目的明确了,我们实现起来就简单很多。

1、作用范围

Android里面具有生命周期的UI组件只有Activity、Fragment和View,扩展方法只需要实现这三个作用域就可以了,而Activity和Fragment都实现了LifecycleOwner接口,我们只需要对LifecycleOwner扩展即可。

2、实现方式

LifecycleOwner只需要在发ON_DESTROY的时候,取消任务即可

class CoroutineLifecycleListener(private val deferred: Deferred<*>) : LifecycleObserver {
    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    fun cancelCoroutine() {
        if (!deferred.isCancelled) {
            deferred.cancel()
        }
    }
}

同理,View在onViewDetachedFromWindow取消任务

class CoroutineViewListener(private val deferred: Deferred<*>) : View.OnAttachStateChangeListener {
    override fun onViewDetachedFromWindow(v: View?) {
        if (!deferred.isCancelled) {
            deferred.cancel()
        }
    }

    override fun onViewAttachedToWindow(v: View?) {
    }
}

在回调主线程的时候,我们需要提供一个block用于UI操作,另外我们利用kotlin的infix关键字,使用起来更像DSL

infix fun  Deferred.then(block: (T) -> Unit): Job {
    return launch(UI) { block([email protected]()) }
}
infix fun  Deferred.then(block: (T) -> R): Deferred {
    return async(UI) { block([email protected]()) }
}

3、结果

最终我们达到了我们的目的----简单优雅

load {
    IOJob()
} then {
    UIJob()
}

广告时间

写了这么多,当然是需要提供下这个库的地址

使用

根目录下的build.gradle添加

allprojects {
        repositories {
            ...
            maven { url 'https://jitpack.io' }
        }
    }

然后添加依赖

implementation 'com.github.TinoGuo:LifecycleKt:v1.0'

之后就可以愉快的使用了!

欢迎大家star或pr

你可能感兴趣的:(基于kotlin的coroutines的生命周期管理)