天天看點

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

[譯]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().

    bindService()

  • 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 記憶體
    1. 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

Use foreground service

使用前台服務

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.

========== THE END ==========