1、协程
coroutines
进程:程序的载体
线程:程序中代码块的载体。
协程:依然是线程,只不过是轻量级线程。通过协程库实现,内部实际上还是线程。
官方描述:协程通过将复杂性放入库来简化异步编程。程序的逻辑可以在协程中顺序地表达,而底层库会为我们解决其异步性。该库可以将用户代码的相关部分包装为回调、订阅相关事件、在不同线程(甚至不同机器)上调度执行,而代码则保持如同顺序执行一样简单。
协程就像非常轻量级的线程。线程是由系统调度的,线程切换或线程阻塞的开销都比较大。而协程依赖于线程,但是协程挂起时不需要阻塞线程,几乎是无代价的,协程是由开发者控制的。所以协程也像用户态的线程,非常轻量级,一个线程中可以创建任意个协程。
协程很重要的一点就是当它挂起的时候,它不会阻塞其他线程。协程底层库也是异步处理阻塞任务,但是这些复杂的操作被底层库封装起来,协程代码的程序流是顺序的,不再需要一堆的回调函数,就像同步代码一样,也便于理解、调试和开发。它是可控的,线程的执行和结束是由操作系统调度的,而协程可以手动控制它的执行和结束。
【案例】使用协程
(1)添加依赖
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.2"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.2"
(2)启动协程的方式:launch()、runBlocking()、
launch(CommonPool){
….
}
CommonPool是一个共享线程池。
项目结构:
build.gradle(Module):
activity_main.xml
MainActivity.kt
日志:
【案例 2】
协程是否阻塞线程?
观察:在开启协程时,其他按钮是否可点击?
区别:sleep和delay之间的差别
activity_main.xml
MainActivity.kt
测试:
【案例 3】
对比java中线程和kotlin中的协程
日志:
【案例 4 】
使用sleep和使用delay之间的差别
日志1:
日志2:
Kotlin协程的简单用法:1、GlobalScope(不建议使用);2、lifecycleScope、viewModelScope(建议使用);
2、挂起函数
挂起和阻塞操作的差别:
delay是挂起。
sleep是阻塞。
协程正是使用挂起操作,才避免了阻塞操作,更加充分利用系统资源。例如delay(1000L)就是一个挂起函数,在使用时,会将线程资源释放回去。
如何定义一个挂起函数?
使用suspend关键字
注意:
挂起函数只能在协程内部使用,不能在协程外部使用。
【案例】
日志:
3、如何启动主协程?
所谓主协程就是只有一条通路去执行代码,代码逐行执行。也就是在app的主线程(UI线程)上执行,会造成线程阻塞。
如何启动?
使用:
(1):Unit=runBlocking{}
【案例 1】 点击 启动主协程1 按钮
(2)runBlocking{}
【案例 2】 点击 启动主协程2 按钮
注意:
【案例 3】 点击 启动一般协程 按钮
参考代码:
activity_main.xml
MainActivity.kt
测试1:
点击“启动主协程1”按钮:
发现:
主协程与UI线程是同一个线程,会造成按钮卡顿
测试2:
点击“启动主协程2”按钮:
发现:
主协程与UI线程是同一个线程,会造成按钮卡顿
多个runBlocking会顺序执行
测试3:
点击“启动一般协程”按钮:
发现:
4、协程中的Job任务
为什么使用job?
一旦协程启动后,希望掌握协程的运行状态,就可以通过job来获取协程的状态。
Job任务的状态:
isNew,判断是否是一个新建的任务
isActive,判断是否是激活状态
isCompleted,判断是否完成状态
【案例1】
单纯的启动协程,主线程中直接观察,不等待协程的完成
日志:
【案例2】
启动协程,主线程中观察,等待协程的完成
日志:
【案例 3】
使用join()实现协程执行完毕后再执行
job.join()表示将协程执行完毕后,才可以执行后续代码,无需知道协程执行多久才可以完毕。
日志:
下一文章将继续介绍协程扩展内容
最新coroutine依赖为下:
dependencies {
// 协程核心库
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.0"
// 协程Android支持库
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.0"
// 协程Java8支持库
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:1.6.0"
// lifecycle对于协程的扩展封装
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.0"
implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.4.1"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.4.1"
}