Android OSåãã«éçºããå ŽåããªãœãŒã¹ãéäžçã«äœ¿çšããæäœãå®æçãå®æçããŸãã¯ãªã³ããã³ãã§å®è¡ããããšãå¿ èŠã«ãªãå ŽåããããŸãããããã®æäœã§ã¯ãããšãã°ã€ã³ã¿ãŒãããã䜿çšããããããã€ã¹ãèµ·åãããŸãŸã«ããããšãéèŠã§ãã ã»ãšãã©ã®å Žåããã®ãããªåé¡ã解決ããã«ã¯ãAlarmManagerãWakefulBroadcastReceiverã䜿çšããããäžè¬ã«WakeLockãæåã§å¶åŸ¡ããŸãã ããã¯ãã¹ãŠAndroidã®éçºè åãã®ããã¥ã¡ã³ãã§ã¯æšå¥šãããŠããããWakefulBroadcastReceiverã¯æ¢ã«APIã¬ãã«26.0.0ã§éæšå¥šãšããŠããŒã¯ãããŠããŸãã
Googleã®æšå¥šäºé ã«åŸããçãšãã«ãŸããŸã泚æãæãAndroid 5.0以éã®ããŒãžã§ã³ã§ãããæè»ãªåäœãããã¢ããªã±ãŒã·ã§ã³ãäœæããã«ã¯ã©ãããã°ããã§ããïŒ ã¢ããªã±ãŒã·ã§ã³ã®æå°APIã¬ãã«21.0.0ãèšå®ããæºåãã§ããŠããå Žåã¯ãJobSchedulerãIntentServiceãšçµã¿åãããŠäœ¿çšââããŠãåŽåéçŽçãªã¿ã¹ã¯ãé çªã«å®è¡ããäŸããå§ãããŸãã
åé¡ãšæèµ·ãããåé¡ã®æ¬è³ª
WakefulBroadcastReceiverã¯ã©ã¹ã®ããã¥ã¡ã³ããéããŠèå³æ·±ãç¶æ³ã確èªããã ãã§ååã§ããã¯ã©ã¹ã¯APIããŒãžã§ã³22.0.0ã§è¿œå ãã ãããŒãžã§ã³26.0.0ã§éæšå¥šãšããŠããŒã¯ãããŸããã Androidéçºè ã¯ãæåã«WakeLockãä¿æããŠã¿ã¹ã¯ãå®è¡ããããã®äŸ¿å©ãªã¯ã©ã¹ãè¿œå ããããšã決ãããšæ³å®ã§ããŸããããã®åŸãã¢ããªã±ãŒã·ã§ã³ããã©ã¢ã°ã©ãŠã³ãã§åäœããããšãä¿èšŒãããã®ã§ã¯ãªããå®éã«ãã¹ãŠã®ã¹ããŒãã¢ããªã±ãŒã·ã§ã³ãWakeLockãä¿æããããšãããšããã€ã¹ã¯ãšãã«ã®ãŒãç¯çŽããŸããïŒ ãããŠã WakefulBroadcastReceiverã®åçã¯ããšããããæ£ããéããããªãã£ãã¬ã·ãŒããŒãWakeLockã®ãªãŒã¯ã«ã€ãªããå¯èœæ§ããããããããããªãŒå¯¿åœã延é·ããããšãã欲æ±ã«éããå§ããŸããã
äžæ¹ãæ®éã®éçºè ã¯ãæ°ããå¶éãã¹ãŠã®äžã§ãããšãã°Dozeã¢ãŒããã¢ã¯ãã£ããªãšãã«å®æçãªã¿ã¹ã¯ãå®è¡ããã®ãå®å šãã©ãããå°ãããããããŸããã å¶éãšæ©äŒã®ãã©ã³ã¹ããšãããã«ã JobSchedulerãäœæãããŸããã ãžã§ãã¹ã±ãžã¥ãŒã©ã¯ãã¿ã¹ã¯ããã€å®äºããããšãã§ããããå®éã«å¿ èŠãªå Žåã«ãããåãå ¥ããæ¹æ³ãæäŸããæ¹æ³ãçãšãããªã·ãŒã«éåãããã©ãã§å€±ããªãããšããåé¡ãåŒãåããŸã-WakeLockã絶察ã«é¢ããªãã§ãã ãã ã
ãã®èšäºã®æºåäžã«ã å¥ã®èè ã«ããèšäºãHabréã«æ²èŒãããŸããããã®èšäºã§ã¯ãããå°ãçè«ãæããã«ãªããå®è·µã«å°ã泚æãæãããŸããã JobSchedulerã®æ¢åã®ä»£æ¿æ¡ããã°ããéå§ããããæ·±ãç解ããã®ã«åœ¹ç«ã¡ãŸãã
JobSchedulerãšIntentServiceã䜿çšããŠãããžã§ã¯ããäœæããäŸ
ç°¡åã«ããããã«ããExerciseããšããåèªããã¡ã€ã«ã«æžã蟌ãã¿ã¹ã¯ããããšããŸãããã ãããŠãŒã¶ãŒã®ã¢ãã€ã«ãã©ãã£ãã¯ãç¡é§ã«ããããšã¯ãªããããã€ã³ã¿ãŒããããå¿ èŠã§ãã åæã«ãæ°ããã¿ã¹ã¯ããšã«ã次ã ã«å®è¡ãããåèªãæžãããã«ããŸãã ã¡ã€ã³ã¹ã¬ããããããã¯ããããšã¯ã§ããïŒããã§ã¯ãã¡ã€ã«ãšãå Žåã«ãã£ãŠã¯ãããã¯ãŒã¯ãªã¯ãšã¹ããåŠçã§ããŸãïŒãã¿ã¹ã¯ã䞊ã¹ãããšãã§ããããã IntentServiceãæ¯æŽããŸãã
ãã®èšäºã§èª¬æãããŠããæé ãå®å šã«åçŸããã«ã¯ãSDK 21ã®æå°ããŒãžã§ã³ã§ãã¢ã¯ãã£ããã£ã®ãªãæ°ãããããžã§ã¯ããäœæããå¿ èŠããããŸãããŸãããã¹ãŠã®ã¢ã¯ã·ã§ã³ã¯ãå°ãªããšã21ã®SDKããŒãžã§ã³ã§æ¢åã®ãããžã§ã¯ãã§å®è¡ã§ããŸãã
ããã¯ã°ã©ãŠã³ãã§ã¿ã¹ã¯ãåŠçããããã®IntentServiceã®è¿œå
æ°ããIntentServiceããããžã§ã¯ãã«è¿œå ãããããExerciseIntentServiceãšåŒã³ãŸããèªåçã«çæãããã¡ãœããã«åºã¥ããŠæšæºçãªã¢ãããŒãã䜿çšããäœåãªãã®ãã¯ãªãŒã³ã¢ããããã¡ãœãããšå®æ°ãæ¡ä»¶ã«åãããŠååãå€æŽããŸãã
ç°¡åãªæäœã®çµæãšããŠã ExerciseIntentServiceã®æ¬¡ã®æ¬äœãååŸããŸãã
private static final String ACTION_WRITE_EXERCISE = "com.github.ihandy.jobschedulerdemo.action.ACTION_WRITE_EXERCISE"; public ExerciseIntentService() { super("ExerciseIntentService"); } public static void startActionWriteExercise(Context context) { Intent intent = new Intent(context, ExerciseIntentService.class); intent.setAction(ACTION_WRITE_EXERCISE); context.startService(intent); } @Override protected void onHandleIntent(Intent intent) { if (intent != null) { final String action = intent.getAction(); if (ACTION_WRITE_EXERCISE.equals(action)) { handleActionWriteExercise(); } } } private void handleActionWriteExercise() { try { FileWriter fileWriter = new FileWriter(getFilesDir().getPath() + "exercise.txt"); fileWriter.write("Exercise"); fileWriter.close(); } catch (IOException e) { e.printStackTrace(); } }
ãããã£ãŠã1ã€ã®ã¿ã€ãã®æ¡ä»¶ä»ãåŽåéçŽã¿ã¹ã¯ãé çªã«çŽæ¥å®è¡ãããµãŒãã¹ã®æºåãã§ããŠããŸãã ã¿ã¹ã¯ãäœæããŠèšç»ããã«ã¯ã BroadcastReceiverã䜿çšã§ãããšã³ããªãã€ã³ããå¿ èŠã§ã ã
BroadcastReceiverãè¿œå ããŠã¿ã¹ã¯ãåæåãã
æšæºã®BroadcastRecieverããŒã«ããããžã§ã¯ãã«è¿œå ãã ExerciseRequestsReceiverãšåŒã³ãŸãã å°æ¥çã«ã¯ãã¿ã¹ã¯ãã¹ã±ãžã¥ãŒã«ããããã«ãã©ãããã§ããããŒããã£ã¹ããã¢ããªã±ãŒã·ã§ã³ã«éä¿¡ã§ããããã«ãªããŸãïŒããšãã°ãããã¯èšäºã®çµããè¿ãã«è¡šç€ºãããã€ã³ã¹ãã«ã¡ã³ã¿ã«ãã¹ãã䜿çšããŠå®è¡ã§ããŸãïŒã
æäœéå¿ èŠãªExerciseRequestsReceiverã³ãŒãã¯æ¬¡ã®ããã«ãªããŸãã
public static final String ACTION_PERFORM_EXERCISE = "ACTION_PERFORM_EXERCISE"; private static int sJobId = 1; @Override public void onReceive(Context context, Intent intent) { switch (intent.getAction()) { case ACTION_PERFORM_EXERCISE: scheduleJob(context); break; default: throw new IllegalArgumentException("Unknown action."); } }
String ACTION_PERFORM_EXERCISE
ã¿ã¹ã¯ã¹ã±ãžã¥ãŒãªã³ã°ããã»ã¹ãéå§ããå¿
èŠæ§ãèå¥ããããã®ã¢ã¯ã·ã§ã³ã
int sJobId
ã¿ã¹ã¯ãã¹ã±ãžã¥ãŒã«ãããšãã«äœ¿çšãããã¿ã¹ã¯èå¥åã®å€æ°ã
scheduleJob(context)
-ã¿ã¹ã¯ã®ã¹ã±ãžã¥ãŒãªã³ã°ã«å¿
èŠãªãã¹ãŠã®ããžãã¯ãå«ãã¡ãœããåŒã³åºãã
ããã§ããããŒããã£ã¹ããåä¿¡ãããšãã«ã Intentã ExerciseIntentServiceã«éä¿¡ã§ãããã¹ãŠãåé¡ãªãã WakeLockã®ã¿ãå¿ èŠã«ãªããŸããWakefulBroadcastReceiverã䜿çšããªãããšã«åæããããã JobSchedulerã®æ°ããã¿ã¹ã¯ãäœæããã³ã¹ã±ãžã¥ãŒã«ããå¿ èŠããããŸããç§ãã¡ã«ãšã£ãŠïŒã»ãŒïŒã
ãšããã§ã JobSchedulerã䜿çšããå Žå ããã®åé¡ã解決ããä»ã®æ¹æ³ãšã¯ç°ãªãã WakeLockã«å¯Ÿããèš±å¯ã¯å¿ èŠãããŸããã
JobSchedulerããã®ã€ãã³ããåŠçããããã®JobServiceçžç¶äººã®å®è£
JobSchedulerã«ã¯ã JobServiceããç¶æ¿ãããå¥åã®ãµãŒãã¹ãå¿ èŠã§ã ã ãããExerciseJobServiceãšåŒã³ãéåžžã®ãµãŒãã¹ãšããŠè¿œå ãã芪ã¯ã©ã¹ã眮ãæããã¢ãžã¥ãŒã«ãããã§ã¹ãã«ã¢ã¯ã»ã¹èš±å¯ãè¿œå ããŸãã
<service android:name=".ExerciseJobService" android:enabled="true" android:exported="true" android:permission="android.permission.BIND_JOB_SERVICE"> </service>
ãã®ãµãŒãã¹ãJobSchedule rãšå¯Ÿè©±ããã«android.permission.BIND_JOB_SERVICE
æš©éandroid.permission.BIND_JOB_SERVICE
å¿
èŠã§ãã
ãŸããå®è£
ã«ã¯2ã€ã®ã¡ãœããonStartJob()
ããã³onStopJob()
ãå¿
é ã§ãã
-
onStartJob()
ã¯ãã¹ã±ãžã¥ãŒã«ãããã¿ã¹ã¯ãå®äºããæéïŒæ¡ä»¶ïŒã«ãªããšåŒã³åºãããŸãã ãã®ã¡ãœããã¯ã¡ã€ã³ã¹ã¬ããã§åŒã³åºãããéçºè ã¯éãæäœãåå¥ã®ã¹ã¬ããã«åå¥ã«éä¿¡ããå¿ èŠããããŸãïŒãã®å Žåãããã¯æ¢ã«æäŸãããŠããŸã-IntentServiceã䜿çšããŸã ïŒãonStartJob()
ããã¿ã¹ã¯ã®å®è¡ãä»ã®ã¹ã¬ããã«å§ä»»ããå Žå ã trueãè¿ãå¿ èŠããããå¿ èŠãªãã¹ãŠã®ã¢ã¯ã·ã§ã³ããã®ã¡ãœããã®æ¬äœã§æ¢ã«å®è¡ãããŠããå Žåã falseãè¿ãå¿ èŠããããŸã ã -
onStopJob()
ã¯ãã¿ã¹ã¯ã«å¿ èŠãªæ¡ä»¶ãæºããããªããªã£ããšãããŸãã¯ã¿ã¹ã¯ã«å²ãåœãŠãããæéã䜿ãæãããããšãã«åŒã³åºãããŸãã ãã®ã¡ãœããã®åŒã³åºãã¯ããã¹ãŠã®ããã¯ã°ã©ãŠã³ãã¿ã¹ã¯ã®å®è¡ãçŽã¡ã«åæ¢ããå¿ èŠãããããšããµãŒãã¹ã«éç¥ããŸãã ããŒã¿ã®æŽåæ§ã確ä¿ããããã«ãå®å šãªã¹ãããã©ã³ããžãã¯ãæäŸããããšãæåã§ãã
onStopJob()
ç¶æ³ãé©åã«åŠçããããã«ãéçãã©ã°ãããã€ãã®è¿œå ã®ãããŒããã£ã¹ããå®è£
ã§ããŸãããŸãããµãŒãã¹éã®å¯Ÿè©±ã®ä»ã®æ段ã䜿çšããããšãã§ããŸãã çŸåšã®èšäºã§ã¯ãããã¯çç¥ããã IntentServiceãã¿ã¹ã¯ãå®äºã§ããªãã£ãå Žåãã¢ããªã±ãŒã·ã§ã³ããžãã¯ãšããŒã¿ã®æŽåæ§ã«ãšã£ãŠã²ã©ããã®ã¯äœãèµ·ãããªããšä»®å®ãããŸãã
onStopJob
ãæ»ãå€ãããã trueã®å ŽåonStopJob
ã¯äžæãããã¿ã¹ã¯ãåã³å®è¡ãã¥ãŒã«å
¥ããŸãonStopJob
ã¿ã¹ã¯ã¯å®äºãããšèŠãªãããåšæçã§ãªãå Žåã¯ãã¥ãŒããåé€ãããŸãã
ç·æ¥äºæ ã®åŠçãçç¥ãããŠããããããã®ã¡ãœããããtrueãè¿ããã¿ã¹ã¯ã®ã¹ã±ãžã¥ãŒã«ãå€æŽããŸã;åæã«ãããã«ããåè©Šè¡åºæºã®äœ¿çšãæ€èšããããšãã§ããŸãã
ãããã£ãŠã2ã€ã®ã¡ã€ã³ã¡ãœããã®æ»ãå€ãèšå®ãã ExerciseIntentServiceã®èµ·åãonStartJob()
ã«è¿œå ããããšã«ããã次ã®ååã«å®¹éã®ãããµãŒãã¹ãååŸããŸãã
public class ExerciseJobService extends JobService { public ExerciseJobService() { } @Override public boolean onStartJob(JobParameters params) { ExerciseIntentService.startActionWriteExercise(getApplicationContext()); return true; } @Override public boolean onStopJob(JobParameters params) { return true; } }
çŸæç¹ã§ã¯ã IntentServiceã®JobSchedulerãä»ããŠã¿ã¹ã¯ãå®è£ ããããã®æå°éã®ã¯ã©ã¹ã»ããããã§ã«æºåãããŠããŸããã€ãŸãã ExerciseIntentService-åå¥ã®ã¹ã¬ããã§ã¿ã¹ã¯ã«å¿ èŠãªæäœãå®è¡ããŸããå€éšãããããŒããã£ã¹ãããã£ãããã次ã«è¡ãããšã§ããJobSchedulerã®ã¿ã¹ã¯ãåæåããå¿ èŠãããè€åäœã®äœæ¥ã
JobSchedulerã®æ°ããã¿ã¹ã¯ãäœæãã
JobSchedulerã®ã¿ã¹ã¯ãäœæããã«ã¯ã JobInfo.Builderãå¿ èŠã§ã ã ãã®ã³ã³ã¹ãã©ã¯ã¿ãŒã¯2ã€ã®ãã©ã¡ãŒã¿ãŒãåãå ¥ããŸãïŒ ExerciseJobServiceã® ã¿ã¹ã¯IDãšComponentNameã§ã ã
ã¿ã¹ã¯IDãšComponentName
èå¥åãããã°ããã¹ãŠãåçŽã§ãïŒãã ãããã¥ã¢ã³ã¹ããªãããã§ã¯ãããŸããïŒ-ä»»æã®æŽæ°å€ïŒ
- æ¢ã«èšç»ãããŠããã¿ã¹ã¯ãæŽæ°ããå ŽåããŸãã¯å®æçãªã¿ã¹ã¯ã®äžææ§ãå¶åŸ¡ããå Žåãæ°žç¶çã
- åã ã®ã¿ã¹ã¯ã®ãã¥ãŒãäœæããå Žåã¯äžæã®å€ã
çªç¶ã¢ããªã±ãŒã·ã§ã³ãã·ã¹ãããã¯ã§ããå ŽåããŸãã¯1ã€ã®sharedUserIdãæã€è€æ°ã®ã¢ããªã±ãŒã·ã§ã³ãããå Žåãè¿œå ã®æ¡ä»¶ãèæ ®ããå¿ èŠããããŸããidã¯1ã€ã®uidãæã€ãã¹ãŠã®ã¢ããªã±ãŒã·ã§ã³éã§äº€å·®ããŠã¯ãªããŸããã ãããã£ãŠãã¢ããªã±ãŒã·ã§ã³ãandroid.uid.systemã䜿çšããå Žåãäžéšã®ã·ã¹ãã ã¿ã¹ã¯ãJobSchedulerã䜿çšããIDã®äžææ§ãç¬ç«ããŠç¶æããå¿ èŠãããããšã«çæããå¿ èŠããããŸãã
ãšããã§ã removeAll()
ãããªJobSchedulerã®ã¡ãœããã䜿çšããå Žåãåãuidãæã€ä»ã®äººã®ã¿ã¹ã¯ãåé€ã§ããŸãã
ãã®ç¶æ³ãå¶åŸ¡ããæ¹æ³ã«é¢ããè±èªã®èšäº ã
ãã®äŸã§ã¯ãUIDã«ã€ããŠå¿é ããå¿ èŠã¯ãªããå¢åå€sJobIdãèå¥åãšããŠäœ¿çšããŸãã
sJobIdã¯æ¬¡ã®ããã«å®çŸ©ãããŸãã
private static int sJobId = 1;
ComponentNameã䜿çšãããšããã¹ãŠãã¯ããã«åçŽã«ãªãã ExerciseJobService.classãæž¡ãããã³ã³ã¹ãã©ã¯ã¿ãŒãžã®ãªããžã§ã¯ãã«ãªããŸãã
ComponentName jobService = new ComponentName(context, ExerciseJobService.class); JobInfo.Builder exerciseJobBuilder = new JobInfo.Builder(sJobId++, jobService);
JobInfo.Builderã䜿çšãããã©ã¡ãŒã¿ãŒã®åæå
以äžã§ã¯ãJobInfo.Builderã¡ãœããã®äž»èŠãªã»ãããæ€èšããŸãã
exerciseJobBuilder.setMinimumLatency(TimeUnit.SECONDS.toMillis(1));
ã¿ã¹ã¯ãå®äºããåã«çµéããæå°æéãã€ãŸãé 延éå§æéã
exerciseJobBuilder.setOverrideDeadline(TimeUnit.SECONDS.toMillis(5));
ã¿ã¹ã¯ããã¥ãŒ/ã¹ã±ãžã¥ãŒã«ç¶æ ã«ããããšãã§ããæ倧æéã 5ç§åŸã«ïŒãã®å ŽåïŒè¯å¥œãªæ¡ä»¶ããŸã å°çããŠããªãå Žåãã¿ã¹ã¯ã¯äœããã£ãŠãå®è¡ããå§ããŸãïŒãããä»ã®JobSchedulerããªã·ãŒãšççŸããªãå ŽåïŒã 䜿çšããªãå Žåãã¿ã¹ã¯ã¯å¿ èŠãªæ¡ä»¶ãæºããããå Žåã«ã®ã¿å®äºããŸãã
exerciseJobBuilder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED);
æ¥ç¶ã®ã¿ã€ããèšå®ãããŸããããšãã°ãã€ã³ã¿ãŒããããå¿ èŠã§ãããç¡æã®WIFiïŒãããã¹ãããã§ã¯ãªãïŒãŸãã¯ã€ãŒãµãããã§ããããã
NETWORK_TYPE_UNMETERED
ãéžæããŸãã
exerciseJobBuilder.setRequiresDeviceIdle(false);
ãŠãŒã¶ãŒãããã€ã¹ãšå¯Ÿè©±ããªããšãã®ç¶æ ã決å®ããŸãããã®å Žåãããã¯éèŠã§ã¯ãããŸããã
exerciseJobBuilder.setRequiresCharging(false);
ãã®äŸã§ã¯ãããã€ã¹ãå é»äžã§ãããã©ããã«ããããããç§ãã¡ã«éãã¯ãªããšä»®å®ããŸãã
ã¿ã¹ã¯ã®ç¹°ãè¿ãåºæºãèšå®ã§ããŸãïŒããã«ã€ããŠã¯ä»¥äžã§è©³ãã説æããŸãïŒã
exerciseJobBuilder.setBackoffCriteria(TimeUnit.SECONDS.toMillis(10), JobInfo.BACKOFF_POLICY_LINEAR);
ããã«ãã¿ã¹ã¯ãå®æçã«ããããšãã§ããŸãïŒ
exerciseJobBuilder.setPeriodic();
å®æçãªã¿ã¹ã¯
ã¿ã¹ã¯ã®åšæãèšå®ãããšãè«ççãªå¶éã«çŽé¢ããŸãã
-
setMinimumLatency()
ããã³setOverrideDeadline()
ã¯æå³ããªããªããã䜿çšã§ããŸãããæå®ãããééå ã§ã¿ã¹ã¯ãäœããã®æ¹æ³ã§1åå®è¡ããå¿ èŠããããäžãŸãã¯äžããã®è¿œå ã®å¶éã¯åãå ¥ããããŸããã äžæ¹ãäœããåŸ ã£ãŠããå®æçãªã¿ã¹ã¯ãéå§ããå¿ èŠãããå ŽåããããŸãããã®ãããªæ¡ä»¶ãè¿œå ããããšã¯ã§ããŸãããåŸ æ©ããå¿ èŠãããå Žåã¯ãå®è¡ããã¿ã¹ã¯ãè¿œå ããåã«åŸ æ©ããå¿ èŠããããŸãã -
onStopJob()
JobServiceã§true
è¿ãããšã¯ã§ããŸãã-äžæãããå®æã¿ã¹ã¯ã¯ã次åã®ã¹ã±ãžã¥ãŒã«æã«ãã¥ãŒããåé€ãããŸããã - ç¹å®ã®ééã®åŸã«ã¿ã¹ã¯ãæ£ç¢ºã«å®äºããããšãä¿èšŒãã人ã¯ããŸããããã®ééã®éã«ã¿ã¹ã¯ãå®äºããã®ã¯1åãŸã§ã§ãã
ãããã¯ãå®æçãªã¿ã¹ã¯ãšéåžžã®ã¿ã¹ã¯ã®äž»ãªéãã§ãã çŸåšã®äŸã§ã¯ãã¿ã¹ã¯ãå®æçã«ããŸããã
ç¹°ãè¿ãåºæº
setBackoffCriteria()
䜿çšãããšãå¿
èŠã«å¿ããŠã¿ã¹ã¯ãå®äºããããã«2åç®ã®è©Šè¡ãè¡ãã«ãŒã«ãèšå®ã§ããŸãïŒããšãã°ã onStopJob()
trueãè¿ããŸããïŒã
JobSchedulerã¯ãç·åœ¢ãšææ°ã®2ã€ã®ããªã·ãŒãæäŸããŸãã
ç·åœ¢ããªã·ãŒã®åŒã¯æ¬¡ã®ãšããã§ãã
retry_time(current_time, num_failures) = current_time + initial_backoff_millis * num_failures, num_failures >= 1
ã€ãŸã çŸåšã®æç¹ããã次ã®è©Šè¡ã¯ãæå®ãããæéã«å€±æã®åæ°ãæããåŸã«è¡ãããŸãã
ææ°ããªã·ãŒåŒïŒ
retry_time(current_time, num_failures) = current_time + initial_backoff_millis * 2 ^ (num_failures - 1), num_failures >= 1
ããã§ã¯ã次ã®è©Šè¡ã®æéãå€§å¹ ã«å€§ãããªããŸãã
ãã¹ãŠãéåžžã«ã·ã³ãã«ã§ééçã§ãããã¿ã¹ã¯ãäœåºŠãæ£åžžã«å®äºã§ããªãå Žåã¯ã©ããªããŸããïŒ æåã®åè©Šè¡æéã1åã®å Žåã10åè©Šè¡ããã®ã«1æéè¿ãããããŸãã ãã®ãããªç¶æ³ãææ¡ããã®ã¯ç°¡åã§ã¯ãããŸããã1æé以å ã«äœãèµ·ãããäºæž¬ã§ããªãããã§ãã JobSchedulerã¯ããã®ãããªç¹°ãè¿ãã5æéã«å¶éããŠããŸãã
ãããã£ãŠã setBackoffCriteria()
ãã©ã¡ãŒã¿ãŒã¯ãã¿ã¹ã¯ã»ããã«åŸã£ãŠããªã·ãŒã®åææéãšã¿ã€ããæ
éã«èæ
®ããŠãéåžžã«æ
éã«åŠçããå¿
èŠããããŸãã ãŸããç¹°ãè¿ãã®åæ°ãªã©ã®è¿œå ã®åŠçãå®è¡ãã JobSchedulerããã¿ã¹ã¯ãåé€ããå¿
èŠãããå ŽåããããŸãã
å®äºã®ããã®ã¿ã¹ã¯ã®éä¿¡
ãããã£ãŠãå¿ èŠãªãã¹ãŠã®ãã©ã¡ãŒã¿ãŒãåããJobBuilderã®æºåãã§ããŸããã å®è¡ãã¥ãŒã«ã¿ã¹ã¯ãè¿œå ããã«ã¯ãã·ã¹ãã ããJobSchedulerã€ã³ã¹ã¿ã³ã¹ãååŸããå¿ èŠããããŸãã
JobScheduler jobScheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
ãããŠãã¡ãœãããåŒã³åºããŠãã«ããŒããJobInfoãè¿œå ããŸã ã
jobScheduler.schedule(exerciseJobBuilder.build());
ä¿¡é Œæ§ã®ããã«ãæåŸã®ã¡ãœããã®æ»ãå€ã確èªã§ããŸããããã«ããããã¥ãŒãžã®ã¿ã¹ã¯ã®è¿œå ãæåããã倱æããããããããŸãã
ããã«ã JobSchedulerãã¿ã¹ã¯ã®æ¡ä»¶ãæé©ã§ããããšãonStartJob()
ãšã ExerciseJobServiceã® onStartJob()
ã¡ãœãããåŒã³åºãããŸããããã¯æ¢ã«äžèšã§è§£æãããŠããŸãã
æ€èšŒãšãããã°
èŠçŽãããšãçµæã¯ã IntentServiceã§æ¡ä»¶ä»ãã§éãæäœãå®è¡ãã1åéãã®ã¿ã¹ã¯ãèšç»ã§ãããã¹ãã¢ããªã±ãŒã·ã§ã³ã§ãã
ããã©ãŒãã³ã¹ããã¹ãããããã«ã次ã®ãããªå°ããªã€ã³ã¹ãã«ã¡ã³ããã¹ããè¿œå ããããšããå§ãããŸãã
@Test public void sendDemoBroadcast() throws Exception { Context appContext = InstrumentationRegistry.getTargetContext(); Intent demoIntentForBroadcast = new Intent(appContext, ExerciseRequestsReceiver.class); demoIntentForBroadcast .setAction(ExerciseRequestsReceiver.ACTION_PERFORM_EXERCISE); appContext.sendBroadcast(demoIntentForBroadcast); }
ãŸããäŸã®åäœã確èªããããã«ãäžéšã®ãã°ããœãŒã¹ã³ãŒãã«è¿œå ãããŸããããäžèšã®æç²ã§ã¯ç€ºãããŠããŸããã
ãã¹ããå®è¡ãããšããidïŒ1ãã®ã¿ã¹ã¯ãéå§ããã³çµäºãéå§ããã³çµäºããããšãããããŸã...ããæ£ç¢ºã«ã¯ã JobSchedulerã匷å¶çã«å®äºãããŸãã
åå¥ã®ã¹ã¬ããã§ã®ã¿ã¹ã¯å®è¡ãšãµãŒãã¹å®äºã®éç¥
ãã®äŸã§ã¯ã onStartJob()
ã¡ãœããããtrueãè¿ããŸãããããã¯ãã¿ã¹ã¯ã®å®è¡ããµã€ãã¹ããªãŒã ã®ã©ããã§ç¶ç¶ããããšãJobSchedulerã«äŒããããšãæå³ããŸãã ã¿ã¹ã¯ã®å®äºãéç¥ããªãããã JobSchedulerã¯åŒ·å¶çã«ã¿ã¹ã¯ãå®äºããŸãããŸãã onStopJob()
ããtrueãè¿ããã ãåè©Šè¡ããªã·ãŒãããªã¬ãŒãããã¿ã¹ã¯ãåã¹ã±ãžã¥ãŒã«ãããŠåèµ·åãããŸãã
ãããé²ãã«ã¯ã ExerciseJobServiceãµãŒãã¹ã¯ã©ã¹ã®jobFinished()
ã¡ãœãããåŒã³åºãå¿
èŠããããŸãã次ã®èšäºã§ããã®äœ¿çšãšIntentServiceããã¿ã¹ã¯ã®å®äºã«é¢ããæ
å ±ãéä¿¡ããããã®ããŸããŸãªãªãã·ã§ã³ã«ã€ããŠèª¬æããŸãã
ããã§ãã¹ãã±ãŒã¹ã®äœæãå®äºããã¿ã¹ã¯ãã©ã³ãã³ã°çšã®äœæ¥ãããžã§ã¯ãã§äœ¿çšããã³é©çšããæºåãæŽããŸããã ããã§ã¯ãããã¯ã°ã©ãŠã³ãã§ã¿ã¹ã¯ãå®è¡ããããã«IntentServiceã䜿çšãããŸããããä»ã®æ¹æ³ãããšãã°ThreadPoolExecutorãŸãã¯HandlerThreadã䜿çšããããšãã§ããŸãã ãŸããAndroid O以éå°çšã®éçºã®å Žåã JobIntentServiceã«æ³šæããããšããå§ãããŸã ã
ãã®äŸã®å®å šãªã³ãŒãã¯GitHubã«ãããŸã ã
developer.android.comã®ActivityããJobSchedulerã®å ¬åŒå®è£ äŸã確èªããããšãã§ããŸãã
ã€ã©ã¹ãïŒ Anni ART ïŒèè ã®åæãåŸãå Žåã®ã¿ã³ããŒããã³è€è£œïŒã