Android Job Scheduler APIを使用しようとしていますが、ジョブスケジューラを5秒ごとに実行させるだけです。ただし、実行すると、対応するサービスが2分。サービスがヒットするたびに記録されるログがあります。これが発生している理由がわかりません。ジョブスケジューラに最小間隔を設定できますか?コードは単純です...
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);
この問題は、もともと毎日タスクを実行しようとしたときに発生しましたが、その日のうちにサービスが複数回トリガーされ、時間のガイドラインに従っていませんでした。
どう考えているか教えてください。
私はこの問題を抱えていて、いくつかのブログと公式ドキュメントを確認した後、JobSchedulerがAndroid N(24 and 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);
}
setPeriodic(int)
の代わりにsetMinimumLatency(int)
をsetOverrideDeadline(int)
とともに使用します。これらの2つの方法は、JobScheduler
の間隔を調整します。
jobFinished(jobParams,needResheduleBoolean);
を呼び出す必要があります。この呼び出しの後、ジョブのみが再度実行されます。これは、ジョブが実行を終了したことを認識して、もう一度開始できるようにする方法です。
JobInfo.Builder builder = new JobInfo.Builder(1,new ComponentName(getPackageName(), JobSchedulerService.class.getName()));
builder.setPeriodic(3000);
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>
_
setPeriodic(long intervalMillis):指定した間隔でこのジョブを繰り返すように指定します。期間ごとに1回だけです。この間隔内でこのジョブが実行されるタイミングを制御することはできません。この間隔内で最大1回実行されることが保証されるだけです。
したがって、この時間中にジョブを実行する必要はないことは明確に述べられています。定期的に特定の時間にジョブを実行する場合は、setRepeating()メソッドでAlarmManagerAPIを使用することをお勧めします。要件については、以下のリンクをクリックしてください。
https://developer.Android.com/training/scheduling/alarms.html#set
次のジョブを待つには最低30秒必要です