Kotlin协程它不香吗?

  • 它需要处理很多回调,一旦业务过多则容易陷入「回调地狱」。

  • 强行把业务拆分成了前台、中间更新、后台三个函数。

回调地狱指多个回调嵌套在一起

在写业务代码的时候,有好几个接口需要你使用,接口A需要接口B的回调结果作为参数去请求数据。这样就会形成回调函数的嵌套。如果有三四层回掉嵌套,最终就会长下面这个样子:

asyncFunc1(opt, (…args1) {

asyncFunc2(opt, (…args2) {

asyncFunc3(opt, (…args3) {

asyncFunc4(opt, (…args4) {

// some operation

});

});

});

});

看起来是不是有点恶心,如果你没有感觉到恶心,笔者觉得你可能经常写这样的代码所以习惯了,有一句“名人”名言:吐着吐着就习惯了。

到这里优秀的你肯定又想到了Rxjava这把利器,我们可以通过它提供的「Observable」的编程范式进行链式调用,可以很好地消除回调。

那么这里介绍的协程到底可以做什么呢?上面的问题它自然是可以解决了,那它相较于RxJava的优势是什么呢?

笔者觉得最主要的是它可以用看起来同步的方式写出异步的代码。这样写代码的人写起来很舒服,读代码的人读起来很畅快。

快速上手

下面笔者利用Retrofit配合协程实现一个登录功能

首先需要添加以下依赖库

implementation “org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.0”

implementation ‘com.squareup.retrofit2:retrofit:2.6.2’

implementation ‘com.squareup.retrofit2:converter-gson:2.6.0’

//为 Retrofit 添加对 Deferred 的支持

implementation ‘com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2’

根据 wanandroid 的登录API接口,通过retrofit框架敲出客户端的登录接口

接口API链接: www.wanandroid.com/blog/show/2

interface ApiService {

companion object {

const val BASE_URL = “https://www.wanandroid.com”

}

@FormUrlEncoded

@POST(“/user/login”)

fun login(@Field(“username”) username: String,

@Field(“password”) password: String): Deferred<WanResponse>

}

Deferred是什么?它是Job的子接口。那,,,Job又是什么呢?可以简单理解,整个登录请求的过程就是会被封装成Job,然后交给协程调度器处理。但Job在完成的时候是没有返回值的,所以就有了Deferred,它的意思就是延迟,结果稍后才能拿到,它可以为任务完成时提供返回值。

根据请求后返回的json,写出返回值的数据类

data class WanResponse(val errorCode: Int,val errorMsg: String,val data: T)

data class User(val collectIds: List,val email: String,

val icon: String,val id: Int,

val password: String, val type: Int, val username: String)

之后构建一个retrofit实例,用它来进行请求登录

class ApiRepository {

val retrofit = Retrofit.Builder()

.baseUrl(ApiService.BASE_URL)

.addConverterFactory(GsonConverterFactory.create())

//添加对Deffered的支持

.addCallAdapterFactory(CoroutineCallAdapterFactory.invoke())

.build()

.create(ApiService::class.java)

fun login(name: String,password: String): Deferred<WanResponse>{

return retrofit.login(name,password)

}

}

接下来主角协程要出场了。我们可以通过launch函数开启一个协程

GlobalScope.launch(Dispatchers.IO) {

var result: WanResponse?=null

result = repository.login(userName,userPassword).await()

launch(Dispatchers.Main) {

btnLogin.text = result.data.username

}

}

这段代码出现了Dispatchers 调度器,它可以将协程限制在一个特定的线程执行,或者将它分派到一个线程池,或者让它不受限制地运行,关于 Dispatchers 这里先不展开了。

常用的 Dispatchers ,有以下三种:

  • Dispatchers.Main:Android 中的主线程
  • Dispatchers.IO:针对磁盘和网络 IO 进行了优化,适合 IO 密集型的任务,比如:读写文件,操作数据库以及网络请求
  • Dispatchers.Default:适合 CPU 密集型的任务,比如计算

但上面的栗子只是一次网络请求,如果有多次请求可能就变成这个样子:

GlobalScope.launch(Dispachers.IO) {

//io操作

launch(Dispachers.Main){

//ui操作

launch(Dispachers.IO) {

//io操作

launch(Dispacher.Main) {

//ui操作

}

}

}

}

这个嵌套???不是说协程可以不用写嵌套代码的吗

于是协程中有一个很实用的函数:withContext这个函数可以切换到指定的线程,并在闭包内的逻辑执行结束之后,自动把线程切回去继续执行,

用 withContext 改写一下,它的结构大致就长这个亚子:

launch(Dispachers.Main) {

withContext(Dispachers.IO) {

}

withContext(Dispachers.IO) {

}

}

复制代码

比如上面的登录的栗子就可以改写成这样:

GlobalScope.launch(Dispatchers.Main) {

var result: WanResponse?=null

withContext(Dispatchers.IO){

//请求登录

result = repository.login(userName,userPassword).await()

}

//更新ui

btnLogin.text = result?.data?.username

}

好像的确变得简洁了许多,但离我们的目标:看起来同步的方式写出异步的代码还差那么一点。

既然不需要嵌套了,那就可以把io线程的操作,拿出来单独作为函数,就可以写成这样:

suspend fun login(name: String,password: String): WanResponse {

return withContext(Dispatchers.IO) {

val repository = ApiRepository()

repository.login(name, password).await()

}

}

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

最后

给大家送上我成功跳槽复习中所整理的资料,由于文章篇幅有限,所以只是把题目列出来了

image

image

image

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!

记、源码讲义、实战项目、讲解视频,并且会持续更新!**

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

最后

给大家送上我成功跳槽复习中所整理的资料,由于文章篇幅有限,所以只是把题目列出来了

[外链图片转存中…(img-40Kt2m2X-1712286465624)]

[外链图片转存中…(img-BAsWDBf5-1712286465624)]

[外链图片转存中…(img-Oe6Melql-1712286465624)]

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!
  • 14
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值