谷歌最近宣布了新的 WorkManager
架构组件。通过在 Worker
类中实现 doWork()
可以轻松安排同步工作,但是如果我想在后台执行一些异步工作怎么办?例如,我想使用 Retrofit 进行网络服务调用。我知道我可以发出同步网络请求,但它会阻塞线程并且感觉不对。是否有任何解决方案或目前不支持?
原文由 Anton Tananaev 发布,翻译遵循 CC BY-SA 4.0 许可协议
谷歌最近宣布了新的 WorkManager
架构组件。通过在 Worker
类中实现 doWork()
可以轻松安排同步工作,但是如果我想在后台执行一些异步工作怎么办?例如,我想使用 Retrofit 进行网络服务调用。我知道我可以发出同步网络请求,但它会阻塞线程并且感觉不对。是否有任何解决方案或目前不支持?
原文由 Anton Tananaev 发布,翻译遵循 CC BY-SA 4.0 许可协议
我使用了一个倒计时锁存器并等待它达到 0,这只会在异步回调更新它后发生。看这段代码:
public WorkerResult doWork() {
final WorkerResult[] result = {WorkerResult.RETRY};
CountDownLatch countDownLatch = new CountDownLatch(1);
FirebaseFirestore db = FirebaseFirestore.getInstance();
db.collection("collection").whereEqualTo("this","that").get().addOnCompleteListener(task -> {
if(task.isSuccessful()) {
task.getResult().getDocuments().get(0).getReference().update("field", "value")
.addOnCompleteListener(task2 -> {
if (task2.isSuccessful()) {
result[0] = WorkerResult.SUCCESS;
} else {
result[0] = WorkerResult.RETRY;
}
countDownLatch.countDown();
});
} else {
result[0] = WorkerResult.RETRY;
countDownLatch.countDown();
}
});
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
return result[0];
}
原文由 TomH 发布,翻译遵循 CC BY-SA 4.0 许可协议
3 回答958 阅读✓ 已解决
2 回答1k 阅读✓ 已解决
1 回答837 阅读✓ 已解决
2 回答946 阅读
2 回答886 阅读
1 回答820 阅读
2 回答689 阅读
根据 WorkManager 文档:
因此,如果您不使用
synchronous()
,您可以安全地从doWork()
执行同步网络调用。从设计的角度来看,这也是一种更好的方法,因为回调很混乱。也就是说,如果你真的想从
doWork()
触发异步作业,你需要暂停执行线程并在异步作业完成后使用wait/notify
机制(或其他线程)恢复它管理机制,例如Semaphore
)。在大多数情况下我不会推荐。作为旁注,WorkManager 处于非常早期的 alpha 阶段。