[译]How to handle background services in ANDROID O?

418 阅读10分钟

[译]How to handle background services in ANDROID O?

如何处理Android O的后台Service

前段时间公司项目中做Android O的适配。在了解Android O新功能时,看到这个文章,虽然介绍的是Android O的预览版,但读了一遍感觉不错,记录下来。顺便翻译一下(不翻译大家肯定也看得懂,只是觉得单纯转一下太low了)…

原文地址:
How to handle background services in ANDROID O? 2017.04.02

Nothing makes an android developer more crazy than a new version of Android.
对于一个Android开发者来说,没有什么比一个新的Android版本发布,让人更加疯狂了。

Google has just revealed the DP1 of the next iteration of android: Android O. There are many new exciting features and under the hood performance improvements in the newest version of android.

谷歌已经发布了Android O的预览版。新版本的Android O对性能进行了提升 并且 增加了很多令人兴奋的新功能。

While others talk about what will be the name of Android O, let’s analyze this flavour of android from developer’s perspective. For android developers there are four groundbreaking changes:

当大家在讨论Andorid O是什么的时候,让我们从开发的角度来讨论一下Android O。对于开发者来说,这里有四个突破性的变化:

  • Background execution limits
    后台任务限制
  • Location updates limit
    位置更新限制
  • Removing of implicit broadcasts
    移除隐式广播
  • Notification channels
    Notification更改

Here, in this article let’s talk about background execution limitation. Background execution limitations mainly apply to two major components:

这里,这篇文章,让我们讨论一下后台服务的限制。后台服务的限制,主要影响两个主要的组件:

  • Service
  • Wakelocks

Let’s talk about the limitations applied on services in this article.
这篇文章里,让我们讨论后台服务限制对 services 的影响。

What is the service in android?

Let’s first refresh what is the service in Android? As per the android documentation:

首先让我们回忆一下在Android中什么是service 。Android API文章

A Service is an application component that can perform long-running operations in the background, and it does not provide a user interface.

Service 不提供用户界面,提供长时间后台操作的一个应用程序组件。

So, fundamentally Service is the same thing as the activity but it doesn't have the UI component in it. So, it doesn't have to perform smooth animation at 60 fps. That’s why it can run perform any task for the longer period of time than the activity.

因此,从根本上讲,除了没有UI组件,Service和Actiivity在功能上是相同的。因此,Service不必执行60 fps的平滑刷帧动画。这是为什么相对于Activity,Service可以执行长时间后台任务的原因。

There are three types of the service:

这里有三种类型的Service:

  • Started Service  — A service is started when an application component (such as an activity) calls startService().
    Activity通过调用startService()方法启动Service
  • Bound Service  — A service is bound when an application component binds to it by calling bindService().
    Activity通过调用bindService()方法启动Service
  • Scheduled Service  — A service is scheduled when an API such as the JobScheduler.
    JobScheduler

Background vs Foreground applications:

后台应用 VS 前台应用

To learn background execution changes, we need to know the difference between background and foreground application first.

为了了解后台运行的更改,首先我们需要了解前台应用和后台应用的不同。

Rule of thumb, your application will be considered as a foreground service if any of the below three cases are true:

根据经验,如果满足一下三个条件的任何一个,你的应用程序将被视为前台应用。

  • Your application has currently visible activity.
    应用当前有可见的Activity。
  • Your application has foreground service running.
    应用有正在运行的前台Service。
  • Your application is connected to another foreground app by binding the service or by consuming their content providers.
    应用绑定了其他前台应用或者被其他content providers使用。

If any of the above scenarios is not true in the current instance, your application is considered to be in the background.

如果以上三种场景,任何一个都不满足,你的应用将被视为后台应用。

Why do we need to restrict the use of background services?

为什么我们要约束后台Service的使用

Whenever your applications run in the background using services, your application consumes two precious resources:

无论任何时候,应用程序使用后台Service,都将消耗两个珍贵的资源:

  • 1) Memory 内存
  • 2) Battery 电量

These two are limited resources on the mobile devices and most of the low to mid-range devices doesn’t have plenty of memory or battery inside it.

在大多数的中端和低端设备上,内存和电量 是不够丰富的。

Suppose, if your application is doing some very intensive tasks in the background and using the larger amount of RAM to perform that task, then this will create the very junky user experience, especially if the user is using another resource-intensive app, such as playing a game or watching a video in foreground.

假使,如果应用程序使用很多的RAM,来运行密集的后台任务,将会产生非常糟糕的用户体验。特别是用户在使用其他消耗资源的应用,例如:打游戏 或 看视频。

As per the documentation for the started service the best practice is,When the operation is complete, the service should stop itself.

根据文档开始一个Service是最好的选择,当操作完成时,Server应当自动停止。

But, many applications have long running background services, which basically runs for the infinite time to either maintain the socket connection with the server or monitor some tasks or user activity. These services create battery drain and also they constantly consume memory.

但是,很多的应用程序一直在运行后台Service,这些应用程序基本上无限运行,保持与服务器套接字连接或监视某些任务和用户活动。这些Service导致了电量消耗和不断的消耗内存。

From past couple of releases of android (Starting from Marshmallow), Google is trying very hard to increase the battery life and reduce the memory consumption used by the applications by introducing the doze mode and app standby by delaying the background execution by some amount of time if the phone is idle.

