28
Application Fundamentals: Android applications are written in the Java programming language. The compiled Java code — along with any data and resource files required by the application — is bundled by the aapt tool into an Android package, an archive file marked by an .apk suffix. This file is the vehicle for distributing the application and installing it on mobile devices; it's the file users download to their devices. All the code in a single .apk file is considered to be one application. In many ways, each Android application lives in its own world: By default, every application runs in its own Linux process. Android starts the process when any of the application's code needs to be executed, and shuts down the process when it's no longer needed and system resources are required by other applications. Each process has its own virtual machine (VM), so application code runs in isolation from the code of all other applications. By default, each application is assigned a unique Linux user ID. Permissions are set so that the application's files are visible only to that user and only to the application itself — although there are ways to export them to other applications as well. It's possible to arrange for two applications to share the same user ID, in which case they will be able to see each other's files. To conserve system resources, applications with the same ID can also arrange to run in the same Linux process, sharing the same VM. Application Components A central feature of Android is that one application can make use of elements of other applications (provided those applications permit it). For example, if your application needs to display a scrolling list of images and another application has developed a suitable scroller and made it available to others, you can call upon that scroller to do the work, rather than develop your own. Your application doesn't incorporate the code of the other application or link to it. Rather, it simply starts up that piece of the other application when the need arises. For this to work, the system must be able to start an application process when any part of it is needed, and instantiate the Java objects for that part. Therefore, unlike applications on most other systems, Android applications don't have a single entry point for everything in the application (no main() function, for example). Rather, they have essential components that the system can instantiate and run as needed. There are four types of components: Activities An activity presents a visual user interface for one focused endeavor the user can undertake. For example, an activity might present a list of menu items users can choose from or it might display photographs along with their captions. A text messaging application might have one activity that shows a list of contacts to send messages to, a second activity to write the message to the chosen contact, and other activities to review old messages or change settings. Though they work together to form a cohesive user interface, each activity is independent of the others. Each one is implemented as a subclass of the Activity base class.

Android Theory

Embed Size (px)

Citation preview

Page 1: Android Theory

Application Fundamentals:

Android applications are written in the Java programming language. The compiled Java code —

along with any data and resource files required by the application — is bundled by the aapt tool

into an Android package, an archive file marked by an .apk suffix. This file is the vehicle for

distributing the application and installing it on mobile devices; it's the file users download to

their devices. All the code in a single .apk file is considered to be one application.

In many ways, each Android application lives in its own world:

• By default, every application runs in its own Linux process. Android starts the process when

any of the application's code needs to be executed, and shuts down the process when it's no

longer needed and system resources are required by other applications.

• Each process has its own virtual machine (VM), so application code runs in isolation from the

code of all other applications.

• By default, each application is assigned a unique Linux user ID. Permissions are set so that the

application's files are visible only to that user and only to the application itself — although there

are ways to export them to other applications as well.

It's possible to arrange for two applications to share the same user ID, in which case they will be able to

see each other's files. To conserve system resources, applications with the same ID can also arrange to

run in the same Linux process, sharing the same VM.

Application Components

A central feature of Android is that one application can make use of elements of other applications

(provided those applications permit it). For example, if your application needs to display a scrolling list

of images and another application has developed a suitable scroller and made it available to others, you

can call upon that scroller to do the work, rather than develop your own. Your application doesn't

incorporate the code of the other application or link to it. Rather, it simply starts up that piece of the

other application when the need arises.

For this to work, the system must be able to start an application process when any part of it is needed,

and instantiate the Java objects for that part. Therefore, unlike applications on most other systems,

Android applications don't have a single entry point for everything in the application (no main()

function, for example). Rather, they have essential components that the system can instantiate and run

as needed. There are four types of components:

Activities An activity presents a visual user interface for one focused endeavor the user can undertake. For

example, an activity might present a list of menu items users can choose from or it might display

photographs along with their captions. A text messaging application might have one activity that

shows a list of contacts to send messages to, a second activity to write the message to the chosen

contact, and other activities to review old messages or change settings. Though they work

together to form a cohesive user interface, each activity is independent of the others. Each one is

implemented as a subclass of the Activity base class.

Page 2: Android Theory

An application might consist of just one activity or, like the text messaging application just

mentioned, it may contain several. What the activities are, and how many there are depends, of

course, on the application and its design. Typically, one of the activities is marked as the first one

that should be presented to the user when the application is launched. Moving from one activity

to another is accomplished by having the current activity start the next one.

Each activity is given a default window to draw in. Typically, the window fills the screen, but it

might be smaller than the screen and float on top of other windows. An activity can also make

use of additional windows — for example, a pop-up dialog that calls for a user response in the

midst of the activity, or a window that presents users with vital information when they select a

particular item on-screen.

The visual content of the window is provided by a hierarchy of views — objects derived from the

base View class. Each view controls a particular rectangular space within the window. Parent

views contain and organize the layout of their children. Leaf views (those at the bottom of the

hierarchy) draw in the rectangles they control and respond to user actions directed at that space.

Thus, views are where the activity's interaction with the user takes place. For example, a view

might display a small image and initiate an action when the user taps that image. Android has a

number of ready-made views that you can use — including buttons, text fields, scroll bars, menu

items, check boxes, and more.

A view hierarchy is placed within an activity's window by the Activity.setContentView() method.

The content view is the View object at the root of the hierarchy. (See the separate User Interface

document for more information on views and the hierarchy.)

Services A service doesn't have a visual user interface, but rather runs in the background for an indefinite

period of time. For example, a service might play background music as the user attends to other

matters, or it might fetch data over the network or calculate something and provide the result to

activities that need it. Each service extends the Service base class.

A prime example is a media player playing songs from a play list. The player application would

probably have one or more activities that allow the user to choose songs and start playing them.

However, the music playback itself would not be handled by an activity because users will expect

the music to keep playing even after they leave the player and begin something different. To keep

the music going, the media player activity could start a service to run in the background. The

system would then keep the music playback service running even after the activity that started it

leaves the screen.

It's possible to connect to (bind to) an ongoing service (and start the service if it's not already

running). While connected, you can communicate with the service through an interface that the

service exposes. For the music service, this interface might allow users to pause, rewind, stop,

and restart the playback.

Like activities and the other components, services run in the main thread of the application

process. So that they won't block other components or the user interface, they often spawn

another thread for time-consuming tasks (like music playback). See Processes and Threads, later.

Page 3: Android Theory

Broadcast receivers A broadcast receiver is a component that does nothing but receive and react to broadcast

announcements. Many broadcasts originate in system code — for example, announcements that

the timezone has changed, that the battery is low, that a picture has been taken, or that the user

changed a language preference. Applications can also initiate broadcasts — for example, to let

