用于在后台运行日常任务的Android WorkManager api

lav*_*elu 13 android android-jobscheduler android-jetpack android-workmanager

即使应用已关闭,我也需要在后台每天调用一个API.我见过有关WorkManager API的信息.对于我的场景,我尝试了PeriodicWorkRequest,但遗憾的是,它不能达到我预期的结果.我做的是我在Application类中使用了这段代码

 PeriodicWorkRequest.Builder myWorkBuilder =
                new PeriodicWorkRequest.Builder(MyWorker.class, 24,
                        TimeUnit.HOURS);

        PeriodicWorkRequest myWork = myWorkBuilder.build();
        WorkManager.getInstance().enqueue(myWork);
Run Code Online (Sandbox Code Playgroud)

但是,当应用程序第一次打开时,它会重复运行11次,而且在24小时后它没有运行.请任何人帮助我解决.

whl*_*hlk 23

如果您想确保PeriodicWorkRequest多次未创建,则可以使用该WorkManager.enqueueUniquePeriodicWork方法来安排您的工作人员:

此方法允许您将唯一命名的PeriodicWorkRequest排入队列,其中一次只能激活特定名称的一个PeriodicWorkRequest.例如,您可能只希望一个同步操作处于活动状态.如果有一个待处理,您可以选择让它运行或用新工作替换它.


例如:

PeriodicWorkRequest.Builder myWorkBuilder =
            new PeriodicWorkRequest.Builder(MyWorker.class, 24, TimeUnit.HOURS);

PeriodicWorkRequest myWork = myWorkBuilder.build();
WorkManager.getInstance()
    .enqueueUniquePeriodicWork("jobTag", ExistingPeriodicWorkPolicy.KEEP, myWork);
Run Code Online (Sandbox Code Playgroud)

  • @Aram你试过[beginUniqueWork(...)](https://developer.android.com/reference/androidx/work/WorkManager#beginuniquework_2)? (4认同)

Sri*_*ddy 11

我认为有三个问题.

1)每次enqueue myWork进入WorkManager实例时,您都要创建一个新的定期工作.

尝试一下,第一次运行doWork()方法中的逻辑,MyWorker.class第二次运行两次.您最有可能向Work Manager添加了11个作品,这就是它最后一次检查时运行11次的原因.如果您创建新作品并将其添加到工作管理器,则myWork运行次数会增加.

与Job Scheduler类似,您必须先检查Work是否存在,然后再将其添加到Work Manager.

示例代码:

final WorkManager workManager = WorkManager.getInstance();
final LiveData<List<WorkStatus>> statusesByTag = workManager
        .getStatusesByTag(TAG_PERIODIC_WORK_REQUEST);

    statusesByTag.observe(this, workStatuses -> {
    if (workStatuses == null || workStatuses.size() == 0) {
        Log.d(TAG, "Queuing the Periodic Work");
        // Create a periodic request
        final PeriodicWorkRequest periodicWorkRequest =
                new PeriodicWorkRequest.Builder(SyncWorker.class, 30, TimeUnit.MINUTES)
                        .addTag(TAG_PERIODIC_WORK_REQUEST)
                        .build();

        // Queue the work
        workManager.enqueue(periodicWorkRequest);
    } else {
        Log.d(TAG, "Work Status Size: " + workStatuses.size());
        for (int i = 0; i < workStatuses.size(); i++) {
            Log.d(TAG, "Work Status Id: " + workStatuses.get(i).getId());
            Log.d(TAG, "Work Status State: " + workStatuses.get(i).getState());
        }
        Log.d(TAG, "Periodic Work already exists");
    }
});
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,我使用唯一标记TAG_PERIODIC_WORK_REQUEST来标识我的定期工作,并在创建它之前检查它是否存在.

2)应用程序被杀时,您的工作可能无法运行.

什么是品牌,你正在测试?是小米吗?您是否已经在其他多个品牌上进行过测试并得到了相同的结果?

它处于打盹模式吗?当你设置24小时时,你如何验证工作没有运行?

Work Manager提供向后兼容性,但您仍需要处理特定于设备的逻辑.在小米设备上,类似于Job Scheduler(或Firebase作业调度程序或警报),定期工作在应用程序被终止时停止.

3)我只是认为所PeriodicWorkRequest提供的WorkManager是有缺陷的.

自上周开始以来,我一直在多台设备上测试它.当应用程序第一次启动时,我创建了一个工作,并且没有打开它三天.它第一次运行一次,第二次同步被触发时两次运行,两次之间,它增加到13次,下降到1次,4次等.

在另一个测试中,我在第一次安装期间使用以下代码创建了一个工作,并从第二次安装中删除了代码.在此测试期间,即使工作成功完成,每次都会运行工作,应用程序在被杀死后打开.

final PeriodicWorkRequest periodicWorkRequest =
            new PeriodicWorkRequest.Builder(SyncWorker.class, 30, TimeUnit.MINUTES)
                    .addTag("periodic-work-request")
                    .build();

// Queue the work
WorkManager.getInstance().enqueue(periodicWorkRequest);
Run Code Online (Sandbox Code Playgroud)

我明白,因为它仍处于alpha状态.我不认为你应该在生产中使用它.