【发布时间】:2021-10-15 15:35:37
【问题描述】:
我想使用 WorkManager 多次调用一个 api。
其中 idsArrayList 是一个 id 列表。 我将 api 中的每个 id 作为 Path 发送以获取响应,对于其他 id 也是如此。 我希望 workManager 在为所有 id 调用 api 后返回成功。
但问题是 WorkManager 只为列表中的一个 id 返回 SUCCESS。这是我第一次使用 WorkManager,我也尝试通过逐个迭代 idsList 并为 for 循环中的每个 id 创建 workManger 实例来为每个 id 启动工作管理器。但我认为将 idsList 作为工作管理器中的数据发送,然后从 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。但如果这不起作用,会切换到其他选项。
【问题讨论】:
-
我认为您需要存储库人员,这是我通过将 Worker 视为活动/片段来解决此问题的唯一方法。工作人员对逻辑一无所知,他们的目的只是在存储库中调用一个函数来使用协程 IO 线程执行一些异步任务。
-
实际问题出在后端,重复调用api返回失败。虽然使用 workmanager,但即使添加延迟也没有太大区别,但使用服务,它在 api 调用之间增加相同的延迟(400 毫秒)时效果更好
标签: android kotlin background-process android-workmanager android-jobscheduler