12

我正在尝试使用 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);

问题最初是在我尝试运行日常任务时出现的,但它会在当天多次触发服务并且不会遵循时间指南。

让我知道你的想法。

4

6 回答 6

23

我遇到了这个问题,在查看了一些博客和官方文档后,我意识到 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);
    }
于 2017-05-24T22:00:35.583 回答
6

而不是setPeriodic(int)与. 这两种方法会调整你的间隔。setMinimumLatency(int)setOverrideDeadline(int)JobScheduler

于 2017-08-16T12:21:35.753 回答
3

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>
于 2016-10-12T07:48:33.403 回答
2

您应该调用jobFinished(jobParams,needResheduleBoolean);,在此调用之后只有作业会再次执行,这是作业知道它已完成执行以便可以再次开始的方式。

于 2016-06-28T20:29:22.000 回答
1

setPeriodic 的 android 文档中

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

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

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

于 2018-04-14T10:50:30.703 回答
0

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

于 2019-10-21T10:29:27.803 回答