Processe and Lifecycle

안드로이드 | 2011.03.15 13:01
Posted by 하드락

[ Processe and Lifecycle ]

The Android system tries to maintain an application process for as long as possible, but eventually needs to remove old processes to reclaim memory for new or more important processes. To determine which processes to keep and which to kill, the system places each process into an "importance hierarchy" based on the components running in the process and the state of those components. Processes with the lowest importance are eliminated first, then those with the next lowest importance, and so on, as necessary to recover system resources.

There are five levels in the importance hierarchy. The following list presents the different types of processes in order of importance (the first process is most important and is killed last):

1. Foreground process

A process that is required for what the user is currently doing. A process is considered to be in the foreground if any of the following conditions are true:

● It hosts an Activity that the user is interacting with (the Activity's onResume() method has been called).

● It hosts a Service that's bound to the activity that the user is interacting with.
● It hosts a Service that's running "in the foreground"—the service has called startForeground().
● It hosts a Service that's executing one of its lifecycle callbacks (onCreate(), onStart(), or onDestroy()).
● It hosts a BroadcastReceiver that's executing its onReceive() method.

Generally, only a few foreground processes exist at any given time. They are killed only as a last resort—if memory is so low that they cannot all continue to run. Generally, at that point, the device has reached a memory paging state, so killing some foreground processes is required to keep the user interface responsive.

2. Visible process

A process that doesn't have any foreground components, but still can affect what the user sees on screen. A process is considered to be visible if either of the following conditions are true:

● It hosts an Activity that is not in the foreground, but is still visible to the user (its onPause() method has been called). This might occur, for example, if the foreground activity started a dialog, which allows the previous activity to be seen behind it.

● It hosts a Service that's bound to a visible (or foreground) activity.

A visible process is considered extremely important and will not be killed unless doing so is required to keep all foreground processes running.

3. Service process

A process that is running a service that has been started with the startService() method and does not fall into either of the two higher categories. Although service processes are not directly tied to anything the user sees, they are generally doing things that the user cares about (such as playing music in the background or downloading data on the network), so the system keeps them running unless there's not enough memory to retain them along with all foreground and visible processes.

4. Background process

A process holding an activity that's not currently visible to the user (the activity's onStop() method has been called). These processes have no direct impact on the user experience, and the system can kill them at any time to reclaim memory for a foreground, visible, or service process.

Usually there are many background processes running, so they are kept in an LRU (least recently used) list to ensure that the process with the activity that was most recently seen by the user is the last to be killed. If an activity implements its lifecycle methods correctly, and saves its current state, killing its process will not have a visible effect on the user experience, because when the user navigates back to the activity, the activity restores all of its visible state. See the Activities document for information about saving and restoring state.

5. Empty process

A process that doesn't hold any active application components. The only reason to keep this kind of process alive is for caching purposes, to improve startup time the next time a component needs to run in it. The system often kills these processes in order to balance overall system resources between process caches and the underlying kernel caches.

[ conclusion ]

Android ranks a process at the highest level it can, based upon the importance of the components currently active in the process. For example, if a process hosts a service and a visible activity, the process is ranked as a visible process, not a service process.

In addition, a process's ranking might be increased because other processes are dependent on it—a process that is serving another process can never be ranked lower than the process it is serving. For example, if a content provider in process A is serving a client in process B, or if a service in process A is bound to a component in process B, process A is always considered at least as important as process B.

Because a process running a service is ranked higher than a process with background activities, an activity that initiates a long-running operation might do well to start a service for that operation, rather than simply create a worker thread—particularly if the operation will likely outlast the activity. For example, an activity that's uploading a picture to a web site should start a service to perform the upload so that the upload can continue in the background even if the user leaves the activity. Using a service guarantees that the operation will have at least "service process" priority, regardless of what happens to the activity. This is the same reason that broadcast receivers should employ services rather than simply put time-consuming operations in a thread.

안드로이드는 기본적으로 생성된 app. Process들을 가능한 유지할려고 한다.
하지만 역시 메모리 문제로 특정 process들은 제거되어야만 하는 상태가 온다.
디바이스의 메모리를 어느정도로 해야 가장 적절한가?
모바일 디바이스의 특성상 사용자가 app.을 동작시킬수 있는 개수 즉 process의 개수는 한정적일 수 있다.
어느정도 충분한 메모리는 시스템으로 하여금 process를 전혀 제거되지 않고도 동작하는데 전혀 문제가 없을 수도 있다.

