Планировщик заданий не работает в пределах заданного интервала
Я пытаюсь использовать API планировщика заданий android, и все, что я пытаюсь сделать, это запустить планировщик заданий каждые 5 секунд. Однако, когда я запускаю его, соответствующая служба ударяется каждые две минуты. У меня есть журнал, который документирует каждый раз, когда служба ударяется. Я не знаю, почему это происходит. Может ли планировщик заданий иметь минимальное время интервала. Мой код просто...
JobInfo jobInfo = new JobInfo.Builder(1, new ComponentName(this, UpdateDatabaseService.class))
.setPeriodic(5000)
.build();
JobScheduler jobScheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
jobScheduler.schedule(jobInfo);
Проблема возникла, когда я пытался выполнять ежедневную задачу, но она вызывала бы службу несколько раз в течение этого дня и не следовала руководящим принципам времени.
Дайте мне знать, что вы думаете.
Ответы
Ответ 1
У меня была эта проблема, и после просмотра некоторых блогов и официальной документации я понял, что JobScheduler имеет разное поведение на Android N (24 и 25). JobScheduler работает с минимальной периодичностью 15 минут.
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public static void setJobScheduler(Context context){
Log.v(TAG, "Job Scheduler is starting");
JobScheduler jobScheduler = (JobScheduler)context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
ComponentName serviceName = new ComponentName(context, JobService.class);
JobInfo jobInfo;
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
jobInfo = new JobInfo.Builder(JOB_ID, serviceName)
.setPeriodic(900000)
.build();
}else{
jobInfo = new JobInfo.Builder(JOB_ID, serviceName)
.setPeriodic(Constants.TIME_INTERVAL)
.build();
}
jobScheduler.schedule(jobInfo);
}
Ответ 2
Вместо setPeriodic(int)
используйте setMinimumLatency(int)
с setOverrideDeadline(int)
. Эти два метода отрегулируют интервал вашего JobScheduler
.
Ответ 3
Вы должны позвонить jobFinished(jobParams,needResheduleBoolean);
, после этого вызова будет выполняться только задание, это значит, что задание знает, что оно завершено, поэтому можно запустить еще раз.
Ответ 4
JobInfo.Builder builder = new JobInfo.Builder(1,new ComponentName(getPackageName(), JobSchedulerService.class.getName()));
builder.setPeriodic(3000);
Edited
MainActivity.java
public class MainActivity extends Activity {
private JobScheduler mJobScheduler;
private Button mScheduleJobButton;
private Button mCancelAllJobsButton;
@Override
protected void onCreate( Bundle savedInstanceState ) {
super.onCreate( savedInstanceState );
setContentView( R.layout.activity_main );
mJobScheduler = (JobScheduler) getSystemService( Context.JOB_SCHEDULER_SERVICE );
mScheduleJobButton = (Button) findViewById( R.id.schedule_job );
mCancelAllJobsButton = (Button) findViewById( R.id.cancel_all );
mScheduleJobButton.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick(View v) {
JobInfo.Builder builder = new JobInfo.Builder( 1,
new ComponentName( getPackageName(), JobSchedulerService.class.getName() ) );
builder.setPeriodic( 3000 );
if( mJobScheduler.schedule( builder.build() ) <= 0 ) {
//If something goes wrong
}
}
});
mCancelAllJobsButton.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick( View v ) {
mJobScheduler.cancelAll();
}
});
}
}
просто нужно изменить
new JobInfo.Builder(1, new ComponentName(this, UpdateDatabaseService.class))
к
new JobInfo.Builder( 1, new ComponentName( getPackageName(), JobSchedulerService.class.getName() ) )
builder.setPeriodic( 3000 );
установит JobInfo
в расписании 3000 мс и вызывается через каждые 3 секунды.
JobSchedulerService.java
public class JobSchedulerService extends JobService {
private Handler mJobHandler = new Handler( new Handler.Callback() {
@Override
public boolean handleMessage( Message msg ) {
Toast.makeText( getApplicationContext(), "JobService task running", Toast.LENGTH_SHORT ).show();
jobFinished( (JobParameters) msg.obj, false );
return true;
}
} );
@Override
public boolean onStartJob(JobParameters params ) {
mJobHandler.sendMessage( Message.obtain( mJobHandler, 1, params ) );
return true;
}
@Override
public boolean onStopJob( JobParameters params ) {
mJobHandler.removeMessages( 1 );
return false;
}
}
AndroidManifest.xml
<service android:name=".JobSchedulerService"
android:permission="android.permission.BIND_JOB_SERVICE" />
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/schedule_job"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Schedule Job"/>
<Button
android:id="@+id/cancel_all"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Cancel All"/>
</LinearLayout>
Ответ 5
Из документации по android setPeriodic ,
setPeriodic (long intervalMillis): Укажите, что это задание должно повторяться с указанным интервалом, не чаще одного раза за период. Вы не контролируете, когда в течение этого интервала будет выполнено это задание, а только гарантируете, что оно будет выполнено не более одного раза в течение этого интервала.
поэтому ясно сказано, что не обязательно, чтобы задание выполнялось в течение этого времени. Если вы хотите запускать задание в определенное периодическое время, лучше использовать AlarmManager Api с методом setRepeating(). Перейдите по этой ссылке ниже для ваших требований.
https://developer.android.com/training/scheduling/alarms.html#set
Ответ 6
Вам нужно минимум 30 секунд, чтобы ждать следующей работы