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请求,那么他也会直接结束?对!!!】
相关推荐
Oneforlove_twoforjob7 分钟前
【Java基础面试题033】Java泛型的作用是什么?
java·开发语言
engchina23 分钟前
如何在 Python 中忽略烦人的警告?
开发语言·人工智能·python
向宇it24 分钟前
【从零开始入门unity游戏开发之——C#篇24】C#面向对象继承——万物之父(object)、装箱和拆箱、sealed 密封类
java·开发语言·unity·c#·游戏引擎
阿甘知识库33 分钟前
宝塔面板跨服务器数据同步教程:双机备份零停机
android·运维·服务器·备份·同步·宝塔面板·建站
诚丞成1 小时前
计算世界之安生:C++继承的文水和智慧(上)
开发语言·c++
Smile灬凉城6661 小时前
反序列化为啥可以利用加号绕过php正则匹配
开发语言·php
元争栈道1 小时前
webview+H5来实现的android短视频(短剧)音视频播放依赖控件资源
android·音视频
lsx2024061 小时前
SQL MID()
开发语言
Dream_Snowar1 小时前
速通Python 第四节——函数
开发语言·python·算法
西猫雷婶1 小时前
python学opencv|读取图像(十四)BGR图像和HSV图像通道拆分
开发语言·python·opencv