kotlin-协程基本操作

kotlin-协程基本操作

一、什么是协程?
    1、协程是一个异步任务的解决方案,可以在不同的线程间来回切换,不会阻塞当前线程。
    2、是一种轻量级的线程,可以挂起和恢复执行。
    
二、协程的特性
    1、挂起和恢复:协程可以在执行过程中被挂起,稍后再恢复执行。能够高效的处理耗时的操作,比如网络请求或读写文件。
    2、轻量级:协程的创建和销毁非常小,通常可以在同一线程中创建成千上万的协程,而不必担心内存和性能问题。
    3、可组合性:协程可以与其他协程进行组合,方便地构建复杂的异步操作。
    
三:创建协程的三种方式:
    1、runBlock{}    
    2、GlobalScope.launch{}
    3、CoroutineScope(Dispatchers.IO).launch{}
    
四:工作原理
    协程是通过suspend函数和CoroutineScope来实现的,协程的基本构建块是挂起函数,这些函数可以在协程中调用,并且可以被挂起。
    
五:suspend关键字
    什么是挂起?不影响主线程的工作,理解为切换到一个指定的线程。
    1、suspend函数是可以在协程中挂起的函数,它们的调用不会阻塞线程,而是将协程挂起,直到操作完成。    
    2、可以看成是一种提醒,表示这是一个耗时方法,不能直接执行,需要在协程中或者被suspend修饰的方法中调用,所以我们在写某个耗时方法的时候需要给它加上suspend关键字,可以有效避免我们在主线程中调用耗时操作造成应用卡顿的情况。

六:runBlocking、launch、async操作符
    1、runBlocking :会阻塞当前线程,等待suspend返回的结果
    2、launch:非阻塞,启动一个协程,不返回结果
    3、async:启动一个协程并返回Deferred对象,可以通过该对象获取结果
    4、delay:延迟操作
    5、withContext:用来在不同的上下文(Context)中执行代码,并在代码执行完毕后返回结果,指定协程执行的线程和启动模式。会阻塞当前协程,直到指定的上下文代码执行完毕,并返回结果。
    
七:协程调度器
    1、Dispatchers.Main:用于在主线程中执行协程,适用于UI更新
    2、Dispatchers.IO:用于进行I/O操作的协程,适用于网络请求或者文件操作
    3、Dispatchers.Default:用于执行CPU密集型任务的协程
        
八:协程的生命周期:
    1、GlobalScope:是应用、进程(process)级别,Activity销毁,协程依然还执行,存在整个app生命周期。适用于执               行长期运行的异步任务,比如定时任务。
    2、MainScope:跟Activity生命周期一样,Activity销毁,MainScope也被销毁。指定了Dispatchers.Main作为其默认协程
    调度器
    3、CoroutineScope:协程作用域,是一个接口,具体实现类:GlobalScope、MainScope
    4、ContextScope:上下文作用域
    5、LifecycleScope:只能在Activity、Fragment中使用,跟Activity生命周期关联,Activity销毁就不存在
    6、ViewModelScope:只能在ViewModel中使用,绑定ViewModel的生命周期
    
九:协程的优势:
    1、简化异步代码:使用协程,可以同步的方式编写异步代码,使代码更加易于理解和维护    
    2、减少回调地狱:传统的异步编程通常依赖于回调函数,容易导致“回调地狱”,而协程通过挂起函数解决了这个问题
    3、轻量级和高效:协程的上下文切换开销非常小,可以在同一线程中高效管理多个线程

例子:

package com.example.androidkotlindemo2.testcoroutine

import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.async
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import org.junit.Test
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter

/**
 * Author : wn
 * Email : maoning20080809@163.com
 * Date : 2024/11/10 9:42
 * Description : 测试协程
 */
class TestCoroutine {

    @Test
    fun test(){
        test1Suspend()
        //testLaunch()
        //testAsync()
        //testWithContext()
    }

    private fun test1Suspend(){
        println("${getTime()} fetchData 1")

        runBlocking {
            //有返回值
            var result = fetchData()
            println("${getTime()} fetchData 3 result : ${result}")
        }

        var job1 = CoroutineScope(Dispatchers.IO).launch {
            //调用没有返回值
            var result = fetchData()
            println("${getTime()} fetchData 4 result : ${result}")
            "test1Suspend job1"
        }
        println("${getTime()} fetchData 5 job1 : ${job1}, ${job1.isCompleted}")

        val deferred = GlobalScope.async {
            //调用没有返回值
            var result = fetchData()
            println("${getTime()} fetchData 6 result : ${result}")
        }

        println("${getTime()} fetchData 7 result : ${deferred.isCompleted}")

        println("${getTime()} fetchData 2")
    }

