Как Worker.setForegroundAsyn c работает за сценой? - PullRequest
0 голосов
/ 18 февраля 2020

В настоящее время, после выхода из приложения, чтобы завершить долгосрочную задачу на переднем плане (чтобы она не была уничтожена ОС), это то, что я сделал, используя WorkManager.

  1. Используйте Worker для вызова ContextCompat.startForegroundService, для запуска IntentService.
  2. Worker немедленно вернется Result.success().
  3. В onHandleIntent на IntentService, это выполнит startForeground перед выполнением длительной задачи.

Вот фрагмент кода.

public class SyncWorker extends Worker {
    @NonNull
    @Override
    public Result doWork() {
        final Intent intent = new Intent(WeNoteApplication.instance(), SyncForegroundIntentService.class);

        ContextCompat.startForegroundService(
                WeNoteApplication.instance(),
                intent
        );

        return Result.success();
    }
}

public class SyncForegroundIntentService extends IntentService {
    private static final String TAG = "com.yocto.wenote.sync.SyncIntentService";

    public SyncForegroundIntentService() {
        super(TAG);
    }

    @Override
    protected void onHandleIntent(@Nullable Intent intent) {

        final Context context = WeNoteApplication.instance();

        NotificationCompat.Builder builder = new NotificationCompat.Builder(...

        startForeground(SYNC_FOREGROUND_INTENT_SERVICE_ID, builder.build());

        // Perform networking operation within foreground service.

        stopForeground(true);

У меня есть сильное намерение перенести код, чтобы использовать setForegroundAsync в WorkManager. Причина в том, что при некоторых редких обстоятельствах я получаю следующий cra sh

Context.startForegroundService () не вызывал Service.startForeground ()

Итак, я думал, что переход на setForegroundAsync может помочь устранить эту проблему.


Однако, неясно, как setForegroundAsync работает за кулисами, глядя на WorkForegroundUpdater souce code .

Вот фрагмент кода setForegroundAsync примера кода из https://developer.android.com/topic/libraries/architecture/workmanager/advanced/long-running

public class DownloadWorker extends Worker {
    public DownloadWorker(
        @NonNull Context context,
        @NonNull WorkerParameters parameters) {
            ...
    }

    @NonNull
    @Override
    public Result doWork() {
        ...

        // What happens behind the scene?!
        setForegroundAsync(createForegroundInfo(progress));

        // The long running task is still executed in Worker thread.
        download(inputUrl, outputFile);

        return Result.success();
    }

Однако неясно, такая миграция приведет к эквивалентному результату. Как, вот их различия.

Перед миграцией на setForegroundAsyn c

  1. Долгосрочная задача выполняется потоком пользователя IntentService.
  2. Перед завершением долго выполняющейся задачи Worker немедленно вернется.

После перехода на setForegroundAsyn c

  1. Долгосрочная задача выполняется пользователем Worker. thread.
  2. Рабочий вернется только после того, как долго выполняемое задание будет завершено.

В настоящее время, благодаря моей текущей реализации, я смогу избежать Чрезмерное использование сети (фон) выпуск. Я не уверен, смогу ли я при setForegroundAsync избежать Чрезмерное использование сети (фон) проблема?

Короче, кто-нибудь имеет представление о том, как Worker.setForegroundAsyn c работа за сценой?

1 Ответ

1 голос
/ 18 февраля 2020

За кулисами setForegroundAsync() запускает службу переднего плана для вас, когда вы используете API> = 26, или обычную службу при работе в старых Android выпусках. Это задокументировано в справке :

. Под капотом WorkManager управляет и запускает службу переднего плана от вашего имени для выполнения этого WorkRequest, показывая уведомление, предоставленное в ForegroundInfo. .

Я думаю, что соответствующий источник находится в Processor.java.

Говоря о метриале витала c Чрезмерное использование мобильной сети в фоновом режиме , я не вижу, как это изменится в этом случае, учитывая, что использование WorkManager setForegroundAsync() также переведет вашего работника в ForegroundService на Android Oreo +.
Для получения дополнительной информации о том, как измеряется показатель c этого витала, ознакомьтесь с Руководством Play Console .

...