본문 바로가기

공부/안드로이드

[Android][core] Background tasks(1)

1. 백그라운드 프로세싱

Every Android app has a main thread which is in charge of handling UI (including measuring and drawing views), coordinating user interactions, and receiving lifecycle events. If there is too much work happening on this thread, the app appears to hang or slow down, leading to an undesirable user experience. Any long-running computations and operations such as decoding a bitmap, accessing the disk, or performing network requests should be done on a separate background thread. In general, anything that takes more than a few milliseconds should be delegated to a background thread. Some of these tasks may be required to be performed while the user is actively interacting with the app. To learn how you can run tasks on background threads and off the main UI thread while the app is actively being used, please take a look at the threading solutions guide.

Applications may also require some tasks to run even when the user is not actively using the app such as syncing periodically with a backend server or fetching new content within an app on a periodic basis. Applications may also require services to run immediately to completion even after the user has completed interacting with the app. This guide will help you learn which solution best meets your needs for these use cases.
  • 모든 안드로이드 앱들은 하나의 메인 스레드가 있고, 그 메인 스레드가 UI 부분을 처리하고, 사용자와 상호작용을 하며, 라이프 사이클 이벤트들을 받아낸다. 그런데, 이 스레드에 너무 많은 작업들이 할당이 된다면, 앱은 느려지고 멈춰보이게 된다. 실행 시간이 긴 작업들, 비트맵을 디코딩하거나, 디스크에 접슨하거나 네트워크 요청을 처리하는 작업들은 별도의 백그라운 스레드에서 처리되어야 한다. 보통은, 밀리세컨즈 이상 이상으로 걸리는 작업들은 백그라운드 스레드에 맡겨야 한다. 이러한 작업들은 사용자가 활발하게 앱과 상호작용을 할 때 처리되어져야만 한다. 백그라운드로 해당 작업들은 돌리고 메인 UI 스레드로부터 빼내기 위해서는, 일단 threading solution guide를 먼저 보도록 하자.
  • 사용자가 앱을 활발하게 사용하는 상태가 아닐 지라도 특정 작업들을 백그라운드로 돌려야할 때가 있다. 가령, 서버와 동기를 맞추거나, 특정 주기로 새로운 컨텐츠를 받아야하는 경우이다. 사용자가 앱을 사용하기를 멈춘 시점에 즉각적으로 완료해야할 때도 있다. 등등  여러 가지 경우가 있다.
Background tasks consume a device's limited resources, like RAM and battery. This may result in a poor experience for the user if not handled correctly.

In order to maximize battery and enforce good app behavior, Android restricts background work when the app (or a foreground service notification) is not visible to the user.

- Android 6.0 (API level 23) introduced Doze mode and app standby. Doze mode restricts app behavior when the screen is off and the device is stationary. App standby puts unused applications into a special state that restricts their network access, jobs, and syncs.
- Android 7.0 (API level 24) limited implicit broadcasts and introduced Doze-on-the-Go.
- Android 8.0 (API level 26) further limited background behavior, such as getting location in the background and releasing cached wakelocks.
- Android 9 (API level 28) introduced App Standby Buckets, in which app requests for resources are dynamically prioritized based on app usage patterns.

It is important to understand your task needs and choose the right solution adhering to system best practices in scheduling your background job.

  • 백그라운드 서비스는 램이나 배터리와 같은 한정된 리소스들을 잡아먹는다. 그래서 정확히 관리되지 못 한다면 사용자에게 불편한 경험들을 주게 된다.
  • 이상적으로 앱이 동작을 하려면, 안드로이드는 앱이 사용자에게 보여지는 상태가 아니라면 백그라운 서비스를 제한해야한다.
  • < 기기별 백그라운 서비스 제한 법  소개 >
  • 작업의 성격에 따라서, 백그라운드 스케쥴링을 통하여 적절한 솔루션을 선택해야한다. 
Can the work be deferred, or does it need to happen right away? For example, if you need to fetch some data from the network in response to the user clicking a button, that work must be done right away. However, if you want to upload your logs to the server, that work can be deferred without affecting your app’s performance or user expectations.

Is the work dependent on system conditions? You might want your job to run only when the device meets certain conditions, such as being connected to power, having internet connectivity, and so on. For example, your app might periodically need to compress its stored data. To avoid affecting the user, you would want this job to happen only when the device is charging and idle.

Does the job need to run at a precise time? A calendar app might let a user set up a reminder for an event at a specific time. The user expects to see the reminder notification at the correct time. In other cases, the app may not care precisely when the job runs. The app might have general requirements—like, "Job A must run first, then Job B, then Job C"—but it doesn't require jobs to run at a specific time.
  • 작업이 연기 가능한 지 (deferred), 아니면 바로 수행되야 하는지(right-away)? 예를 들어, 버튼 한번 클릭을 했을 때 네트워크로부터 어떤 데이터를 받아와야 한다면 right-away에 해당할 것인데. 반면에, 앱 로그를 서버에 올려야하는 경우라면, 사용자의 기대나 앱의 성능에 영향을 주는 것이 없어, 미뤄도 될 문제가 된다.
  • 작업이 시스템의 상태에 연관된 문제인가?(dependency on System condition) 전원이 연결되었을 때/인터넷에 연결된 상태와 같을 때 어떤 작업이 이뤄지지길 바란다고 치자. 그랬을 때, 앱은 주기적으로 저장된 데이터를 압축할 필요가 있을 거다. 사용자에게 이러한 영향을 주지 않으려면, 앱이 충전 중이거나 아무런 작업을 하지 않을 때 해당 작업이 일어나면 된다.
  • 작업이 정확한 시간에 실행되어야하나?(right time) 달력 앱과 같은 경우, 정확한 시간에 사용자에게 무언가를 알려준다. 사용자는 올바른 시간에 달력앱이 알림을 주기를 기대를 한다. 정반대로, 작업이 수행되더라도 앱이 정확한 시간에 실행될 필요가 없는 경우이고, 아주 일반적인 요구사항을 따를 때다. 예를 들어, A 다음에 B, C를 순서대로 실행을 해라.

Figure 1. What's the best way to do background work?

 

2. 그래서?

(1) 알아둬야할 사실

  • 위 Condition flow
  • Doze-mode/Stanby 등과 같은 Android API 별 특징