    /**
     * 非阻塞,启动一个协程,不返回结果
     */
    private fun testLaunch(){
        CoroutineScope(Dispatchers.IO).launch {
            println("${getTime()} testLaunch fetchData a1 ------")
            var resul1 = fetchData()
            println("${getTime()} testLaunch fetchData a1 ------ ${resul1}")
        }

        var jon2 = CoroutineScope(Dispatchers.IO).launch {
            println("${getTime()} testLaunch fetchData a2 ------")
            var resul2 = fetchData()
            println("${getTime()} testLaunch fetchData a2 ------ ${resul2}")
            "testLaunch2 result2 = ${resul2}"
        }
        println("${getTime()} testLaunch fetchData a2 jon2 ------ ${jon2}")
        //runBlocking会阻塞当前主线程,也就是Dispatchers.Main会等待runBlocking执行完成后,才去执行。这是AndroidJUnitRunner测试代码,真实环境,把前面2个Dispatchers.IO替换为Dispatchers.Main能看出效果
        runBlocking {
            //想要获取fetchData()返回的值往外传递,必须使用runBlocking、Dispatchers.IO、await()
            var job3 = CoroutineScope(Dispatchers.IO).async {
                println("${getTime()} testLaunch fetchData a3 ------")
                var resul3 = fetchData()
                println("${getTime()} testLaunch fetchData a3 ------ ${resul3}")
                "testLaunch2 result3 = ${resul3}"
            }

            var job3Result = job3.await()
            println("${getTime()} testLaunch fetchData a3 job3 ------ ${job3Result}")
        }
    }

    /**
     * 测试Async:启动一个协程并返回Deferred对象,可以通过该对象获取结果
     */
    private fun testAsync(){
        //runBlocking会阻塞线程,等待异步返回的结果
        runBlocking {
            println("${getTime()} fetchData a1 ------")
            var resul1 = fetchData()
            println("${getTime()} fetchData a2 resul1 : ${resul1}")
        }
        println("${getTime()} ------------- testAsync  ----------")
        runBlocking {
            //在线程中开启子协程
            var job2 = CoroutineScope(Dispatchers.IO).async {
                println("${getTime()} fetchData b1 ------")
                var result2 = fetchData()
                println("${getTime()} fetchData b3 result2 : ${result2}")
                "my job2 resul2 ${result2}"
            }
            //b1和b2,没有固定的执行顺序,所以async和job2.await()之间,不要执行任何语句
            println("${getTime()} fetchData b2 job2 : ${job2}")
            //会等待fetchData()执行完成,再执行后面的语句,等待async返回的结果
            var job2Result = job2.await()
            println("${getTime()} fetchData b4 ${job2Result}")
        }
        println("${getTime()} -------22------ testAsync  ------22----")
        //可以异步调用,但是没有不能使用fetchData返回结果,得处理suspend
        var job3 = CoroutineScope(Dispatchers.IO).async {
            var result3 = fetchData()
            "my job3 result3 ${result3}"
        }
        //不能使用await,
        //var job3Result = job3.await()
        println("${getTime()} fetchData job3 ${job3}")
    }

    /**
     * delay:延迟操作,挂起函数
     */
    private suspend fun testDelay(){
        runBlocking {
            delay(1000)
            var result1 = fetchData()
        }

        MainScope().launch {
            delay(100)
        }

        CoroutineScope(Dispatchers.IO).launch{
            delay(100)
        }

        GlobalScope.launch {
            delay(100)
        }

    }

    private fun testWithContext(){
        runBlocking {
            //更新UI
            withContext(Dispatchers.IO){

            }

            //执行异步耗时任务
            withContext(Dispatchers.IO){
                fetchData()
            }
        }
    }

    private suspend fun fetchData() : String{
        println("${getTime()} fetchData aa ")
        delay(1000)
        return "数据加载中。。。"
    }

