Job Scheduler未在设定的时间间隔内运行

时间:2015-04-07 12:48:22

标签: android android-task android-jobscheduler

我正在尝试使用android Job Scheduler API,而我正在尝试做的就是让Job Scheduler每5秒运行一次。但是当我运行它时,相应的服务每两分钟就会命中一次。我有一个日志记录每次服务时都会记录。我不确定为什么会这样。 Job Scheduler是否具有最小间隔时间。我的代码很简单......

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

问题最初是在我尝试运行每日任务时产生的,但它会在当天多次触发服务,并且不遵循时间准则。

让我知道你的想法。

6 个答案:

答案 0 :(得分:17)

我遇到了这个问题,在查看了一些博客和官方文档后,我意识到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);
    }

答案 1 :(得分:2)

你应该调用jobFinished(jobParams,needResheduleBoolean);,在此调用之后只有作业会再次执行,这就是作业知道它已经完成执行的方式,所以可以再次启动。

答案 2 :(得分:2)

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 );会在3000毫秒的时间表中设置JobInfo并在每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>

答案 3 :(得分:2)

而不是setPeriodic(int)使用setMinimumLatency(int)setOverrideDeadline(int)。这两种方法将调整JobScheduler的间隔。

答案 4 :(得分:2)

来自android documentation of setPeriodic

  

setPeriodic(long intervalMillis):   指定此作业应以提供的间隔重复,每个周期不超过一次。您无法控制何时在此时间间隔内执行此作业,只能保证在此时间间隔内最多执行一次。

因此清楚地提到,在此期间没有必要运行作业。如果您想在某个特定的特定时间运行作业,那么您最好使用 AlarmManager Api和setRepeating()方法。请按照以下链接了解您的要求。

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

答案 5 :(得分:0)

您至少需要30秒才能等待下一份工作

相关问题