定期工作请求未在Work Manager中执行doWork

6

I'm trying to get data from a remote url periodically using PeriodicWorkRequest in WorkManager. I have implemented the logic, the issue here is that i don't get any response from the Worker.

However it seems to call doWork() at first launch, but it doesn't get data from the network call. I am surprised that when i use OneTimeWorkRequest i get a success result from doWork() and the data from server as well.

what could i be doing wrong?

code below:

Worker Class

public class WorkerClass extends Worker {

private Context context;
public static final String EXTRA_WORKER_CLASS = "extra_tag";

public SpecialOffer(@NonNull Context context, @NonNull WorkerParameters workerParams) {
    super(context, workerParams);
    this.context = context;
}

@NonNull
@Override
public Result doWork() {
    Log.d("WORKER_PERIOD", "started");
    String url = "https://sampleurl/get.php";
    //Volley synchronous call
    RequestFuture<String> future = RequestFuture.newFuture();
    StringRequest request = new StringRequest(url, future, future);
    MySingleton.getInstance(context).addToRequestQueue(request);

    try {
        String response = future.get();
        Data data = new Data.Builder()
                .putString(EXTRA_SPECIAL_CARS, response)
                .build();
        setOutputData(data);
        Log.d("WORKER_RESPONSE", response);
        return Result.SUCCESS;
    } catch (InterruptedException | ExecutionException e) {
        return Result.FAILURE;
    }
}
}

Method to call task

public void callTask(){
     PeriodicWorkRequest periodicRequest =
                new PeriodicWorkRequest.Builder(WorkerClass.class, 15, TimeUnit.MINUTES)
                        .setConstraints(constraints)
                        .addTag("SPECIAL_OFFER")
                        .build();

        workManager.enqueueUniquePeriodicWork("SPECIAL_OFFER",
                ExistingPeriodicWorkPolicy.KEEP, periodicRequest);

        workManager.getWorkInfoByIdLiveData(periodicRequest.getId())
                .observe(getActivity(), workInfo -> {
                    Log.d("WORKER_PERIOD", "observed");
                    // Do something with the status
                    if (workInfo != null && workInfo.getState().isFinished()) {
                        Log.d("WORKER_PERIOD", "observed");
                        String ava = workInfo.getOutputData().getString(SpecialOffer.EXTRA_SPECIAL_CARS);
                        if (ava.equals("available")) {
                            showSpecialOffer(true);
                        } else {
                            showSpecialOffer(true);
                        }
                    }
                });
}


你应该尝试使用ExistingPeriodicWorkPolicy.REPLACE策略。 - Jeel Vankhede
还是不行,你为什么建议使用 REPLACE 策略? - Tobi Oyelekan
我认为replace策略会替换已经存在的worker,而不是像keep一样简单地忽略它。你可以尝试提供退避准则给你的worker,这样如果它运行失败了,就可以在给定的准则后再次尝试。我也遇到过同样的问题,但通过提供的解决方法已经解决了。如果问题仍然存在,请告诉我。我们会为您尝试其他方法。 - Jeel Vankhede
我尝试使用Result.RETRY,以便在失败时重试,但这也不起作用。我认为问题出在PeriodicWorkRequest没有返回任务的FINISHED状态。您可以在GitHub上查看类似的问题:https://github.com/googlecodelabs/android-workmanager/issues/75 - Tobi Oyelekan
考虑到您要执行的工作性质(从网络下载某些内容),我建议使用在 WorkManager 最新 alpha 版本中引入的 ListenableWorker 和 ResolvableFuture。您可以在此视频中大约第 11 分钟看到一些示例。顺便说一下,如果您打算使用 WorkManager,观看完整视频会是一个信息宝库。 - pfmaggi
1个回答

5
根据周期性工作请求文档,周期性工作请求的正常生命周期为ENQUEUED -> RUNNING -> ENQUEUED。按照定义,由于它必须重复出现,因此周期性工作无法以成功或失败状态终止。它只有在明确取消时才能终止。
因此,在.observe中执行workInfo.getState().isFinished()始终返回false,因为.isFinished()方法文档表示:
对于SUCCEEDED、FAILED和CANCELLED状态返回true。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接