other applications know that some data has been downloaded to the device and is available for

them to use.

An application can have any number of broadcast receivers to respond to any announcements it

considers important. All receivers extend the BroadcastReceiver base class.

Broadcast receivers do not display a user interface. However, they may start an activity in

response to the information they receive, or they may use the NotificationManager to alert the

user. Notifications can get the user's attention in various ways — flashing the backlight, vibrating

the device, playing a sound, and so on. They typically place a persistent icon in the status bar,

which users can open to get the message.

Content providers A content provider makes a specific set of the application's data available to other applications.

The data can be stored in the file system, in an SQLite database, or in any other manner that

makes sense. The content provider extends the ContentProvider base class to implement a

standard set of methods that enable other applications to retrieve and store data of the type it

controls. However, applications do not call these methods directly. Rather they use a

ContentResolver object and call its methods instead. A ContentResolver can talk to any content

provider; it cooperates with the provider to manage any interprocess communication that's

involved.

See the separate Content Providers document for more information on using content providers.

Whenever there's a request that should be handled by a particular component, Android makes sure that

the application process of the component is running, starting it if necessary, and that an appropriate

instance of the component is available, creating the instance if necessary.

Activating components: intents

Content providers are activated when they're targeted by a request from a ContentResolver. The other

three components — activities, services, and broadcast receivers — are activated by asynchronous

messages called intents. An intent is an Intent object that holds the content of the message. For

activities and services, it names the action being requested and specifies the URI of the data to act on,

among other things. For example, it might convey a request for an activity to present an image to the

user or let the user edit some text. For broadcast receivers, the Intent object names the action being

announced. For example, it might announce to interested parties that the camera button has been

pressed.

There are separate methods for activating each type of component:

• An activity is launched (or given something new to do) by passing an Intent object to

Page 4: Android Theory

Context.startActivity() or Activity.startActivityForResult(). The responding activity can look at

the initial intent that caused it to be launched by calling its getIntent() method. Android calls the

activity's onNewIntent() method to pass it any subsequent intents.

One activity often starts the next one. If it expects a result back from the activity it's starting, it

calls startActivityForResult() instead of startActivity(). For example, if it

starts an activity that lets the user pick a photo, it might expect to be returned the chosen photo.

The result is returned in an Intent object that's passed to the calling activity's onActivityResult()

method.

• A service is started (or new instructions are given to an ongoing service) by passing an Intent

object to Context.startService(). Android calls the service's onStart() method and passes it the

Intent object.

Similarly, an intent can be passed to Context.bindService() to establish an ongoing connection

between the calling component and a target service. The service receives the Intent object in an

onBind() call. (If the service is not already running, bindService() can optionally start it.)

For example, an activity might establish a connection with the music playback service

mentioned earlier so that it can provide the user with the means (a user interface) for controlling

the playback. The activity would call bindService() to set up that connection, and then call

methods defined by the service to affect the playback.

A later section, Remote procedure calls, has more details about binding to a service.

• An application can initiate a broadcast by passing an Intent object to methods like

Context.sendBroadcast(), Context.sendOrderedBroadcast(), and Context.sendStickyBroadcast()

in any of their variations. Android delivers the intent to all interested broadcast receivers by

calling their onReceive() methods.

For more on intent messages, see the separate article, Intents and Intent Filters.

Shutting down components

A content provider is active only while it's responding to a request from a ContentResolver. And a

broadcast receiver is active only while it's responding to a broadcast message. So there's no need to

explicitly shut down these components.

Activities, on the other hand, provide the user interface. They're in a long-running conversation with

the user and may remain active, even when idle, as long as the conversation continues. Similarly,

services may also remain running for a long time. So Android has methods to shut down activities and

services in an orderly way:

• An activity can be shut down by calling its finish() method. One activity can shut down another

activity (one it started with startActivityForResult()) by calling finishActivity().

• A service can be stopped by calling its stopSelf() method, or by calling Context.stopService().

Components might also be shut down by the system when they are no longer being used or when

Page 5: Android Theory

Android must reclaim memory for more active components. A later section, Component Lifecycles,

discusses this possibility and its ramifications in more detail.

The manifest file

Before Android can start an application component, it must learn that the component exists. Therefore,

applications declare their components in a manifest file that's bundled into the Android package, the

.apk file that also holds the application's code, files, and resources.

The manifest is a structured XML file and is always named AndroidManifest.xml for all applications. It

does a number of things in addition to declaring the application's components, such as naming any

libraries the application needs to be linked against (besides the default Android library) and identifying

any permissions the application expects to be granted.

The name attribute of the <activity> element names the Activity subclass that implements the activity.

The icon and label attributes point to resource files containing an icon and label that can be

displayed to users to represent the activity.

The other components are declared in a similar way — <service> elements for services, <receiver>

elements for broadcast receivers, and <provider> elements for content providers. Activities, services,

and content providers that are not declared in the manifest are not visible to the system and are

consequently never run. However, broadcast receivers can either be declared in the manifest, or they

can be created dynamically in code (as BroadcastReceiver objects) and registered with the system by

calling Context.registerReceiver().

For more on how to structure a manifest file for your application, see The AndroidManifest.xml File.

Intent filters

An Intent object can explicitly name a target component. If it does, Android finds that component

(based on the declarations in the manifest file) and activates it. But if a target is not explicitly named,

Android must locate the best component to respond to the intent. It does so by comparing the Intent

object to the intent filters of potential targets. A component's intent filters inform Android of the kinds

of intents the component is able to handle. Like other essential information about the component,

they're declared in the manifest file. Here's an extension of the previous example that adds two intent

filters to the activity:

The first filter in the example — the combination of the action

"android.intent.action.MAIN" and the category

"android.intent.category.LAUNCHER" — is a common one. It marks the activity as one that

should be represented in the application launcher, the screen listing applications users can launch on the

device. In other words, the activity is the entry point for the application, the initial one users would see

when they choose the application in the launcher.

The second filter declares an action that the activity can perform on a particular type of data.

Page 6: Android Theory

A component can have any number of intent filters, each one declaring a different set of capabilities. If

it doesn't have any filters, it can be activated only by intents that explicitly name the component as the

target.

For a broadcast receiver that's created and registered in code, the intent filter is instantiated directly as

an IntentFilter object. All other filters are set up in the manifest.

For more on intent filters, see a separate document, Intents and Intent Filters.

Activities and Tasks

As noted earlier, one activity can start another, including one defined in a different application.

Suppose, for example, that you'd like to let users display a street map of some location. There's already

an activity that can do that, so all your activity needs to do is put together an Intent object with the

required information and pass it to startActivity(). The map viewer will display the map. When

