0
点赞
收藏
分享

微信扫一扫

“吹Kotlin协程的,可能吹错了,android模块化

楠蛮鬼影 2022-02-03 阅读 48

目录

前言

Kotlin协程,现在已经成为了面试甚至是工作中一个非常火的东西。

本人在刚开始了解Kotlin协程的时候,断断续续看了网上不少文章,用长篇大论把Kotlin协程描述的非常玄乎,但是看完后还是依然云里雾里,所以决定来写一篇关于协程的文章,希望能够帮助大家能够更快的上手Kotlin协程.

注意:如果没有特殊提及,文中所有“协程”均代表“Kotlin协程”

为什么要学习Kotlin协程?(官方版)

现在Android技术栈上的新东西层出不穷,kotlin、jetpack、flutter等等。很多人是为了准备面试而学习,所以往往往更偏向于去看一些概念性的东西,以便面试的时候能够蒙混过关。

但是我觉得,我们还是先要了解这个新的技术能够给我们的开发带来哪些实质性的帮助,我们再去针对性学习可能会更加有意义.

我们先来看看Kotlin官网是怎么体现使用协程的优势的

https://www.kotlincn.net/docs/reference/coroutines/basics.html

网上很多文章也用这个例子,也用这个官方例子来说明使用协程的优势,然后就说协程是什么轻量级的线程,又是什么用户态的,协程像线程但又不是线程…诸如此类。

所以很多人自认为学会了协程,最后就可能只能说出来使用协程的目的是比线程性能更好。

先不说这些概念对不对,我相信对于一个普通的Android开发来说,听到这些概念,第一反应肯定觉得协程这个东西非常的神秘且不好理解。

所以,不好理解我们就先不理解,我们先基于我们已有的知识来分析一下官网这个例子。

官网这个例子就是通过repeat函数启动了10000个协程,然后它让我们试一试使用Thread来实现会发生什么,也就是像下面这样:

repeat(100_000) {
val executor = Executors.newSingleThreadScheduledExecutor()
val task = Runnable {
print(".")
}
repeat(100_00) {
executor.schedule(task, 1, TimeUnit.SECONDS)
}
}

这个例子我们不用跑也知道大概会发生什么了。

但是,我想说的是,kotlin官方用这个例子真的有点不厚道了,用java底层的Thread类,和他们造出来的一个基于Thread类封装的“工具包”进行对比。

真正要比的话,我们用java的Executor和他比比?

repeat(100_000) {
val executor = Executors.newSingleThreadScheduledExecutor()
val task = Runnable {
print(".")
}
repeat(100_00) {
executor.schedule(task, 1, TimeUnit.SECONDS)
}
}

我用上面这段程序跑了一下,用协程相对于java的线程池,并没有发现什么实质上的性能优势。感兴趣的也可以自己借助Android Studio Profiler试一试

所以,到目前为止,我们可以下一个结论。

使用Kotlin协程,本质上其实并没有比我们原先的开发模式有多大性能上的优势,因为我们所使用的的OkHttp、AsyncTask等内部都帮我们封装了线程池,而不是直接使用Thread类。

我上面还提到了一个可能有点争议的观点,Kotlin协程只是一个基于Thread类封装的”工具包“而已。但目前还没有得到证明,我们不妨继续往下看。

Kotlin协程运行在单线程里面吗?

这里我截了一个百度搜索Kotlin协程,比较高赞的一篇文章,文章中截取了各种概念,到网上找了各种和协程相关的图,但我想说,这其实是误导人!

很简单,我们做一个小实验就能知道结果:

fun main(){
//在没有开启协程前,先打印一下进程名称和进程id
println(
"Main: " +
"threadName = " + Thread.currentThread().name
+ " threadId = " + Thread.currentThread().id
)

//循环20次
repeat(20) {
GlobalScope.launch {
//开启协程后,先打印一下进程名称和进程id
println(
"IO: " +
"threadName = " + Thread.currentThread().name
+ " threadId = " + Thread.currentThread().id
)
delay(1000L)
}
}

}

日志打印结果:

发现了什么?所谓的协程完全就是开启了一个新的线程来执行任务,有些任务的线程名称和线程id还是完全一致的!这像不像java中的线程池?

