当前位置:网站首页>[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 .
边栏推荐
- 过气光刻机也不能卖给中国!美国无理施压荷兰ASML,国产芯片再遭打压
- 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
- How does vscade use the built-in browser?
- 【數模】Matlab allcycles()函數的源代碼(2021a之前版本沒有)
- Monitoring cannot be started after Oracle modifies the computer name
- Camera calibration (I): robot hand eye calibration
- Thread和Runnable创建线程的方式对比
- ACL2022 | 分解的元学习小样本命名实体识别
- Common Oracle SQL statements
- Win11 control panel shortcut key win11 multiple methods to open the control panel
猜你喜欢

namespace基础介绍

JDBC link Oracle reference code

Programmers go to work fishing, so play high-end!

Introduction to the PureMVC series

【Android Kotlin协程】利用CoroutineContext实现网络请求失败后重试逻辑

九章云极DataCanvas公司摘获「第五届数字金融创新大赛」最高荣誉!

A row of code r shows the table of Cox regression model

acwing 843. n-皇后问题

JS variable plus

Chapter 9 Yunji datacanvas company won the highest honor of the "fifth digital finance innovation competition"!
随机推荐
PLC模拟量输出 模拟量输出FB analog2NDA(三菱FX3U)
Code source de la fonction [analogique numérique] MATLAB allcycles () (non disponible avant 2021a)
组织实战攻防演练的5个阶段
Can I specify a path in an attribute to map a property in my class to a child property in my JSON?
两个div在同一行,两个div不换行「建议收藏」
R language principal component PCA, factor analysis, clustering analysis of regional economy analysis of Chongqing Economic Indicators
当 Knative 遇见 WebAssembly
【ArcGIS教程】专题图制作-人口密度分布图——人口密度分析
Common methods of list and map
mpf2_ Linear programming_ CAPM_ sharpe_ Arbitrage Pricin_ Inversion Gauss Jordan_ Statsmodel_ Pulp_ pLU_ Cholesky_ QR_ Jacobi
Thread和Runnable创建线程的方式对比
[digital analog] source code of MATLAB allcycles() function (not available before 2021a)
Field data acquisition and edge calculation scheme of CNC machine tools
Tree map: tree view - draw covid-19 array diagram
Thesis landing strategy | how to get started quickly in academic thesis writing
Flex layout and usage
深入解析Kubebuilder
【数模】Matlab allcycles()函数的源代码(2021a之前版本没有)
A simple and beautiful regression table is produced in one line of code~
Factor analysis r practice (with R installation tutorial and code)