web-dev-qa-db-ja.com

ジョブスケジューラが設定された間隔内で実行されていません

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);

この問題は、もともと毎日タスクを実行しようとしたときに発生しましたが、その日のうちにサービスが複数回トリガーされ、時間のガイドラインに従っていませんでした。

どう考えているか教えてください。

11
Papajohn000

私はこの問題を抱えていて、いくつかのブログと公式ドキュメントを確認した後、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);
    }
19
jmarkstar

setPeriodic(int)の代わりにsetMinimumLatency(int)setOverrideDeadline(int)とともに使用します。これらの2つの方法は、JobSchedulerの間隔を調整します。

3

jobFinished(jobParams,needResheduleBoolean);を呼び出す必要があります。この呼び出しの後、ジョブのみが再度実行されます。これは、ジョブが実行を終了したことを認識して、もう一度開始できるようにする方法です。

2
Vaishakh

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>
_
2
Chirag Sheta

setPeriodicのAndroidドキュメント から、

setPeriodic(long intervalMillis):指定した間隔でこのジョブを繰り返すように指定します。期間ごとに1回だけです。この間隔内でこのジョブが実行されるタイミングを制御することはできません。この間隔内で最大1回実行されることが保証されるだけです。

したがって、この時間中にジョブを実行する必要はないことは明確に述べられています。定期的に特定の時間にジョブを実行する場合は、setRepeating()メソッドでAlarmManagerAPIを使用することをお勧めします。要件については、以下のリンクをクリックしてください。

https://developer.Android.com/training/scheduling/alarms.html#set

2
Abhishek Luthra

次のジョブを待つには最低30秒必要です

0
Pradeep Kumar