Android WorkManager 中的异步 Worker

新手上路,请多包涵

谷歌最近宣布了新的 WorkManager 架构组件。通过在 Worker 类中实现 doWork() 可以轻松安排同步工作,但是如果我想在后台执行一些异步工作怎么办?例如,我想使用 Retrofit 进行网络服务调用。我知道我可以发出同步网络请求,但它会阻塞线程并且感觉不对。是否有任何解决方案或目前不支持?

原文由 Anton Tananaev 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 721
2 个回答

根据 WorkManager 文档

默认情况下,WorkManager 在后台线程上运行其操作。如果您已经在后台线程上运行并且需要对 WorkManager 进行同步(阻塞)调用,请使用 synchronous() 来访问此类方法。

因此,如果您不使用 synchronous() ,您可以安全地从 doWork() 执行同步网络调用。从设计的角度来看,这也是一种更好的方法,因为回调很混乱。

也就是说,如果你真的想从 doWork() 触发异步作业,你需要暂停执行线程并在异步作业完成后使用 wait/notify 机制(或其他线程)恢复它管理机制,例如 Semaphore )。在大多数情况下我不会推荐。

作为旁注,WorkManager 处于非常早期的 alpha 阶段。

原文由 Vasiliy 发布,翻译遵循 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 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题