Android Kotlin:协程

目录:

1)协程是什么?

2)协程和线程的关系?

3)协程如何使用?切线程是什么

4)挂起函数是什么?

5)withContext和lanuch的区别在哪里?

6)Defualt、IO和Main的区别

7)lifecycleScope

一、协程是什么?

协程就是用线程来实现的并发管理库,简单来说就是对线程的封装。那么他的作用是什么?

下面我们来看看一个例子。

以前java

java 复制代码
Thread {
            //进行耗时操作:比如Http操作
            var user = api.getUser()
            runOnUiThread {
                tvName.text = user.getName()
                //处理后,切换到UI线程,将数据显示出来。
            }
        }.start()

现在协程

kotlin 复制代码
 CoroutineScope(Dispatchers.Main).launch {
            var user = api.getUser()
                tvName.text = user.getName()
}

以前我们要进行一些耗时操作,需要另外起来一个线程,线程处理后,如果要将数据回显到UI,还需要使用方法切换的UI线程。然而,如果使用了协程,这些步骤全部都被封装了起来,我们可以用串行的方式写并行的代码。

二、协程和线程的关系

通过下面这张图,我们可以看到,协程是在线程里面的,就像线程和进程的关系一样。

三、协程如何使用?切线程是什么

为什么要切线程:因为我要执行耗时操作。

切线程一般两种:

  1. 切到后台线程或子线程。
  2. 切到UI线程。

那么如何切换呢?

(1)这就是一个切换协程的方法(launch )。从任意线程切换到了IO协程。

kotlin 复制代码
CoroutineScope(Dispatchers.IO).launch {
    ...
}

(2)使用withContext 方法切换协程

kotlin 复制代码
val coroutineScope = CoroutineScope(Dispatchers.Main)

        coroutineScope.launch(Dispatchers.Main) {        // 在 UI 线程开始
            withContext(Dispatchers.IO) {    // 切换到 IO 线程
                //getImage(imageId)                        // 在 IO 线程执行
            }
            textView.text = "asdfasdfasdf"              // 回到 UI 线程更新 UI
        }
kt 复制代码
// 在UI线程上执行操作
CoroutineScope(Dispatchers.Main).launch {
    // 更新UI组件
    textView.text = "Hello,!"
}

// 在IO线程上执行网络请求
CoroutineScope(Dispatchers.IO).launch {
    val result = performNetworkRequest()
    withContext(Dispatchers.Main) {
        // 在UI线程上更新UI组件
        textView.text = result
    }
}

// 在默认的调度器上执行计算密集型任务
CoroutineScope(Dispatchers.Default).launch {
    val result = performComplexCalculation()
    withContext(Dispatchers.Main) {
        // 在UI线程上更新UI组
        textView.text = result.toString()
    }
}

四、挂起函数是什么

挂起函数是什么?

他其实就是暂停的意思。就是他执行这个函数的时候,协程就被挂起,协程函数给到其他线程执行,所在的协程就暂停了,执行完后,挂起函数后面的代码才会执行。

挂起的本质就是,协程和线程脱离,暂时不占用线程了,你可以去做别的事情了。协程在其他线程执行完,再切回来。

挂起函数必须在协程里面才能使用,不然挂起谁。

下面我们来看一个例子。

(1)比如我们现在需要发起一个请求

kt 复制代码
interface HomeApiService {

    /**
     * 获取首页Banner数据
     *
     * @return BaseResponse<List<BannerBean>> Banner列表
     */
    @GET("banner/json")
    suspend fun getBanners(): BaseResponse<List<BannerBean>> //suspend: 表示这是一个挂起函数,可以在协程中调用,并可以在执行过程中挂起。

    /**
     * 获取置顶文章
     * @return BaseResponse<MutableList<ArticleBean>> 置顶文章列表
     */
    @GET("article/top/json")
    suspend fun getTopArticle(): BaseResponse<MutableList<ArticleBean>>

    /**
     * 根据页面获取分页的文章数据
     * @param page Int 获取的文章页码 从 0 开始
     * @return BaseResponse<ArticlePageBean>
     */
    @GET("article/list/{page}/json")
    suspend fun getArticleByPage(@Path("page") page: Int): BaseResponse<ArticlePageBean>
}

(2)发起请求

kt 复制代码
  val coroutineScope = CoroutineScope(Dispatchers.Main)

        coroutineScope.launch(Dispatchers.IO) {       
            var result = HomeApiService.getBanners()
            showResult(result)
        }

HomeApiService.getBanners()这里会挂起,等结果返回后,执行showResult方法。

五、withContext和lanuch的区别

lanuch开启的是并行的切线程,withContext则是串行,也就是withContext其实也是一个挂起函数,后面的代码会等待前面的代码执行完成。而lanuch则不会。

六、Defualt、IO和Main的区别

  1. io:跟内存之外的世界去交互【读写磁盘,以及进行HTTP请求之类的网络访问】
  2. main:是Android应用程序的主线程调度器,也称为UI线程。它用于执行与用户面相关的操作,例如更新UI组件、处理用户输入等。
  3. Default:这是一个适用于CPU集型任务的调度器。它使用一个线程池来执行并发的计算密集型任务,例如排序、解析大型数据等。Dispatchers.Default通常比Dispatchers.IO更适合执行需要较长时间的计算任务但仍建议将长时间运行的任务放在后台线程中,以避免阻塞UI线程。
  4. main.immediate:main.immediate和main线程的区别就是,如果已经在主线程就不需要使用handler.post抛到主线程,而是直接执行。

七、lifecycleScope

lifecycleScope,是什么?直接再activity里面了。可以直接调用。

他的特点:

  1. 他的生命周期和activity绑定,如果是fragment,则是fragment【意思是如果你正在http请求,那么他也会直接结束?对!!!】
相关推荐
伞伞悦读19 小时前
【第36期】Python 目录与路径详解:pathlib、文件遍历、创建、复制、移动和删除风险
开发语言·python
北京自在科技21 小时前
谷歌 Find Hub 迎来新版本更新
android·安卓
2601_966949651 天前
只拿到股票代码还不够:量化程序到底还需要哪些标的信息?——从数据建模开始理解股票元数据
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash
m0_734571761 天前
深入理解5g <十八>传输块tbsize的计算
开发语言·5g
RAN11426760081 天前
1.3第一个程序的介绍
开发语言·qt
blue_ice .1 天前
Verilog DDS 数字信号发生器:DAC 输出模拟波形与 ADC 回采观测
开发语言·单片机·嵌入式硬件·fpga开发
远翔调光芯片^138287988721 天前
ECP5702能芯科技PD取电芯片在市场上的优势有哪些?
开发语言·人工智能·单片机·嵌入式硬件·智能家居
泡海椒1 天前
规则引擎对比:JQuick-Java vs Drools 轻量场景选型对比
java·开发语言
泡泡鱼(敲代码中)1 天前
Python 容器类型学习笔记:列表、元组、字典、集合
开发语言·笔记·python·pycharm
2501_933670791 天前
平台招商运营校招能力模型:数据分析、SQL与增长场景拆解
开发语言