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

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

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

最后别忘了在 onDestroy() 中打消协程,通过扩展函数 cancel() 来实现:

  1. override fun onDestroy() { 
  2.  super.onDestroy() 
  3.  cancel() 

此刻来测试一下 launchFromMainScope() 要领吧!你会发明这完全切合你的需求。现实开拓中可以把 MainScope 整合到 BaseActivity 中,就不必要反回信写模板代码了。

ViewModelScope

假如你行使了 MVVM 架构,基础就不会在 Activity 上誊写任何逻辑代码,更别说启动协程了。这个时辰大部门事变就要交给 ViewModel 了。那么如安在 ViewModel 中界说协程浸染域呢?还记得上面 MainScope() 的界说吗?没错,搬过来直接行使就可以了。

  1. class ViewModelOne : ViewModel() { 
  2.  private val viewModelJob = SupervisorJob() 
  3.  private val uiScope = CoroutineScope(Dispatchers.Main + viewModelJob) 
  4.  val mMessage: MutableLiveData<String> = MutableLiveData() 
  5.  fun getMessage(message: String) { 
  6.  uiScope.launch { 
  7.  val deferred = async(Dispatchers.IO) { 
  8.  delay(2000) 
  9.  "post $message" 
  10.  } 
  11.  mMessage.value = deferred.await() 
  12.  } 
  13.  } 
  14.  override fun onCleared() { 
  15.  super.onCleared() 
  16.  viewModelJob.cancel() 
  17.  } 

这里的 uiScope 着实就等同于 MainScope。挪用 getMessage() 要领和之前的 launchFromMainScope() 结果也是一样的,记得在 ViewModel 的 onCleared() 回调里打消协程。

你可以界说一个 BaseViewModel 来处理赏罚这些逻辑,停止反回信写模板代码。然而 Kotlin 就是要让你做同样的事,写更少的代码,于是 viewmodel-ktx 来了。看到 ktx ,你就应该大白它是来简化你的代码的。引入如下依靠:

  1. implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0-alpha03" 

然后,什么都不必要做,直接行使协程浸染域 viewModelScope 就可以了。viewModelScope 是 ViewModel 的一个扩展属性,界说如下:

  1. val ViewModel.viewModelScope: CoroutineScope 
  2.  get() { 
  3.  val scope: CoroutineScope? = this.getTag(JOB_KEY) 
  4.  if (scope != null) { 
  5.  return scope 
  6.  } 
  7.  return setTagIfAbsent(JOB_KEY, 
  8.  CloseableCoroutineScope(SupervisorJob() + Dispatchers.Main)) 
  9.  } 

看下代码你就应该大白了,照旧认识的那一套。当 ViewModel.onCleared() 被挪用的时辰,viewModelScope 会自动打消浸染域内的全部协程。行使示譬喻下:

  1. fun getMessageByViewModel() { 
  2.  viewModelScope.launch { 
  3.  val deferred = async(Dispatchers.IO) { getMessage("ViewModel Ktx") } 
  4.  mMessage.value = deferred.await() 
  5.  } 

写到这里,viewModelScope 是能满意需求的最简写法了。现实上,写完全篇,viewModelScope 如故是我以为的最好的选择。

LiveData

Kotlin 同样为 LiveData 赋予了直接行使协程的手段。添加如下依靠:

  1. implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.2.0-alpha03" 

直接在 liveData {} 代码块中挪用必要异步执行的挂起函数,并挪用 emit() 函数发送处理赏罚功效。示例代码如下所示:

  1. val mResult: LiveData<String> = liveData { 
  2.  val string = getMessage("LiveData Ktx") 
  3.  emit(string) 

你也许会好奇这里仿佛并没有任何的表现挪用,那么,liveData 代码块是在什么执行的呢?当 LiveData 进入 active 状态时,liveData{ } 会自动执行。当 LiveData 进入 inactive 状态时,颠末一个可设置的 timeout 之后会自动打消。假如它在完成之前就打消了,当 LiveData 再次 active 的时辰会从头运行。假如上一次运行乐成竣事了,就不会再从头运行。也就是说只有自动打消的 liveData{ } 可以从头运行。其他缘故起因(好比 CancelationException)导致的打消也不会从头运行。

(编辑:湖南网)

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

热点阅读