Kotlin 协程之三:Android中的应用
系列文章:
Kotlin 协程之一:基础使用
Kotlin 协程之二:原理剖析
Kotlin 协程之三:Android中的应用
至此,我们完全了解了协程的使用和实现原理,那么如何应用到我们Android项目中呢?这里讲一些简单的例子。
1.将线程改为协程
通常我们有一些小的延时任务或异步任务,会使用线程池来解决,这里我们可以用协程来解决,比如:在页面创建后,异步读取数据库中的内容,然后展示到TextView上。
CoroutineScope(Dispatchers.Main).launch {
val data = withContext(Dispatchers.IO){ //get data from DB }
textView.text = data
}
2.将网络请求改为协程
通常我们的网络请求都是使用的第三方库,如retrofit等,他们的共同点都是结果需要通过Callback回调,这显然是我们不愿意看到的,这里我们可以改为协程实现。
//假如这是网络库的Call对象
private class Call(data: String = "") {
fun addCallback(cb: Callback) {
//register callback
}
}
private interface Callback {
fun onCall(res: String)
fun onError(error: Exception)
}
假如这是网络库的Call对象,我们通过其来添加Callback,那么我们为他增加一个扩展函数。
private suspend fun Call.await(): String = suspendCancellableCoroutine {
addCallback(object : Callback {
//请求异常时调用resumeWithException恢复协程
override fun onError(error: Exception) {
it.resumeWithException(error)
}
//请求成功时调用resume恢复协程
override fun onCall(res: String) {
it.resume(res)
}
})
}
这样一来,我们的请求和处理就可以写成协程的样子,甚至多个有依赖关系的接口也支持:
CoroutineScope(Dispatchers.Main).launch {
val data1 = Call().await()
val data2 = Call(data1).await()
textView.text = data2
}
这样一来,我们大量回调嵌套的异步任务就清晰了很多。
3.生命周期
以上都是我们如何使用协程完成一个任务,那么对于应用来说,还要考虑的是声明周期,就比如网络请求在页面退出时应该及时cancel,有效避免资源浪费、崩溃和内存泄露。
open class BaseActivity : AppCompatActivity() {
private val scope = CoroutineScope(Dispatchers.Main)
fun startCoroutine(context: CoroutineContext = EmptyCoroutineContext,
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> Unit): Job = scope.launch(context, start, block)
override fun onDestroy() {
super.onDestroy()
scope.cancel()
}
}
首先我们可以在基类创建一个scope,每个页面一个单独的scope;然后在onDestroy()进行scope的cancel,相当于取消掉当前页面所有未完成的协程;最后实现一个开启协程的方法,保证我们的子类开启协程时用的都是该scope的。
class MainActivity : BaseActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
startCoroutine(Dispatchers.Main) {
showLoadingView()
val data1 = Call().await()
val data2 = Call(data1).await()
displayData(data2)
}
}
}
在子类里就可以正常使用了,并且不用关注cancel事件。
版权声明:本文为qq_15827013原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。