我可以在 Worker 类和非 Worker 类(Android WorkManager)之间共享逻辑吗?

问题描述 投票:0回答:0

我想在一个方法中执行一个API请求,并按以下方式处理:

  • 如果请求没有产生 HTTP 5XX 响应,返回 响应方法调用者
  • 如果请求导致 HTTP 5XX 响应,请使用
    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
应该如何工作有一个根本性的误解。

android kotlin android-workmanager
© www.soinside.com 2019 - 2024. All rights reserved.