看到这里,是不是有点颠覆你原来对协程的认识?难道网上的所有文章都是错误的?

其实网上大部分文章说的协程,指的可能都是其他语言的协程的特点,比如Go、Lua…

而我们要学的,是Kotlin协程,它不是真正意义上的协程,它也没有那么的神秘,本质上还是一套基于原生Java Thread API 的封装。只要你没有魔改JVM,start了几个线程,操作系统就会创建几个线程,Kotlin协程只是做了一个类似线程池的封装,根本谈不上什么性能更好。

总结下来Kotlin协程其实就是为了让我们更方便的来进行多线程开发而已,所以我们就抱着当初学习Handler、AsyncTask这些的心态来学习协程这个工具包就好了,不要想那么多复杂的东西来扰乱自己的思路。

Kotlin协程有那么好用吗

一个新的技术的出现,大家往往从学习到真正在项目中实践往往需要一个过程,这里面有非常多的因素,有个人学习成本的因素,有公司方面的因素等等,但是最重要的,其实还是这个新的技术,到底是不是真的有取代我们现有技术的必要。接下来我就带大家一起来用用协程吧。

okhttp异步请求

这是我们常规的一个异步请求,通过回调的方式来处理请求结果

fun enqueue() {    ApiService.enqueue("/test", object : Callback {
override fun onResponse(call: Call, response: Response) {
runOnUiThread {
//切到主线程更新UI
tv_content.text = response.body.toString()                  
}
}

override fun onFailure(call: Call, e: IOException) {
}
})
}

使用协程的okhttp同步请求

这里先记住一句话,我们什么时候要用到协程的?

所以想切到什么线程,就用GlobalScope.launch(Dispatchers.XX)切一下就好了,代码如下

fun execute() {
GlobalScope.launch(Dispatchers.Main) {
//切到子线程执行任务
var result = withContext(Dispatchers.IO) {
ApiService.execute("/test")
}
//任务执行完后自动回到主线程
tv_content.text = result
}
}

看到这里,有的人可能觉得有点怪怪的,这看起来完全不足以吸引我使用协程,用回调不好吗?

kotlin毕竟是一门比较新的语言,所以在协程中,它同时给我们提供了一些非常实用的函数,所以上面的代码可以写成下面这样:

fun execute() {
GlobalScope.launch(Dispatchers.Main) {
//切到子线程执行任务
var result = withContext(Dispatchers.IO) {
ApiService.execute("/test")
}
//任务执行完后自动回到主线程
tv_content.text = result
}
}

这个withContext函数的意义呢,就是能把耗时任务切到子线程去,然后任务执行完之后,又会自动切回主线程。

如何成为Android高级架构师!

架构师必须具备抽象思维和分析的能力,这是你进行系统分析和系统分解的基本素质。只有具备这样的能力,架构师才能看清系统的整体,掌控全局,这也是架构师大局观的形成基础。 你如何具备这种能力呢?一是来自于经验,二是来自于学习。

架构师不仅要具备在问题领域上的经验,也需要具备在软件工程领域内的经验。也就是说,架构师必须能够准确得理解需求,然后用软件工程的思想,把需求转化和分解成可用计算机语言实现的程度。经验的积累是需要一个时间过程的,这个过程谁也帮不了你,是需要你去经历的。

但是,如果你有意识地去培养,不断吸取前人的经验的话,还是可以缩短这个周期的。这也是我整理架构师进阶此系列的始动力之一。


成为Android架构师必备知识技能

对应导图的学习笔记(由阿里P8大牛手写,我负责整理成PDF笔记)

部分内容展示

《设计思想解读开源框架》

  • 目录
  • 热修复设计
  • 插件化框架设计

    《360°全方面性能优化》
  • 设计思想与代码质量优化
  • 程序性能优化

计**
[外链图片转存中…(img-qIZCUyR1-1643885219972)]
《360°全方面性能优化》
[外链图片转存中…(img-la6fmxuw-1643885219972)]

  • 设计思想与代码质量优化
    [外链图片转存中…(img-kCwROvZe-1643885219973)]
  • 程序性能优化
    [外链图片转存中…(img-IdXY1gOo-1643885219973)]
举报

相关推荐

0 条评论