我的一部分问题是,如何在" Nougat"中以不到15分钟的间隔建立一份工作,被#34;暴雪"在他的回答中:
Job Scheduler not running on Android N
他解释了这个问题并建议使用以下解决方法:
JobInfo jobInfo;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
jobInfo = new JobInfo.Builder(JOB_ID, serviceName)
.setMinimumLatency(REFRESH_INTERVAL)
.setExtras(bundle).build();
} else {
jobInfo = new JobInfo.Builder(JOB_ID, serviceName)
.setPeriodic(REFRESH_INTERVAL)
.setExtras(bundle).build();
}
但是,使用建议的
.setMinimumLatency(REFRESH_INTERVAL)
只需启动一次工作;
但是如何在Android牛轧糖设备(不使用处理程序或报警管理器)上定期获得约30秒的周期?
答案 0 :(得分:8)
如果有人仍在努力克服这种情况,
以下是> = Android N的解决方法(如果您要将定期作业设置为低于15分钟)
检查是否仅使用了setMinimumLatency。此外,如果您正在运行需要很长时间的任务,则下一个作业将安排在,当前JOB结束时间+ PROVIDED_TIME_INTERVAL
.SetPeriodic(long millis)适用于Android N以下的API级别
@Override
public boolean onStartJob(final JobParameters jobParameters) {
Log.d(TAG,"Running service now..");
//Small or Long Running task with callback
//Reschedule the Service before calling job finished
if(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
scheduleRefresh();
//Call Job Finished
jobFinished(jobParameters, false );
return true;
}
@Override
public boolean onStopJob(JobParameters jobParameters) {
return false;
}
private void scheduleRefresh() {
JobScheduler mJobScheduler = (JobScheduler)getApplicationContext()
.getSystemService(JOB_SCHEDULER_SERVICE);
JobInfo.Builder mJobBuilder =
new JobInfo.Builder(YOUR_JOB_ID,
new ComponentName(getPackageName(),
GetSessionService.class.getName()));
/* For Android N and Upper Versions */
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
mJobBuilder
.setMinimumLatency(60*1000) //YOUR_TIME_INTERVAL
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY);
}
<强>更新强> 如果您在打盹模式中考虑重复工作并考虑JobScheduler, FYI:JobSchedulers不允许在打盹模式下运行。
我没有讨论过Dozing,因为我们谈论的是JobScheduler。谢谢, @Elletlar ,指出有些人可能认为即使应用处于打盹模式也会运行,但实际情况并非如此。
对于打盹模式,AlarmManager仍然提供最佳解决方案。如果要在确切时间段运行定期作业或使用,可以使用 setExactAndAllowWhileIdle() > setAndAllowWhileIdle()如果你很灵活的话。
您还可以使用 setAlarmClock(),因为设备始终从闹钟的打盹模式中退出并再次返回打盹模式。另一种方法是使用FCM。
参考:打盹限制
https://developer.android.com/training/monitoring-device-state/doze-standby
答案 1 :(得分:0)
jobFinished(JobParameters, boolean)
之后再次使用相同的ID设置Job。我认为它应该每次都在主线程上工作。
我设置Job的功能如下:
JobInfo generateRefreshTokenJobInfo(long periodTime){
JobInfo.Builder jobBuilder = new JobInfo.Builder(1L, new ComponentName(mContext, JobService.class));
jobBuilder.setMinimumLatency(periodTime);
jobBuilder.setOverrideDeadline((long)(periodTime * 1.05));
jobBuilder.setRequiresDeviceIdle(false);
return jobBuilder.build();
}
当我第一次打电话给我完成工作后,我打电话给主线程
jobFinished(mJobParameters, true);
registerRefreshJob(5*60*1000L);
这将在同一个id上相同的时间内重新安排我的工作。当设备处于空闲状态时,您仍然需要考虑在打瞌睡时缺少唤醒锁定,因此您的工作可能无法按照您的意愿频繁启动。它在https://developer.android.com/about/versions/nougat/android-7.0-changes.html
中提到如果设备在进入Doze后静止一段时间,系统会将其余的Doze限制应用于PowerManager.WakeLock,AlarmManager警报,GPS和Wi-Fi扫描。无论是否应用了部分或全部Doze限制,系统都会唤醒设备以进行简短的维护窗口,在此期间允许应用程序访问网络并执行任何延迟作业/同步。