3

I am implementing Firebase Jobdispatcher with trigger time specified between 10 to 20 seconds. This is my code to schedule a job:

public static void scheduleCompatibleJob(Context context) {
    FirebaseJobDispatcher dispatcher = new FirebaseJobDispatcher(new GooglePlayDriver(context));
    Job myJob = dispatcher.newJobBuilder()
            .setService(DataTrackerJobService.class) // the JobService that will be called
            .setTag("api_trigger")
            .setRecurring(true)
            .setLifetime(Lifetime.FOREVER)
            .setTrigger(Trigger.executionWindow(10, 20)) // 10 to 20 seconds
            .setReplaceCurrent(true)
            .setRetryStrategy(RetryStrategy.DEFAULT_LINEAR)
            .setConstraints(Constraint.ON_ANY_NETWORK)
            .build();

    dispatcher.mustSchedule(myJob);
}

And the service class:

public class DataTrackerJobService extends JobService {
@Override
public boolean onStartJob(final JobParameters job) {
    Log.e("start job", "started " + job);
    (new Handler()).postDelayed(new Runnable() {
        @Override
        public void run() {
            Log.e("handler", "run");
            jobFinished(job, true);
        }
    }, 2000);
    return true;
}

@Override
public boolean onStopJob(JobParameters job) {
    Log.e("stop job", "stopped " + job);
    return false;
}

}

Job dispatcher is running, but the time in logcat is not correct. With every rescheduling of job, the time gap keeps on increasing, and was never in between 10 to 20 seconds.

06-07 11:19:16.429 26174-26174/com.example.jobdispatcher E/start job: started com.firebase.jobdispatcher.JobInvocation@f4250de4 06-07 11:19:18.432 26174-26174/com.example.jobdispatcher E/handler: run 06-07 11:20:16.436 26174-26174/com.example.jobdispatcher E/start job: started com.firebase.jobdispatcher.JobInvocation@f16ceb31 06-07 11:20:18.438 26174-26174/com.example.jobdispatcher E/handler: run 06-07 11:21:58.519 26174-26174/com.example.jobdispatcher E/start job: started com.firebase.jobdispatcher.JobInvocation@f4c635cd 06-07 11:22:00.520 26174-26174/com.example.jobdispatcher E/handler: run 06-07 11:23:40.602 26174-26174/com.example.jobdispatcher E/start job: started com.firebase.jobdispatcher.JobInvocation@f15f8e29 06-07 11:23:42.605 26174-26174/com.example.jobdispatcher E/handler: run 06-07 11:25:52.642 26174-26174/com.example.jobdispatcher E/start job: started com.firebase.jobdispatcher.JobInvocation@f48c1045 06-07 11:25:54.644 26174-26174/com.example.jobdispatcher E/handler: run 06-07 11:28:52.652 26174-26174/com.example.jobdispatcher E/start job: started com.firebase.jobdispatcher.JobInvocation@f3b49821 06-07 11:28:54.655 26174-26174/com.example.jobdispatcher E/handler: run 06-07 11:32:04.688 26174-26174/com.example.jobdispatcher E/start job: started com.firebase.jobdispatcher.JobInvocation@e7f3c1bd 06-07 11:32:06.690 26174-26174/com.example.jobdispatcher E/handler: run

Please check time in logcat. Guide me where am I going wrong in this, or is it supposed to work this way only? Basically I want to implement it for a time gap of 24 hours, but I wonder if this is the working then at one time job will be invoked after double the time specified in the trigger time.

4

1 回答 1

6

如果您查看 Trigger 类的来源,您会注意到您不确定您的工作是否会在给定时间运行。

/**
 * Creates a new ExecutionWindow based on the provided time interval.
 *
 * @param windowStart The earliest time (in seconds) the job should be
 *                    considered eligible to run. Calculated from when the
 *                    job was scheduled (for new jobs) or last run (for
 *                    recurring jobs).
 * @param windowEnd   The latest time (in seconds) the job should be run in
 *                    an ideal world. Calculated in the same way as
 *                    {@code windowStart}.
 * @throws IllegalArgumentException if the provided parameters are too
 *                                  restrictive.
 */
public static JobTrigger.ExecutionWindowTrigger executionWindow(int windowStart, int windowEnd) {
    if (windowStart < 0) {
        throw new IllegalArgumentException("Window start can't be less than 0");
    } else if (windowEnd < windowStart) {
        throw new IllegalArgumentException("Window end can't be less than window start");
    }

    return new JobTrigger.ExecutionWindowTrigger(windowStart, windowEnd);
}

您还应该注意,下一个重复工作只有在前一个工作结束时才开始。所以当你的工作时间长且成本高时,下一次执行时间可能会出乎意料。对于耗时的工作,您应该扩展 SimpleJobService。

为了创建一个重复的任务,我使用了我的 util 方法来创建一个适当的触发器:

public class JobDispatcherUtils {
    public static JobTrigger periodicTrigger(int frequency, int tolerance) {
        return Trigger.executionWindow(frequency - tolerance, frequency);
    }
}

用法:

class DataTrackerJobService extends SimpleJobService {
    // ...
}

public static void scheduleCompatibleJob(Context context) {
    FirebaseJobDispatcher dispatcher = new FirebaseJobDispatcher(new GooglePlayDriver(context));
    Job myJob = dispatcher.newJobBuilder()
            .setService(DataTrackerJobService.class) // the JobService that will be called
            .setTag("api_trigger")
            .setRecurring(true)
            .setLifetime(Lifetime.FOREVER)
            .setTrigger(JobDispatcherUtils.periodicTrigger(20, 1)) // repeated every 20 seconds with 1 second of tollerance
            .setReplaceCurrent(true)
            .setRetryStrategy(RetryStrategy.DEFAULT_LINEAR)
            .setConstraints(Constraint.ON_ANY_NETWORK)
            .build();

    dispatcher.mustSchedule(myJob);
}
于 2017-06-11T22:27:01.877 回答