Запускать воркера каждый раз, когда доступен интернет

Я разрабатываю приложение для Android и использовал библиотеку Firebase JobDispatcher для запуска фонового задания каждый раз, когда пользователь включает Wi-Fi или мобильные данные, но, к сожалению, библиотека устарела, и теперь можно использовать новый WorkerManager.

У меня вопрос: как запускать задание с помощью WorkerManager каждый раз, когда Интернет доступен только?

Я проверил руководство и документацию по миграции библиотеки WorkerManager, но не смог добиться этого с помощью OneTimeWorkRequest или PeriodicWorkRequest.

Вот код, который я использовал для этого с библиотекой Firebase JobDispatcher.

FirebaseJobDispatcher dispatcher = new FirebaseJobDispatcher(new GooglePlayDriver(this));

Job networkJob = dispatcher.newJobBuilder()
        .setService(NetworkJobService.class)
        .setTag(Const.NETWORK_JOB_TAG)
        .setReplaceCurrent(true)
        .setLifetime(Lifetime.FOREVER)
        .setRetryStrategy(RetryStrategy.DEFAULT_LINEAR)
        .setRecurring(true)
        .setTrigger(Trigger.executionWindow(0, 0))
        .setConstraints(Constraint.ON_ANY_NETWORK)
        .build();

    dispatcher.schedule(networkJob);

person Waxren    schedule 21.08.2019    source источник
comment
Привет, @Waxren, вы просто хотите запускать слушателя, когда приходит Интернет, независимо от использования android-jobscheduler или android-workmanager?   -  person Zain    schedule 21.08.2019
comment
Да, но даже когда приложение закрыто и не запущено   -  person Waxren    schedule 21.08.2019


Ответы (2)


Официальная документация WorkManager включает руководство по миграции для преобразования приложения из Firebase JobDispatcher в WorkManager.

Ключевым моментом является то, что WorkManager позволяет аналогично Firebase JobDispatcher устанавливать _ 1_ на ваш WorkRequest:

Constraints constraints = new Constraints.Builder()
    // The Worker needs Network connectivity
    .setRequiredNetworkType(NetworkType.CONNECTED)
    .build();

PeriodicWorkRequest request =
    // Executes MyWorker every 15 minutes
    new PeriodicWorkRequest.Builder(MyWorker.class, 15, TimeUnit.MINUTES)
        // Sets the input data for the ListenableWorker
        .setConstraints(constraints)
        .build();

Это запускает вашего воркера каждые 15 минут (минимальный интервал), когда есть соединение. Другое ограничение, которое вы должны учитывать, - это то, что Worker не может работать более 10 минут. По истечении этого интервала ОС остановит ваш Worker.

Оба ограничения исходят из базового API JobScheduler в Android Framework.

person pfmaggi    schedule 21.08.2019
comment
Рассмотрим следующий пример: пользователь включил Wi-Fi, задание будет выполняться, затем после этого и до истечения 15-минутного интервала пользователь выключил, а затем включил Wi-Fi задание не будет выполнено. - person Waxren; 21.08.2019
comment
Это проблема. Мне нужно повторяющееся задание, но не периодическое, другими словами, задание должно запускаться после того, как устройство подключено к сети один раз, а в следующий раз оно запускается не через 15 минут (или любой конкретный интервал), а после устройство снова подключено. - person Waxren; 21.08.2019
comment
Рабочий будет выполнен только через 15 минут после предыдущего выполнения. Если вам нужно выполнить его, как только соединение станет доступным, учитывая неявные ограничения широковещательной передачи в API 26+, я бы посоветовал вам использовать службу переднего плана со слушателем для подключения. - person pfmaggi; 21.08.2019
comment
Спасибо за комментарий. Я думаю, что это отсутствующая функция в библиотеке вместо использования службы переднего плана. Потому что многим приложениям необходимо запускать код задания, как только соединение становится доступным. - person Waxren; 21.08.2019
comment
Боюсь, что у библиотеки нет возможности добавить эту поддержку, поскольку она просто использует то, что уже доступно в системе (JobScheduler), и запускается из процесса вашего приложения с тем же ограничением. Если вы считаете, что эта функция важна, вы можете открыть запрос функции в общедоступном трекере проблем для WorkManager: issueetracker.google.com/issues/ - person pfmaggi; 21.08.2019
comment
Другое ограничение, которое вы должны учитывать, заключается в том, что Worker не может работать более 10 минут, не могли бы вы подробнее об этом ... когда этот сценарий произойдет? ясно, что менеджер работ не работает постоянно. Менеджер работ просто выполняет задание с помощью одноразового запроса или периодически .. его метод работы вызывается периодически, тогда как рабочий класс может продолжать работать даже в течение 10 минут? Диспетчер работы был введен для многих целей, одна из них - потребление батареи? если рабочий класс может работать так долго, почему бы нам не использовать класс Service? - person Quick learner; 22.08.2019
comment
Я считаю, что вы хотите указать ВРЕМЯ ЗАДАЧИ, которое должно выполняться в классе диспетчера работы в doWork () .. ?? Если задача, которую вы хотите выполнить, требует времени, то почему бы вам выбрать Диспетчер работ ... определенно не лучший выбор - person Quick learner; 22.08.2019
comment
WorkManager использует JobScheduler на API 23+ в качестве основного планировщика, и это дает ограничение в 10 минут на то, сколько времени может занять задача (в данном случае мы говорим о том, что находится внутри вашего doWork() метода). Если doWork() не вернется до этого предела HARD, ОС остановит Worker. Это упоминается в документации: developer.android .com / topic / libraries / architecture / workmanager /. - person pfmaggi; 22.08.2019

