Retrofit+Flow网络请求与Android网络请求的演变

Retrofit网络请求我想大家都不陌生,今天我就来梳理一下技术是如何一步一步进步,逼格是如何一步一步变高的。

Retrofit使用方式演变

萌新

刚开始接触Retrofit的时候是从okhttp和volley以及android系统源码里面那个HttpPost与HttpGet切换过来的。

public interface AuthService {@POST("v1/login")@FormUrlEncodedResponseBody login(@Field("username") String username, @Field("password") String password);
}

那个时候市面上主流还是用的Java,也不知道从哪天开始,突然发现Retrofit这种代理接口的方式用着很爽。于是用着用着就上瘾了,甚至都不知道Retrofit是使用的动态代理的方式。这种方式是通过responseBody.body().string()拿到json字符串,然后再自己通过json解析库解析出数据的。

小白

然后有一天到处看博客或技术文章,于是就发现了Retrofit的返回值原来不仅仅可以是ResponseBody,还可以是T。

public interface AuthService {@POST("v2/login")@FormUrlEncodedLoginResponse login(@Field("username") String username, @Field("password") String password);
}

这时已经意识到可以json解析的过程交给retrofit框架。

implementation(‘com.squareup.retrofit2:converter-gson:2.8.1’)

加了个gson转换器的依赖,对吧?

新手

后来,为了满足对更高逼格的追求,返回值直接跟OkHttp的Call结合,然后使用enqueue的方式进行请求,于是就变成了Call。

public interface AuthService {@POST("v3/login")@FormUrlEncodedCall<LoginResponse> login(@Field("username") String username, @Field("password") String password);
}
初级

再后来,发现市面上RxJava的热度突然飙升,于是乎,就开始研究起了RxJava,这时候,功力开始有所长进。

public interface AuthService {@POST("v4/login")@FormUrlEncodedObservable<LoginResponse> login(@Field("username") String username, @Field("password") String password);
}

这时你可能就需要依赖这几个库了,版本号偏高暂且不去计较,也有可能用的是rxjava第一代。

implementation ‘com.squareup.retrofit2:adapter-rxjava2:2.8.1’
implementation ‘io.reactivex.rxjava2:rxjava:2.0.1’
implementation ‘io.reactivex.rxjava2:rxandroid:2.0.1’
中级

随着Kotlin的兴起,市面上对网络请求的写法也是大相径庭,网络框架也开始演变出自己的风格,甚至有些公司自己封装网络请求库,没有什么问题啊,反正主要思路就是动态代理。百花齐放的时代来临。

interface AuthService {@POST("v5/login")fun login(@Body body: RequestBody): Observable<BaseResponse<LoginUser>>
}

为了追求更加新颖的写法,将@Field换成了@Body,返回值模型增加了公共的code、msg等。

高级一阶

由于经验逐渐变得丰富,你开始使用Kotlin的协程,因为你对更牛逼技术的追求一直没有停止过。

interface AuthService {@POST("v6/login")suspend fun login(@Body body: RequestBody): BaseResponse<LoginUser>
}

这个时候retrofit的写法就已经进入到了第6代,你问为什么是第6代?这个不是重点,我编的。你直接将API接口中定义的函数变成了suspend函数,方便在协程作用域发起。同时你去掉了Observable这个RxJava的产物,返回值又回到了最初的状态。你不禁感慨,从哪里来,到哪里去。返璞归真了!

高级二阶

你以为到这就结束了?随着Flow的问世,网络请求就进入到了第七世代。Flow是基于协程的产物,可以不用挂起函数了。而且Flow具备RxJava的优良特性,可以对数据流进行变换,也可以监听函数执行的生命周期。这样就方便添加显示加载中对话框和隐藏加载中对话框,以及加载进度了。

interface AuthService {@POST("v7/login")fun login(@Body body: RequestBody): Flow<BaseResponse<LoginUser>>
}

dcache框架如何支持协程和Flow

我的dcache框架1.x的稳定版本,不支持flow。

implementation("com.github.dora4:dcache-android:1.8.5")

你需要使用2.0.12及以上版本,对flow请求有很好的支持。

implementation("com.github.dora4:dcache-android:2.0.12")

接下来我们简单阅读下DoraHttp.kt的源代码。

