В настоящее время, после выхода из приложения, чтобы завершить долгосрочную задачу на переднем плане (чтобы она не была уничтожена ОС), это то, что я сделал, используя WorkManager
.
- Используйте
Worker
для вызова ContextCompat.startForegroundService
, для запуска IntentService
. Worker
немедленно вернется Result.success()
. - В
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
- Долгосрочная задача выполняется потоком пользователя
IntentService
. - Перед завершением долго выполняющейся задачи Worker немедленно вернется.
После перехода на setForegroundAsyn c
- Долгосрочная задача выполняется пользователем
Worker
. thread. - Рабочий вернется только после того, как долго выполняемое задание будет завершено.
В настоящее время, благодаря моей текущей реализации, я смогу избежать Чрезмерное использование сети (фон) выпуск. Я не уверен, смогу ли я при setForegroundAsync
избежать Чрезмерное использование сети (фон) проблема?
Короче, кто-нибудь имеет представление о том, как Worker.setForegroundAsyn c работа за сценой?