当前位置:网站首页>Kotlin collaboration uses coroutinecontext to implement the retry logic after a network request fails
Kotlin collaboration uses coroutinecontext to implement the retry logic after a network request fails
2022-07-05 13:47:00 【Big fish SS】

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() {
}
}
summary
This is the end of it , Put a little benefit at the end of the article , The following is a story about Flutter Learning ideas and direction , Engaged in Internet development , The most important thing is to learn technology well , And learning technology is a slow and hard road , You can't rely on a moment of passion , It's not like you can learn it in a few days and nights , We must form the habit of studying hard at ordinary times , More effective learning needs to be achieved .
Because of the large amount of content, I only put a general outline , If you need to learn mind mapping in more detail, you can scan the QR code below for free .
And free premium UI、 performance optimization 、 Architect course 、NDK、 Hybrid development (ReactNative+Weex) Wechat applet 、Flutter All aspects Android Advanced practice technical data , And there are technical experts to discuss, communicate and solve problems together .**

Last , The information in the article is too big to put . Friends in need, if necessary Scan the QR code below for free .
Change your life , There is no shortcut , This road needs to be taken in person , Only in-depth thinking , Constantly reflect and summarize , Keep your passion for learning , Step by step to build their own complete knowledge system , Is the ultimate way to win , It's also the mission of programmers .
author : Rhett
link :https://juejin.cn/post/7080826259785121822
边栏推荐
- 一网打尽异步神器CompletableFuture
- Integer ==比较会自动拆箱 该变量不能赋值为空
- 【华南理工大学】考研初试复试资料分享
- leetcode 10. Regular expression matching regular expression matching (difficult)
- redis6主从复制及集群
- 今年上半年,通信行业发生了哪些事?
- 搭建一个仪式感点满的网站,并内网穿透发布到公网 2/2
- PHP generate Poster
- 运筹说 第68期|2022年最新影响因子正式发布 快看管科领域期刊的变化
- Backup and restore of Android local SQLite database
猜你喜欢

Liar report query collection network PHP source code

These 18 websites can make your page background cool

TortoiseSVN使用情形、安装与使用
![[deep learning paper notes] hnf-netv2 for segmentation of brain tumors using multimodal MR imaging](/img/52/5e85743b1817de96a52e02b92fd08c.png)
[deep learning paper notes] hnf-netv2 for segmentation of brain tumors using multimodal MR imaging

Internal JSON-RPC error. {"code":-32000, "message": "execution reverted"} solve the error

基于微信小程序的订餐系统

How to deal with the Yellow Icon during the installation of wampserver

嵌入式软件架构设计-消息交互

Network security - Novice introduction

Idea设置方法注释和类注释
随机推荐
What happened to the communication industry in the first half of this year?
Mmseg - Mutli view time series data inspection and visualization
搭建一个仪式感点满的网站,并内网穿透发布到公网 2/2
Usage, installation and use of TortoiseSVN
Liar report query collection network PHP source code
Data Lake (VII): Iceberg concept and review what is a data Lake
Laravel generate entity
Go string operation
Solution to the prompt of could not close zip file during phpword use
Apicloud studio3 WiFi real machine synchronization and WiFi real machine preview instructions
zabbix 监控
Catch all asynchronous artifact completable future
Basic characteristics and isolation level of transactions
【Hot100】34. Find the first and last positions of elements in a sorted array
asp.net 读取txt文件
mysql获得时间
龙芯派2代烧写PMON和重装系统
Jetpack Compose入门到精通
一网打尽异步神器CompletableFuture
【 script secret pour l'utilisation de MySQL 】 un jeu en ligne sur l'heure et le type de date de MySQL et les fonctions d'exploitation connexes (3)