首页 > 解决方案 > androidx中的定期工作者

问题描述

androidx.work.Worker 仅在应用程序运行时工作。如果应用程序终止,PeriodicWorkRequest 将停止执行定期启动。

有必要在某个时间间隔显示通知,我使用 PeriodicWorkRequest,当应用程序正在运行(甚至最小化)时,它可以正常工作,当进程终止时没有更多通知。

工人阶级

import androidx.work.ExistingPeriodicWorkPolicy;
import androidx.work.Operation;
import androidx.work.PeriodicWorkRequest;
import androidx.work.WorkManager;
import androidx.work.WorkerParameters;
import java.util.concurrent.TimeUnit;

public class Worker extends androidx.work.Worker {

    public static final String NOTIFICATION_TAG = "Notification";

    public Worker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
       super(context, workerParams);
       Log.d(TAG, "NotificationWorkerInit");
    }

   @NonNull
   @Override
   public Result doWork() {
      Log.d(TAG, "doWork: START");
      Notification.showNotification(getApplicationContext());
      return Result.success();
   }


   public static void doNotifications(Context context, int quantityPerDay) {
      if (quantityPerDay > 0) {
          startNotifications(context, quantityPerDay);
      } else {
          stopNotifications(context);
      }
   }

   private static void startNotifications(Context context, int interval) {
       int minInterval = 1;
       PeriodicWorkRequest notificationsWorker = new PeriodicWorkRequest
              .Builder(Worker.class, interval, TimeUnit.SECONDS, minInterval, TimeUnit.SECONDS)
              .addTag(NOTIFICATION_TAG)
              .build();
       Log.d(TAG, "startNotificationsService: tag " + notificationsWorker.getTags());
       Log.d(TAG, "startNotificationsService: id  " + notificationsWorker.getId());

       WorkManager workManager = WorkManager.getInstance(context);
       Operation enqueue = workManager.enqueueUniquePeriodicWork(NOTIFICATION_TAG, 
            ExistingPeriodicWorkPolicy.REPLACE, notificationsWorker);
   }

   private static void stopNotifications(Context context) {
      WorkManager.getInstance(context).cancelAllWorkByTag(NOTIFICATION_TAG);
      Log.d(TAG, "stopNotifications: ");
   }
}

依赖 build.gradle (app)

dependencies {
  implementation fileTree(dir: 'libs', include: ['*.jar'])
  implementation 'androidx.appcompat:appcompat:1.2.0'
  implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
  implementation 'androidx.recyclerview:recyclerview:1.1.0'
  // implementation 'org.jetbrains:annotations-java5:15.0'
  implementation 'androidx.work:work-runtime:2.4.0'
  implementation 'com.github.judemanutd:autostarter:1.0.8'
  testImplementation 'junit:junit:4.13'
  androidTestImplementation 'androidx.test.ext:junit:1.1.1'
  androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}

清单许可(服务,接收者编号)

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>

日志中没有错误,这是关闭应用程序时写入的内容:

2020-08-09 18:28:31.772 1940-2694/system_process I/ActivityManager: Killing 5972:ego.emy.test/u0a85 (adj 900): remove task
2020-08-09 18:28:31.846 1940-2031/system_process W/InputDispatcher: channel 'e5ad803 ego.emy.test/ego.emy.test.MainActivity (server)' ~ Consumer closed input channel or an error occurred.  events=0x9
2020-08-09 18:28:31.846 1940-2031/system_process E/InputDispatcher: channel 'e5ad803 ego.emy.test/ego.emy.test.MainActivity (server)' ~ Channel is unrecoverably broken and will be disposed!
2020-08-09 18:28:31.851 1940-4150/system_process I/WindowManager: WIN DEATH: Window{e5ad803 u0 ego.emy.test/ego.emy.test.MainActivity}
2020-08-09 18:28:31.851 1940-4150/system_process W/InputDispatcher: Attempted to unregister already unregistered input channel 'e5ad803 ego.emy.test/ego.emy.test.MainActivity (server)'
2020-08-09 18:28:31.856 1795-2041/? W/SurfaceFlinger: Attempting to destroy on removed layer: AppWindowToken{4ba78aa token=Token{5a74f95 ActivityRecord{634d34c u0 ego.emy.test/.MainActivity t9}}}#0
2020-08-09 18:28:32.285 1940-2261/system_process I/ActivityManager: Force stopping ego.emy.test appid=10085 user=0: from pid 6295

以前,类似的任务在升级到 androidx 问题开始后工作

标签: javaandroidbackgroundworkerandroidx

解决方案


Well this what I found on official documentation -

WorkManager is an API that makes it easy to schedule deferrable, asynchronous tasks that are expected to run even if the app exits or the device restarts.

I believe your PeriodicWorkRequest is not working for you because you are creating PeriodicWorkRequest with incorrect time interval.

Note: The minimum repeat interval that can be defined is 15 minutes (more info)

PeriodicWorkRequest notificationsWorker = new PeriodicWorkRequest
              .Builder(Worker.class, interval, TimeUnit.HOURS)
              .addTag(NOTIFICATION_TAG)
              .build(); 

Will repeat work in every 1 hours.

Similary periodic work that can run during the last 15 minutes of every one hour period.

PeriodicWorkRequest periodicWorkRequest =
       new PeriodicWorkRequest.Builder(Worker.class,
               1, TimeUnit.HOURS,
               15, TimeUnit.MINUTES)
           .build();

Happy Coding !


推荐阅读