Retrofit+kotlin Coroutines(协程)+mvvm(Jetpack架构组件)实现更简洁的网络请求
前言
使用kotlin协程也有一段时间了,给我最大的感受就是完全可以替代Rxjava了,并且写起来更加的简洁。
6月份Retrofit发布的2.6.0版本内部支持了kotlin协程中的挂起(suspend)修饰符,这就意味着我们可以更加方便的用Retrofit结合kotlin协程来实现网络请求了。
之前我都是使用Rxjava2+Retrofit实现网络请求的功能,然后加入了AutoDispose来实现自动解绑以免发生内存泄漏的问题,感兴趣的可以看看AutoDispose代替RxLifecycle优雅的解决RxJava内存泄漏问题
那协程有没有自动解绑的东西呢。当然有了
目前google官方也给我们提供了androidx.lifecycle:lifecycle-viewmodel-ktx
的依赖包,给ViewModel中扩展了一个作用域叫viewModelScope
viewModelScope是一个绑定到当前viewModel的作用域 当ViewModel被清除时会自动取消该作用域,所以不用担心内存泄漏为问题
那这样一来,我们完全可以使用Retrofit+Coroutines这个方案来代替之前用Retrofit+Rxjava+AutoDispose的方案了。
话不多说,直接上代码
我在网上找了个公开的API接口 https://www.apiopen.top/novelApi
我们就请求这个接口了
添加依赖
首先是添加需要的依赖包,如下
implementation 'androidx.appcompat:appcompat:1.1.0'implementation 'androidx.core:core-ktx:1.1.0'implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.1"implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.1"implementation "androidx.lifecycle:lifecycle-extensions:2.1.0"implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.1.0"implementation "com.squareup.okhttp3:okhttp:4.2.0"implementation "com.squareup.retrofit2:retrofit:2.6.1"implementation "com.squareup.okhttp3:logging-interceptor:4.2.0"implementation "com.squareup.retrofit2:converter-gson:2.6.1"
代码
在看下面的代码之前,你可能需要先看一下下面几篇文章,如果你都知道的话 直接跳过即可
对ViewModel和LiveData 还不是很了解的话先看一下这篇文章
mvp过渡到mvvm(Android 架构组件)
关于一些好用的扩展方法,看一下这个
Kotlin基于RxJava的扩展方法(超级好用)
这里我们主要是看对数据类的扩展,节省一些无用代码
关于Retrofit的工厂类这里我就不放出来了,估计大家的代码都差不多,需要的可以看demo,这里我就不再浪费篇幅,直接用了。
实体类
响应基类
data class BaseResp<T>(var code: Int = 0,var msg: String = "",var `data`: T
)
小说数据实体类
package com.yzq.coroutineretofitmvvm.beanimport com.google.gson.annotations.SerializedNamedata class Fiction(var bid: String = "",var bookname: String = "",var introduction: String = "",@SerializedName("book_info")var bookInfo: String = "",var chapterid: String = "",var topic: String = "",@SerializedName("topic_first")var topicFirst: String = "",@SerializedName("date_updated")var dateUpdated: Int = 0,var author: String = "",@SerializedName("author_name")var authorName: String = "",@SerializedName("top_class")var topClass: String = "",var state: String = "",var readCount: String = "",var praiseCount: String = "",@SerializedName("stat_name")var statName: String = "",@SerializedName("class_name")var className: String = "",var size: String = "",@SerializedName("book_cover")var bookCover: String = "",@SerializedName("chapterid_first")var chapteridFirst: String = "",var chargeMode: String = "",var digest: String = "",var price: String = "",var tag: List<String> = listOf(),@SerializedName("is_new")var isNew: Int = 0,var discountNum: Int = 0,@SerializedName("quick_price")var quickPrice: Int = 0,var formats: String = "",@SerializedName("audiobook_playCount")var audiobookPlayCount: String = "",var chapterNum: String = "",var isShortStory: Boolean = false,var userid: String = "",@SerializedName("search_heat")var searchHeat: String = "",@SerializedName("num_click")var numClick: String = "",@SerializedName("recommend_num")var recommendNum: String = "",@SerializedName("first_cate_id")var firstCateId: String = "",@SerializedName("first_cate_name")var firstCateName: String = "",var reason: String = ""
)
定义请求接口
这个没什么好说的,需要注意的就是我们的方法前面用 suspend 修饰
interface ApiService {@GET("https://www.apiopen.top/novelApi")suspend fun getFictions(): BaseResp<List<Fiction>>
}
用于解析响应数据的扩展方法
/*数据解析扩展函数*/
fun <T> BaseResp<T>.dataConvert(): T {if (code == 200) {return data} else {throw Exception(msg)}
}
ViewModel
注释也很详细了,这里就不多说了
class NetViewModel : ViewModel() {var fictions = MutableLiveData<List<Fiction>>()fun getFictions() {/*viewModelScope是一个绑定到当前viewModel的作用域 当ViewModel被清除时会自动取消该作用域,所以不用担心内存泄漏为问题*/viewModelScope.launch {try {/*dataConvert扩展函数可以很方便的解析出我们想要的数据 接口很多的情况下下可以节省不少无用代码*/val data =RetrofitFactory.instance.getService(ApiService::class.java).getFictions().dataConvert() /*给LiveData赋值 ui会自动更新*/fictions.value = data} catch (e: Exception) {/*请求异常的话在这里处理*/e.printStackTrace()Log.i("请求失败", "${e.message}")}}}}
Activity
Activity中代码就很简单了,主要就是创建ViewModel示例,更新ui
class MainActivity : AppCompatActivity() {private lateinit var netViewModel: NetViewModeloverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)/*创建viewmodel*/netViewModel = ViewModelProviders.of(this).get(NetViewModel::class.java)btn.setOnClickListener {/*请求数据*/netViewModel.getFictions()}/*数据发生变化时更新ui*/netViewModel.fictions.observe(this, Observer {tv.text = Gson().toJson(it)})}
}
下面我们来看看运行结果:
可以看到,网络请求的功能已经实现了。
那对比RxJava的实现方式,你觉得哪种方式更好呢?
好了,本篇文章到此结束。
demo
如果你觉得本文对你有帮助,麻烦动动手指顶一下,算是对本文的一个认可,如果文中有什么错误的地方,还望指正,转载请注明转自喻志强的博客 ,谢谢!
Retrofit+kotlin Coroutines(协程)+mvvm(Jetpack架构组件)实现更简洁的网络请求相关推荐
- kotlin coroutines 协程教程-入门用法
kotlin coroutines 协程教程-入门用法 Coroutine 协程,是kotlin 上的一个轻量级的线程库,对比 java 的 Executor,主要有以下特点: 更轻量级的 api 实 ...
- Android MVVM + Retrofit + OkHttp + Coroutine 协程 + Room + 组件化架构的Android应用开发规范化架构
BaseDemo 介绍 BaseDemo 是Android MVVM + Retrofit + OkHttp + Coroutine 协程 + Room + 组件化架构的Android应用开发规范化架 ...
- Kotlin 之 协程
初识协程,启动取消协程,Flow异步流,协程并发 目录 (一)初识协程 协程是什么? Android中协程解决了什么问题? 协程的挂起与恢复 挂起和阻塞 协程的调度器 Dispatchers 任务泄露 ...
- Kotlin的协程与生命周期
文章目录 一.前言 二.引入依赖 三.代码示例 1.基础用法 2.repeatOnLifecycle 3.flowWithLifecycle 4.lifecycle.whenCreated.lifec ...
- 十一、kotlin的协程(一)
theme: Chinese-red 学习的前提 java线程需要大概知道点 协程是线程执行的任务, 协程和用户线程的区别在于, 协程背靠强大的编译器, 协程有专属于协程的调度器和一堆方便好用的函数, ...
- Kotlin高级协程
Kotlin高级协程 一.前言 二.先从线程说起 三.协程的设计思想 四.协程特点:优雅的实现移步任务 五.协程基本使用 六.协程和线程相比有什么特点,如何优雅的实现异步任务 一.前言 在文章正式上干 ...
- 【对比Java学Kotlin】协程简史
文章目录 一.概念释义 1.1 协程定义 1.2 与线程的关系 1.3 协程简史 二.种类划分 2.1 按调用栈分类 2.2 按调度方式分类 三.异步编程 3.1 多线程 3.2 回调 3.3 Pro ...
- Kotlin(3)-协程和操作符重载,Java程序员秋招三面蚂蚁金服
Kotlin 文件和类不存在一对一关系 共生体 继承 修饰符 空指针问题 正文 重难点 协程 想了很久,关于协程的内容,在官网上确实有很多内容,基础知识概念,基本使用,以及 流操作,通道,异常处理,并 ...
- 十一、kotlin的协程 - 缓存、volatile、内存屏障和cas(四) --- 跑题篇
本章写着写着就跑题了, 又不舍得删除, 新手看 # 协程的共享变量安全问题简单入门和## volatile 不保证原子性部分代码, 其他可以不看, 太乱, 也没用 协程的共享变量安全问题简单入门 在使 ...
最新文章
- 利用计算机技术教学图片,教育教学论文 科学学科如何利用计算机技术提高教学效率.doc...
- iOS 新窗口在最上层
- python常用内置模块-python 常用内置模块使用
- Python eval函数用法简介
- Android 编译 SDK
- 系统架构设计师考试999999999999
- 人工智能的本源与展望:从亚里士多德到平行智能
- C#LeetCode刷题之#26-删除排序数组中的重复项(Remove Duplicates from Sorted Array)
- 使用ByteArray及AMF来提高Data Object的操作效率
- 程序员分析了 50 万条拼多多商品数据,告诉你到底是消费升级还是降级!
- JavaScript--百度地图那些坑
- [na]802.1x协议无线认证协议dot1x有线认证实验
- cvSplit(),cv图像颜色通道分割和融合
- 西电计算机网络ppt,《西安电子科技大学》PPT课件
- python 论文降重_我用Python写了一个论文降重工具-Go语言中文社区
- vim中文乱码问题解决方式
- 将base64指纹编码输出为指定大小的图片
- 吴恩达 02.改善深层神经网络:超参数调试、正则化以及优化 第一周作业
- Gensim学习笔记-1--理解corpora.Dictionary
- echarts legend图例显示数值和百分比