当前位置:网站首页>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
边栏推荐
猜你喜欢
随机推荐
web3.eth. Filter related
这18个网站能让你的页面背景炫酷起来
Basic characteristics and isolation level of transactions
Simple PHP paging implementation
Clock cycle
Summary and arrangement of JPA specifications
Go string operation
[server data recovery] a case of RAID5 data recovery stored in a brand of server
Can and can FD
一网打尽异步神器CompletableFuture
asp. Net read TXT file
How to apply the updated fluent 3.0 to applet development
MySQL if else use case use
FPGA learning notes: vivado 2019.1 add IP MicroBlaze
MySQL get time
基于微信小程序的订餐系统
Nantong online communication group
What is a network port
Catch all asynchronous artifact completable future
PostgreSQL Usage Summary (PIT)