近日 Retrofit 更新到了 2.6.0 版本,内置了对 Kotlin Coroutines 的支持,进一步简化了使用 Retrofit 和协程来进行网络请求的过程。其实纵观编程语言的发展历史,从汇编到 C/C++,从 Java,OC 到 Swift,Kotlin,甚至被归入教材的 Python,都有一个共同的特色。随着 CPU 性能的愈来愈强悍,提升生产力彷佛都成了现代高级编程语言的共同目标。Kotlin 就是一个好例子,作一样的事情,完成一样的功能,Java 的确须要更多的代码,Kotlin 也的确给 Android 开发提高了效率。特别是在异步任务方面,Kotlin 提供了协程,而这是 Java 所不具有的。关于 Kotlin Coroutines 的介绍,能够阅读我以前的三篇译文:java
在 Android 上使用协程(一):Getting The Backgroundandroid
回到正题,本篇主要介绍 Retrofit 2.6.0 版本中协程的使用方式,不会过多涉及原理。我以我本身的 wanandroid 应用为例进行改造,源代码中 Retrofit 版本是 2.4.0
。这个 wanandroid 是基于 Kotlin + 协程 + LiveData + MVVM
实现的,具体架构可见个人文章 真香!Kotlin+MVVM+LiveData+协程 打造 Wanandroid! ,我的以为代码仍是比较清晰的,很适合做为 Kotlin 的 入门项目。编程
在介绍如何使用 Retrofit 2.6.0
以前,咱们先来看一下老版本的 Retrofit 是如何基于 Kotlin Coroutines 工做的,以登陆接口为例。api
首先在 WanService 接口中做以下定义:bash
@POST("/user/login")
fun login(@Field("username") userName: String, @Field("password") passWord: String): Deferred<WanResponse<User>>
复制代码
注意这里使用的返回值是 Deferred<T>
对象,这就意味着使用的时候要经过 await
来获取返回值。那么如何让 Retrofit 直接返回 Deferred<T>
呢?使用的也是 JakeWharton 的开源库:微信
implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2'
复制代码
在构建 Client 的时候添加上这个适配器:网络
...
.addCallAdapterFactory(CoroutineCallAdapterFactory.invoke())
...
复制代码
而后给 LoginRepository 提供一个 suspend 方法:架构
suspend fun login(userName: String, passWord: String): WanResponse<User> {
return apiCall { WanRetrofitClient.service.login(userName, passWord).await() }
}
复制代码
这里使用 await
来获取 Deferred<T>
的返回值。
最后在 LoginViewModel 中是这样调用的:
fun login(userName: String, passWord: String) {
launch {
val response = withContext(Dispatchers.IO) { repository.login(userName, passWord) }
executeResponse(response, { mLoginUser.value = response.data }, { errMsg.value = response.errorMsg })
}
}
复制代码
launch()
方法作了简单的封装,感兴趣的同窗能够到源码中看一下。
以上就是在 Retrofit 2.4.0
中使用协程的基本方式了,其实代码也很简洁。而 Retrofit 2.6.0
让这一切更加简单!就让咱们一睹为快吧!
Talking is cheap, show me the code !
仍是上面的登陆接口,基于 Retrofit 2.6.0
来改造一下。
第一步,修改 Retrofit 依赖。
implementation 'com.squareup.retrofit2:retrofit:2.6.0'
复制代码
第二步,修改 WanService
中接口的定义。
@POST("/user/login")
suspend fun login(@Field("username") userName: String, @Field("password") passWord: String): WanResponse<User>
复制代码
看到区别了吗?首先,再也不返回 Deferred<T>
对象,而是直接返回咱们须要的 WanResponse
对象。其次,使用了 suspend
来修改方法,标记这是挂起函数。
第三步,修改 LoginRepository
中方法定义。
suspend fun login(userName: String, passWord: String): WanResponse<User> {
return apiCall { WanRetrofitClient.service.login(userName, passWord) }
}
复制代码
与以前的版本相比,这里不须要调用 await
方法了。其实并非不调用了,而是 Retrofit 帮助咱们自动调用了。
最后别忘了去除以前添加的 kotlin-coroutines-adapter
,由于咱们再也不须要人工返回 Deferred<T>
对象,也再也不须要手动调用 await
了。
...
//.addCallAdapterFactory(CoroutineCallAdapterFactory.invoke())
...
复制代码
至此,基于 Retrofit 2.6.0
版本的改造就已经完成了。个人 Wanandroid 项目已经完成所有修改,具体修改内容可见 commit。
随着 Kotlin 成为 Android 开发的首选语言,愈来愈多的新特性都将在 Kotlin 上优先实现。协程做为 Kotlin 的异步利器,很值得咱们学习。若是你尚未入手,那么,从个人 Wanandroid 开始吧 !
文章首发微信公众号:
秉心说
, 专一 Java 、 Android 原创知识分享,LeetCode 题解。更多相关知识,扫码关注我吧!