2016-09-22 83 views
7

我的问题的一部分,我如何在“牛轧糖”中以小于15分钟的时间间隔设置作业,在他的回答中回答了“暴风雪”:
Job Scheduler not running on Android N
他解释这个问题,并建议使用以下解决方法:安卓N中的作业调度程序,时间间隔小于15分钟

JobInfo jobInfo; 
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { 
    jobInfo = new JobInfo.Builder(JOB_ID, serviceName) 
     .setMinimumLatency(REFRESH_INTERVAL) 
     .setExtras(bundle).build(); 
} else { 
    jobInfo = new JobInfo.Builder(JOB_ID, serviceName) 
     .setPeriodic(REFRESH_INTERVAL) 
     .setExtras(bundle).build(); 
}  

然而,使用建议

.setMinimumLatency(REFRESH_INTERVAL)  

刚开始工作一次;
但我怎样才能得到它与周期约30秒的Android nougat设备(不使用处理程序或报警管理器)?

+2

除了当您的应用程序处于前台并被用户主动使用时,每30秒执行一次操作在用户的眼中是不恰当的,因为用户大声抱怨后台应用程序会耗费电量。 – CommonsWare

+0

但是,如果您的用户在开始使用手机时希望获得最新信息(可能他们现在没有互联网......),则需要可靠的后台服务。还是你想告诉我,这显然是不可能的?那么你可以这样做,而不是试图教我关于我所知道的事情。 – tomseitz

+1

“如果您的用户希望在启动手机时获得最新信息” - 不需要每30秒进行一次工作。 “或者你想告诉我,这显然是不可能的?” - 没有什么能够可靠地做到这一点,除非你的应用程序在前台并且正在被使用。 – CommonsWare

回答

0

当我想要设置作业来刷新一小部分数据时,我在同样的事情上挣扎。我发现解决这个问题的方法可能是在我打电话给jobFinished(JobParameters, boolean)之后再次使用相同的ID设置Job。我认为它应该每次都在主线程中工作。

我的设置工作的功能如下:

JobInfo generateRefreshTokenJobInfo(long periodTime){ 
    JobInfo.Builder jobBuilder = new JobInfo.Builder(1L, new ComponentName(mContext, JobService.class)); 
    jobBuilder.setMinimumLatency(periodTime); 
    jobBuilder.setOverrideDeadline((long)(periodTime * 1.05)); 
    jobBuilder.setRequiresDeviceIdle(false); 
    return jobBuilder.build(); 
} 

当我工作的第一次通话后完成我的工作,我在主线程中调用

jobFinished(mJobParameters, true); 
registerRefreshJob(5*60*1000L); 

这将重新安排我的工作更多的时间在相同的ID上持续相同的时间。当设备处于空闲状态时,您仍然需要考虑在睡眠中不使用唤醒锁,以免您的工作频繁发生。它在https://developer.android.com/about/versions/nougat/android-7.0-changes.html

如果设备是固定的进入打盹一定时间后提到的,系统应用的打盹限制PowerManager.WakeLock,AlarmManager报警器,全球定位系统,以及Wi-Fi扫描的休息。无论是否应用部分或全部打盹限制,系统都会将设备唤醒以进行简短维护时段,在此期间允许应用程序访问网络并可执行任何延期作业/同步。

+3

但是,请注意,jobcheduler会在1分钟内超时。如果你的任务需要一分钟以上,'jobFinished'将不会运行。在超时后调用onStopJob。所以如果我是你,我也会在'onStopJob'内重新注册。 – Thupten

+0

1分钟的限制是在Android 5.1.1上 – Thupten

0

如果有人仍试图克服这种情况,

这里是一个> = Android的N A的解决方法(如果你想设置的定期工作超过15分钟以下)确保只有setMinimumLatency使用。此外,如果您正在运行需要较长时间的任务,接下来的工作将在,目前的工作完成时间+ PROVIDED_TIME_INTERVAL

.SetPeriodic(long millis)来安排非常适用于Android的下方ñ

@Override 
public boolean onStartJob(final JobParameters jobParameters) { 
    Log.d(TAG,"Running service now.."); 
    //Small or Long Running task with callback 

    //Reschedule the Service before calling job finished 
    if(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) 
       scheduleRefresh(); 

    //Call Job Finished 
    jobFinished(jobParameters, false); 

    return true; 
} 

@Override 
public boolean onStopJob(JobParameters jobParameters) { 
    return false; 
} 

private void scheduleRefresh() { 
    JobScheduler mJobScheduler = (JobScheduler)getApplicationContext() 
        .getSystemService(JOB_SCHEDULER_SERVICE); 
    JobInfo.Builder mJobBuilder = 
    new JobInfo.Builder(YOUR_JOB_ID, 
        new ComponentName(getPackageName(), 
        GetSessionService.class.getName())); 

    /* For Android N and Upper Versions */ 
    if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { 
     mJobBuilder 
       .setMinimumLatency(60*1000) //YOUR_TIME_INTERVAL 
       .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY); 
    } 
API级别
0

如果你想定期运行代码少于15分钟,那么你可以使用一个棘手的方式。设置您的jobFinished()这样的

jobFinished(parameters, true); 

它会重新安排与重试策略的代码。使用

.setBackoffCriteria(); 

在构建器中定义自定义退避标准。然后它会定期运行

相关问题