Привет Хабр! Предлагаю вашему вниманию свободный перевод статьи «Schedule tasks and jobs intelligently in Android» от Ankit Sinhal.


В современной разработке приложений очень часто выполняются задачи асинхронно, и их объем выходит за пределы жизненного цикла приложения. В некоторых ситуациях мы также должны выполнять некоторые работы, но это не обязательно делать прямо сейчас. Чтобы запланировать фоновые работы, Android представила несколько API, которые мы можем грамотно использовать в наших приложениях.


Выбор подходящего планировщика может улучшить производительность приложений и время автономной работы устройства.


Для планирования задач на Android доступно несколько API:


  • Alarm Manager
  • Job Scheduler
  • GCM Network Manager
  • Firebase Job Dispatcher
  • Sync Adapter

Проблемы с сервисами


Сервисы позволяют выполнять длительные операции в фоновом режиме. Запуск сервисов в фоновом режиме очень негативно влияет на заряд батареии.


Сервисы особенно вредны, когда они постоянно использует ресурсы устройства, даже если не выполняет полезные задачи.


Запланированный задачи во время жизненного цикла приложения


Когда приложение запущено, и мы хотим запланировать или запустить задачу в определенное время, рекомендуется использовать класс Handler вместе с Timer и Thread.


Запланированные задачи при выключенном приложении


Alarm Manager


AlarmManager обеспечивает доступ к службам уведомлений. Это дает возможность выполнять любые операции за пределами жизненного цикла вашего приложения. Таким образом, вы можете инициировать события или действия, даже если ваше приложение не запущено. AlarmManager может запустить сервис в будущем.


Мы должны использовать API AlarmManager только для задач, которые должны выполняться в определенное время

Пример использования: предположим, что мы хотим выполнить задачу через 1 час или каждый час. В этом случае AlarmManager нам поможет.


Job Scheduler


Это главный из всех упомянутых вариантов планирования и очень эффективный с фоновыми работами. JobScheduler API, который был представлен в Android 5.0 (API уровня 21).


Этот API позволяет выполнять задания, когда у устройства больше доступных ресурсов или при соблюдении правильных условий. Все условия могут быть определены при создании задания. Когда объявленные критерии будут выполнены, система выполнит это задание в JobService вашего приложения. JobScheduler также отменяет выполнение, если необходимо, чтобы соблюдать ограничения режима Doze и App Standby.


GCM Network Manager


GCM (Google Cloud Messaging) Network Manager имеет все функции расписания из JobScheduler. GCM Network Manager также предназначен для выполнения многократной или одноразовой, неминуемой работы при сохранении времени автономной работы.


Он используется для поддержки обратной совместимости и может также использоваться под Android 5.0 (API уровня 21). Начиная с уровня API 23 или выше, GCM Network Manager использует JobScheduler для платформы. GCM Network Manager использует механизм планирования в службах Google Play, поэтому этот класс будет работать только в том случае, если на устройстве установлены сервисы Google Play.


Google настоятельно рекомендовал пользователям GCM перейти на FCM и вместо этого использовать диспетчер заданий Firebase для планирования любых задач.


Firebase Job Dispatcher


Firebase JobDispatcher также является библиотекой для планирования фоновых заданий. Он также используется для поддержки обратной совместимости (ниже API 21) и работает во всех последних версиях Android (API 9+).


Эта библиотека также будет работать, если на устройстве нет установленных сервисов Google Play. В этом состоянии эта библиотека внутренне использует AlarmManager. Если на устройстве доступно приложение Google Play, он использует механизм планирования в службах Google Play.


Sync Adapter


Sync adapters разработаны специально для синхронизации данных между устройством и облаком. Он должен использоваться только для этого типа задач. Синхронизация может быть вызвана изменениями данных в облаке или на устройстве или по истекшему времени.
Система будет пытаться синхронизировать только тогда, когда устройство подключено к сети.


