十六、Kotlin进阶学习:协程详细学习。

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"
}


版权声明:本文为weixin_43936741原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。