当前位置:网站首页>[Android kotlin collaboration] use coroutinecontext to realize the retry logic after a network request fails
[Android kotlin collaboration] use coroutinecontext to realize the retry logic after a network request fails
2022-07-07 04:55:00 【Programmer Xiao He SS】
Preface
stay Android There is a typical scenario in development : Try again after the network request fails : The general logic is to pop up a Dialog Remind users “ Network request failed ”, And provide a retry button .

If the current page has only one network request , Then the logic is very simple : Just call the method that initiates the network request again . When a page has multiple network requests , My common method is to add status for failure callback , Call different methods according to different states . But this method is somewhat cumbersome , It's also a little unsafe . First , You need to add extra status , And pass it around . In some cases , You even need to reinitialize the network request parameters . What's worse : You have to manage this state , Once mismanaged , Will result in calling methods that should not be called , Introduce serious BUG.
Until one day I saw CoroutineExceptionHandler, Flash of light —— You can use the collaboration context to save network requests and... That may need to be retried in the future Request data , This will solve the above problem .
Because most of the projects I have developed adopt ViewModel Implement network request logic and UI Decoupling of layers , The network request is basically based on Coroutine+Retrofit The way to achieve , It's basically using viewModelScope.
viewModelScope.launch() {
request()
}
viewModelScope It's essentially a ViewModel The extension function of , It can be used conveniently in ViewModel Create coroutines , The specific code will not be expanded . By default , its CoroutineContext from Job and CoroutineDispatcher form . The context of a collaborative process is essentially an implementation key-value Linked list structure of access mode . We can do it through inheritance AbstractCoroutineContextElement To implement custom CoroutineContext Context :
class RetryCallback(val callback: () -> Unit) : AbstractCoroutineContextElement(RetryCallback) {
companion object Key : CoroutineContext.Key<RetryCallback>
}
Then , When the network request is abnormal CoroutineExceptionHandler Get the operation we need to perform again :
val coroutineExceptionHandler = CoroutineExceptionHandler { coroutineContext, throwable ->
val callback = coroutineContext[RetryCallback]
?.callback
}
Then , To put coroutineExceptionHandler Add to the context of the process that initiates the network request :
viewModelScope.launch(exceptionHandler
+ RetryCallback { request() }) {
request()
}
here , Just get it on the page that initiates the network request callback, And call it when you click the retry button , The logic of retry can be realized .
Further encapsulate it and add automatic retry logic after failure , Create for ViewModel Interface used , Subsequent logic used to handle network request errors :
interface ViewModelFailed {
/**
* @param throwable: Abnormal information
* @param callback: Function to retry
* */
fun requestFailed(throwable: Throwable, callback: () -> Unit)
}
Create an extension function for it , Used to create CoroutineExceptionHandler and RetryCallback Context instance :
/**
* @param autoReTry: Retry automatically
* @param callback: Function to retry
* */
fun ViewModelFailed.initRetry(autoReTry: Boolean = false, callback: () -> Unit) =
CoroutineExceptionHandler { coroutineContext, throwable ->
val retryCallBack = {
coroutineContext[RetryCallback]
?.callback?.invoke()
}
if (autoReTry) {
// Automatic start retry logic
onRetry()
retryCallBack.invoke()
} else {
// Do not automatically start retry , Subsequent operations are left to the user for decision
requestFailed(throwable) {
retryCallBack
}
}
} + RetryCallback(callback)
ViewModel Need to achieve ViewModelFailed Interface , And calls in the association of the network requests. initRetry Method to add an exception handling context :
class MainViewViewModel : ViewModel(), ViewModelFailed {
val liveData: MutableLiveData<BaseData> = MutableLiveData()
/**
* @param num: For demonstration Request Request data
* @param repeat: Number of automatic retries after failure
* */
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) {
// Simulate network requests
...
}
override fun requestFailed(throwable: Throwable, callback: () -> Unit) {
// Processing failure logic
dialog()
// retry
callback.invoke()
}
override fun onRetry() {
}
}
Last
Android Learning is a long way to go , What we need to learn is not only superficial technology , We have to go down to the bottom , Figure out the following principle , That's the only way , We can improve our competitiveness , In today's highly competitive world .
Life can't be smooth , When there are peaks, there are valleys , To believe in , Those who can't beat us , It will make us stronger in the end , To be your own ferry man .
I've sorted myself out in this period of time Android The most important and popular learning direction materials are placed in the QR code below , There are also different directions of self-study programming route 、 Interview question set / Face the 、 And a series of technical articles .**
Resources are constantly updated , Welcome to study and discuss together .
边栏推荐
- AttributeError: module ‘torch._C‘ has no attribute ‘_cuda_setDevice‘
- Web3 社区中使用的术语
- A simple and beautiful regression table is produced in one line of code~
- ACL2022 | 分解的元学习小样本命名实体识别
- Poor math students who once dropped out of school won the fields award this year
- Two methods of chromosome coordinate sequencing
- 01机器学习相关规定
- Structure actual training camp | after class homework | module 6
- 微信能开小号了,拼多多“砍一刀”被判侵权,字节VR设备出货量全球第二,今日更多大新闻在此
- Basic idea of counting and sorting
猜你喜欢
![[practice leads to truth] is the introduction of import and require really the same as what is said on the Internet](/img/58/4337f0972f7171a5c21e640f03e0b7.png)
[practice leads to truth] is the introduction of import and require really the same as what is said on the Internet

5G VoNR+之IMS Data Channel概念

Markdown编辑器

Common Oracle SQL statements

Vscode automatically adds a semicolon and jumps to the next line

01机器学习相关规定

How does vscade use the built-in browser?

为什么很多人对技术债务产生误解

Lessons and thoughts of the first SQL injection

In depth analysis of kubebuilder
随机推荐
C语言中函数指针与指针函数
STM32封装ESP8266一键配置函数:实现实现AP模式和STA模式切换、服务器与客户端创建
STM32F103ZE+SHT30检测环境温度与湿度(IIC模拟时序)
【ArcGIS教程】专题图制作-人口密度分布图——人口密度分析
树与图的深度优先遍历模版原理
DFS和BFS概念及实践+acwing 842 排列数字(dfs) +acwing 844. 走迷宫(bfs)
3GPP信道模型路损基础知识
Tiktok may launch an independent grass planting community platform: will it become the second little red book
AI表现越差,获得奖金越高?纽约大学博士拿出百万重金,悬赏让大模型表现差劲的任务
Flex layout and usage
Section 1: (3) logic chip process substrate selection
A simple and beautiful regression table is produced in one line of code~
九章云极DataCanvas公司摘获「第五届数字金融创新大赛」最高荣誉!
ServiceMesh主要解决的三大痛点
Up to 5million per person per year! Choose people instead of projects, focus on basic scientific research, and scientists dominate the "new cornerstone" funded by Tencent to start the application
Windows are not cheap things
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
广告归因:买量如何做价值衡量?
两个div在同一行,两个div不换行「建议收藏」
How to conduct website testing of software testing? Test strategy let's go!