加入收藏 | 设为首页 | 会员中心 | 我要投稿 湖南网 (https://www.hunanwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 业界 > 正文

如何正确的在 Android 上使用 Kotlin 协程?

发布时间:2019-10-24 15:17:41 所属栏目:业界 来源:kengsirLi
导读:媒介 你还记得是哪一年的 Google IO 正式公布 Kotlin 成为 Android 一级开拓说话吗?是 Google IO 2017 。现在两年时刻已往了,站在一名 Android 开拓者的角度来看,Kotlin 的生态情形越来越好了,相干的开源项目和进修资料也日渐富厚,身边乐意去行使可能
副问题[/!--empirenews.page--]

媒介

你还记得是哪一年的 Google IO 正式公布 Kotlin 成为 Android 一级开拓说话吗?是 Google IO 2017 。现在两年时刻已往了,站在一名 Android 开拓者的角度来看,Kotlin 的生态情形越来越好了,相干的开源项目和进修资料也日渐富厚,身边乐意去行使可能试用 Kotlin 的伴侣也变多了。常年混迹掘金的我也能明明感受到 Kotlin 标签下的文章逐步变多了(着实如故少的可怜)。本年的 Google IO 也放出了 Kotlin First 的标语,很多新的 API 和成果特征将优先提供 Kotlin 支持。以是,时至今天,其实找不到安卓开拓者不学 Kotlin 的来由了。

本日想聊聊的是 Kotlin Coroutine。固然在 Kotlin 宣布之初就有了协程,可是直到 2018 年的 KotlinConf 大会上,JetBrain 宣布了 Kotlin1.3RC,这才带来了不变版的协程。纵然不变版的协程已经宣布了一年之余,可是仿佛并没有足够多的用户,至少在我看来是这样。在我进修协程的各个阶段中,碰着题目都鲜有处所可以告急,抛到技能群根基就石沉大海了。根基只能靠一些英文文档来办理题目。

在看完官方文档的很长一段时刻,我险些只知道 GlobalScope。简直,官方文档上根基从新到尾都是在用 GlobalScope 写示例代码。以是一部门开拓者,也包罗我本身,在写本身的代码时也就直接 GlobalScope 了。一次偶尔的机遇才发明其拭魅这样的题目是很大的。在 Android 中,一样平常是不提议直接行使 GlobalScope 的。那么,在 Android 中应该怎样正确行使协程呢?再细分一点,怎样直接在 Activity 中行使呢?怎样共同 ViewModel 、LiveData 、LifeCycle 等行使呢?我会通过简朴的示例代码来叙述 Android 上的协程行使,你也可以随着下手敲一敲。

怎样正确的在 Android 上行使 Kotlin 协程?

协程在 Android 上的行使

GlobalScope

在一样平常的应用场景下,我们都但愿可以异步举办耗时使命,好比收集哀求,数据处理赏罚等等。当我们分开当前页面的时辰,也但愿可以打消正在举办的异步使命。这两点,也正是行使协程中所必要留意的。既然不提议直接行使 GlobalScope,我们就先试验一下行使它会是什么结果。

  1. private fun launchFromGlobalScope() { 
  2.  GlobalScope.launch(Dispatchers.Main) { 
  3.  val deferred = async(Dispatchers.IO) { 
  4.  // network request 
  5.  delay(3000) 
  6.  "Get it" 
  7.  } 
  8.  globalScope.text = deferred.await() 
  9.  Toast.makeText(applicationContext, "GlobalScope", Toast.LENGTH_SHORT).show() 
  10.  } 

在 launchFromGlobalScope() 要领中,我直接通过 GlobalScope.launch() 启动一个协程,delay(3000) 模仿收集哀求,三秒后,会弹出一个 Toast 提醒。行使上是没有任何题目的,可以正常的弹出 Toast 。可是当你执行这个要领之后,当即按返回键返回上一页面,如故会弹出 Toast 。假如是现实开拓中通过收集哀求更新页面的话,当用户已经不在这个页面了,就基础没有须要再去哀求了,只会挥霍资源。GlobalScope 显然并不切合这一特征。https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-global-scope/index.html 中着实也具体声名白,如下所示:

  1. Global scope is used to launch top-level coroutines which are operating on the whole application lifetime and are not cancelled prematurely. Another use of the global scope is operators running in Dispatchers.Unconfined, which don’t have any job associated with them. 
  2.  
  3. Application code usually should use an application-defined CoroutineScope. Using async or launch on the instance of GlobalScope is highly discouraged. 

大抵意思是,Global scope 凡是用于启动顶级协程,这些协程在整个应用措施生命周期内运行,不会被过早地被打消。措施代码凡是应该行使自界说的协程浸染域。直接行使 GlobalScope 的 async 可能 launch 要领是凶猛不提议的。

GlobalScope 建设的协程没有父协程,GlobalScope 凡是也不与任何生命周期组件绑定。除非手动打点,不然很难满意我们现实开拓中的需求。以是,GlobalScope 能不消就只管不消。

MainScope

官方文档中提到要行使自界说的协程浸染域,虽然,Kotlin 已经给我们提供了吻合的协程浸染域 MainScope 。看一下 MainScope 的界说:

  1. public fun MainScope(): CoroutineScope = ContextScope(SupervisorJob() + Dispatchers.Main) 

记取这个界说,在后头 ViewModel 的协程行使中也会小心这种写法。

给我们的 Activity 实现本身的协程浸染域:

  1. class BasicCorotineActivity : AppCompatActivity(), CoroutineScope by MainScope() {} 

通过扩展函数 launch() 可以直接在主线程中启动协程,示例代码如下:

  1. private fun launchFromMainScope() { 
  2.  launch { 
  3.  val deferred = async(Dispatchers.IO) { 
  4.  // network request 
  5.  delay(3000) 
  6.  "Get it" 
  7.  } 
  8.  mainScope.text = deferred.await() 
  9.  Toast.makeText(applicationContext, "MainScope", Toast.LENGTH_SHORT).show() 
  10.  } 

(编辑:湖南网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读