在 android 中使用 WorkManager 多次调用 api

calling an api multiple times using WorkManager in android

我想使用 WorkManager 多次调用 api。

其中 idsArrayList 是一个 ID 列表。 我将 api 中的每个 id 作为 Path 发送以获得响应,对于其他 id 也是如此。 我希望 workManager 在为所有 ID 调用 api 后 return 成功。

但问题是 WorkManager 仅 return 列表中的一个 ID 成功。这是我第一次使用 WorkManager,我也尝试通过逐个迭代 idsList 并为 for 循环中的每个 id 创建 workManger 实例来为每个 id 启动工作管理器。但我认为将 idsList 作为数据发送到 workmanager 中,然后从 doWork() 内部迭代 id 会更好,但它没有像我想要的那样工作,我不明白为什么。这是我的代码:

    class MyWorkManager(appContext: Context, workerParams: WorkerParameters):
    Worker(appContext, workerParams) {

    private lateinit var callGrabShifts: Call<ConfirmStatus>

    override fun doWork(): Result {
        val idsList = inputData.getStringArray("IDS_LIST")
        val idsArrayList = idsList?.toCollection(ArrayList())
        var response = ""
        if (idsArrayList != null) {
            try {
      
                response = callConfirmShiftApi(idsArrayList)
                if (response.contains("CONFIRM")) {
                 
                    return Result.success()
                } 
            } catch (e: Exception) {
                e.printStackTrace()
                return Result.failure()
            }
        }

        return Result.retry()
    }

    private fun callConfirmShiftApi(idsArrayList: ArrayList<String>): String {
        var response = ""
        for ((index, id) in idsArrayList.withIndex()) {
         
            response = callApiForId(id)
           
            if(index == idsArrayList.lastIndex) {
                response = "CONFIRM"
            }
        }
        return response
    }

    private fun callApiForId(id: String): String {
        var shiftGrabStatus = ""
      
        callGrabShifts = BaseApp.apiInterface.confirmGrabAllShifts(BaseApp.userId, id)
        callGrabShifts.enqueue(object : Callback<ConfirmStatus> {
            override fun onResponse(call: Call<ConfirmStatus>, response: Response<ConfirmStatus>) {
                if (response.body() != null) {
                    shiftGrabStatus = response.body()!!.status
                    if (shiftGrabStatus != null) {
                        if (shiftGrabStatus.contains("CONFIRM")) {
                            
                            val shiftNumber = ++BaseApp.noOfShiftsGrabbed
                            
                            sendNotification(applicationContext)
                            shiftGrabStatus = "CONFIRM"
                            return
                        } else {
                            shiftGrabStatus = "NOT CONFIRM"
                            return
                        }
                    } else {
                        shiftGrabStatus = "NULL"
                        return
                    }
                } else {
                    shiftGrabStatus = "NULL"
                    return
                }
            }

            override fun onFailure(call: Call<ConfirmStatus>, t: Throwable) {
               
                shiftGrabStatus = "FAILURE"
                return
            }
        })
        return shiftGrabStatus
    }    
}

这是我启动 WorkManager 的代码:

private fun confirmShiftApi(availableShiftsIdList: ArrayList<String>) {
        
        val data = Data.Builder()
        data.putStringArray("IDS_LIST", availableShiftsIdList.toArray(arrayOfNulls<String>(availableShiftsIdList.size)))

        val oneTimeWorkRequest = OneTimeWorkRequestBuilder<MyWorkManager>().setInputData(data.build())
            .build()
        WorkManager.getInstance(applicationContext).enqueue(oneTimeWorkRequest)
      
        WorkManager.getInstance(this).getWorkInfoByIdLiveData(oneTimeWorkRequest.id)
            .observe(this, Observer { workInfo: WorkInfo? ->
                if (workInfo != null && workInfo.state.isFinished) {
                    val progress = workInfo.progress           
                }
                Log.d("TESTING", "(MainActivity) : observing work manager - workInfo?.state - ${workInfo?.state}")
            })
    }

