目前,在退出应用程序后,要在前台完成一个长时间运行的任务(以便操作系统不会将其杀死),我使用WorkManager
实现了以下操作:
- 使用
Worker
调用ContextCompat.startForegroundService
,启动一个IntentService
。 Worker
随即立刻返回Result.success()
。- 在
IntentService
的onHandleIntent
方法中,它会在执行长时间运行的任务之前,调用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() did not then call Service.startForeground()
因此,我认为迁移到 setForegroundAsync
可以帮助消除这个问题。
然而,从 WorkForegroundUpdater 源代码 看,setForegroundAsync
的工作方式并不清楚。
以下是来自 https://developer.android.com/topic/libraries/architecture/workmanager/advanced/long-running 的 setForegroundAsync
代码示例片段:
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 之前
- 长时间运行的任务由
IntentService
的用户线程执行。 - 在长时间运行的任务完成之前,Worker 将立即返回。
迁移至 setForegroundAsync 之后
- 长时间运行的任务由
Worker
的用户线程执行。 - Worker 仅在长时间运行的任务完成执行后才会返回。
目前,通过我当前的实现,我将能够避免Excessive network usage (background)问题。但我不确定使用setForegroundAsync
后,我是否仍能避免Excessive network usage (background)问题?
简而言之,有人知道 Worker.setForegroundAsync 在幕后如何工作吗?