2016-09-22 79 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(); 

在構建器中定義自定義退避標準。然後它會定期運行

相關問題