我想在一个方法中执行一个API请求,并按以下方式处理:
WorkManager
在后台重试,它可以静默失败/成功尝试 1:
我最初的想法是将所有必需的逻辑放在扩展
Worker
的同一个类中。但是,鉴于类签名,我无法再实例化如下所示的 Client
类,因为我不知道为 WorkerParameters
参数提供什么(这通常由系统在创建工作请求时提供,例如在我的 enqueueRequest 方法中)。正如 this StackOverflow post 中所指出的,通常 Worker
类没有明确创建。
internal open class Client(private val context: Context, workerParams: WorkerParameters) : Worker(context, workerParams) {
fun executeRequest(request: Request): Response? {
// Sends API request and returns a response or null
}
fun executeRetriableRequest(request: Request): Response? {
val response = executeRequest(request) ?: return null
if (response.code > 499) {
enqueueRequestForRetry(request)
} else {
return response
}
}
private fun enqueueRequest(request: Request) {
val data = Data.Builder()
data.putString(REQUEST_DATA_KEY, request.toString())
val requestToRetry = PeriodicWorkRequestBuilder<Client>(REQUEST_RETRY_PERIOD, TimeUnit.MINUTES).setInputData(data.build())
WorkManager.getInstance(context).enqueue(requestToRetry.build())
}
override fun doWork(): Result {
val request = stringToRequest(inputData.getString(REQUEST_DATA_KEY)) // Converts a string to a Request object
val response = executeRequest(request)
return if (response.code > 499) { // Request failed with 5XX error and should be retried
Result.retry()
} else if (response.code > 299) { // Request failed and should not be retried
Result.failure()
} else {
Result.success()
}
}
}
尝试 2:
我的下一个想法是创建一个类
RequestWorker
,它只负责重试请求。这样我就可以轻松地从我想要的任何地方实例化我的 Client
类,并且可以执行重试而无需显式实例化我的 RequestWorker 类。这个问题是 RequestWorker
现在不能再调用 executeRequest
(如下所示),所以我必须将该方法复制到 RequestWorker
中,这是非常多余的。
internal open class Client(private val context: Context) {
fun executeRequest(request: Request): Response? {
// Sends API request and returns a response
}
fun executeRetriableRequest(request: Request): Response? {
val response = executeRequest(request) ?: return null
if (response.code > 499) {
enqueueRequestForRetry(request)
} else {
return response
}
}
private fun enqueueRequest(request: Request) {
val data = Data.Builder()
data.putString(REQUEST_DATA_KEY, request.toString())
val requestToRetry = PeriodicWorkRequestBuilder<RequestWorker>(REQUEST_RETRY_PERIOD, TimeUnit.MINUTES).setInputData(data.build())
WorkManager.getInstance(context).enqueue(requestToRetry.build())
}
}
internal class RequestWorker(context: Context, workerParams: WorkerParameters) : Worker(context, workerParams,) {
override fun doWork(): kotlin.Result {
val request = stringToRequest(inputData.getString(REQUEST_DATA_KEY))
val response = executeRequest(request)
return if (response.code > 499) {
kotlin.Result.retry()
} else if (response.code > 299) {
kotlin.Result.failure()
} else {
kotlin.Result.success()
}
}
fun executeRequest(request: Request): Response? {
// Sends API request and returns a response or null
// This is a copy of the method in the Client class. No good!
}
}
似乎没有一个直接的方法来完成我想要的,这让我想知道我是否对
WorkManager
应该如何工作有一个根本性的误解。