기본적으로 사용자는 사용하는 app.만 사용하게 되므로.. 가끔 새로운 app.을 설치할 수도 있겠지만 제한적이지 않을까?
어쨌든 안드로이드는 어떤 process는 제거하고 살릴것인가를 판단해야 한다. 이 기준은 무엇인가?
안드로이드는 각 process를 일종의 "importance hierarchy"에 넣어놓고 관리한다.
그 기준은 각 component 종류와 각각의 상태가 된다.

다음과 같은 5 level의 hierarchy가 있다. 중요도에 따른 리스트는 다음과 같다.

1. Foreground process 

● Activity : 사용자와 Interact하고 있는 Activity. (onResume() 상태)

● Service : 사용자와 Interact하고 있는 Activity와 Bind 된 Service.
● Service : Foreground 상태로 동작 중인 Service. (startForeground() 메서드를 호출함)

● Service : onCreate(), onStart(), onDestroy() 중 하나의 상태를 실행하고 있는 동안
● BroadcastReceiver : onReceive()를 실행하고 있는 동안

2. Visible process

● Activity : Interact 하지는 않지만,
사용자가 화면에서 볼 수 있는 상태  (onPause() 상태)
● Service : Visible 또는 Foreground Activity와 Bind된 Service.

3. Service process

● 위에서 언급된 상태가 아닌 startService()를 통해 동작하고 있는 Service Process

● 사용자와 직접 Interat하고 있지는 않지만 무언가를 하고 있는 (mp3 재생, 네트웍을 통한 다운 등) 상태의 Service이므로 시스템 입장에서는 가능한 유지시켜야 하는 Process이다.

4. Background process

● Activity : 화면에 보여주지 않는 상태 (
onStop() 상태)

5. Empty process

● Active된 Application Component가 전혀 없는 Process.

● 일종의 Startup Time을 줄이기 위해 유지되는 경우가 있다.

안드로이드는 프로세스 내에 현재 활성화되어 있는 컴포넌트의 중요성에 기초해서, 가능한 한 가장 높은 등급에 프로세스를 위치 시킨다. 예를 들어 만약 프로세스가 하나의 서비스와 하나의 비저블 액티비티를 보유하고 있다면, 그 프로세스는 서비스 프로세스가 아니라 비저블 프로세스로 위치 시킬 것이다.

서비스를 실행하는 프로세스가 백그라운드 액티비티를 보유하고 있는 프로세스보다 더 높은 등급을 보유하기 때문에, 오랜시간 동안 실행되는 오퍼레이션은 간단하게 쓰레드를 생성하는 것보다 해당 오퍼레이션을 위한 서비스를 시작하는 것이 더 좋을 수 있다. 이런 예제들에는, 백그라운드로 음악을 재생하는 것과 카메라로 찍은 사진을 웹 사이트로 업로드하는 것이 있다. 서비스를 사용하는 것은 액티비티에서 일어나는 것과 상관없이 그 오퍼레이션에 최소한 “서비스 프로세스” 우선순위를 보증할 것이다. 앞의 “브로드캐스트 리시버 생명주기” 섹션에서 언급했듯이, 이것이 바로 시간이 걸리는 오퍼레이션을 쓰레드로 구현하기보다는 오히려 서비스를 사용해서 구현해야 하는 같은 이유이다.

[ Activity ]

Process Lifecycle

The Android system attempts to keep application process around for as long as possible, but eventually will need to remove old processes when memory runs low. As described in Activity Lifecycle, the decision about which process to remove is intimately tied to the state of the user's interaction with it. In general, there are four states a process can be in based on the activities running in it, listed here in order of importance. The system will kill less important processes (the last ones) before it resorts to killing more important processes (the first ones).

1. The foreground activity (the activity at the top of the screen that the user is currently interacting with) is considered the most important. Its process will only be killed as a last resort, if it uses more memory than is available on the device. Generally at this point the device has reached a memory paging state, so this is required in order to keep the user interface responsive.

2. A visible activity (an activity that is visible to the user but not in the foreground, such as one sitting behind a foreground dialog) is considered extremely important and will not be killed unless that is required to keep the foreground activity running.

3. A background activity (an activity that is not visible to the user and has been paused) is no longer critical, so the system may safely kill its process to reclaim memory for other foreground or visible processes. If its process needs to be killed, when the user navigates back to the activity (making it visible on the screen again), its onCreate(Bundle) method will be called with the savedInstanceState it had previously supplied in onSaveInstanceState(Bundle) so that it can restart itself in the same state as the user last left it.

4. An empty process is one hosting no activities or other application components (such as Service or BroadcastReceiver classes). These are killed very quickly by the system as memory becomes low. For this reason, any background operation you do outside of an activity must be executed in the context of an activity BroadcastReceiver or Service to ensure that the system knows it needs to keep your process around.

