Worker.setForegroundAsync如何在后台工作?

时间:2020-02-18 12:37:22

标签: android android-workmanager

当前,退出应用程序后,要在前台完成长时间运行的任务(这样它就不会被OS杀死),这就是我使用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);

我强烈打算迁移代码,以利用WorkManager中的setForegroundAsync。原因是,在某些罕见的情况下,我会遇到以下崩溃

Context.startForegroundService()然后没有调用 Service.startForeground()

因此,我认为迁移到setForegroundAsync可能有助于消除此问题。


但是,通过观察WorkForegroundUpdater souce code,尚不清楚setForegroundAsync在后​​台如何工作。

这是https://developer.android.com/topic/libraries/architecture/workmanager/advanced/long-runningsetForegroundAsync代码示例的代码片段

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();
    }

但是,目前尚不清楚这种迁移是否会达到相同的结果。因为,这是它们之间的差异。

在迁移到setForegroundAsync之前

  1. 长期运行的任务由IntentService的用户线程执行。
  2. 长时间运行的任务完成之前,Worker将立即返回。

迁移到setForegroundAsync后

  1. 长期运行的任务由Worker的用户线程执行。
  2. 仅在长时间运行的任务完成执行后,工作人员才会返回。

当前,通过当前的实现,我将能够避免出现Excessive network usage (background)问题。我不确定setForegroundAsync是否还能避免Excessive network usage (background)问题?

简而言之,有谁知道Worker.setForegroundAsync在后台如何工作?

1 个答案:

答案 0 :(得分:1)

在后台,setForegroundAsync()在使用API​​> = 26时为您启动前台服务,或者在较旧的Android版本上运行时在正常服务下为您启动前台服务。 reference中对此进行了记录:

在后台,WorkManager代表您管理并运行前台服务以执行此WorkRequest,并显示ForegroundInfo中提供的通知。

我认为相关来源在Processor.java中。

谈论关键指标Excessive Mobile Network Usage in Background时,鉴于使用WorkManager setForegroundAsync()也会将您的工作人员移动到Android Oreo +上的ForegroundService,因此在这种情况下,我看不出会有什么变化。
有关如何测量此重要指标的其他信息,请查看Play Console's guide