Android WorkManager против JobScheduler

Зачем нам нужен новый WorkManager Android, если у нас уже есть JobScheduler вместе с несколькими отличными резервными копиями (AndroidJob и FirebaseJobDispatcher) с той же функциональностью? Есть ли в нем какие-то убийственные функции или что-то в этом роде? Потому что я не вижу ничего, что заставило бы меня перейти на еще один планировщик.


person Nikolay Kulachenko    schedule 10.05.2018    source источник
comment
Также следует отметить, что WorkManager является частью androidx, а JobScheduler - частью старых библиотек поддержки.   -  person Sir Codesalot    schedule 30.07.2019


Ответы (7)


«WorkManager имеет много хороших функций, но его основная цель - использовать API JobScheduler на старых устройствах» ... Подождите, но у нас уже есть некоторые резервные копии. Что с ними не так? Короче:

  1. FireaseJobDispatcher работает нормально, но требует Google Play для планирования заданий, которые нехорошо, например, если мы нацелены на Китай.

  2. AndroidJob от Evernote является отличным резервным портом с множеством функций. Imho, это был лучший выбор для планирования любой работы. Но теперь последняя версия библиотеки использует вышеупомянутый WorkManager под капотом. И, к сожалению, рано или поздно библиотека устареет:

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

Они предлагают переключиться на WorkManager, потому что он предоставляет больше возможностей, а также дают нам небольшое сравнение:

|   Feature          | android-job | WorkManager |
| ------------------ | ----------- | ----------- |
| Exact jobs         | Yes         | No          |
| Transient jobs     | Yes         | No          |
| Daily jobs         | Yes         | No          |
| Custom Logger      | Yes         | No          |
| Observe job status | No          | Yes         |
| Chained jobs       | No          | Yes         |
| Work sequences     | No          | Yes         |

Imo, последние 3 функции очень полезны и поддерживаются только WorkManager. Итак, ответ на мой последний вопрос - да, у него есть некоторые убийственные функции:

  • Google Play не требуется
  • Запрашиваемый
  • Цепной
  • Оппортунистический

Чтобы узнать больше о WorkManager, обязательно посмотрите этот доклад Сумира Катарии.

P.S. Если кто-нибудь знает, почему FirebaseJobDispatcher активно поддерживается инженерами Google вместо того, чтобы быть устаревшим, напишите в комментариях ниже :)

person Nikolay Kulachenko    schedule 25.06.2018

WorkManager использует JobScheduler службу для планирования заданий. Если JobScheduler не поддерживается устройством, оно использует службу Firebase JobDispatcher. Если Firebase JobDispatcher недоступна на устройстве, будет использоваться AlarmManager и BroadcastReceiver.

Так что с WorkManager вам не нужно беспокоиться об обратной совместимости. В дополнение к этому, он позволяет определять ограничения, которые должны быть соблюдены для выполнения задания, такие как определение сетевых ограничений, уровня заряда батареи, состояния зарядки и уровня хранения.

Это позволяет объединять задачи в цепочку и передавать аргументы заданию.

http://www.zoftino.com/scheduling-tasks-with-workmanager-in-android

person Arnav Rao    schedule 11.11.2018

WorkManager выглядит как ответ Google на библиотеку Evernote Android-Job, но с некоторыми улучшениями. Он использует JobScheduler, Firebase JobDispatcher и AlarmManager так же, как Android-Job, в зависимости от уровня API устройства. Их использование тегов выглядит примерно одинаково, и назначение ограничений для заданий / работы достаточно похоже.

Две особенности, которые мне нравятся, - это возможность объединить работу в цепочку и способность подходить к работе с ограничениями. Первый позволит мне разделить работу (рабочие места) и сделать ее более модульной. А при большей модульной работе каждая часть работы может иметь меньше ограничений, что увеличивает вероятность того, что они завершатся раньше (оппортунистический). Например, большая часть обработки может быть завершена до того, как потребуется выполнить работу с сетевым ограничением.

Так что, если вас устраивает текущая реализация планировщика и две упомянутые мною функции не добавляют ценности, я пока не вижу огромных преимуществ в переходе на нее. Но если вы пишете что-то новое, вероятно, стоит использовать WorkManager.