从过去发布的几个Android版本开始(从 Marshmallow版本开发),为了提升电池的使用寿命和减少内存的消耗,Google做了很多工作。包括引入doze模式 和 手机空闲时,延迟后台运行服务的执行。

But most of the time despite of knowing the downsides of the long-running services developers still use them. (Mostly because it is easy to implement and maintain rather than using other workarounds.)

但大多数时候,尽管developers了解长时间运行后台服务的缺点,但任然这样使用。(主要是它容易实现和维护而不使用其他变通方法)

What are the limitations on services starting from Android O?

从Android O开始,新增了哪些Server的限制

Starting from Android O, if your application is in the background (check above three conditions), your application is allowed to create and run background services for some minutes.

从Android O开始,如果你的应用运行在后台(检查以上三个条件),你的应用只允许在后台运行几分钟。

After some minutes passed, your application will enter in the idle stage. When your application enteres in the idle stage, the system will stop all the background services just like your service calls Service.stopSelf().

几分钟之后,应用程序将进入闲置状态。当应用程序进入闲置状态,Andorid系统将停止后台Service,就像Server调用了Service.stopSelf() 方法。

And here comes the fun part…

As I discussed above, the problem of battery drain and memory consumption are mainly caused by started services. To eliminate this, Android O completely prevents the use of startService() method to start the service. If you call startService() on Android O, you will end up getting IllegalArgumentException 😲.

正如前边讨论的,电量消耗和内存消耗问题主要是由于开启Service。为了消除这一隐患,Android O彻底阻止了startService()方法的调用。在Android O中,如果开发者调用startService()方法,将会得到一个IllegalArgumentException异常。

There are some exceptions in these scenarios when your application is whitelisted temporarily for some time window. During this period, your application can create background services freely. The application will put into temporary whitelist under below situations:

有一些例外,在这些场景中,当应用程序白名单暂时一段时间窗口。在此期间,您的应用程序可以自由创建背景服务。应用程序将放入临时白名单在以下情况:

  • When high priority FCM message received
  • Receiving a broadcas
  • Executing a PendingIntent from a notification.

How can you run background tasks?

如何执行后台任务

If you are building a very large android application, there might be some genuine scenarios where you need to perform some tasks​ in background. Since starting a service using startService() command is not an option, we need to find out another ways​ to perform the tasks in background.

如果您正在构建一个非常大的android应用程序,可能会有一些真实的场景中,您需要执行某些任务的背景。自从startService()命令不是一个好的选择,我们需要找到另一个方法来执行后台任务。

Scheduling your tasks using Job Scheduler API:

通过Job Scheduler来运行后台任务:


  • JobScheduler api introduced in API21 to perform background tasks.
    JobScheduler在API 21被引入,用于执行后台任务

  • This API allows you to run scheduled service and the android system will batch all the services from different applications and run them together in some particular timeframe. The reason behind this is to reduce the amount of time your phone’s CPU and radio wakes up by batching the tasks together. This will consume less battery and maintains system health.
    这个API允许您运行后台Service,android系统将不同的应用程序,在一个特定的时间段统一处理运行。这背后的机制是通过广播唤醒CPU统一处理所有任务,减少手机CPU的消耗。这将减少电池消耗和维护系统的健康。

  • What if your application has minSdkVersion < 21? In this situation the official way to schedule the job is to use Firebase Job Dispatcher. Firebase Job Dispatcher is supported to all the way down upto API9. 如果应用程序的 `minSdkVersion<21 && minSdkVersion>19,官方的解决方案是Firebase Job Dispatcher </li> </ul> ¨K14K

    ¨K15K

    If you want some long running tasks to be performed in the background, consider using foreground services for that.None of the above background execution limitations applies to the foreground services.

    如果你想要一些长时间运行的Service在后台执行,考虑使用前台服务。以上services限制不适用于前台服务。

    This will also keep your user aware that your application is performing some background tasks by displaying the ongoing notification. This will increase transparency with your user.

    通过展示notification,可以保持后台服务的运行。notification对用户是可见的。

    Before Android O, if you want to create foreground service, you usually start a background service by calling startService(). Then after you can promote your service to the foreground service by assigning an ongoing notification using startForeground() method. But starting from Android O, you cannot use startService() anymore.So to create foreground service you have to use NotificationManager.startServiceInForeground(). This method is equivalent to creating background service and promoting it to the foreground service combine.

    Android O之前,如果开发者想创建前台Service。开发者任然可以通过调用startService()启动一个Service,然后通过startForeground()方法创建一个正在运行的notification,将Service提升为一个前台Service。但是从Android O开始,startService()不再允许被使用。因此创建前台Service,开发者必须使用NotificationManager.startServiceInForeground(). 方法,这个方法等同于创建一个后台Service,并将其提升为一个前台服务。`

    Conclusion:

    结论

    These limitations applied to the background service will definitely provide extended battery life and also lower RAM usage. Ultimately it will make your applications smooth and your user happy.

    这些适用于后台服务的限制,肯定会延长电池寿命和降低内存的消耗。最终会使应用程序平滑和提升用户体验。

    Should you make changes in your application code now?

    Android O is still in DP1. There are 3 more developer previews to be release before the final version of Android O gets released. There might be some API changes in upcoming releases. So, right now it’s time to think the effects of these changes in your application and think about the alternative solution for them. Once developer preview 3–4 gets released, apply those changes to your applications and make your application Android O compatible.