在一天中的特定时间有一份工作 运行,每天都有 Evernote 的 android-工作
Have a job run at certain time of day, everyday with Evernote's android-job
Evernote 的 android 工作 运行 是每天凌晨 1 点到 2 点之间的工作模式吗?
我认为在我的 Application.onCreate
和 Job.onRunJob
结尾做一些事情可能有意义
// use the current time to see how long it will be until 1AM
long timeUntil1Am = getTimeUntil1Am(currentUnixTimeStamp);
new JobRequest.Builder(DemoSyncJob.TAG)
.setExecutionWindow(timeUntil1Am, timeUntil1Am + 3600_000L)
.setBackoffCriteria(5_000L, JobRequest.BackoffPolicy.EXPONENTIAL)
.setRequiresCharging(true)
.setRequiresDeviceIdle(false)
.setRequiredNetworkType(JobRequest.NetworkType.CONNECTED)
.setRequirementsEnforced(true)
.setPersisted(true)
.setUpdateCurrent(true)
.build()
.schedule();
这将 运行 第一次在 ~1AM 从应用程序创建作业,然后使用 onRunJob
以菊花链方式连接下一个 运行 时间。
我认为这可行,但我担心该作业会被安排多次,因为每次构建 Application
时都会创建一个新作业。如果我知道工作已经安排好了,我可以避免这种情况,但不确定是否可能。
所以我的问题是使用这个菊花链是一个合理的模式,我如何避免 运行每天多次执行该作业?
我使用了类似于@CommonsWare 提到的常见问题解答中的模式的东西
为了让这更容易,我创建了一个包装器 class 来获得每日执行 window
Class 获取相对于当前时间的开始和结束时间
class DailyExecutionWindow {
final long startMs;
final long endMs;
/**
* Holds the start end time in ms for a job.
* Will wrap around to next day if currentHour < targetHour.
* If the current time is exactly now it will be forced to 60 seconds in the future.
*
* @param currentHour - current currentHour
* @param currentMinute - current currentMinute
* @param targetHour - currentHour we want to start
* @param targetMinute - currentMinute we want to start
* @param windowLengthInMinutes - number of minutes for the execution window
*/
DailyExecutionWindow(int currentHour, int currentMinute, long targetHour, long targetMinute, long windowLengthInMinutes) {
long hourOffset;
long minuteOffset;
if (targetHour == currentHour && targetMinute < currentMinute) {
hourOffset = TimeUnit.HOURS.toMillis(23);
} else if (targetHour - currentHour == 1) { // if we are less then an hour ahead, but into the next hour
// move forward to 0 minute of next hour
hourOffset = TimeUnit.MINUTES.toMillis(60 - currentMinute);
currentMinute = 0;
} else if (targetHour >= currentHour) {
hourOffset = TimeUnit.HOURS.toMillis(targetHour - currentHour);
} else {
hourOffset = TimeUnit.HOURS.toMillis((24 + targetHour) - currentHour);
}
if (targetMinute >= currentMinute) {
minuteOffset = TimeUnit.MINUTES.toMillis(targetMinute - currentMinute);
} else {
minuteOffset = TimeUnit.MINUTES.toMillis((60 + targetMinute) - currentMinute);
}
this.startMs = Math.max(hourOffset + minuteOffset, 60000);
this.endMs = this.startMs + TimeUnit.MINUTES.toMillis(windowLengthInMinutes);
}
}
我的链接Job
实现
public class UpdateFeedsJob extends Job {
public static final String TAG = UpdateFeedsJob.class.getName();
private static final long TARGET_HOUR = 2L;
private static final long TARGET_MINUTE = 15;
private static final long WINDOW_LENGTH = 60;
private static final int WAKE_LOCK_AWAIT_TIME_SECONDS = 60;
// called in <MyApplication extends Application>.onCreate()
public static void schedule() {
schedule(true);
}
private static void schedule(boolean updateCurrent) {
Calendar calendar = Calendar.getInstance();
int hour = calendar.get(Calendar.HOUR_OF_DAY);
int minute = calendar.get(Calendar.MINUTE);
DailyExecutionWindow executionWindow =
new DailyExecutionWindow(hour, minute, TARGET_HOUR, TARGET_MINUTE, WINDOW_LENGTH);
new JobRequest.Builder(UpdateFeedsJob.TAG)
.setExecutionWindow(executionWindow.startMs, executionWindow.endMs)
.setPersisted(true)
.setUpdateCurrent(updateCurrent)
.build()
.schedule();
}
@NonNull
@Override
protected Result onRunJob(Params params) {
try {
// ... do work
return Result.SUCCESS;
} finally {
schedule(false);
}
return Result.FAILURE;
}
}
您可以在我的 Podcast Player 应用程序中看到一个工作示例 on github
接受的答案中的示例看起来不错。请注意,版本 1.2.0 每天会有 helper class 到 运行 个作业。
Evernote 的 android 工作 运行 是每天凌晨 1 点到 2 点之间的工作模式吗?
我认为在我的 Application.onCreate
和 Job.onRunJob
// use the current time to see how long it will be until 1AM
long timeUntil1Am = getTimeUntil1Am(currentUnixTimeStamp);
new JobRequest.Builder(DemoSyncJob.TAG)
.setExecutionWindow(timeUntil1Am, timeUntil1Am + 3600_000L)
.setBackoffCriteria(5_000L, JobRequest.BackoffPolicy.EXPONENTIAL)
.setRequiresCharging(true)
.setRequiresDeviceIdle(false)
.setRequiredNetworkType(JobRequest.NetworkType.CONNECTED)
.setRequirementsEnforced(true)
.setPersisted(true)
.setUpdateCurrent(true)
.build()
.schedule();
这将 运行 第一次在 ~1AM 从应用程序创建作业,然后使用 onRunJob
以菊花链方式连接下一个 运行 时间。
我认为这可行,但我担心该作业会被安排多次,因为每次构建 Application
时都会创建一个新作业。如果我知道工作已经安排好了,我可以避免这种情况,但不确定是否可能。
所以我的问题是使用这个菊花链是一个合理的模式,我如何避免 运行每天多次执行该作业?
我使用了类似于@CommonsWare 提到的常见问题解答中的模式的东西
为了让这更容易,我创建了一个包装器 class 来获得每日执行 window
Class 获取相对于当前时间的开始和结束时间
class DailyExecutionWindow {
final long startMs;
final long endMs;
/**
* Holds the start end time in ms for a job.
* Will wrap around to next day if currentHour < targetHour.
* If the current time is exactly now it will be forced to 60 seconds in the future.
*
* @param currentHour - current currentHour
* @param currentMinute - current currentMinute
* @param targetHour - currentHour we want to start
* @param targetMinute - currentMinute we want to start
* @param windowLengthInMinutes - number of minutes for the execution window
*/
DailyExecutionWindow(int currentHour, int currentMinute, long targetHour, long targetMinute, long windowLengthInMinutes) {
long hourOffset;
long minuteOffset;
if (targetHour == currentHour && targetMinute < currentMinute) {
hourOffset = TimeUnit.HOURS.toMillis(23);
} else if (targetHour - currentHour == 1) { // if we are less then an hour ahead, but into the next hour
// move forward to 0 minute of next hour
hourOffset = TimeUnit.MINUTES.toMillis(60 - currentMinute);
currentMinute = 0;
} else if (targetHour >= currentHour) {
hourOffset = TimeUnit.HOURS.toMillis(targetHour - currentHour);
} else {
hourOffset = TimeUnit.HOURS.toMillis((24 + targetHour) - currentHour);
}
if (targetMinute >= currentMinute) {
minuteOffset = TimeUnit.MINUTES.toMillis(targetMinute - currentMinute);
} else {
minuteOffset = TimeUnit.MINUTES.toMillis((60 + targetMinute) - currentMinute);
}
this.startMs = Math.max(hourOffset + minuteOffset, 60000);
this.endMs = this.startMs + TimeUnit.MINUTES.toMillis(windowLengthInMinutes);
}
}
我的链接Job
实现
public class UpdateFeedsJob extends Job {
public static final String TAG = UpdateFeedsJob.class.getName();
private static final long TARGET_HOUR = 2L;
private static final long TARGET_MINUTE = 15;
private static final long WINDOW_LENGTH = 60;
private static final int WAKE_LOCK_AWAIT_TIME_SECONDS = 60;
// called in <MyApplication extends Application>.onCreate()
public static void schedule() {
schedule(true);
}
private static void schedule(boolean updateCurrent) {
Calendar calendar = Calendar.getInstance();
int hour = calendar.get(Calendar.HOUR_OF_DAY);
int minute = calendar.get(Calendar.MINUTE);
DailyExecutionWindow executionWindow =
new DailyExecutionWindow(hour, minute, TARGET_HOUR, TARGET_MINUTE, WINDOW_LENGTH);
new JobRequest.Builder(UpdateFeedsJob.TAG)
.setExecutionWindow(executionWindow.startMs, executionWindow.endMs)
.setPersisted(true)
.setUpdateCurrent(updateCurrent)
.build()
.schedule();
}
@NonNull
@Override
protected Result onRunJob(Params params) {
try {
// ... do work
return Result.SUCCESS;
} finally {
schedule(false);
}
return Result.FAILURE;
}
}
您可以在我的 Podcast Player 应用程序中看到一个工作示例 on github
接受的答案中的示例看起来不错。请注意,版本 1.2.0 每天会有 helper class 到 运行 个作业。