Упражнение


Мы обсудили достаточно теории, поэтому теперь посмотрим, как использовать планировщик заданий Android.


Создание Job Service


Создайте JobSchedulerService extends JobService, который требует, чтобы были созданы два метода onStartJob (параметры JobParameters) и onStopJob (параметры JobParameters).


public class JobSchedulerService extends JobService {
   @Override
   public boolean onStartJob(JobParameters params) {
     return false;
   }
   @Override
   public boolean onStopJob(JobParameters params) {
     return false;
   }
}

Метод onStartJob вызывается, когда JobScheduler решает запустить вашу работу. JobService работает в основном потоке, поэтому любая логика должна выполняться в отдельном потоке. Метод onStopJob вызывается, если система решила, что вы должны прекратить выполнение своей работы. Метод вызывается до jobFinished (JobParameters, boolean).


Вам также необходимо зарегистрировать свою службу в AndroidManifest.


<application>
   <service
   android:name=”.JobSchedulerService “
   android:permission=”android.permission.BIND_JOB_SERVICE”
   android:exported=”true”/>
</application>

Создать объект JobInfo


Чтобы построить объект JobInfo, передайте JobService в JobInfo.Builder (), как показано ниже. Этот конструктор заданий позволяет установить множество различных параметров управления при выполнении задания.


ComponentName serviceName = new ComponentName(context, JobSchedulerService.class);
JobInfo jobInfo = new JobInfo.Builder(JOB_ID, serviceName)
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)
.setRequiresDeviceIdle(true)
.setRequiresCharging(true)
.build();

Запланированная задача


Теперь у нас есть JobInfo и JobService, поэтому пришло время планировать нашу работу. Все, что нам нужно сделать, это запланировать работу с требуемой JobInfo, как показано ниже:


JobScheduler scheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
int result = scheduler.schedule(jobInfo);
if (result == JobScheduler.RESULT_SUCCESS) {
   Log.d(TAG, “Job scheduled successfully!”);
}

Заключение


При планировании задания вам нужно тщательно подумать о том, когда и что должно вызвать вашу задачу, и что должно произойти, если она по какой-то причине не сработает. Вы должны быть очень осторожны с производительностью вашего приложения, а также с другими аспектами, такими как заряд батареи.


JobScheduler легко реализуется и обрабатывает большую часть за вас. При использовании JobScheduler наши запланированные задания сохраняются, даже если система перезагружается. В настоящий момент единственным недостатком JobScheduler является то, что он доступен только для 21 уровня api (Android 5.0).

Комментарии (10)


  1. petrovichtim
    22.08.2017 18:53

    1. velkonost Автор
      22.08.2017 18:59

      Нет. Это свободный перевод этой статьи


      1. StanZakharov
        22.08.2017 19:56
        +1

        что-то тут не чисто, кто у кого переписал?


        1. Bublik
          23.08.2017 12:09
          +1

          На medium статья от 1 июня, перевод у petrovichtim от 14 июля.


        1. praeivis
          23.08.2017 12:17
          +1

          2017 06 01 Schedule tasks and jobs intelligently in Android
          2017 07 14 Разумное планирование задач и работы в Android


    1. slartus
      23.08.2017 12:14
      +1

      (AlarmManager) — Менеджер аварийных сообщений- серьезно?


      1. velkonost Автор
        23.08.2017 12:15

        Не совсем понимаю, о чем вы? Я не вижу этого утверждения в моей статье


        1. slartus
          23.08.2017 12:26

          не в вашей. а в petrovichtim


  1. barskykd
    23.08.2017 12:15

    Firebase JobDispatcher не работает без сервисов Google Play.
    Есть github.com/evernote/android-job, которое как раз и использует если что Alaram Manager, но оно только для API 14+


  1. MrMuradin
    23.08.2017 12:27

    Было бы интереснее с примерами не только для JobScheduler, но все равно познавательно, спасибо