用于后台任务的最佳做法是什么?

what is the best practice to use for background tasks?

我有一个用例,每当交易完成或失败时,我都必须在后台等待(不会冻结 UI)5 分钟并在没有用户的情况下调用一段代码干涉。所以 AFAIK 我需要为此实现后台服务。

我想知道哪个更适合我的场景。

  1. Workermanager (JetPack)
  2. Jobscheduler(对于 API 14 - 21,Firebase JobDispatcher)
  3. 意图服务

在 Oreo 及更高版本中,如果我 运行 后台服务,它会在通知中显示该应用程序正在 运行ning 在后台吗?

展望未来,官方 android 文档建议您使用 JobScheduler 代替后台服务。

In many cases, apps that previously registered for an implicit broadcast can get similar functionality by using a JobScheduler job. For example, a social photo app might need to perform cleanup on its data from time to time, and prefer to do this when the device is connected to a charger. Previously, the app registered a receiver for ACTION_POWER_CONNECTED in its manifest; when the app received that broadcast, it would check whether cleanup was necessary. To migrate to Android 8.0 or higher, the app removes that receiver from its manifest. Instead, the app schedules a cleanup job that runs when the device is idle and charging. https://developer.android.com/about/versions/oreo/background#services

现在推荐的后台处理方式是 Jetpack WorkManager API。我会引用官方文档的原因:

WorkManager chooses the appropriate way to run your task based on such factors as the device API level and the app state. If WorkManager executes one of your tasks while the app is running, WorkManager can run your task in a new thread in your app's process. If your app is not running, WorkManager chooses an appropriate way to schedule a background task--depending on the device API level and included dependencies, WorkManager might use JobScheduler, Firebase JobDispatcher, or AlarmManager. You don't need to write device logic to figure out what capabilities the device has and choose an appropriate API; instead, you can just hand your task off to WorkManager and let it choose the best option.

In addition, WorkManager provides several advanced features. For example, you can set up a chain of tasks; when one task finishes, WorkManager queues up the next task in the chain. You can also check a task's state and its return values by observing its LiveData; this can be useful if you want to show UI indicating your task's status.

因此,不必每次都担心选择哪个后台处理(因为每个任务都有推荐和合适的方式),您只需使用 WorkManager 即可完成它的工作。

这是考虑到以下陷阱:

WorkManager is intended for tasks that require a guarantee that the system will run them even if the app exits, like uploading app data to a server. It is not intended for in-process background work that can safely be terminated if the app process goes away; for situations like that, we recommend using ThreadPools.

P.S。由于 WorkManager API 在后台使用 JobScheduler、Firebase JobDistpacher 或 AlarmManager,您必须考虑所用功能的最低 API 级别。 JobScheduler 至少需要 API 21,Firebase JobDispatcher 至少需要 API 14 和 Google Play 服务。

完整文档检查:https://developer.android.com/topic/libraries/architecture/workmanager

关于您的第二个问题:据我所知,您将始终看到该通知,因为它是在通知用户您的应用正在耗电。用户可以通过 Android Oreo 8.1.

中的设置禁用通知

WorkManager 可能(最终)是您正在寻找的解决方案。它充当抽象,决定是使用 JobScheduler(如果可用)还是使用 Firebase JobDispatcher(如果可用),否则回退到默认实现。通过这种方式,您可以获得世界上最好的。但是,它仍处于 alpha 阶段,因此您可能至少要考虑其他选择。

如果您选择不使用 WorkManager,JobScheduler 和 JobDispatcher 的组合可能是合适的(参见 here)。

但是,如果您的目标设备没有 Google 低于 API 22 的播放服务,您将需要使用其他解决方案。在那种情况下,AlarmManager 可能就是您要查找的内容,因为您需要延迟任务并保证执行。为此使用 IntentService 是可能的,但并不那么容易。它涉及引入某种延迟机制,其中有多种选择。

请注意,如果您使用作业 API 或 WorkManager 之一,您将使用批处理机制,因此您将不会在 Oreo 中看到通知。基于 AlarmManager/IntentService 的解决方案可能会显示通知,但可能不会显示很长时间,因为任务相当短。对于 AlarmManager 尤其如此。