当前位置:网站首页>[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 .
边栏推荐
- AI表现越差,获得奖金越高?纽约大学博士拿出百万重金,悬赏让大模型表现差劲的任务
- A series of shortcut keys for jetbrain pychar
- MySQL数据库(基础篇)
- Two methods of chromosome coordinate sequencing
- 架构实战训练营|课后作业|模块 6
- Chapter 9 Yunji datacanvas company has been ranked top 3 in China's machine learning platform market
- Thesis landing strategy | how to get started quickly in academic thesis writing
- If you ask me about R code debugging, I will tell you head, STR, help
- DFS和BFS概念及实践+acwing 842 排列数字(dfs) +acwing 844. 走迷宫(bfs)
- sscanf,sscanf_s及其相关使用方法「建议收藏」
猜你喜欢
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
【线段树实战】最近的请求次数 + 区域和检索 - 数组可修改+我的日程安排表Ⅰ/Ⅲ
Case reward: Intel brings many partners to promote the innovation and development of multi domain AI industry
namespace基础介绍
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
为什么很多人对技术债务产生误解
Chapter 9 Yunji datacanvas was rated as 36 krypton "the hard core technology enterprise most concerned by investors"
Read of shell internal value command
Chapter 9 Yunji datacanvas company won the highest honor of the "fifth digital finance innovation competition"!
AI landing new question type RPA + AI =?
随机推荐
【线段树实战】最近的请求次数 + 区域和检索 - 数组可修改+我的日程安排表Ⅰ/Ⅲ
Vscode 如何使用内置浏览器?
How to open win11 remote desktop connection? Five methods of win11 Remote Desktop Connection
什么是Web3
Flask项目使用flask-socketio异常:TypeError: function() argument 1 must be code, not str
Programmers go to work fishing, so play high-end!
The worse the AI performance, the higher the bonus? Doctor of New York University offered a reward for the task of making the big model perform poorly
A picture to understand! Why did the school teach you coding but still not
MySQL数据库(基础篇)
Tree map: tree view - draw covid-19 array diagram
GPT-3当一作自己研究自己,已投稿,在线蹲一个同行评议
深入解析Kubebuilder
STM32 system timer flashing LED
两个div在同一行,两个div不换行「建议收藏」
Monitoring cannot be started after Oracle modifies the computer name
全国气象数据/降雨量分布数据/太阳辐射数据/NPP净初级生产力数据/植被覆盖度数据
ACL2022 | 分解的元学习小样本命名实体识别
Section 1: (3) logic chip process substrate selection
Chapter 9 Yunji datacanvas company won the highest honor of the "fifth digital finance innovation competition"!
Canteen user dish relationship system (C language course design)