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()
    }
}

相关推荐

  1. kotlin学习总结

    2024-02-21 12:30:05       32 阅读
  2. Kotlin学习之-02

    2024-02-21 12:30:05       30 阅读
  3. Kotlin

    2024-02-21 12:30:05       39 阅读
  4. Kotlin SharingStarted

    2024-02-21 12:30:05       37 阅读
  5. 快速入门Kotlin

    2024-02-21 12:30:05       18 阅读
  6. kotlin相关

    2024-02-21 12:30:05       13 阅读
  7. Kotlin->Kotlin作用域

    2024-02-21 12:30:05       14 阅读
  8. Kotlin : Coroutines —简单应用

    2024-02-21 12:30:05       33 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-02-21 12:30:05       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-02-21 12:30:05       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-02-21 12:30:05       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-02-21 12:30:05       20 阅读

热门阅读

  1. 3DTile是不是没有坐标的选择?

    2024-02-21 12:30:05       30 阅读
  2. flask get请求

    2024-02-21 12:30:05       23 阅读
  3. 511. 游戏玩法分析 I

    2024-02-21 12:30:05       34 阅读
  4. 实现一个Windows环境一键启停Oracle的bat脚本

    2024-02-21 12:30:05       28 阅读
  5. WPS AI功能测试

    2024-02-21 12:30:05       38 阅读
  6. git 创建远程分支和本地分支,并将分支关联

    2024-02-21 12:30:05       28 阅读
  7. 正则表达式的一些高级用法

    2024-02-21 12:30:05       31 阅读