Sometimes an Activity may need to do a long-running operation that exists independently of the activity lifecycle itself. An example may be a camera application that allows you to upload a picture to a web site. The upload may take a long time, and the application should allow the user to leave the application will it is executing. To accomplish this, your Activity should start a Service in which the upload takes place. This allows the system to properly prioritize your process (considering it to be more important than other non-visible applications) for the duration of the upload, independent of whether the original activity is paused, stopped, or finished.

[ Service ]

Process Lifecycle

The Android system will attempt to keep the process hosting a service around as long as the service has been started or has clients bound to it. When running low on memory and needing to kill existing processes, the priority of a process hosting the service will be the higher of the following possibilities:

● If the service is currently executing code in its onCreate(), onStartCommand(), or onDestroy() methods, then the hosting process will be a foreground process to ensure this code can execute without being killed.

If the service has been started, then its hosting process is considered to be less important than any processes that are currently visible to the user on-screen, but more important than any process not visible. Because only a few processes are generally visible to the user, this means that the service should not be killed except in extreme low memory conditions.

● If there are clients bound to the service, then the service's hosting process is never less important than the most important client. That is, if one of its clients is visible to the user, then the service itself is considered to be visible.

● A started service can use the startForeground(int, Notification) API to put the service in a foreground state, where the system considers it to be something the user is actively aware of and thus not a candidate for killing when low on memory. (It is still theoretically possible for the service to be killed under extreme memory pressure from the current foreground application, but in practice this should not be a concern.)

Note this means that most of the time your service is running, it may be killed by the system if it is under heavy memory pressure. If this happens, the system will later try to restart the service. An important consequence of this is that if you implement onStartCommand() to schedule work to be done asynchronously or in another thread, then you may want to use START_FLAG_REDELIVERY to have the system re-deliver an Intent for you so that it does not get lost if your service is killed while processing it.

Other application components running in the same process as the service (such as an Activity) can, of course, increase the importance of the overall process beyond just the importance of the service itself.

[ BroadcastReceiver ]

Receiver Lifecycle

A BroadcastReceiver object is only valid for the duration of the call to onReceive(Context, Intent). Once your code returns from this function, the system considers the object to be finished and no longer active.

This has important repercussions to what you can do in an onReceive(Context, Intent) implementation: anything that requires asynchronous operation is not available, because you will need to return from the function to handle the asynchronous operation, but at that point the BroadcastReceiver is no longer active and thus the system is free to kill its process before the asynchronous operation completes.

In particular, you may not show a dialog or bind to a service from within a BroadcastReceiver. For the former, you should instead use the NotificationManager API. For the latter, you can use Context.startService() to send a command to the service.

Process Lifecycle

A process that is currently executing a BroadcastReceiver (that is, currently running the code in its onReceive(Context, Intent) method) is considered to be a foreground process and will be kept running by the system except under cases of extreme memory pressure.

Once you return from onReceive(), the BroadcastReceiver is no longer active, and its hosting process is only as important as any other application components that are running in it. This is especially important because if that process was only hosting the BroadcastReceiver (a common case for applications that the user has never or not recently interacted with), then upon returning from onReceive() the system will consider its process to be empty and aggressively kill it so that resources are available for other more important processes.

This means that for longer-running operations you will often use a Service in conjunction with a BroadcastReceiver to keep the containing process active for the entire time of your operation.

[ AppWidget ]

Because AppWidgetProvider is an extension of BroadcastReceiver, your process is not guaranteed to keep running after the callback methods return (see BroadcastReceiver for information about the broadcast lifecycle). If your App Widget setup process can take several seconds (perhaps while performing web requests) and you require that your process continues, consider starting a Service in the onUpdated() method. From within the Service, you can perform your own updates to the App Widget without worrying about the AppWidgetProvider closing down due to an Application Not Responding (ANR) error. See the Wiktionary sample's AppWidgetProvider for an example of an App Widget running a Service.

'안드로이드' 카테고리의 다른 글

Processe and Lifecycle  (0) 2011.03.15
안드로이드 2.0 Service API 의 변화  (0) 2011.03.11
안드로이드 프로그래밍 추천 교재  (1) 2011.02.16
뷰 (View) & 레이아웃 (Layout)  (0) 2010.10.07
액티비티(Activity)  (0) 2010.10.07
android.Manifest.permission  (0) 2010.10.07

댓글을 달아 주세요

블로그 이미지


I ♡ Android !!!


분류 전체보기 (14)
안드로이드 (13)
Google Play (1)
안드로이드 팁 (0)
참고자료 (0)