You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android使用WorkManager批量调用API完成后统一返回成功问题求助

问题诊断

你的代码核心有三个错误点:

  • 你使用的默认Worker类的doWork方法是同步执行的,方法执行结束就会直接返回任务结果,不会等待你发起的异步API回调。你调用Retrofit的enqueue方法发起异步请求后,doWork不会等待回调执行就会继续往下走,导致Worker结束时大部分API请求还没有返回结果。
  • callApiForId方法中,你直接返回初始化的空值shiftGrabStatus,异步回调还没执行,返回值永远是空字符串。你后续在callConfirmShiftApi中直接在循环到最后一个元素时硬编码response = "CONFIRM",等于完全忽略了所有API的真实返回结果。
  • 你把callGrabShifts声明为类成员变量,每次循环调用API都会覆盖上一个请求的Call实例,会导致前面的请求回调异常、甚至被意外取消。
推荐解决方案

改用官方提供的CoroutineWorker实现,配合Retrofit的挂起函数能力,用同步写法执行异步请求,保证所有API请求执行完成后再返回Worker结果。

步骤1:修改API接口定义

将你的接口方法改为挂起函数,无需返回Call类型:

// 原代码:fun confirmGrabAllShifts(userId: String, id: String): Call<ConfirmStatus>
// 修改为:
suspend fun confirmGrabAllShifts(userId: String, id: String): Response<ConfirmStatus>

步骤2:替换Worker实现

// 需引入work-runtime-ktx依赖
class MyWorkManager(appContext: Context, workerParams: WorkerParameters):
    CoroutineWorker(appContext, workerParams) {

    override suspend fun doWork(): Result {
        val idsList = inputData.getStringArray("IDS_LIST") ?: return Result.failure()
        var allRequestSuccess = true
        try {
            // 按顺序遍历所有id执行请求,会等待前一个请求返回后再执行下一个
            for (id in idsList) {
                val response = BaseApp.apiInterface.confirmGrabAllShifts(BaseApp.userId, id)
                if (response.isSuccessful && response.body()?.status?.contains("CONFIRM") == true) {
                    // 请求成功逻辑
                    val shiftNumber = ++BaseApp.noOfShiftsGrabbed
                    sendNotification(applicationContext)
                } else {
                    // 单个请求失败,按需设置整体任务状态
                    allRequestSuccess = false
                    // 如果要求所有请求必须全部成功才返回成功,可直接break return Result.failure()
                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
            // 网络异常等情况可返回重试
            return Result.retry()
        }
        return if (allRequestSuccess) Result.success() else Result.failure()
    }
}

启动Worker的逻辑不需要修改,原有代码可直接复用。

替代实现思路

如果你需要每个id的请求可以独立重试、互不影响,可以为每个id单独创建一个OneTimeWorkRequest,通过WorkManager的链式任务能力批量执行,所有子任务全部成功后才会返回整体成功:

private fun confirmShiftApi(availableShiftsIdList: ArrayList<String>) {
    val workList = availableShiftsIdList.map { id ->
        val data = Data.Builder().putString("SHIFT_ID", id).build()
        OneTimeWorkRequestBuilder<SingleIdWorkWorker>().setInputData(data).build()
    }
    WorkManager.getInstance(applicationContext)
        .beginWith(workList)
        .enqueue()
    // 可监听整体任务的执行状态
}

你只需要单独实现一个处理单个id请求的Worker即可。

内容的提问来源于stack exchange,提问作者Pooja Singh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 13:36:03