对我可能做错了什么有什么建议或执行相同操作的任何其他替代方法吗?我选择 workmanager 基本上是为了执行此任务,即使在应用程序关闭时也是如此,并且出于学习目的,因为我以前没有使用过 WorkManager。但如果这不起作用,将切换到其他选项。

我尝试了以下操作:

  1. 删除了我用来设置响应的每个方法中的 'var 响应行,尽管我临时添加它只是为了早些时候进行调试,但它导致了问题。
  2. 我在 doWork() 方法中删除了对“CONFIRM”的检查,只是进行了 api 调用,删除了额外的 return 行。
  3. 我尝试在每个 ID 的 api 个调用之间添加手动延迟。
  4. 我删除了在调用 workmanager 之前从我的 activity 发送 ids 数据的代码,并进行了 api 调用以在 workmanager 中获取这些 ids 并在这些调用之间增加了更多延迟为了保持 运行 在后台检查一轮完成的数据(为之前获取的所有 ID 调用 api,它必须再次调用 api 以重复检查更多 ID )
  5. 我从 onRestart() 和其他需要再次调用 api 的条件中删除了额外的 api 调用。
  6. 我只测试了一轮 api 延迟调用所有 ID,并删除了重复调用部分只是为了先测试。没用。
上面的

None 有效,它只是删除了额外的代码行。

这是我经过测试的最终代码,它消除了我的疑虑。虽然它没有解决这个问题,因为这个问题是因为后端服务器和 Apis return大多数 ID 的 onResponse 回调失败(当使用for loop for each id) 除了列表中的第一个 id 和随机的最后一个 id 有时(有延迟)对于其余的 id,它没有 return 使用 Workmanager 确认来自 api 的状态消息。添加延迟并没有太大的区别。

这是我的 Workmanager 代码:

    class MyWorkManager(appContext: Context, workerParams: WorkerParameters):
        Worker(appContext, workerParams) {
    
        private lateinit var callGrabShifts: Call<ConfirmStatus>
    
        override fun doWork(): Result {
            val idsList = inputData.getStringArray("IDS_LIST")
            val idsArrayList = idsList?.toCollection(ArrayList())
            if (idsArrayList != null) {
                try {
                    response = callConfirmShiftApi(idsArrayList)
                    if (response.contains("CONFIRM")) {
                        return Result.success()
                    } 
                } catch (e: Exception) {
                    e.printStackTrace()
                    return Result.failure()
                }
            }
            return Result.success()
        }
    
        private fun callConfirmShiftApi(idsArrayList: ArrayList<String>): String {
            for ((index, id) in idsArrayList.withIndex()) {
                response = callApiForId(id)
                Thread.sleep(800)
                if(index == idsArrayList.lastIndex) {
                    response = "CONFIRM"
                }
            }
            return response
        }
    
        private fun callApiForId(id: String): String {
callGrabShifts = BaseApp.apiInterface.confirmGrabAllShifts(BaseApp.userId, id)
 callGrabShifts.enqueue(object : Callback<ConfirmStatus> {
                override fun onResponse(call: Call<ConfirmStatus>, response: Response<ConfirmStatus>) {
                    if (response.body() != null) {
                        shiftGrabStatus = response.body()!!.status
                        if (shiftGrabStatus != null) {
                            if (shiftGrabStatus.contains("CONFIRM")) {
                                return
                            } else {
                                return
                            }
                        } else {
                            return
                        }
                    } else {
                        return
                    }
                }
    
                override fun onFailure(call: Call<ConfirmStatus>, t: Throwable) {
                    return
                }
            })
    
            return shiftGrabStatus
        }

最终这个问题(当对一个 id 进行单独调用时,它总是 return 成功但是当我使用循环为每个 id 调用 api 时,它只 returns 第一次调用成功而其他人失败)使用服务解决了,它也没有 apis 的完全成功率,但是对于 6/11 ids api returned 成功(每次 api 调用之间有 400 毫秒的延迟),所以它现在达到了目的。