the user hits the BACK key, your activity will reappear on screen.

To the user, it will seem as if the map viewer is part of the same application as your activity, even

though it's defined in another application and runs in that application's process. Android maintains this

user experience by keeping both activities in the same task. Simply put, a task is what the user

experiences as an "application." It's a group of related activities, arranged in a stack. The root activity

in the stack is the one that began the task — typically, it's an activity the user selected in the application

launcher. The activity at the top of the stack is one that's currently running — the one that is the focus

for user actions. When one activity starts another, the new activity is pushed on the stack; it becomes

the running activity. The previous activity remains in the stack. When the user presses the BACK key,

the current activity is popped from the stack, and the previous one resumes as the running activity.

The stack contains objects, so if a task has more than one instance of the same Activity subclass open

— multiple map viewers, for example — the stack has a separate entry for each instance. Activities in

the stack are never rearranged, only pushed and popped.

A task is a stack of activities, not a class or an element in the manifest file. So there's no way to set

values for a task independently of its activities. Values for the task as a whole are set in the root

activity. For example, the next section will talk about the "affinity of a task"; that value is read from the

affinity set for the task's root activity.

All the activities in a task move together as a unit. The entire task (the entire activity stack) can be

brought to the foreground or sent to the background. Suppose, for instance, that the current task has

four activities in its stack — three under the current activity. The user presses the HOME key, goes to

the application launcher, and selects a new application (actually, a new task). The current task goes into

the background and the root activity for the new task is displayed. Then, after a short period, the user

goes back to the home screen and again selects the previous application (the previous task). That task,

with all four activities in the stack, comes forward. When the user presses the BACK key, the screen

does not display the activity the user just left (the root activity of the previous task). Rather, the activity

on the top of the stack is removed and the previous activity in the same task is displayed.

The behavior just described is the default behavior for activities and tasks. But there are ways to

Page 7: Android Theory

modify almost all aspects of it. The association of activities with tasks, and the behavior of an activity

within a task, is controlled by the interaction between flags set in the Intent object that started the

activity and attributes set in the activity's <activity> element in the manifest. Both requester and

respondent have a say in what happens.

In this regard, the principal Intent flags are:

FLAG_ACTIVITY_NEW_TASK

FLAG_ACTIVITY_CLEAR_TOP FLAG_ACTIVITY_RESET_TASK_IF_NEEDED FLAG_ACTIVITY_SINGLE_TOP

The principal <activity> attributes are:

taskAffinity launchMode allowTaskReparenting clearTaskOnLaunch

alwaysRetainTaskState finishOnTaskLaunch

The following sections describe what some of these flags and attributes do, how they interact, and what

considerations should govern their use.

Affinities and new tasks

By default, all the activities in an application have an affinity for each other — that is, there's a

preference for them all to belong to the same task. However, an individual affinity can be set for each

activity with the taskAffinity attribute of the <activity> element. Activities defined in

different applications can share an affinity, or activities defined in the same application can be assigned

different affinities. The affinity comes into play in two circumstances: When the Intent object that

launches an activity contains the FLAG_ACTIVITY_NEW_TASK flag, and when an activity has its

allowTaskReparenting attribute set to "true".

The FLAG_ACTIVITY_NEW_TASK flag

As described earlier, a new activity is, by default, launched into the task of the activity that called

startActivity(). It's pushed onto the same stack as the caller. However, if the Intent object

passed to startActivity() contains the FLAG_ACTIVITY_NEW_TASK flag, the system

looks for a different task to house the new activity. Often, as the name of the flag implies, it's a

new task. However, it doesn't have to be. If there's already an existing task with the same affinity

as the new activity, the activity is launched into that task. If not, it begins a new task.

The allowTaskReparenting attribute

If an activity has its allowTaskReparenting attribute set to "true", it can move from the

task it starts in to the task it has an affinity for when that task comes to the fore. For example,

suppose that an activity that reports weather conditions in selected cities is defined as part of a

travel application. It has the same affinity as other activities in the same application (the default

affinity) and it allows reparenting. One of your activities starts the weather reporter, so it initially

Page 8: Android Theory

belongs to the same task as your activity. However, when the travel application next comes

forward, the weather reporter will be reassigned to and displayed with that task.

If an .apk file contains more than one "application" from the user's point of view, you will probably

want to assign different affinities to the activities associated with each of them.

Launch modes

There are four different launch modes that can be assigned to an <activity> element's launchMode

attribute:

"standard" (the default mode)

"singleTop"

"singleTask"

"singleInstance"

The modes differ from each other on these four points:

• Which task will hold the activity that responds to the intent. For the "standard" and

"singleTop" modes, it's the task that originated the intent (and called startActivity()) —

unless the Intent object contains the FLAG_ACTIVITY_NEW_TASK flag. In that case, a

different task is chosen as described in the previous section, Affinities and new tasks.

In contrast, the "singleTask" and "singleInstance" modes mark activities that are

always at the root of a task. They define a task; they're never launched into another task.

• Whether there can be multiple instances of the activity. A "standard" or "singleTop"

activity can be instantiated many times. They can belong to multiple tasks, and a given task can

have multiple instances of the same activity.

In contrast, "singleTask" and "singleInstance" activities are limited to just one

instance. Since these activities are at the root of a task, this limitation means that there is never

more than a single instance of the task on the device at one time.

• Whether the instance can have other activities in its task. A "singleInstance" activity

stands alone as the only activity in its task. If it starts another activity, that activity will be

launched into a different task regardless of its launch mode — as if

FLAG_ACTIVITY_NEW_TASK was in the intent. In all other respects, the

"singleInstance" mode is identical to "singleTask".

The other three modes permit multiple activities to belong to the task. A "singleTask"

activity will always be the root activity of the task, but it can start other activities that will be

assigned to its task. Instances of "standard" and "singleTop" activities can appear

anywhere in a stack.

• Whether a new instance of the class will be launched to handle a new intent. For the default

Page 9: Android Theory

"standard" mode, a new instance is created to respond to every new intent. Each instance

handles just one intent. For the "singleTop" mode, an existing instance of the class is re-used

to handle a new intent if it resides at the top of the activity stack of the target task. If it does not

reside at the top, it is not re-used. Instead, a new instance is created for the new intent and

pushed on the stack.

For example, suppose a task's activity stack consists of root activity A with activities B, C, and

D on top in that order, so the stack is A-B-C-D. An intent arrives for an activity of type D. If D

has the default "standard" launch mode, a new instance of the class is launched and the stack

becomes A-B-C-D-D. However, if D's launch mode is "singleTop", the existing instance is

