当前位置:网站首页>【Android Kotlin协程】利用CoroutineContext实现网络请求失败后重试逻辑
【Android Kotlin协程】利用CoroutineContext实现网络请求失败后重试逻辑
2022-07-06 22:22:00 【程序员小何SS】
前言
在Android开发中有一个典型场景:网络请求失败后重试:一般的逻辑是弹出一个Dialog提醒用户“网络请求失败”,并提供重试的按钮。
如果当前页面只有一个网络请求,那么逻辑就很简单了:只需要再调用一下发起这个网络请求的方法就可以了。而当一个页面有多个网络请求时,我常用的办法为失败回调加状态,根据不同的状态调用不同的方法。但是这个方法不免有些繁琐,也有点不安全。首先,你要额外的增加状态,并将它传来传去。有些情况下,你甚至还需要重新初始化网络请求参数。更要命的是:你还要管理这个状态,一旦管理不善,就会导致调用了不该调用的方法,引入严重的BUG。
直到有一天我看到CoroutineExceptionHandler
,灵光突现——可以使用协程上下文来保存将来可能需要重试的网络请求和Request数据,这样就能解决上面的问题了。
由于我所开发的大多数项目都是采用ViewModel实现网络请求逻辑和UI层的解耦,而网络请求基本上是采用Coroutine+Retrofit的方式实现的,基本上都是使用viewModelScope。
viewModelScope.launch() {
request()
}
viewModelScope本质上是一个ViewModel的扩展函数,利用它可以便捷的在ViewModel创建协程,具体的代码就不展开了。默认情况下,它的CoroutineContext由Job和CoroutineDispatcher组成。而协程的上下文本质上就是一个实现了key-value访问的方式的链表结构。我们可以通过继承AbstractCoroutineContextElement
的方式实现自定义的CoroutineContext上下文:
class RetryCallback(val callback: () -> Unit) : AbstractCoroutineContextElement(RetryCallback) {
companion object Key : CoroutineContext.Key<RetryCallback>
}
紧接着,当网络请求发生异常时借助CoroutineExceptionHandler
获取到我们需要重新执行的操作:
val coroutineExceptionHandler = CoroutineExceptionHandler { coroutineContext, throwable ->
val callback = coroutineContext[RetryCallback]
?.callback
}
紧接着,要将coroutineExceptionHandler添加到发起网络请求的协程上下文里:
viewModelScope.launch(exceptionHandler
+ RetryCallback { request() }) {
request()
}
此时,只要在发起网络请求的页面里获取到callback
,并在点击重试按钮的时候调用它,就能实现重试的逻辑。
进一步对它进行封装并增加失败后自动重试逻辑,创建供ViewModel使用的接口,用来处理网络请求错误的后续逻辑:
interface ViewModelFailed {
/**
* @param throwable:异常信息
* @param callback:需要重试的函数
* */
fun requestFailed(throwable: Throwable, callback: () -> Unit)
}
为它创建扩展函数,用来创建CoroutineExceptionHandler
和RetryCallback
上下文实例:
/**
* @param autoReTry:是否自动重试
* @param callback:需要重试的函数
* */
fun ViewModelFailed.initRetry(autoReTry: Boolean = false, callback: () -> Unit) =
CoroutineExceptionHandler { coroutineContext, throwable ->
val retryCallBack = {
coroutineContext[RetryCallback]
?.callback?.invoke()
}
if (autoReTry) {
//自动开始重试逻辑
onRetry()
retryCallBack.invoke()
} else {
//不自动开始重试,后续操作交给用户决定
requestFailed(throwable) {
retryCallBack
}
}
} + RetryCallback(callback)
ViewModel需要实现ViewModelFailed接口,并在发起网络请求的协程中调用initRetry
方法添加异常处理上下文:
class MainViewViewModel : ViewModel(), ViewModelFailed {
val liveData: MutableLiveData<BaseData> = MutableLiveData()
/**
* @param num:用来演示Request请求数据
* @param repeat:失败后自动重试的次数
* */
fun request(num: Int, repeat: Int = 0) {
liveData.value = BaseData.loading()
viewModelScope.launch(initRetry(repeat > 0) {
request(num,repeat - 1)
}) {
liveData.value = BaseData.success(simulateHttp(num))
}
}
private suspend fun simulateHttp(num: Int) = withContext(Dispatchers.IO) {
//模拟网络请求
...
}
override fun requestFailed(throwable: Throwable, callback: () -> Unit) {
//处理失败逻辑
dialog()
//重试
callback.invoke()
}
override fun onRetry() {
}
}
最后
Android学习是一条漫长的道路,我们要学习的东西不仅仅只有表面的 技术,还要深入底层,弄明白下面的 原理,只有这样,我们才能够提高自己的竞争力,在当今这个竞争激烈的世界里立足。
人生不可能一帆风顺,有高峰自然有低谷,要相信,那些打不倒我们的,终将使我们更强大,要做自己的摆渡人。
我把自己这段时间整理的Android最重要最热门的学习方向资料放在了下方二维码中,里面还有不同方向的自学编程路线、面试题集合/面经、及系列技术文章等。**
资源持续更新中,欢迎大家一起学习和探讨。
边栏推荐
- Structure actual training camp | after class homework | module 6
- sscanf,sscanf_s及其相关使用方法「建议收藏」
- Is there any way to bookmark the code in the visual studio project- Is there a way to bookmark code in a Visual Studio project?
- Fiance donated 500million dollars to female PI, so that she didn't need to apply for projects, recruited 150 scientists, and did scientific research at ease!
- Case reward: Intel brings many partners to promote the innovation and development of multi domain AI industry
- 【数模】Matlab allcycles()函数的源代码(2021a之前版本没有)
- Factor analysis r practice (with R installation tutorial and code)
- 一度辍学的数学差生,获得今年菲尔兹奖
- Lecture 3 of "prime mover x cloud native positive sounding, cost reduction and efficiency enhancement lecture" - kubernetes cluster utilization improvement practice
- 5G VoNR+之IMS Data Channel概念
猜你喜欢
What about the collapse of win11 playing pubg? Solution to win11 Jedi survival crash
Camera calibration (I): robot hand eye calibration
MySQL forgot how to change the password
Analyse approfondie de kubebuilder
3GPP信道模型路损基础知识
Break the memory wall with CPU scheme? Learn from PayPal to expand the capacity of aoteng, and the volume of missed fraud transactions can be reduced to 1/30
How to open win11 remote desktop connection? Five methods of win11 Remote Desktop Connection
Gavin teacher's perception of transformer live class - rasa project actual combat e-commerce retail customer service intelligent business dialogue robot microservice code analysis and dialogue experim
R language principal component PCA, factor analysis, clustering analysis of regional economy analysis of Chongqing Economic Indicators
Lessons and thoughts of the first SQL injection
随机推荐
C # use Siemens S7 protocol to read and write PLC DB block
Unit test asp Net MVC 4 Application - unit testing asp Net MVC 4 apps thoroughly
Introduction to the PureMVC series
GPT-3当一作自己研究自己,已投稿,在线蹲一个同行评议
What about the collapse of win11 playing pubg? Solution to win11 Jedi survival crash
R语言主成分pca、因子分析、聚类对地区经济研究分析重庆市经济指标
DFS和BFS概念及实践+acwing 842 排列数字(dfs) +acwing 844. 走迷宫(bfs)
日常工作中程序员最讨厌哪些工作事项?
Intel and Xinbu technology jointly build a machine vision development kit to jointly promote the transformation of industrial intelligence
图灵诞辰110周年,智能机器预言成真了吗?
DFS and BFS concepts and practices +acwing 842 arranged numbers (DFS) +acwing 844 Maze walking (BFS)
B站大佬用我的世界搞出卷积神经网络,LeCun转发!爆肝6个月,播放破百万
Mathematical analysis_ Notes_ Chapter 10: integral with parameters
The root file system of buildreoot prompts "depmod:applt not found"
Wechat can play the trumpet. Pinduoduo was found guilty of infringement. The shipment of byte VR equipment ranks second in the world. Today, more big news is here
Vscode automatically adds a semicolon and jumps to the next line
Comment les tests de logiciels sont - ils effectués sur le site Web? Testez la stratégie!
How to conduct website testing of software testing? Test strategy let's go!
Deeply cultivate the developer ecosystem, accelerate the innovation and development of AI industry, and Intel brings many partners together
Analyse approfondie de kubebuilder