当前位置:网站首页>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
边栏推荐
- Summit review | baowanda - an integrated data security protection system driven by compliance and security
- kafaka 日志收集
- 记录一下在深度学习-一些bug处理
- [deep learning paper notes] hnf-netv2 for segmentation of brain tumors using multimodal MR imaging
- 不知道这4种缓存模式,敢说懂缓存吗?
- 【华南理工大学】考研初试复试资料分享
- Jasypt configuration file encryption | quick start | actual combat
- Integer ==比较会自动拆箱 该变量不能赋值为空
- ZABBIX monitoring
- Laravel框架运行报错:No application encryption key has been specified
猜你喜欢
FPGA learning notes: vivado 2019.1 add IP MicroBlaze
Go array and slice
Win10——轻量级小工具
Huawei push service content, read notes
What is a network port
Jenkins installation
私有地址有那些
Solve the problem of invalid uni app configuration page and tabbar
[daily question] 1200 Minimum absolute difference
MySQL - database query - sort query, paging query
随机推荐
Interviewer soul torture: why does the code specification require SQL statements not to have too many joins?
Flutter 3.0更新后如何应用到小程序开发中
内网穿透工具 netapp
PHP basic syntax
南理工在线交流群
Usage, installation and use of TortoiseSVN
Cloudcompare - point cloud slice
49. Grouping of alphabetic ectopic words: give you a string array, please combine the alphabetic ectopic words together. You can return a list of results in any order. An alphabetic ectopic word is a
Can and can FD
Godson 2nd generation burn PMON and reload system
什么是网络端口
Require, require in PHP_ once、include、include_ Detailed explanation of the efficiency of repeated introduction of once class library
荐号 | 有趣的人都在看什么?
Matlab paper chart standard format output (dry goods)
Basic characteristics and isolation level of transactions
[server data recovery] a case of RAID5 data recovery stored in a brand of server
Zhubo Huangyu: it's really bad not to understand these gold frying skills
RK3566添加LED
"Baidu Cup" CTF competition in September, web:upload
那些考研后才知道的事