expected to handle the new intent (since it's at the top of the stack) and the stack remains A-B-

C-D.

If, on the other hand, the arriving intent is for an activity of type B, a new instance of B would

be launched no matter whether B's mode is "standard" or "singleTop" (since B is not at

the top of the stack), so the resulting stack would be A-B-C-D-B.

As noted above, there's never more than one instance of a "singleTask" or

"singleInstance" activity, so that instance is expected to handle all new intents. A

"singleInstance" activity is always at the top of the stack (since it is the only activity in

the task), so it is always in position to handle the intent. However, a "singleTask" activity

may or may not have other activities above it in the stack. If it does, it is not in position to

handle the intent, and the intent is dropped. (Even though the intent is dropped, its arrival would

have caused the task to come to the foreground, where it would remain.)

When an existing activity is asked to handle a new intent, the Intent object is passed to the activity in

an onNewIntent() call. (The intent object that originally started the activity can be retrieved by calling

getIntent().)

Note that when a new instance of an Activity is created to handle a new intent, the user can always

press the BACK key to return to the previous state (to the previous activity). But when an existing

instance of an Activity handles a new intent, the user cannot press the BACK key to return to what that

instance was doing before the new intent arrived.

For more on launch modes, see the description of the <activity> element.

Clearing the stack

If the user leaves a task for a long time, the system clears the task of all activities except the root

activity. When the user returns to the task again, it's as the user left it, except that only the initial

activity is present. The idea is that, after a time, users will likely have abandoned what they were doing

before and are returning to the task to begin something new.

That's the default. There are some activity attributes that can be used to control this behavior and

modify it:

The alwaysRetainTaskState attribute

Page 10: Android Theory

If this attribute is set to "true" in the root activity of a task, the default behavior just described

does not happen. The task retains all activities in its stack even after a long period.

The clearTaskOnLaunch attribute

If this attribute is set to "true" in the root activity of a task, the stack is cleared down to the root

activity whenever the user leaves the task and returns to it. In other words, it's the polar opposite

of alwaysRetainTaskState. The user always returns to the task in its initial state, even

after a momentary absence.

The finishOnTaskLaunch attribute

This attribute is like clearTaskOnLaunch, but it operates on a single activity, not an entire

task. And it can cause any activity to go away, including the root activity. When it's set to

"true", the activity remains part of the task only for the current session. If the user leaves and

then returns to the task, it no longer is present.

There's another way to force activities to be removed from the stack. If an Intent object includes the

FLAG_ACTIVITY_CLEAR_TOP flag, and the target task already has an instance of the type of

activity that should handle the intent in its stack, all activities above that instance are cleared away so

that it stands at the top of the stack and can respond to the intent. If the launch mode of the designated

activity is "standard", it too will be removed from the stack, and a new instance will be launched to

handle the incoming intent. That's because a new instance is always created for a new intent when the

launch mode is "standard".

FLAG_ACTIVITY_CLEAR_TOP is most often used in conjunction with

FLAG_ACTIVITY_NEW_TASK. When used together, these flags are a way of locating an existing

activity in another task and putting it in a position where it can respond to the intent.

Starting tasks

An activity is set up as the entry point for a task by giving it an intent filter with

"android.intent.action.MAIN" as the specified action and

"android.intent.category.LAUNCHER" as the specified category. (There's an example of this

type of filter in the earlier Intent Filters section.) A filter of this kind causes an icon and label for the

activity to be displayed in the application launcher, giving users a way both to launch the task and to

return to it at any time after it has been launched.

This second ability is important: Users must be able to leave a task and then come back to it later. For

this reason, the two launch modes that mark activities as always initiating a task, "singleTask" and

"singleInstance", should be used only when the activity has a MAIN and LAUNCHER filter.

Imagine, for example, what could happen if the filter is missing: An intent launches a "singleTask"

activity, initiating a new task, and the user spends some time working in that task. The user then

presses the HOME key. The task is now ordered behind and obscured by the home screen. And,

because it is not represented in the application launcher, the user has no way to return to it.

A similar difficulty attends the FLAG_ACTIVITY_NEW_TASK flag. If this flag causes an activity to

begin a new task and the user presses the HOME key to leave it, there must be some way for the user to

navigate back to it again. Some entities (such as the notification manager) always start activities in an

external task, never as part of their own, so they always put FLAG_ACTIVITY_NEW_TASK in the

Page 11: Android Theory

intents they pass to startActivity(). If you have an activity that can be invoked by an external

entity that might use this flag, take care that the user has a independent way to get back to the task

that's started.

For those cases where you don't want the user to be able to return to an activity, set the <activity>

element's finishOnTaskLaunch to "true". See Clearing the stack, earlier.

Processes and Threads

When the first of an application's components needs to be run, Android starts a Linux process for it

with a single thread of execution. By default, all components of the application run in that process and

thread.

However, you can arrange for components to run in other processes, and you can spawn additional

threads for any process.

Processes

The process where a component runs is controlled by the manifest file. The component elements —

<activity>, <service>, <receiver>, and <provider> — each have a process attribute

that can specify a process where that component should run. These attributes can be set so that each

component runs in its own process, or so that some components share a process while others do not.

They can also be set so that components of different applications run in the same process — provided

that the applications share the same Linux user ID and are signed by the same authorities. The

<application> element also has a process attribute, for setting a default value that applies to all

components.

All components are instantiated in the main thread of the specified process, and system calls to the

component are dispatched from that thread. Separate threads are not created for each instance.

Consequently, methods that respond to those calls — methods like View.onKeyDown() that report user

actions and the lifecycle notifications discussed later in the Component Lifecycles section — always

run in the main thread of the process. This means that no component should perform long or blocking

operations (such as networking operations or computation loops) when called by the system, since this

will block any other components also in the process. You can spawn separate threads for long

operations, as discussed under Threads, next.

Android may decide to shut down a process at some point, when memory is low and required by other

processes that are more immediately serving the user. Application components running in the process

are consequently destroyed. A process is restarted for those components when there's again work for

them to do.

When deciding which processes to terminate, Android weighs their relative importance to the user. For

example, it more readily shuts down a process with activities that are no longer visible on screen than a

process with visible activities. The decision whether to terminate a process, therefore, depends on the

state of the components running in that process. Those states are the subject of a later section,

Component Lifecycles.

Page 12: Android Theory

Threads

Even though you may confine your application to a single process, there will likely be times when you

will need to spawn a thread to do some background work. Since the user interface must always be

quick to respond to user actions, the thread that hosts an activity should not also host time-consuming

operations like network downloads. Anything that may not be completed quickly should be assigned to

a different thread.

Threads are created in code using standard Java Thread objects. Android provides a number of

convenience classes for managing threads — Looper for running a message loop within a thread,

Handler for processing messages, and HandlerThread for setting up a thread with a message loop.

