java - 如何安排任务以便它在android中的任何条件下执行
问题描述
我正在开发一个需要在某些时候运行一些任务的 Android 项目。用户选择要执行的任务以及需要执行的时间。我曾尝试使用 BroadcastReceiver
并AlarmManager
在当时执行任务。但问题是 -当应用程序关闭时任务停止执行。下面是我的代码BroadcastReceiver
和AlarmManager
类。
public class AlarmReceiver extends BroadcastReceiver {
private static final String TAG = "AlarmReceiver";
@Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "onReceive: Alarm received");
// perform the task here using the values received by Intent
}
}
AlarmReceiver
我称之为AlarmManager
:
Intent alarmIntent = new Intent(this, AlarmReceiver.class);
alarmIntent.putExtra("foo", foo);
alarmIntent.putExtra("bar", bar);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, alarmIntent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, date.getTime(), pendingIntent);
date.getTime()
执行任务的时间在哪里。
一切正常。但我想要一个解决方案,即使应用程序被强制关闭,它也能正常工作。 我还希望解决方案能够执行一个接一个甚至第二天安排的多个此类任务。如果可能的话
注意:我想用一个Service
类来完成这个,但不知道如何编写这个Service
类。
解决方案
我认为强制关闭不会让任务继续工作。但是,您可以在系统事件上注册一个 BroadcastReceiver 以让应用程序恢复运行(例如 android.intent.action.BOOT_COMPLETED 和 QUICKBOOT_POWERON)
对于任务,您应该真正查看 WorkManager 库。
请参阅:https ://developer.android.com/reference/androidx/work/package-summary和https://developer.android.com/topic/libraries/architecture/workmanager 它为你做了很多工作来听系统事件。它为重复性和单一任务提供了 PeriodicWorkRequest 和 OneTimeWorkRequest。
最新库:androidx.work:work-runtime:2.2.0
import androidx.work.Constraints
import androidx.work.ExistingPeriodicWorkPolicy.REPLACE
import androidx.work.PeriodicWorkRequest
import androidx.work.WorkManager
private fun startTask(interval: Int) {
val flexInterval = when {
interval > 200 -> 30L
interval > 59 -> 15L
else -> 5L
}
val constraints = Constraints.Builder().setRequiresBatteryNotLow(true).build()
val fileFinderWork = PeriodicWorkRequest.Builder(
FileFindWorker::class.java,
interval.toLong(), TimeUnit.MINUTES,
flexInterval, TimeUnit.MINUTES
).setConstraints(constraints).addTag(WORK_TAG).build()
Logger.e("Enqueueing file finder worker ($interval min.)")
val manager: WorkManager = WorkManager.getInstance(ctx)
manager.enqueueUniquePeriodicWork(WORK_NAME, REPLACE, fileFinderWork)
}
或者在 Java 中
import androidx.work.Constraints;
import androidx.work.ExistingPeriodicWorkPolicy;
import androidx.work.OneTimeWorkRequest;
import androidx.work.PeriodicWorkRequest;
import androidx.work.WorkManager;
private UUID startTask() {
int interval = 99 /* Just a value from configuration */;
TimeUnit unit;
int flexInterval;
if (interval % 60 == 0) {
interval = interval / 60;
unit = TimeUnit.HOURS;
} else {
unit = TimeUnit.MINUTES;
}
if (interval >= 240) {
flexInterval = 30;
} else if (interval >= 60) {
flexInterval = 15;
} else {
flexInterval = 5;
}
final Constraints constraints = new Constraints.Builder()
.setRequiresBatteryNotLow(true)
.build();
final PeriodicWorkRequest fileFinderWork = new PeriodicWorkRequest.Builder(
FileFindWorker.class, interval, unit, flexInterval, TimeUnit.MINUTES)
.setConstraints(constraints)
.addTag(WORK_TAG)
.build();
lastPeriodicUuid = fileFinderWork.getId();
WorkManager manager = WorkManager.getInstance(ctx)
manager.enqueueUniquePeriodicWork(WORK_NAME, ExistingPeriodicWorkPolicy.REPLACE, fileFinderWork);
return fileFinderWork.getId();
}
推荐阅读
- asynchronous - 事件循环何时在 Dart 中启动以及事件队列如何工作
- java - java在使用mockMvc测试spring boot应用程序时无法解析符号'param'
- .net - 在 F# 中分别设置 DateTime 的日期/时间
- node.js - 如何在 Electron 的 MacOS 菜单栏右侧添加图标?
- r - 如何在 R 中使用聚集而不是联合
- firebase - 如何使用云功能保护 Firebase 消息传递主题?
- matlab - 如何在热图中设置 x 轴值
- sql - 皱眉(错误)错误消息:“值不在预期范围内。” - 在 ListObjects.Add().QueryTable
- java - FragmentManager 无法在 androidx 中解析
- mysql - 最佳架构同时元素到用户和组