person Steve Miskovetz    schedule 10.05.2018
comment
хе-хе. Меньше Android-Job от EverNote и больше Йигита, который принес в Google свое прошлое дитя: github.com/path/android -priority-jobqueue :) - person Andrew G; 16.05.2018
comment
Lol, возможно, но мне кажется, что это все еще больше похоже на Android-Job с периодическими заданиями, большим количеством ограничений и использованием AlarmManager для устройств, не поддерживающих GMS до Lollipop. Но я уверен, что Evernote тоже был вдохновлен им. - person Steve Miskovetz; 16.05.2018

Во-первых, WorkManager используется для работ, которые могут быть отложены и требуют выполнения гарантии. Учитывая обратную совместимость, JobScheduler работает только с API 23+. Чтобы избежать необходимости работать над обратной совместимостью, WorkManager сделает это за вас: -

введите описание изображения здесь

Особенности работы менеджера

  • Гарантированное исполнение с учетом ограничений
  • Соблюдайте системные ограничения фона
  • Quarreable, вы можете проверить статус, например, сбой, успех и т. Д.
  • В цепочке, например, работа-A зависит от работы-B -> Рабочий график
  • Оппортунист, постарайтесь выполнить все, как только будут соблюдены ограничения, без необходимости вмешательства планировщика заданий, т.е. пробудить приложение или дождаться, пока JobSheduler выполнит пакетную обработку вашей работы, если ваш процесс запущен и работает
  • Обратная совместимость, с сервисом Google Play или без него

WorkManager обеспечивает совместимость с уровнем API 14. WorkManager выбирает подходящий способ планирования фоновой задачи в зависимости от уровня API устройства. Он может использовать JobScheduler (на API 23 и выше) или комбинацию AlarmManager и BroadcastReceiver.

Расширенная архитектура под капотом

введите описание изображения здесь

person Emmanuel Mtali    schedule 28.03.2020

WorkManager находится поверх JobScheduler и AlarmManager. WorkManager выбирает подходящие API-интерфейсы на основе таких условий, как уровень API-интерфейса устройства пользователя.

WorkManager - это простая, но невероятно гибкая библиотека, обладающая множеством дополнительных преимуществ. Это включает:

 -Support for both asynchronous one-off and periodic tasks.
 -Support for constraints such as network conditions, storage space, and charging -status 
 -Chaining of complex work requests, including running work in parallel.
 -Output from one work request used as input for the next.
 -Handles API level compatibility back to API level 14.
 -Works with or without Google Play services.
 -Follows system health best practices.
 -LiveData support to easily display work request state in UI.
person Tarun Varshney    schedule 09.08.2019

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

Я тестировал Nexus 5X под управлением Oreo Android 8.0.0 (API 26). Возможно, мне просто повезло, что эта комбинация устройства и ОС могла продолжить работу после закрытия приложения. Я считаю, что это может быть связано с конкретным устройством из-за того, что я прочитал в этом ответе https://stackoverflow.com/a/52605503/2848676 на Android. Работает ли WorkManager при закрытии приложения?. "Вы можете найти полный список различных вариантов поведения OEM на dontkillmyapp.com."

ПРИМЕЧАНИЕ. Я заметил, что, когда пользователь закрыл приложение, для перезапуска JobService потребовалось несколько секунд или даже минут.

Чтобы заставить JobScheduler запустить службу, которая переживает смерть приложения, создайте службу следующим образом:

    JobScheduler jobScheduler = (JobScheduler)applicationContext.getSystemService(Context.JOB_SCHEDULER_SERVICE);
    ComponentName componentName = new ComponentName(applicationContext, ScannerAsJobService.class);
    JobInfo jobInfo = new JobInfo.Builder(JOB_ID, componentName)
            .setPersisted(true)  // relaunch on reboot
            .setMinimumLatency(1)
            .setOverrideDeadline(1)
            .build();
    int result = jobScheduler.schedule(jobInfo);

ScannerAsJobService обновляет уведомление текущей информацией, в том числе о том, находится ли служба «в фоновом режиме» (я цитирую это, потому что существуют разные определения «фона», но это точно отражает, было ли приложение больше не запущено):

