英文:
Periodic Worker in 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(应用程序)
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 '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 后正常工作。
英文:
androidx.work.Worker works only when the application is running. If the application terminates, the PeriodicWorkRequest stops performing periodic startup.
It is necessary to show notifications at a certain time interval for this I use PeriodicWorkRequest, when the application is running (even minimized) it works as it should, when the process dies there are no more notifications.
worker class
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: ");
}
}
dependencies 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'
}
manifest permission (service, receiver no)
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
There are no errors in the Log, this is what it writes when the application is closed:
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
Previously, similar tasks worked after upgrading to androidx problems started
答案1
得分: 1
这是我在官方文档上找到的信息 -
WorkManager是一个API,它使得调度可延迟、异步的任务变得容易,即使应用退出或 设备重新启动,这些任务也有望运行。
我认为您的PeriodicWorkRequest之所以无法正常工作,是因为您使用了不正确的时间间隔。
注意:可以定义的最小重复间隔为15分钟(更多信息)
PeriodicWorkRequest notificationsWorker = new PeriodicWorkRequest
.Builder(Worker.class, interval, TimeUnit.HOURS)
.addTag(NOTIFICATION_TAG)
.build();
将在每1小时内重复执行工作。
类似地,定期工作可以在每小时周期的最后15分钟运行。
PeriodicWorkRequest periodicWorkRequest =
new PeriodicWorkRequest.Builder(Worker.class,
1, TimeUnit.HOURS,
15, TimeUnit.MINUTES)
.build();
祝编程愉快!
英文:
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 !
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论