最近入了Android坑,目前还处于疯狂学习的状态,所以很久都没有写博客了。今天记录一个小代码片段,在Android上使用coroutine 的小例子。
由于我自己是做一个记账软件来学习的,我用了gRPC,最开始我是使用线程来做网络请求的:
thread { // 网络请求代码 runOnUiThread { // 更新UI的代码 } }
今天把这一套全部重写成用coroutine。
首先coroutine得有个调度器,英文叫做 “Dispatchers”,有这么几个:
然后,为了多个coroutine之间可以分组啊,就像进程里可以放很多线程那样,又搞了一个概念,叫做 scope,默认有一个全局scope,叫做 GlobalScope,全局的, 就和全局变量一样,在Android上,这个里面跑的coroutine,生命周期和app一样久,不推荐在这里起coroutine。
推荐的方式是每个Activity里起一个scope,然后再launch。
所以我就这样写基类:
abstract class BaseActivity : AppCompatActivity(), CoroutineScope { /* 默认的coroutine scope是Main,也就是UI线程(主线程)。如果要做IO,比如网络请求,记得 包裹在 launch(Dispatchers.IO) {} 里,如果要大量计算,包裹在 launch(Dispatcher.Default) {} 里 或者直接写 launch。 UI操作则用 withContext(Dispatchers.Main) {} 切回来 */ private val job = SupervisorJob() override val coroutineContext: CoroutineContext get() = Dispatchers.Main + job override fun onDestroy() { super.onDestroy() coroutineContext.cancelChildren() }
这样子之后,就可以直接launch,起coroutine了:
launch { val req = CreateFeedbackReq.newBuilder().build() val respAny = callRPC { api.createFeedback(req) } respAny?:return@launch val resp = respAny as CreateFeedbackResp if (handleRespAction(resp.action)) { withContext(Dispatchers.Main) { showSnackBar(R.string.thank_you_for_feedback) delay(1000) finish() } } }
如上,默认情况下,root coroutine就是当前所在activity,而他们默认会在 Dispatchers.Main 上执行,如果想要coroutine在 别的 dispatcher 上执行,就用 withContext,然后里面如果又想更新UI的话,就用 withContext(Dispatchers.Main)。
那为啥 launch 不传参数的话,就是直接用的 Dispatchers.Main 呢?因为其实 CoroutineScope 是一个接口,而 coroutineContext 是里面的一个变量:
public interface CoroutineScope { /** * The context of this scope. * Context is encapsulated by the scope and used for implementation of coroutine builders that are extensions on the scope. * Accessing this property in general code is not recommended for any purposes except accessing the [Job] instance for advanced usages. * * By convention, should contain an instance of a [job][Job] to enforce structured concurrency. */ public val coroutineContext: CoroutineContext }
我们再来看看 launch 的实现:
public fun CoroutineScope.launch( context: CoroutineContext = EmptyCoroutineContext, start: CoroutineStart = CoroutineStart.DEFAULT, block: suspend CoroutineScope.() -> Unit ): Job { val newContext = newCoroutineContext(context) val coroutine = if (start.isLazy) LazyStandaloneCoroutine(newContext, block) else StandaloneCoroutine(newContext, active = true) coroutine.start(start, coroutine, block) return coroutine } @ExperimentalCoroutinesApi public actual fun CoroutineScope.newCoroutineContext(context: CoroutineContext): CoroutineContext { val combined = coroutineContext + context val debug = if (DEBUG) combined + CoroutineId(COROUTINE_ID.incrementAndGet()) else combined return if (combined !== Dispatchers.Default && combined[ContinuationInterceptor] == null) debug + Dispatchers.Default else debug }
可以看到,默认情况下,会把当前的 coroutineContext 放在前面。
Kotlin的coroutine很好用,不过我感觉还是有点复杂,我也还在学习。
ref:
https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-dispatchers/index.html
到此这篇关于Android结合kotlin使用coroutine的文章就介绍到这了,更多相关Android结合kotlin使用coroutine内容请搜索小牛知识库以前的文章或继续浏览下面的相关文章希望大家以后多多支持小牛知识库!
Kotlin Coroutines - Use Cases on Android �� Learning Kotlin Coroutines for Android by example. �� Sample implementations for real-world Android use cases. �� Unit tests included! This repository is in
本文向大家介绍javascript的replace方法结合正则使用实例总结,包括了javascript的replace方法结合正则使用实例总结的使用技巧和注意事项,需要的朋友参考一下 本文实例总结了javascript的replace方法结合正则使用方法。分享给大家供大家参考,具体如下: replace()方法用于在字符串中用一些字符替换另一些字符,或者替换一个正则表达式匹配的字符串 例子一:直接
本文向大家介绍Android Kotlin环境使用ButterKnife的方法,包括了Android Kotlin环境使用ButterKnife的方法的使用技巧和注意事项,需要的朋友参考一下 Butter Knife 黄油刀大家应该都挺熟悉的,有这个之后,就不用写一堆的findViewById,体力活,最近试着玩玩Kotlin语言,也就尝试在Kotlin语言环境下使用ButterKnife,有一点
本文向大家介绍android使用mysql的方法总结,包括了android使用mysql的方法总结的使用技巧和注意事项,需要的朋友参考一下 android可以使用mysql数据库,android连接数据库的方式有两种。 第一种是通过连接服务器,再由服务器读取数据库来实现数据的增删改查,这也是我们常用的方式。 第二种方式是android直接连接数据库,这种方式非常耗手机内存,而且容易被反编译造成安全
本文向大家介绍Android Kotlin的使用及简单实例,包括了Android Kotlin的使用及简单实例的使用技巧和注意事项,需要的朋友参考一下 Android Kotlin的使用及简单实例 写在前面的话,作为一个不熬夜的人,一觉醒来发现Kotlin成为了Android的官方语言,可谓是大喜过望。为了趁热打铁,我决定提前三天放出原定本周日Release的文章。希望能及时让大家了解一下Kotl
本文向大家介绍Android shape和selector 结合使用实例代码,包括了Android shape和selector 结合使用实例代码的使用技巧和注意事项,需要的朋友参考一下 shape和selector是Android UI设计中经常用到的,比如我们要自定义一个圆角Button,点击Button有些效果的变化,就要用到shape和selector。可以这样说,shape和select