Лучше запустить диспетчер работы один раз и установить ограничение с типом сети, которое проверяет, доступно ли соединение в doWork () Workmanager, а не вызывает диспетчер работы снова и снова.

 setConstraints(new Constraints.Builder()
                     .setRequiredNetworkType(NetworkType.CONNECTED)

Попробуйте это решение

менеджер по импорту работ

https://developer.android.com/jetpack/androidx/releases/work

Затем инициируйте Worker класс

PeriodicWorkRequest periodicWorkRequest = new PeriodicWorkRequest.Builder(WorkManagerDemo.class, 15, TimeUnit.MINUTES)
            .addTag("WorkManagerDemo").setConstraints(new Constraints.Builder()
            .setRequiredNetworkType(NetworkType.CONNECTED)
            .build();
    WorkManager.getInstance().enqueueUniquePeriodicWork("WorkManagerDemo", ExistingPeriodicWorkPolicy.KEEP, periodicWorkRequest);

где WorkManagerDemo класс

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.support.annotation.NonNull;

import androidx.work.Worker;
import androidx.work.WorkerParameters;

public class WorkManagerDemo extends Worker {

    public WorkManagerDemo(@NonNull Context context, @NonNull WorkerParameters workerParams) {
        super(context, workerParams);
    }

    @NonNull
    @Override
    public Result doWork() {
        //do your work here
        return Result.success();
    }


}
person Quick learner    schedule 21.08.2019
comment
WorkManager включает в себя ограничения, которые вы можете использовать для запуска своего воркера, только когда устройство подключено к сети. Ваш подход более агрессивен по отношению к батарее и не принимает во внимание 10-минутный лимит выполнения, который имеет Worker. Через 10 минут воркер автоматически останавливается ОС. - person pfmaggi; 21.08.2019
comment
Я проголосовал против использования очень устаревшей версии WorkManager и использования ПЛОХОЙ реализации проверки сети (подсказка: вы должны использовать ограничения, не используйте ConnectivityManager) - person Zun; 21.08.2019
comment
@pfmaggi FYI Минимальное время повторения - 15 минут, а не 10 минут - person Quick learner; 21.08.2019
comment
Да, минимальное время повторения - 15 минут. однако 10 минут, о которых я писал здесь, - это максимальное время выполнения Worker'а: если ваш Worker работает более 10 минут, ОС остановит его. - person pfmaggi; 21.08.2019
comment
Прочтите больше о диспетчере работ и ИСПОЛЬЗУЙТЕ ИТ, чтобы убедиться, как он работает на практике ... ну, нет никакого смысла, когда рабочий работает без остановки 10 минут, насколько мне известно .. Диспетчер работ может не работать в режиме DOZE - person Quick learner; 22.08.2019
comment
@pfmaggi добавил ограничение в запрос менеджера работы, как вы упомянули ... обновил ответ - person Quick learner; 22.08.2019
comment
@Zun обновил мой ответ ... теперь с использованием ограничения типа сети, а не с использованием класса диспетчера соединений - person Quick learner; 22.08.2019
comment
Вы все же выслушали мою критику и отредактировали свой пост, лол. Хороший приятель, я изменил свой голос - person Zun; 22.08.2019
comment
если ваш комментарий полезен, я ценю это и всегда буду делать это .. Я не скажу, что я настоящий разработчик. Я позволю своему коду говорить ... но да, я учусь каждый день, спасибо, проголосовали ли вы за или против - person Quick learner; 22.08.2019