import android.app.ActivityManager;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.job.JobParameters;
import android.app.job.JobService;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.os.Build;
import android.os.Handler;

import androidx.annotation.RequiresApi;

import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

public class ScannerAsJobService extends JobService {
    private static final String TAG = "ScannerAsJobService";

    private static final String NOTIFICATION_CHANNEL_ID = "ll_notification_channel";

    final Handler workHandler = new Handler();
    Runnable workRunnable;

    @Override
    public boolean onStartJob(JobParameters params) {
        workRunnable = new Runnable() {
            @Override
            public void run() {
                // See https://stackoverflow.com/questions/45692181/android-job-scheduler-schedule-job-to-execute-immediately-and-exactly-once
                (new Timer()).schedule(new TimerTask() {
                    @Override
                    public void run() {
                        String message = "Time: " + (new Date()).toString() + " background: " + appIsInBackground();

                        // https://stackoverflow.com/a/32346246/2848676
                        Intent intent = new Intent();

                        PendingIntent pendingIntent = PendingIntent.getActivity(ScannerAsJobService.this, 1, intent, 0);

                        Notification.Builder builder = new Notification.Builder(ScannerAsJobService.this);

                        builder.setAutoCancel(false);
                        builder.setTicker("my ticker info");
                        builder.setContentTitle("my content title");
                        builder.setContentText(message);
                        builder.setSmallIcon(R.drawable.my_icon);
                        builder.setContentIntent(pendingIntent);
//                        builder.setOngoing(true);   // optionally uncomment this to prevent the user from being able to swipe away the notification
                        builder.setSubText("my subtext");   //API level 16
                        builder.setNumber(100);
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                            setupNotificationChannel(NOTIFICATION_CHANNEL_ID);
                            builder.setChannelId(NOTIFICATION_CHANNEL_ID);
                        }
                        builder.build();

                        NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
                        manager.notify(93423, builder.build());

                        Log.d(TAG + " Notification message: " + message);

                    }
                }, 1 * 1000, 5 * 1000);

                jobFinished(params, true);
            }
        };
        workHandler.post(workRunnable);

        // return true so Android knows the workRunnable is continuing in the background
        return true;
    }

    // https://stackoverflow.com/a/45692202/2848676
    @RequiresApi(api = Build.VERSION_CODES.O)
    private void setupNotificationChannel(String channelId) {
        NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

        // The user-visible name of the channel.
        CharSequence name = getString(R.string.my_channel_name);

        // The user-visible description of the channel.
        String description = getString(R.string.my_channel_name);

        int importance = NotificationManager.IMPORTANCE_LOW;

        NotificationChannel mChannel = new NotificationChannel(channelId, name, importance);

        // Configure the notification channel.
        mChannel.setDescription(description);

        mChannel.enableLights(true);
        // Sets the notification light color for notifications posted to this
        // channel, if the device supports this feature.
        mChannel.setLightColor(Color.RED);

        mChannel.enableVibration(true);
        mChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});

        mNotificationManager.createNotificationChannel(mChannel);
    }

    /**
     * Source: <a href="https://stackoverflow.com/a/39589149/2848676">https://stackoverflow.com/a/39589149/2848676</a>
     * @return true if the app is in the background, false otherwise
     */
    private boolean appIsInBackground() {
        ActivityManager.RunningAppProcessInfo myProcess = new ActivityManager.RunningAppProcessInfo();
        ActivityManager.getMyMemoryState(myProcess);
        boolean isInBackground = myProcess.importance != ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
        return isInBackground;
    }

    @Override
    public boolean onStopJob(JobParameters params) {
        // returning true schedules the job for retry (we're using it to implement periodicity since
        // JobInfo.Builder.setPeriodic() didn't work
        return true;
    }
}
person Michael Osofsky    schedule 31.10.2019

В документации Google рекомендуется использовать WorkManger для всех предыдущих фоновых задач, включая FirebaseJobDispatcher, GcmNetworkManager и Job Scheduler.

см. https://developer.android.com/topic/libraries/architecture/workmanager < / а>

person sanren1024    schedule 11.06.2020
comment
Это не ответ на вопрос @Nicholas Ni - person androminor; 05.09.2020