Você está na página 1de 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.
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.
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
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
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.
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
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
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
"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


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
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.
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:
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
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.
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.
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().
• 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 next


able
onCreate() Called when the activity is first created. This is where you No onStart()
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().

onRestart() Called after your activity has been stopped, prior to it being No onStart()
started again.
Always followed by onStart()

onStart() Called when the activity is becoming visible to the user. No onResume()
Followed by onResume() if the activity comes to the or onStop()
foreground, or onStop() if it becomes hidden.

onResume() Called when the activity will start interacting with the user. At No onPause()
this point your activity is at the top of the activity stack, with
user input going to it.
Always followed by onPause().

onPause() Called when the system is about to start resuming a previous Yes onResume()
activity. This is typically used to commit unsaved changes to or
persistent data, stop animations and other things that may be onStop()
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.

onStop() Called when the activity is no longer visible to the user, Yes onRestart(
because another activity has been resumed and is covering this ) or
one. This may happen either because a new activity is being onDestroy(
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.

onDestroy() The final call you receive before your activity is destroyed. Yes Nothing
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.

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().
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.
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.
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
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.)
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.
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
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
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.
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
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

Você também pode gostar