Android中的Coroutine协程原理详解

本文深入探讨了Android中Kotlin的Coroutine协程原理,包括协程的生态架构、相关依赖库和为何协程概念让人困惑。通过复习Kotlin函数基础知识,如函数类型、函数引用和Lambda,解释了挂起函数的工作机制。文章详细分析了标准库提供的挂起函数工具,如createCoroutineUnintercepted,揭示了协程如何将异步回调代码转换为同步形式,以及SafeContinuation在协程中的作用。
摘要由CSDN通过智能技术生成

Coroutine

前言

协程是一个并发方案。也是一种思想。

传统意义上的协程是单线程的,面对io密集型任务他的内存消耗更少,进而效率高。但是面对计算密集型的任务不如多线程并行运算效率高。

不同的语言对于协程都有不同的实现,甚至同一种语言对于不同平台的操作系统都有对应的实现。

我们kotlin语言的协程是 coroutines for jvm的实现方式。底层原理也是利用java 线程。

基础知识

生态架构

QQ截图20220228141259-16460288074381.png

相关依赖库

dependencies {
   // Kotlin
   implementation "org.jetbrains.kotlin:kotlin-stdlib:1.4.32"

   // 协程核心库
   implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.3"
   // 协程Android支持库
   implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.3"
   // 协程Java8支持库
   implementation "org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:1.4.3"
 
   // lifecycle对于协程的扩展封装
   implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0"
   implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.2.0"
   implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.2.0"
}
​

为什么一些人总觉得协程晦涩难懂?

1.网络上没有详细的关于协程的概念定义,每种语言、每个系统对其实现都不一样。可谓是众说纷纭,什么内核态用户态巴拉巴拉,很容易给我们带偏

2.kotlin的各种语法糖对我们造成的干扰。如:

  • 高阶函数
  • 源码实现类找不到

所以扎实的kotlin语法基本功是学习协程的前提。

实在看不懂得地方就反编译为java,以java最终翻译为准。

协程是什么?有什么用?

kotlin中的协程干的事就是把异步回调代码拍扁了,捋直了,让异步回调代码同步化。除此之外,没有任何特别之处。

创建一个协程,就是编译器背后偷偷生成一系列代码,比如说状态机

通过挂起恢复让状态机状态流转实现把层层嵌套的回调代码变成像同步代码那样直观、简洁。

它不是什么线程框架,也不是什么高深的内核态,用户态。它其实对于咱们安卓来说,就是一个关于回调函数的语法糖。。。

本文将会围绕挂起恢复彻底剖析协程的实现原理

Kotlin函数基础知识复习

再Kotlin中函数是一等公民,有自己的类型

函数类型
fun foo(){}
//类型为 () -> Unit
fun foo(p: Int){}
//类型为 (Int) -> String

class Foo{
    fun bar(p0: String,p1: Long):Any{}
    
}
//那么 bar 的类型为:Foo.(String,Long) -> Any
//Foo就是bar的 receiver。也可以写成 (Foo,String,Long) ->Any

函数引用
fun foo(){} 
//引用是 ::foo
fun foo(p0: Int): String
//引用也是 ::foo

咋都一样?没办法,就这样规定的。使用的时候 只能靠编译器推断

val f: () -> Unit = ::foo //编译器会推断出是fun foo(){} 
val g: (Int) -> String = ::foo //推断为fun foo(p0: Int): String

带Receiver的写法

class Foo{
    fun bar(p0: String,p1: Long):Any{}
}

val h: (Foo,String,Long) -> Any = Foo:bar

绑定receiver的函数引用:

val foo: Foo = Foo()
val m: (String,Long) -> Any = foo:bar

额外知识点

val x: (Foo,String,Long) -> Any = Foo:bar
val y: Function3<Foo,String,Long,Any> = x

Foo.(String,Long) -> Any = (Foo,String,Long) ->Any = Function3<Foo,String,Long,Any>

函数作为参数传递
fun yy(p: (Foo,String,Long)->Any){
	p(Foo(),"Hello",3L)//直接p()就能调用
    //p.invoke(Foo(),"Hello",3L) 也可以用invoke形式
}

Lambda

就是匿名函数,它跟普通函数比是没有名字的,听起来好像是废话

//普通函数
fun func(){
   println("hello");
}
​
//去掉函数名 func,就成了匿名函数
fun(){
   println("hello");    
}
​
//可以赋值给一个变量
val func = fun(){
   println("hel
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值