Kotlin 协程的简单学习使用 - Go语言中文社区

Kotlin 协程的简单学习使用


Kotlin 协程的简单学习使用

参考文章:如何正确的在 Android 上使用协程 ?

引入

Android 引入协程

//Coroutines
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.2.1'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.2.1'

1、直接使用GlobalScope

直接使用GlobalScope,启动一个协程,并模拟延迟返回数据。
此方法会存在一个问题,Activity退出后,依然会获取到数据和弹出Toast。

mTvShow.setOnClickListener {
    GlobalScope.launch(Dispatchers.Main) {
        val deferred = async(Dispatchers.IO) {
            delay(3000)
            "数据返回了"
        }
        mTvShow.text = deferred.await()
        Toast.makeText(applicationContext, "数据返回", Toast.LENGTH_SHORT).show()
    }
}

2、使用MainScope

MainScope是官方定义的适合的协程作用域。官方是这样定义的。

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

我们可以这样使用MainScope

首先实现接口

class MainActivity : AppCompatActivity(), CoroutineScope by MainScope()

然后使用MainScope请求数据

launch {
    val deferred = async(Dispatchers.IO) {
        delay(3000)
        "数据返回了"
    }
    mBtn1.text = deferred.await()
    Toast.makeText(applicationContext, "MainScope", Toast.LENGTH_SHORT).show()
}

最后在退出时,取消协程

override fun onDestroy() {
    super.onDestroy()
    cancel()
}

3、ViewModel中使用协程

ViewModel使用愈来愈频繁,所以还应该学习在ViewModel中使用协程。

首先创建协程

 private val viewModelJob = SupervisorJob()
 private val mainScope = CoroutineScope(Dispatchers.Main + viewModelJob)

获取数据,并将数据返回到LiveData

val message: MutableLiveData<String> = MutableLiveData()
fun getMessage() {
    mainScope.launch {
        val deferred = async(Dispatchers.IO) {
            delay(3000)
            Log.e("AppKt","数据返回了")
            "数据返回了"
        }
        message.value = deferred.await()
    }
}

在ViewModel退出时,需要结束协程

override fun onCleared() {
    super.onCleared()
    mainScope.cancel()
}

4、ViewModel 拓展

上一个方法,ViewModel中使用协程,需要每个ViewModel都自己定义,所以可以使用ktx拓展的viewModelScope。

引入ktx拓展

//ViewModel KTX
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0-alpha03"

viewModelScope是ViewModel的一扩展属性,关闭时自动取消协程

val ViewModel.viewModelScope: CoroutineScope
        get() {
            val scope: CoroutineScope? = this.getTag(JOB_KEY)
            if (scope != null) {
                return scope
            }
            return setTagIfAbsent(JOB_KEY,
                CloseableCoroutineScope(SupervisorJob() + Dispatchers.Main))
        }

internal class CloseableCoroutineScope(context: CoroutineContext) : Closeable, CoroutineScope {
    override val coroutineContext: CoroutineContext = context

    override fun close() {
        coroutineContext.cancel()
    }
}

使用更为简单

val message: MutableLiveData<String> = MutableLiveData()
fun getMessage(){
    viewModelScope.launch {
        val deferred = async(Dispatchers.IO){
            delay(3000)
            Log.e("AppKt","数据返回了")
            "数据返回了"
        }
        message.value = deferred.await()
    }
}
版权声明:本文来源简书,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://www.jianshu.com/p/96354fc8d30c
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-01-12 13:04:14
  • 阅读 ( 1368 )
  • 分类:

0 条评论

请先 登录 后评论

官方社群

GO教程

推荐文章

猜你喜欢