Remote procedure calls

Android has a lightweight mechanism for remote procedure calls (RPCs) — where a method is called

locally, but executed remotely (in another process), with any result returned back to the caller. This

entails decomposing the method call and all its attendant data to a level the operating system can

understand, transmitting it from the local process and address space to the remote process and address

space, and reassembling and reenacting the call there. Return values have to be transmitted in the

opposite direction. Android provides all the code to do that work, so that you can concentrate on

defining and implementing the RPC interface itself.

An RPC interface can include only methods. By default, all methods are executed synchronously (the

local method blocks until the remote method finishes), even if there is no return value.

In brief, the mechanism works as follows: You'd begin by declaring the RPC interface you want to

implement using a simple IDL (interface definition language). From that declaration, the aidl tool

generates a Java interface definition that must be made available to both the local and the remote

process. It contains two inner class, as shown in the following diagram:

Page 13: Android Theory

The inner classes have all the code needed to administer remote procedure calls for the interface you

declared with the IDL. Both inner classes implement the IBinder interface. One of them is used locally

and internally by the system; the code you write can ignore it. The other, called Stub, extends the

Binder class. In addition to internal code for effectuating the IPC calls, it contains declarations for the

methods in the RPC interface you declared. You would subclass Stub to implement those methods, as

indicated in the diagram.

Typically, the remote process would be managed by a service (because a service can inform the system

about the process and its connections to other processes). It would have both the interface file

generated by the aidl tool and the Stub subclass implementing the RPC methods. Clients of the

service would have only the interface file generated by the aidl tool.

Here's how a connection between a service and its clients is set up:

• Clients of the service (on the local side) would implement onServiceConnected() and

onServiceDisconnected() methods so they can be notified when a successful connection to the

remote service is established, and when it goes away. They would then call bindService() to set

up the connection.

• The service's onBind() method would be implemented to either accept or reject the connection,

depending on the intent it receives (the intent passed to bindService()). If the connection is

accepted, it returns an instance of the Stub subclass.

• If the service accepts the connection, Android calls the client's onServiceConnected()

method and passes it an IBinder object, a proxy for the Stub subclass managed by the service.

Through the proxy, the client can make calls on the remote service.

This brief description omits some details of the RPC mechanism. For more information, see Designing

a Remote Interface Using AIDL and the IBinder class description.

Thread-safe methods

In a few contexts, the methods you implement may be called from more than one thread, and therefore

must be written to be thread-safe.

This is primarily true for methods that can be called remotely — as in the RPC mechanism discussed in

the previous section. When a call on a method implemented in an IBinder object originates in the same

process as the IBinder, the method is executed in the caller's thread. However, when the call originates

in another process, the method is executed in a thread chosen from a pool of threads that Android

maintains in the same process as the IBinder; it's not executed in the main thread of the process. For

example, whereas a service's onBind() method would be called from the main thread of the service's

process, methods implemented in the object that onBind() returns (for example, a Stub subclass that

implements RPC methods) would be called from threads in the pool. Since services can have more than

one client, more than one pool thread can engage the same IBinder method at the same time. IBinder

methods must, therefore, be implemented to be thread-safe.

Similarly, a content provider can receive data requests that originate in other processes. Although the

Page 14: Android Theory

ContentResolver and ContentProvider classes hide the details of how the interprocess communication

is managed, ContentProvider methods that respond to those requests — the methods query(), insert(),

delete(), update(), and getType() — are called from a pool of threads in the content provider's process,

not the main thread of the process. Since these methods may be called from any number of threads at

the same time, they too must be implemented to be thread-safe.

Activity: An activity is a single, focused thing that the user can do. Almost all activities interact with

the user, so the Activity class takes care of creating a window for you in which you can place your UI

with setContentView(View). While activities are often presented to the user as

full-screen windows, they can also be used in other ways: as floating windows (via a theme with

windowIsFloating set) or embedded inside of another activity (using

ActivityGroup). There are two methods almost all subclasses of Activity will

implement:

• onCreate(Bundle) is where you initialize your activity. Most importantly, here you will usually

call setContentView(int) with a layout resource defining your UI, and using findViewById(int)

to retrieve the widgets in that UI that you need to interact with programmatically.

• onPause() is where you deal with the user leaving your activity. Most importantly, any changes

made by the user should at this point be committed (usually to the ContentProvider holding the

data).

To be of use with Context.startActivity(), all activity classes must have a corresponding <activity>

declaration in their package's AndroidManifest.xml.

The Activity class is an important part of an application's overall lifecycle, and the way activities are

launched and put together is a fundamental part of the platform's application model. For a detailed

perspective on the structure of Android applications and lifecycles, please read the Dev Guide

document on Application Fundamentals.

1. Activity Lifecycle

2. Configuration Changes

3. Starting Activities and Getting Results

4. Saving Persistent State

5. Permissions

6. Process Lifecycle

Activity Lifecycle

Activities in the system are managed as an activity stack. When a new activity is started, it is placed on

the top of the stack and becomes the running activity -- the previous activity always remains below it in

the stack, and will not come to the foreground again until the new activity exits.

Page 15: Android Theory

An activity has essentially four states:

• If an activity in the foreground of the screen (at the top of the stack), it is active or running.

• If an activity has lost focus but is still visible (that is, a new non-full-sized or transparent

activity has focus on top of your activity), it is paused. A paused activity is completely alive (it

maintains all state and member information and remains attached to the window manager), but

can be killed by the system in extreme low memory situations.

• If an activity is completely obscured by another activity, it is stopped. It still retains all state and

member information, however, it is no longer visible to the user so its window is hidden and it

will often be killed by the system when memory is needed elsewhere.

• If an activity is paused or stopped, the system can drop the activity from memory by either

asking it to finish, or simply killing its process. When it is displayed again to the user, it must be

completely restarted and restored to its previous state.

The following diagram shows the important state paths of an Activity. The square rectangles represent

callback methods you can implement to perform operations when the Activity moves between states.

The colored ovals are major states the Activity can be in.

Page 16: Android Theory

There are three key loops you may be interested in monitoring within your activity:

• The entire lifetime of an activity happens between the first call to onCreate(Bundle) through to

a single final call to onDestroy(). An activity will do all setup of "global" state in onCreate(),

and release all remaining resources in onDestroy(). For example, if it has a thread running in the

background to download data from the network, it may create that thread in onCreate() and then

stop the thread in onDestroy().

Page 17: Android Theory

• The visible lifetime of an activity happens between a call to onStart() until a corresponding call

to onStop(). During this time the user can see the activity on-screen, though it may not be in the

foreground and interacting with the user. Between these two methods you can maintain

resources that are needed to show the activity to the user. For example, you can register a