/*** 将一个普通的api接口包装成Flow返回值的接口。*/
suspend fun <T> flowResult(requestBlock: suspend () -> T,loadingBlock: ((Boolean) -> Unit)? = null,errorBlock: ((String) -> Unit)? = null,
) : Flow<T> {return flow {// 设置超时时间为10秒val response = withTimeout(10 * 1000) {requestBlock()}emit(response)}.flowOn(Dispatchers.IO).onStart {loadingBlock?.invoke(true)}.catch { e ->errorBlock?.invoke(e.toString())}.onCompletion {loadingBlock?.invoke(false)}
}

这个函数建议在net作用域内执行,net协程作用域的定义请参见DoraHttp.kt的详细源代码,github.com/dora4/dcach… 。高阶函数的block参数定义中,如果加suspend关键字,则可以传入suspend块,也可以传入普通的方法块。如果不加suspend关键字,则只能传入普通方法块。这个函数对应第6代的写法,可以翻看前面的内容。Flow最终调用collect {} 来处理业务逻辑。


/*** 直接发起Flow请求,如果你使用框架内部的[dora.http.retrofit.RetrofitManager]的话,需要开启* [dora.http.retrofit.RetrofitManager]的flow配置选项[dora.http.retrofit.RetrofitManager.Config.useFlow]* 为true。*/
suspend fun <T> flowRequest(requestBlock: () -> Flow<T>,successBlock: ((T) -> Unit),failureBlock: ((String) -> Unit)? = null,loadingBlock: ((Boolean) -> Unit)? = null
) {requestBlock().flowOn(Dispatchers.IO).onStart {loadingBlock?.invoke(true)}.catch { e ->failureBlock?.invoke(e.toString())}.onCompletion {loadingBlock?.invoke(false)}.collect {successBlock(it)}
}

这个源码对应第7代的写法。

Android 学习笔录

Android 性能优化篇:https://qr18.cn/FVlo89
Android Framework底层原理篇:https://qr18.cn/AQpN4J
Android 车载篇:https://qr18.cn/F05ZCM
Android 逆向安全学习笔记:https://qr18.cn/CQ5TcL
Android 音视频篇:https://qr18.cn/Ei3VPD
Jetpack全家桶篇(内含Compose):https://qr18.cn/A0gajp
OkHttp 源码解析笔记:https://qr18.cn/Cw0pBD
Kotlin 篇:https://qr18.cn/CdjtAF
Gradle 篇:https://qr18.cn/DzrmMB
Flutter 篇:https://qr18.cn/DIvKma
Android 八大知识体:https://qr18.cn/CyxarU
Android 核心笔记:https://qr21.cn/CaZQLo
Android 往年面试题锦:https://qr18.cn/CKV8OZ
2023年最新Android 面试题集:https://qr18.cn/CgxrRy
Android 车载开发岗位面试习题:https://qr18.cn/FTlyCJ
音视频面试题锦:https://qr18.cn/AcV6Ap

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/113197.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

GEO生信数据挖掘(九)肺结核数据-差异分析-WGCNA分析(900行代码整理注释更新版本)

第六节&#xff0c;我们使用结核病基因数据&#xff0c;做了一个数据预处理的实操案例。例子中结核类型&#xff0c;包括结核&#xff0c;潜隐进展&#xff0c;对照和潜隐&#xff0c;四个类别。第七节延续上个数据&#xff0c;进行了差异分析。 第八节对差异基因进行富集分析。…

Git 安装和基础命令、IDEA 基础操作

目录 总结命令&#xff1a;1、安装&#xff1a;1、安装2、配置环境变量&#xff1a; 2、Git操作&#xff1a;1、初始化&#xff1a;1、姓名邮箱&#xff1a;2、初始化仓库&#xff1a;3、工作区和暂存区分析 2、提交文件3、查看版本库状态4、安装小乌龟git不显示图标 5、查看提…

解线性方程组python实现迭代法(Jacobi迭代、Gauss-Seidel迭代、松弛迭代)

1. Jacobi迭代 Jacobi迭代法是一种用于求解线性方程组的迭代算法。它属于迭代法中的直接迭代法&#xff0c;通过不断迭代更新解向量来逼近线性方程组的解。 Jacobi迭代法的基本概念如下&#xff1a; 给定线性方程组的系数矩阵A和右侧常数向量b。 将系数矩阵A进行对角分解&…

解剖—单链表相关OJ练习题

目录 一、移除链表元素 二、找出链表的中间节点 三、合并两个有序链表 四、反转链表 五、求链表中倒数第k个结点 六、链表分割 七、链表的回文结构 八、判断链表是否相交 九、判断链表中是否有环(一) 十、 判断链表中是否有环(二) 注&#xff1a;第六题和第七题牛…

docker 基本用法-操作镜像

1.下载镜像 docker search centos #默认从 Docker Hub 中搜索镜像 访问 dockerhub&#xff1a;https://registry.hub.docker.com docker pull centos 拉取镜像 如果不能拉取 方法 1.需要配置配置镜像加速器 tee /etc/docker/daemon.json << EOF {"registry-mirro…

【文献copilot】调用文心一言api对论文逐段总结

文献copilot&#xff1a;调用文心一言api对论文逐段总结 当我读文献的时候&#xff0c;感觉读得太慢了&#xff0c;看翻译软件翻译的又觉得翻译的不好。于是我就写了个程序辅助我读文献&#xff0c;它可以逐段总结&#xff0c;输出格式是&#xff1a;原文一句话总结分段总结&a…

css钟表数字样式

如图&#xff1a; 代码 font-size: 28px;font-family: Yourname;font-weight: 500;color: #00e8ff;

CSS基础入门01

目录 1.CSS是什么 2.基本语法规范 3.引入方式 3.1内部样式表 3.2行内样式表 3.3外部样式 4.代码风格 4.1样式格式 4.2样式大小写 4.3空格规范 5.选择器 5.1选择器的功能 5.2选择器的种类 6.基础选择器 6.1标签选择器 6.2类选择器 6.3id 选择器 6.4通配符选择…

jQuery实现输入框提示并点击回显功能呢

html代码: <input type"text" id"affOrganization" name"affOrganization" class"form-control" placeholder"Search..." style"width: 300px" > <div class"search_suggest" id"gov_se…

黑豹程序员-架构师学习路线图-百科:开启分布式架构开发先河,让Java戴上全球第一的皇冠-EJB

文章目录 1、EJB的传奇2、什么是 EJB3、从拥抱到抛弃4、最终版EJB3.0 1、EJB的传奇 EJB这项技术其实已经消亡了&#xff0c;但为何我还专门单另拿出来讲呢&#xff1f;原因有三。 第一、EJB是J2EE雄霸全球的功臣&#xff0c;它把我们编程推向了分布式架构开发&#xff0c;为开…

Ubuntu的EFI分区无法删除

本文解决的问题&#xff1a;双系统装完后需要删除ubuntu的分区&#xff0c;但是EFI系统分区无法删除。 第一步&#xff1a;cmd中输入命令 diskpart 并回车&#xff0c;如图中①&#xff1b; 第二步&#xff1a;在弹出窗口②中依次输入如下命令即可删除EFI分区&#xff1b; /…

创新的营销模式与线上商城的完美结合

分享购&#xff0c;一个与众不同的电商平台&#xff0c;以一种全新的营销模式和独特的商业运营模式&#xff0c;颠覆了传统电商的观念&#xff0c;让每个人都能拥有属于自己的线上商城。它集自营品牌、供应链管理和CPS等多种优势于一身&#xff0c;形成了一种创新的交易和共享生…

移动App安全检测的必要性,app安全测试报告的编写注意事项

随着移动互联网的迅猛发展&#xff0c;移动App已经成为人们日常生活中不可或缺的一部分。然而&#xff0c;虽然App给我们带来了便利和乐趣&#xff0c;但也伴随着一些潜在的安全风险。黑客、病毒、恶意软件等威胁着用户的隐私和财产安全&#xff0c;因此进行安全检测就显得尤为…

Vue 组件和文件及文件夹命名规范、SPA、创建路由、router-link 相关属性、路由建立多视图单页应用

目录 一.vue组件&#xff08;重点&#xff09; 1.1 组件介绍 1.2 局部组件 1.3 全局组件 二.自定义事件 2.1 子 -> 父 2.2 父 -> 子 三.vue中文件及文件夹命名规范 四.SPA 4.1 SPA简介 4.2 SPA技术点 五.使用路由建立多视图单页应用 5.1 引入依赖库 5.2 创建…

算法进修Day-33

算法进修Day-33 65. 有效数字 难度&#xff1a;困难 题目要求 有效数字&#xff08;按顺序&#xff09;可以分成以下几个部分&#xff1a; 一个 小数 或者 整数&#xff08;可选&#xff09;一个 e 或 E &#xff0c;后面跟着一个 整数 小数&#xff08;按顺序&#xff09;…

什么是USRP软件无线电设备?

什么是USRP软件无线电设备&#xff1f; USRP软件无线电设备提供软件定义的RF架构&#xff0c;可让工程师使用自定义信号处理功能来设计、原型验证和部署无线系统。从基于大型开放式FPGA的经济款到高性能无线电设备&#xff0c;多种硬件可满足您的不同需求。您可以使用LabVIEW或…

施密特正交化

相信大家在平时的期末考试中一定少不了对某某向量组执行标准正交化类型的题目。今天我们从这个题目入手&#xff0c;说明这个如何执行施密特正交化&#xff0c;以及为什么要进行正交化。 一、例子 例子&#xff1a;设 a 1 [ 1 2 − 1 ] a_1\begin{bmatrix}1\\2\\-1\end{bmat…

Node-创建Web应用

题记 node创建web应用&#xff0c;以下是所有流程和代码 与php比较&#xff1a;使用 PHP 来编写后端的代码&#xff0c;需要 Apache 或者 Nginx 的 HTTP 服务器&#xff0c;并配上 mod_php5 模块和 php-cgi。 Node应用的组成 node应用由三部分组成&#xff1a; require 指令&a…

vulkan SDK安装

文章目录 一. vulcan官网二.安装流程 一. vulcan官网 https://vulkan.lunarg.com/sdk/home#windows 二.安装流程 点击下载 双击下载的*.exe进行安装 点击下一步 点击下一步 选择安装位置&#xff0c;点击下一步 点击全选&#xff0c;选择下一步 勾选同意&#xf…

PTrade财务数据获取函数的问题

前文介绍了PTrade的get_fundamentals函数&#xff0c;可以用于获取股票的财务数据。但在实际应用中&#xff0c;会遇到如下的问题。 前文我们通过将回测时间设置为2023-05-05进行回测调用get_fundamentals&#xff0c;得到如下查询结果&#xff1a; secu_codepubl_dateend_da…