    private fun getTime() : String{
        val currentDateTime = LocalDateTime.now()
        val currentFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss SSS")
        val formatDateTime = currentDateTime.format(currentFormat)
        return formatDateTime
    }


}
<think>嗯,用户的问题是关于Kotlin 1.3.40中kotlin-stdlib-jdk7和kotlin-stdlib的区别以及它们的用法差异。我需要先回顾之前的对话,确保回答的一致性。用户之前遇到了ARouter的问题,现在转向了Kotlin标准库的不同版本的问题。 首先,用户引用了四个参考资料,其中提到了一些版本变更,比如将jre7改为jdk7,还有协程库的版本问题。这可能意味着用户在使用旧版本时遇到了兼容性问题,或者需要明确不同库之间的区别。 我需要先解释这两个库的基本区别。kotlin-stdlib是Kotlin的核心标准库,而kotlin-stdlib-jdk7是扩展库,针对JDK7以上的API进行扩展。在Kotlin 1.3.40的版本中,这些库的使用有什么不同呢? 根据用户提供的引用[1],原来的jre7被替换为jdk7,这可能是因为JDK的命名从JRE改为JDK,所以库的命名也随之改变。因此,在Kotlin 1.3.x版本中,应该使用jdk7而不是jre7。需要指出这一点,避免用户混淆。 然后,用户提到不同版本下的用法差异。比如在Kotlin 1.1到1.2版本中,可能需要显式添加jdk7或jdk8的库,而1.3之后可能自动包含。但需要确认具体版本的变化,确保回答准确。 另外,用户之前的回答中提到了ARouter的问题,可能与Kotlin版本和注解处理器有关。所以,在回答时可能需要提到版本兼容性对库选择的影响,特别是在多模块或混合Java/Kotlin项目中的注意事项。 用户可能需要了解如何正确配置依赖,尤其是在Gradle中如何声明这些库,以及不同版本之间的兼容性。例如,引用[2]提到Kotlin协程需要1.3.+版本,并且Gradle插件版本要3.0.0以上。这可能与标准库的版本选择有关联,需要指出。 还要注意用户的问题中提到的是Kotlin 1.3.40,这个版本是否有什么特殊之处?比如是否在1.3.40中,stdlib的结构有变化,或者是否推荐使用某个特定的库版本。 另外,用户引用的资料中有关于Gradle插件版本的配置,比如使用3.6.0-alpha12,这可能影响构建过程,但用户现在的问题是关于标准库的差异,可能需要简要提及构建配置中的相关部分,但重点还是库的区别。 总结一下,回答的结构应该是先介绍两个库的基本区别,然后说明在Kotlin 1.3.40中的具体用法,包括依赖配置、版本兼容性,以及可能遇到的常见问题,比如重复依赖或版本冲突。同时,结合用户之前的ARouter问题,指出正确选择库的重要性,以避免类似的问题再次发生。 需要确保回答准确,并且参考用户提供的引用资料,特别是关于版本替换的部分,比如jre7改为jdk7,以及协程库的版本要求。同时,用户可能希望知道在混合项目中的最佳实践,比如是否需要同时引入两个库,或者如何避免依赖冲突。 最后,生成的相关问题需要与当前主题相关,比如版本升级的影响、依赖冲突解决、多JDK版本的支持等,帮助用户进一步了解可能遇到的问题。</think>### Kotlin 1.3.40 中 `kotlin-stdlib-jdk7` 与 `kotlin-stdlib` 的区别及用法解析 --- #### 一、核心区别 1. **`kotlin-stdlib`** - **基础标准库**:包含Kotlin语言的核心API,例如集合操作、协程基础、字符串处理等。 - **最低兼容性**:支持所有JDK版本(包括JDK 6+)。 - **依赖声明**: ```gradle implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" ``` 2. **`kotlin-stdlib-jdk7`** - **扩展标准库**:在`kotlin-stdlib`基础上,扩展了针对**JDK 7+**的API支持,例如: - `AutoCloseable`扩展(如`use`函数) - `Path`和`Files`的Kotlin DSL - JDK 7的时间日期API适配(如`java.nio.file`相关操作) - **依赖声明**: ```gradle implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" ``` --- #### 二、在 Kotlin 1.3.40 中的使用差异 | 场景 | `kotlin-stdlib` | `kotlin-stdlib-jdk7` | |--------------------------|-------------------------------------|-------------------------------------| | **JDK版本要求** | JDK 6+ | JDK 7+ | | **功能覆盖** | 基础Kotlin功能 | 基础功能 + JDK 7扩展API | | **混合项目兼容性** | 通用 | 需确保项目JDK版本 ≥7 | | **依赖冲突处理** | 自动包含在Kotlin插件中[^1] | 需显式声明,与`kotlin-stdlib`共存 | --- #### 三、版本适配规则 1. **Kotlin 1.1-1.2 版本** - `kotlin-stdlib`默认包含**JDK 6**兼容实现。 - 如需使用JDK 7/8扩展API,必须显式添加`kotlin-stdlib-jdk7`或`kotlin-stdlib-jdk8`。 2. **Kotlin 1.3+ 版本(含1.3.40)** - **自动依赖传递**: `kotlin-stdlib-jdk7`会**自动包含`kotlin-stdlib`**,无需重复声明[^1]。 - **版本对齐要求**: 所有Kotlin库版本需严格一致(如协程库`kotlinx-coroutines-core`也需使用1.3.x版本)[^2]。 --- #### 四、典型配置示例(Kotlin 1.3.40) ```gradle // build.gradle (Module) dependencies { // 基础库(自动包含kotlin-stdlib) implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.40" // 协程库(需版本对齐) implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.0-M2" } ``` --- #### 五、常见问题解决 1. **`jre7`与`jdk7`命名差异** - **历史遗留问题**:早期版本使用`kotlin-stdlib-jre7`,自Kotlin 1.2起统一改为`kotlin-stdlib-jdk7`[^1]。 - **错误示例**: ```gradle // 已废弃的写法(会导致依赖缺失) implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:1.3.40" ``` 2. **版本冲突警告** 若出现类似`Conflict with dependency 'org.jetbrains.kotlin:kotlin-stdlib'`错误,添加强制版本约束: ```gradle configurations.all { resolutionStrategy { force "org.jetbrains.kotlin:kotlin-stdlib:1.3.40" } } ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王宁-Android

你的鼓励是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值