BroadcastReceiver in onStart() to monitor for changes that impact your UI, and unregister it in

onStop() when the user an no longer see what you are displaying. The onStart() and onStop()

methods can be called multiple times, as the activity becomes visible and hidden to the user.

• The foreground lifetime of an activity happens between a call to onResume() until a

corresponding call to onPause(). During this time the activity is in front of all other activities

and interacting with the user. An activity can frequently go between the resumed and paused

states -- for example when the device goes to sleep, when an activity result is delivered, when a

new intent is delivered -- so the code in these methods should be fairly lightweight.

The entire lifecycle of an activity is defined by the following Activity methods. All of these are hooks

that you can override to do appropriate work when the activity changes state. All activities will

implement onCreate(Bundle) to do their initial setup; many will also implement onPause() to commit

changes to data and otherwise prepare to stop interacting with the user. You should always call up to

your superclass when implementing these methods.

In general the movement through an activity's lifecycle looks like this:

Method Description Kill

able

next

onCreate() Called when the activity is first created. This is where you

should do all of your normal static set up: create views, bind

data to lists, etc. This method also provides you with a Bundle

containing the activity's previously frozen state, if there was

one.

Always followed by onStart().

No onStart()

onRestart() Called after your activity has been stopped, prior to it being

started again.

Always followed by onStart()

No onStart()

onStart() Called when the activity is becoming visible to the user.

Followed by onResume() if the activity comes to the

foreground, or onStop() if it becomes hidden.

No onResume()

or onStop()

onResume() Called when the activity will start interacting with the user. At

this point your activity is at the top of the activity stack, with

No onPause()

Page 18: Android Theory

user input going to it.

Always followed by onPause().

onPause() Called when the system is about to start resuming a previous

activity. This is typically used to commit unsaved changes to

persistent data, stop animations and other things that may be

consuming CPU, etc. Implementations of this method must be

very quick because the next activity will not be resumed until

this method returns.

Followed by either onResume() if the activity returns back

to the front, or onStop() if it becomes invisible to the user.

Yes onResume()

or onStop()

onStop() Called when the activity is no longer visible to the user,

because another activity has been resumed and is covering this

one. This may happen either because a new activity is being

started, an existing one is being brought in front of this one, or

this one is being destroyed.

Followed by either onRestart() if this activity is coming

back to interact with the user, or onDestroy() if this

activity is going away.

Yes onRestart(

) or

onDestroy()

onDestroy() The final call you receive before your activity is destroyed.

This can happen either because the activity is finishing

