扔物线--Kotlin协程训练营2期-1

笔记仅做自己学习用,方便自己复习知识。若正好可以帮助到Viewer,万分欣喜~

若博客侵权,扔物线大大不允许放上面,麻烦告知


本文是扔物线Kotlin第二期协程训练营的第一篇文章

 

目录

一、Kotlin协程是什么

1. 协程是什么?

2. Kotlin的协程是什么?

二、Kotlin协程的优势

1. 流式的代码写法

2. 协程的额外天然优势:性能

三、suspend关键字

四、练习题

1. Kotlin的协程是什么?它有什么优势?为什么?

2. Kotlin 协程的 suspend 关键字有什么意义?

3. 如果不使用协程,让你自己实现一个和协程类似的框架,你认为难点在哪里?


 

一、Kotlin协程是什么

1. 协程是什么?

协程是一个广义的概念,在很多编程语言里都有协程的编程思想。协程是一种在程序中处理并发任务的方案,也是这种方案的一个组件。

协程和线程属于同一个层级的概念,是一种和线程不同的并发任务解决方案:一套系统(可以是操作系统,也可以是一种编程语言)可以选择不同的方案来处理并发任务,你可以使用线程,也可以使用协程。

2. Kotlin的协程是什么?

Kotlin的协程和广义的协程不是一种东西,Kotlin的协程(准确地说是Kotlin for JVM的协程)是一个线程框架。类似于Java提供的线程池Executor

二、Kotlin协程的优势

1. 流式的代码写法

考虑一种需求:通过网络加载一张图片,展示在页面上,再对图片进行处理后,再展示在界面上。

需求的流程: 1. 加载图片;2.展示原图;3.对图片进行处理;4.展示处理后的图片。

其中1、3步是IO操作,需要放在后天执行,而2、4属于UI操作,需要在主线程运行。

一般情况下我们会使用线程切换或使用回调,来实现,代码如下:

        new Thread(new Runnable() {
            @Override
            public void run() {
                getBitmapFromNet(); // 1.通过网络加载图片
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        showBitmap1(); // 2.在界面上展示原图
                        new Thread(new Runnable() {
                            @Override
                            public void run() {
                                dealWithBimap(); // 3.对原图进行处理(放缩、裁剪等)
                                runOnUiThread(new Runnable() {
                                    @Override
                                    public void run() {
                                        showBitmap2(); // 4.在界面上展示处理后的图
                                    }
                                });
                            }
                        });
                    }
                });
            }
        });

如果使用callback,最少也需要使用两次回调。

再来看看协程的写法:

    init {
        GlobalScope.launch(Dispatchers.Main) {
            getBitmapFromNet()  // 1.通过网络加载图片
            showBitmap1()       // 2.在界面上展示原图
            dealWithBimap()     // 3.对原图进行处理(放缩、裁剪等)
            showBitmap2()       // 4.在界面上展示处理后的图
        }
    }

    suspend fun getBitmapFromNet(String url): Bitmap = withContext(Dispatchers.IO) {
        Bitmap bitmap = ...
        return@withContext bitmap
    }
    
    fun showBitmap1(Bitmap bitmap){
    }

    suspend fun dealWithBimap(Bitmap bitmap): Bitmap = withContext(Dispatchers.IO) {
        Bitmap bitmap = ...
        return@withContext bitmap
    }
    
    fun showBitmap2(Bitmap bitmap){
    }

看init里的代码,纳尼???IO操作的代码和UI操作的代码放在一起线性执行,这代码会把界面卡死的吧。再仔细看GlobalScope.launch(Dispatchers.Main)和withContext(Dispatchers.IO),以及函数前的suspend关键词。慢慢会发现,难道这个代码那么NB,可以把线程代码和主线程代码不用切换地一起写!!!是的,这就是Kotlin的协程,它会自动切换线程,将应该在线程中运行的代码放在线程里执行,应该在UI线程运行的代码还在UI线程运行。GlobalScope.launch(Dispatchers.Main)这里的Dispatchers.Main表示该代码块中的协程代码主要在主线程运行,当协程里运行的函数没有指定线程时,就会在主线程运行。如果在函数里加上withContext(Dispatchers.IO)和suspend关键词,就代表这个函数需要在IO线程运行。线程会自动切换。

这就是协程,流式的代码写法,佩服的五体投地...

写法总结:

a. 用launch来开启一段协程,一般需要指定Dispatchers.Main

b. 把需要在后头工作的函数,使用suspend关键词标记,并调用其他suspend函数(这里的withContext(Dispatchers.IO))来真正地切换线程

c. 按照一条线写下来,线程会自动切换

2. 协程的额外天然优势:性能

不知道你在工作中有没有遇见过这种情况:比如一个查询数据库的函数,查询的量不算大,也不算小。有时候就直接把它放在主线程执行了,在测试时发现没有卡顿主线程。但是这段代码如果在性能低下的手机上运行,就可能会造成几十毫秒的卡顿,导致丢帧。这样的情况,我们很难判断这个代码是否“耗时”,有时候一个不注意就放在了主线程运行。

但是,用协程就可以很好地解决这个问题,我们可以把所有的IO操作,数据操作代码都放在后台运行,协程可以在后台执行完任务后自动切回到主线程。保证耗时代码100%放在后台执行,就能解决这方面的性能问题。

三、suspend关键字

suspend并不是来切回线程的,实际的切换线程操作是由其他函数完成的,比如withContext。

suspend主要是起到标记和提醒的作用。标记这个代码需要在协程里执行。

四、练习题

1. Kotlin的协程是什么?它有什么优势?为什么?

它是Kotlin基于JVM的线程来实现的一个并发任务处理框架(或者方案)。

优势:用起来方便,不需要回调,用纯线程的方式就可以完成线程的切回。

所有耗时任务可以保证一定放在后台执行,从而提高软件性能。

2. Kotlin 协程的 suspend 关键字有什么意义?

语法层面:作为一个标记和提醒。通过报错来提醒调用者和编译器,这是一个耗时函数,需要放在后台执行。

编译器层面:辅助Kotlin编译器来把代码转换成JVM的字节码。

3. 如果不使用协程,让你自己实现一个和协程类似的框架,你认为难点在哪里?

在不使用回调的前提下完成线程切换;
在挂起函数执行完毕时,自动判断应该回到哪个线程。

 

第二篇文章讲解RxJava、Retorfit、Jetpack对协程的支持,以及协程的本质探秘

第二篇文章传送:https://blog.csdn.net/bluerheaven/article/details/106971483

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值