kotlin协程学习总结

1.协程是什么?

kotlin中的协程是基于协程框架Coroutine实现的轻量级线程,提供一种简化处理异步任务的方式。

2.怎么使用协程?

使用协程框架中的launch方法包裹的代码块就是协程的内容,常规的代码如下:

val coroutineScope = CoroutineScope(context)
coroutineScope.launch {
    getImage(imageId)
}

在实际的项目中,我们通常使用ViewModel.viewModelScope来直接使用launch函数:

// 这里定义了一个高阶函数,便于其他调用的地方直接传入携程代码块
//viewModelScope.launch 函数用于创建并启动一个新的协程,以异步执行一段代码块,不会阻塞当前主线程
// viewModelScope是属于ViewModel的扩展属性,方便在ViewModel中使用协程,并且可以监测Activity或者Fragment的生命周期,然后自动取消,避免内存泄漏
private fun launch(block: suspend () -> Unit, error: suspend (Throwable) -> Unit) = viewModelScope.launch {
        try {
            block()
        } catch (e: Throwable) {
            error(e)
        }
    }

3.怎么理解挂起?

viewModelScope.launch {
	var heFengCity = repository.transPortAdCodeToLocationID(areaid)
	Toast.makeText(CoolWeatherApplication.context, heFengCity, Toast.LENGTH_SHORT)
}
......
suspend fun transPortAdCodeToLocationID(adcode: String) : HeFengCity = withContext(Dispatchers.IO) {
       var city = hefengNetWork.fetchFefengLocation(adcode)
        caCheCurrentName(city?.location?.get(0)?.name)
        city
    }

当执行到transPortAdCodeToLocationID函数的时候,launch中的协程代码就会被切换到另外的IO线程执行,相当于是在当前线程做了一个post的动作,并不会阻塞当前线程的继续执行。当协程代码中的transPortAdCodeToLocationID方法在IO线程执行完之后,会自动切换回之前的线程,并执行toast方法。这样在遇到suspend方法发生线程切换执行,在完成方法执行之后再切换回来原来线程的过程,就叫做挂起。

4.suspend关键字的作用

使用suspend关键字修饰的方法,表示这是一个挂起函数。但仅仅是有suspend,是不能实现挂起的动作的,挂起的动作是由协程内部框架帮我们实现的,即需要直接或者间接调用协程系统内部的suspend方法。比如这里的就调用了withContext方法,它就是协程框架提供的挂起函数。
同时,一个挂起函数,只能在协程代码块中被调用或者被另一个挂起函数调用,最终还是要在协程代码块中被调用,不然就会报错误:

fun getImage(imageId: Int) = withContext(Dispatchers.IO) {
    // IDE 报错 Suspend function'withContext' should be called only from a coroutine or another suspend funcion
}

5.什么是非阻塞式挂起

既然协程挂起可以实现切线程,那肯定就不会阻塞当前的线程了。至于为什么叫非阻塞式挂起,是因为在实现协程代码的时候,是使用了看似阻塞式的书写方式,但是又实现了非阻塞式的效果。如:

main {
    GlobalScope.launch(Dispatchers.Main) {
        val user = suspendingRequestUser() // 耗时操作
        updateView(user)
    }
    
    private suspend fun suspendingRequestUser() : User = withContext(Dispatchers.IO) {
        api.requestUser()
    }
}

你可能感兴趣的:(kotlin,kotlin,开发语言,协程)