(someone called finish() on it, or because the system is

temporarily destroying this instance of the activity to save

space. You can distinguish between these two scenarios with

the isFinishing() method.

Yes Nothing

Note the "Killable" column in the above table -- for those methods that are marked as being killable,

after that method returns the process hosting the activity may killed by the system at any time without

another line of its code being executed. Because of this, you should use the onPause() method to write

any persistent data (such as user edits) to storage. In addition, the method onSaveInstanceState(Bundle)

is called before placing the activity in such a background state, allowing you to save away any dynamic

instance state in your activity into the given Bundle, to be later received in onCreate(Bundle) if the

activity needs to be re-created. See the Process Lifecycle section for more information on how the

lifecycle of a process is tied to the activities it is hosting. Note that it is important to save persistent data

in onPause() instead of onSaveInstanceState(Bundle) because the later is not part of the lifecycle

callbacks, so will not be called in every situation as described in its documentation.

For those methods that are not marked as being killable, the activity's process will not be killed by the

system starting from the time the method is called and continuing after it returns. Thus an activity is in

the killable state, for example, between after onPause() to the start of onResume().

Page 19: Android Theory

Configuration Changes

If the configuration of the device (as defined by the Resources.Configuration class) changes, then

anything displaying a user interface will need to update to match that configuration. Because Activity is

the primary mechanism for interacting with the user, it includes special support for handling

configuration changes.

Unless you specify otherwise, a configuration change (such as a change in screen orientation, language,

input devices, etc) will cause your current activity to be destroyed, going through the normal activity

lifecycle process of onPause(), onStop(), and onDestroy() as appropriate. If the activity had been in the

foreground or visible to the user, once onDestroy() is called in that instance then a new instance of the

activity will be created, with whatever savedInstanceState the previous instance had generated from

onSaveInstanceState(Bundle).

This is done because any application resource, including layout files, can change based on any

configuration value. Thus the only safe way to handle a configuration change is to re-retrieve all

resources, including layouts, drawables, and strings. Because activities must already know how to save

their state and re-create themselves from that state, this is a convenient way to have an activity restart

itself with a new configuration.

In some special cases, you may want to bypass restarting of your activity based on one or more types of

configuration changes. This is done with the android:configChanges attribute in its manifest. For any

types of configuration changes you say that you handle there, you will receive a call to your current

activity's onConfigurationChanged(Configuration) method instead of being restarted. If a configuration

change involves any that you do not handle, however, the activity will still be restarted and

onConfigurationChanged(Configuration) will not be called.

Starting Activities and Getting Results

The startActivity(Intent) method is used to start a new activity, which will be placed at the top of the

activity stack. It takes a single argument, an Intent, which describes the activity to be executed.

Sometimes you want to get a result back from an activity when it ends. For example, you may start an

activity that lets the user pick a person in a list of contacts; when it ends, it returns the person that was

selected. To do this, you call the startActivityForResult(Intent, int) version with a second integer

parameter identifying the call. The result will come back through your onActivityResult(int, int, Intent)

method.

When an activity exits, it can call setResult(int) to return data back to its parent. It must always supply

a result code, which can be the standard results RESULT_CANCELED, RESULT_OK, or any custom

values starting at RESULT_FIRST_USER. In addition, it can optionally return back an Intent

containing any additional data it wants. All of this information appears back on the parent's

Activity.onActivityResult(), along with the integer identifier it originally supplied.

If a child activity fails for any reason (such as crashing), the parent activity will receive a result with

the code RESULT_CANCELED.

Page 20: Android Theory

Saving Persistent State

There are generally two kinds of persistent state than an activity will deal with: shared document-like

data (typically stored in a SQLite database using a content provider) and internal state such as user

preferences.

For content provider data, we suggest that activities use a "edit in place" user model. That is, any edits

a user makes are effectively made immediately without requiring an additional confirmation step.

Supporting this model is generally a simple matter of following two rules:

• When creating a new document, the backing database entry or file for it is created immediately.

For example, if the user chooses to write a new e-mail, a new entry for that e-mail is created as

soon as they start entering data, so that if they go to any other activity after that point this e-mail

will now appear in the list of drafts.

• When an activity's onPause() method is called, it should commit to the backing content

provider or file any changes the user has made. This ensures that those changes will be seen by

any other activity that is about to run. You will probably want to commit your data even more

aggressively at key times during your activity's lifecycle: for example before starting a new

activity, before finishing your own activity, when the user switches between input fields, etc.

This model is designed to prevent data loss when a user is navigating between activities, and allows the

system to safely kill an activity (because system resources are needed somewhere else) at any time after

it has been paused. Note this implies that the user pressing BACK from your activity does not mean

"cancel" -- it means to leave the activity with its current contents saved away. Cancelling edits in an

activity must be provided through some other mechanism, such as an explicit "revert" or "undo" option.

See the content package for more information about content providers. These are a key aspect of how

different activities invoke and propagate data between themselves.

The Activity class also provides an API for managing internal persistent state associated with an

activity. This can be used, for example, to remember the user's preferred initial display in a calendar

(day view or week view) or the user's default home page in a web browser.

Activity persistent state is managed with the method getPreferences(int), allowing you to retrieve and

modify a set of name/value pairs associated with the activity. To use preferences that are shared across

multiple application components (activities, receivers, services, providers), you can use the underlying

Context.getSharedPreferences() method to retrieve a preferences object stored under a specific name.

(Note that it is not possible to share settings data across application packages -- for that you will need a

content provider.)

Permissions

The ability to start a particular Activity can be enforced when it is declared in its manifest's <activity>

tag. By doing so, other applications will need to declare a corresponding <uses-permission> element in

their own manifest to be able to start that activity.

Page 21: Android Theory

See the Security and Permissions document for more information on permissions and security in

general.

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.

Intents and Intent Filters

Three of the core components of an application — activities, services, and broadcast receivers — are

activated through messages, called intents. Intent messaging is a facility for late run-time binding

between components in the same or different applications. The intent itself, an Intent object, is a

Page 22: Android Theory

passive data structure holding an abstract description of an operation to be performed — or, often in the

case of broadcasts, a description of something that has happened and is being announced. There are

separate mechanisms for delivering intents to each type of component:

• An Intent object is passed to Context.startActivity() or Activity.startActivityForResult() to

launch an activity or get an existing activity to do something new. (It can also be passed to

Activity.setResult() to return information to the activity that called

startActivityForResult().)

• An Intent object is passed to Context.startService() to initiate a service or deliver new

instructions to an ongoing service. Similarly, an intent can be passed to Context.bindService() to

establish a connection between the calling component and a target service. It can optionally

initiate the service if it's not already running.

• Intent objects passed to any of the broadcast methods (such as Context.sendBroadcast(),

Context.sendOrderedBroadcast(), or Context.sendStickyBroadcast()) are delivered to all

interested broadcast receivers. Many kinds of broadcasts originate in system code.

In each case, the Android system finds the appropriate activity, service, or set of broadcast receivers to

respond to the intent, instantiating them if necessary. There is no overlap within these messaging

systems: Broadcast intents are delivered only to broadcast receivers, never to activities or services. An

intent passed to startActivity() is delivered only to an activity, never to a service or broadcast

receiver, and so on.

This document begins with a description of Intent objects. It then describes the rules Android uses to

map intents to components — how it resolves which component should receive an intent message. For

intents that don't explicitly name a target component, this process involves testing the Intent object

against intent filters associated with potential targets.

Intent filters

To inform the system which implicit intents they can handle, activities, services, and broadcast

receivers can have one or more intent filters. Each filter describes a capability of the component, a set

of intents that the component is willing to receive. It, in effect, filters in intents of a desired type, while

filtering out unwanted intents — but only unwanted implicit intents (those that don't name a target

class). An explicit intent is always delivered to its target, no matter what it contains; the filter is not

consulted. But an implicit intent is delivered to a component only if it can pass through one of the

component's filters.

A component has separate filters for each job it can do, each face it can present to the user. For

example, the NoteEditor activity of the sample Note Pad application has two filters — one for starting

up with a specific note that the user can view or edit, and another for starting with a new, blank note

that the user can fill in and save. (All of Note Pad's filters are described in the Note Pad Example

section, later.)

Page 23: Android Theory

Service

A Service is an application component representing either an application's desire to perform a longer-

running operation while not interacting with the user or to supply functionality for other applications to

use. Each service class must have a corresponding <service> declaration in its package's

AndroidManifest.xml. Services can be started with Context.startService() and

Context.bindService().

Note that services, like other application objects, run in the main thread of their hosting process. This

means that, if your service is going to do any CPU intensive (such as MP3 playback) or blocking (such

as networking) operations, it should spawn its own thread in which to do that work. More information

on this can be found in Application Fundamentals: Processes and Threads. The IntentService class is

available as a standard implementation of Service that has its own thread where it schedules its work to

be done.

The Service class is an important part of an application's overall lifecycle.

What is a Service?

Most confusion about the Service class actually revolves around what it is not:

• A Service is not a separate process. The Service object itself does not imply it is running in its

own process; unless otherwise specified, it runs in the same process as the application it is part

of.

• A Service is not a thread. It is not a means itself to do work off of the main thread (to avoid

Application Not Responding errors).

Thus a Service itself is actually very simple, providing two main features:

• A facility for the application to tell the system about something it wants to be doing in the

background (even when the user is not directly interacting with the application). This

corresponds to calls to Context.startService(), which ask the system to schedule work for the

service, to be run until the service or someone else explicitly stop it.

• A facility for an application to expose some of its functionality to other applications. This

corresponds to calls to Context.bindService(), which allows a long-standing connection to be

made to the service in order to interact with it.

When a Service component is actually created, for either of these reasons, all that the system actually

does is instantiate the component and call its onCreate() and any other appropriate callbacks on the

main thread. It is up to the Service to implement these with the appropriate behavior, such as creating a

secondary thread in which it does its work.

Note that because Service itself is so simple, you can make your interaction with it as simple or

complicated as you want: from treating it as a local Java object that you make direct method calls on

(as illustrated by Local Service Sample), to providing a full remoteable interface using AIDL.

Page 24: Android Theory

Service Lifecycle

There are two reasons that a service can be run by the system. If someone calls Context.startService()

then the system will retrieve the service (creating it and calling its onCreate() method if needed) and

then call its onStartCommand(Intent, int, int) method with the arguments supplied by the client. The

service will at this point continue running until Context.stopService() or stopSelf() is called. Note that

multiple calls to Context.startService() do not nest (though they do result in multiple corresponding

calls to onStartCommand()), so no matter how many times it is started a service will be stopped once

Context.stopService() or stopSelf() is called; however, services can use their stopSelf(int) method to

ensure the service is not stopped until started intents have been processed.

For started services, there are two additional major modes of operation they can decide to run in,

depending on the value they return from onStartCommand(): START_STICKY is used for services that

are explicitly started and stopped as needed, while START_NOT_STICKY or

START_REDELIVER_INTENT are used for services that should only remain running while

processing any commands sent to them. See the linked documentation for more detail on the semantics.

Clients can also use Context.bindService() to obtain a persistent connection to a service. This likewise

creates the service if it is not already running (calling onCreate() while doing so), but does not call

onStartCommand(). The client will receive the IBinder object that the service returns from its

onBind(Intent) method, allowing the client to then make calls back to the service. The service will

remain running as long as the connection is established (whether or not the client retains a reference on

the service's IBinder). Usually the IBinder returned is for a complex interface that has been written in

aidl.

A service can be both started and have connections bound to it. In such a case, the system will keep the

service running as long as either it is started or there are one or more connections to it with the

Context.BIND_AUTO_CREATE flag. Once neither of these situations hold, the service's onDestroy()

method is called and the service is effectively terminated. All cleanup (stopping threads, unregistering

receivers) should be complete upon returning from onDestroy().

Permissions

Global access to a service can be enforced when it is declared in its manifest's <service> tag. By doing

so, other applications will need to declare a corresponding <uses-permission> element in their own

manifest to be able to start, stop, or bind to the service.

In addition, a service can protect individual IPC calls into it with permissions, by calling the

checkCallingPermission(String) method before executing the implementation of that call.

See the Security and Permissions document for more information on permissions and security in

general.

Process Lifecycle

The Android system will attempt to keep the process hosting a service around as long as the service has

Page 25: Android Theory

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.

Local Service Sample

One of the most common uses of a Service is as a secondary component running alongside other parts

of an application, in the same process as the rest of the components. All components of an .apk run in

the same process unless explicitly stated otherwise, so this is a typical situation.

When used in this way, by assuming the components are in the same process, you can greatly simplify

the interaction between them: clients of the service can simply cast the IBinder they receive from it to a

concrete class published by the service.

Remote Messenger Service Sample

If you need to be able to write a Service that can perform complicated communication with clients in

remote processes (beyond simply the use of Context.startService to send commands to it), then you can

Page 26: Android Theory

use the Messenger class instead of writing full AIDL files.

If we want to make this service run in a remote process (instead of the standard one for its .apk), we

can use android:process in its manifest tag to specify one:

<service android:name=".app.MessengerService"

android:process=":remote" />

Note that the name "remote" chosen here is arbitrary, and you can use other names if you want

additional processes. The ':' prefix appends the name to your package's standard process name.

With that done, clients can now bind to the service and send messages to it. Note that this allows clients

to register with it to receive messages back as well:

BroadcastReceiver

Base class for code that will receive intents sent by sendBroadcast(). You can either

dynamically register an instance of this class with Context.registerReceiver() or statically

publish an implementation through the <receiver> tag in your AndroidManifest.xml.

Note: If registering a receiver in your Activity.onResume() implementation, you should

unregister it in Activity.onPause(). (You won't receive intents when paused, and this will cut

down on unnecessary system overhead). Do not unregister in Activity.onSaveInstanceState(),

because this won't be called if the user moves back in the history stack.

• There are two major classes of broadcasts that can be received:

• Normal broadcasts (sent with Context.sendBroadcast) are completely asynchronous. All

receivers of the broadcast are run in an undefined order, often at the same time. This is more

efficient, but means that receivers cannot use the result or abort APIs included here.

• Ordered broadcasts (sent with Context.sendOrderedBroadcast) are delivered to one receiver at

a time. As each receiver executes in turn, it can propagate a result to the next receiver, or it can

completely abort the broadcast so that it won't be passed to other receivers. The order receivers

run in can be controlled with the android:priority attribute of the matching intent-filter;

receivers with the same priority will be run in an arbitrary order.

Even in the case of normal broadcasts, the system may in some situations revert to delivering the

broadcast one receiver at a time. In particular, for receivers that may require the creation of a process,

only one will be run at a time to avoid overloading the system with new processes. In this situation,

however, the non-ordered semantics hold: these receivers still cannot return results or abort their

broadcast.

Note that, although the Intent class is used for sending and receiving these broadcasts, the Intent

broadcast mechanism here is completely separate from Intents that are used to start Activities with

Context.startActivity(). There is no way for a BroadcastReceiver to see or capture Intents used with

startActivity(); likewise, when you broadcast an Intent, you will never find or start an Activity. These

two operations are semantically very different: starting an Activity with an Intent is a foreground

operation that modifies what the user is currently interacting with; broadcasting an Intent is a

background operation that the user is not normally aware of.

Page 27: Android Theory

The BroadcastReceiver class (when launched as a component through a manifest's <receiver> tag) is an

important part of an application's overall lifecycle.

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.

Permissions

Access permissions can be enforced by either the sender or receiver of an Intent.

To enforce a permission when sending, you supply a non-null permission argument to

sendBroadcast(Intent, String) or sendOrderedBroadcast(Intent, String, BroadcastReceiver,

android.os.Handler, int, String, Bundle). Only receivers who have been granted this permission (by

requesting it with the <uses-permission> tag in their AndroidManifest.xml) will be able to

receive the broadcast.

To enforce a permission when receiving, you supply a non-null permission when registering your

receiver -- either when calling registerReceiver(BroadcastReceiver, IntentFilter, String,

android.os.Handler) or in the static <receiver> tag in your AndroidManifest.xml. Only

broadcasters who have been granted this permission (by requesting it with the <uses-permission> tag in

their AndroidManifest.xml) will be able to send an Intent to the receiver.

See the Security and Permissions document for more information on permissions and security in

general.

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

Page 28: Android Theory

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.

Content providers

Content providers are one of the primary building blocks of Android applications, providing content to

applications. They encapsulate data and provide it to applications through the single ContentResolver

interface. A content provider is only required if you need to share data between multiple applications.

For example, the contacts data is used by multiple applications and must be stored in a content

provider. If you don't need to share data amongst multiple applications you can use a database directly

via SQLiteDatabase.

For more information, read Content Providers.

When a request is made via a ContentResolver the system inspects the authority of the given URI and

passes the request to the content provider registered with the authority. The content provider can

interpret the rest of the URI however it wants. The UriMatcher class is helpful for parsing URIs.

The primary methods that need to be implemented are:

• query(Uri, String[], String, String[], String) which returns data to the caller

• insert(Uri, ContentValues) which inserts new data into the content provider

• update(Uri, ContentValues, String, String[]) which updates existing data in the content provider

• delete(Uri, String, String[]) which deletes data from the content provider

• getType(Uri) which returns the MIME type of data in the content provider