03 services

58
Services. A Service is an application component that can perform long-running operations in the background and does not provide a user interface. Another application component can start a service and it will continue to run in the background even if the user switches to another application. Additionally, a component can bind to a service to interact with it and even perform interprocess communication (IPC). For example, a service might handle network transactions, play music, perform file I/O, or interact with a content provider, all from the background. A service can essentially take two forms: Started A service is "started" when an application component (such as an activity) starts it by calling startService() . Once started, a service can run in the background indefinitely, even if the component that started it is destroyed. Usually, a started service performs a single operation and does not return a result to the caller. For example, it might download or upload a file over the network. When the operation is done, the service should stop itself. Bound A service is "bound" when an application component binds to it by calling bindService() . A bound service offers a client-server interface that allows components to interact with the service, send requests, get results, and even do so across processes with interprocess communication (IPC). A bound service runs only as long as another application component is bound to it. Multiple components can bind to the service at once, but when all of them unbind, the service is destroyed. Although this documentation generally discusses these two types of services separately, your service can work both waysit can be started (to run indefinitely) and also allow binding. It's simply a matter of whether you implement a couple callback methods: onStartCommand() to allow components to start it and onBind() to allow binding. Regardless of whether your application is started, bound, or both, any application component can use the service (even from a separate application), in the same way that any component can use an activityby starting it with an Intent . However, you can declare the service as private, in the manifest file, and block access from other applications. This is discussed more in the section about Declaring the service in the manifest . Caution: A service runs in the main thread of its hosting processthe service does not create its own thread and does not run in a separate process (unless you specify otherwise). This means that, if your service is going to do any CPU intensive work or blocking operations (such as MP3 playback or networking), you should create a new thread within the service to do that work. By using a separate thread, you will reduce the risk of Application Not Responding (ANR) errors and the application's main thread can remain dedicated to user interaction with your activities.

Upload: co-nieto

Post on 17-May-2015

2.127 views

Category:

Technology


1 download

DESCRIPTION

Part III of Android Tutorial

TRANSCRIPT

Page 1: 03 services

Services

A Service is an application component that can perform long-running operations in the background and

does not provide a user interface Another application component can start a service and it will

continue to run in the background even if the user switches to another application Additionally a

component can bind to a service to interact with it and even perform interprocess communication

(IPC) For example a service might handle network transactions play music perform file IO or

interact with a content provider all from the background

A service can essentially take two forms

Started

A service is started when an application component (such as an activity) starts it by calling

startService() Once started a service can run in the background indefinitely even if the

component that started it is destroyed Usually a started service performs a single operation

and does not return a result to the caller For example it might download or upload a file over

the network When the operation is done the service should stop itself

Bound

A service is bound when an application component binds to it by calling bindService() A

bound service offers a client-server interface that allows components to interact with the

service send requests get results and even do so across processes with interprocess

communication (IPC) A bound service runs only as long as another application component is

bound to it Multiple components can bind to the service at once but when all of them unbind

the service is destroyed

Although this documentation generally discusses these two types of services separately your service

can work both waysmdashit can be started (to run indefinitely) and also allow binding Its simply a matter

of whether you implement a couple callback methods onStartCommand() to allow components to start

it and onBind() to allow binding

Regardless of whether your application is started bound or both any application component can use

the service (even from a separate application) in the same way that any component can use an

activitymdashby starting it with an Intent However you can declare the service as private in the manifest

file and block access from other applications This is discussed more in the section about Declaring

the service in the manifest

Caution A service runs in the main thread of its hosting processmdashthe service does not create its

own thread and does not run in a separate process (unless you specify otherwise) This means

that if your service is going to do any CPU intensive work or blocking operations (such as MP3

playback or networking) you should create a new thread within the service to do that work By

using a separate thread you will reduce the risk of Application Not Responding (ANR) errors and

the applications main thread can remain dedicated to user interaction with your activities

The Basics

Should you use a service or a thread

A service is simply a component that can run in the background even when the user is not interacting

with your application Thus you should create a service only if that is what you need

If you need to perform work outside your main thread but only while the user is interacting with your

application then you should probably instead create a new thread and not a service For example if

you want to play some music but only while your activity is running you might create a thread in

onCreate() start running it in onStart() then stop it in onStop() Also consider using AsyncTask or

HandlerThread instead of the traditional Thread class See the Processes and Threading document

for more information about threads

Remember that if you do use a service it still runs in your applications main thread by default so you

should still create a new thread within the service if it performs intensive or blocking operations

To create a service you must create a subclass of Service (or one of its existing subclasses) In your

implementation you need to override some callback methods that handle key aspects of the service

lifecycle and provide a mechanism for components to bind to the service if appropriate The most

important callback methods you should override are

onStartCommand()

The system calls this method when another component such as an activity requests that the

service be started by calling startService() Once this method executes the service is started

and can run in the background indefinitely If you implement this it is your responsibility to stop

the service when its work is done by calling stopSelf() or stopService() (If you only want to

provide binding you dont need to implement this method)

onBind()

The system calls this method when another component wants to bind with the service (such as

to perform RPC) by calling bindService() In your implementation of this method you must

provide an interface that clients use to communicate with the service by returning an IBinder

You must always implement this method but if you dont want to allow binding then you should

return null

onCreate()

The system calls this method when the service is first created to perform one-time setup

procedures (before it calls either onStartCommand() or onBind()) If the service is already

running this method is not called

onDestroy()

The system calls this method when the service is no longer used and is being destroyed Your

service should implement this to clean up any resources such as threads registered listeners

receivers etc This is the last call the service receives

If a component starts the service by calling startService() (which results in a call to

onStartCommand()) then the service remains running until it stops itself with stopSelf() or another

component stops it by calling stopService()

If a component calls bindService() to create the service (and onStartCommand() is not called) then the

service runs only as long as the component is bound to it Once the service is unbound from all clients

the system destroys it

The Android system will force-stop a service only when memory is low and it must recover system

resources for the activity that has user focus If the service is bound to an activity that has user focus

then its less likely to be killed and if the service is declared to run in the foreground (discussed later)

then it will almost never be killed Otherwise if the service was started and is long-running then the

system will lower its position in the list of background tasks over time and the service will become

highly susceptible to killingmdashif your service is started then you must design it to gracefully handle

restarts by the system If the system kills your service it restarts it as soon as resources become

available again (though this also depends on the value you return from onStartCommand() as

discussed later) For more information about when the system might destroy a service see the

Processes and Threading document

In the following sections youll see how you can create each type of service and how to use it from

other application components

Declaring a service in the manifest

Like activities (and other components) you must declare all services in your applications manifest file

To declare your service add a ltservicegt element as a child of the ltapplicationgt element For

example

ltmanifest gt ltapplication gt ltservice androidname=ExampleService gt ltapplicationgt ltmanifestgt

There are other attributes you can include in the ltservicegt element to define properties such as

permissions required to start the service and the process in which the service should run The

androidname attribute is the only required attributemdashit specifies the class name of the service Once

you publish your application you should not change this name because if you do you might break

some functionality where explicit intents are used to reference your service (read the blog post Things

That Cannot Change)

See the ltservicegt element reference for more information about declaring your service in the manifest

Just like an activity a service can define intent filters that allow other components to invoke the service

using implicit intents By declaring intent filters components from any application installed on the

users device can potentially start your service if your service declares an intent filter that matches the

intent another application passes to startService()

If you plan on using your service only locally (other applications do not use it) then you dont need to

(and should not) supply any intent filters Without any intent filters you must start the service using an

intent that explicitly names the service class More information about starting a service is discussed

below

Additionally you can ensure that your service is private to your application only if you include the

androidexported attribute and set it to false This is effective even if your service supplies intent

filters

For more information about creating intent filters for your service see the Intents and Intent Filters

document

Creating a Started Service

Targeting Android 16 or lower

If youre building an application for Android 16 or lower you need to implement onStart() instead of

onStartCommand() (in Android 20 onStart() was deprecated in favor of onStartCommand())

For more information about providing compatibility with versions of Android older than 20 see the

onStartCommand() documentation

A started service is one that another component starts by calling startService() resulting in a call to the

services onStartCommand() method

When a service is started it has a lifecycle thats independent of the component that started it and the

service can run in the background indefinitely even if the component that started it is destroyed As

such the service should stop itself when its job is done by calling stopSelf() or another component

can stop it by calling stopService()

An application component such as an activity can start the service by calling startService() and

passing an Intent that specifies the service and includes any data for the service to use The service

receives this Intent in the onStartCommand() method

For instance suppose an activity needs to save some data to an online database The activity can

start a companion service and deliver it the data to save by passing an intent to startService() The

service receives the intent in onStartCommand() connects to the Internet and performs the database

transaction When the transaction is done the service stops itself and it is destroyed

Caution A services runs in the same process as the application in which it is declared and in the

main thread of that application by default So if your service performs intensive or blocking

operations while the user interacts with an activity from the same application the service will slow

down activity performance To avoid impacting application performance you should start a new

thread inside the service

Traditionally there are two classes you can extend to create a started service

Service

This is the base class for all services When you extend this class its important that you create

a new thread in which to do all the services work because the service uses your applications

main thread by default which could slow the performance of any activity your application is

running

IntentService

This is a subclass of Service that uses a worker thread to handle all start requests one at a

time This is the best option if you dont require that your service handle multiple requests

simultaneously All you need to do is implement onHandleIntent() which receives the intent for

each start request so you can do the background work

The following sections describe how you can implement your service using either one for these

classes

Extending the IntentService class

Because most started services dont need to handle multiple requests simultaneously (which can

actually be a dangerous multi-threading scenario) its probably best if you implement your service

using the IntentService class

The IntentService does the following

Creates a default worker thread that executes all intents delivered to onStartCommand() separate from

your applications main thread

Creates a work queue that passes one intent at a time to your onHandleIntent() implementation so

you never have to worry about multi-threading

Stops the service after all start requests have been handled so you never have to call stopSelf()

Provides default implementation of onBind() that returns null

Provides a default implementation of onStartCommand() that sends the intent to the work queue and

then to your onHandleIntent() implementation

All this adds up to the fact that all you need to do is implement onHandleIntent() to do the work

provided by the client (Though you also need to provide a small constructor for the service)

Heres an example implementation of IntentService

public class HelloIntentService extends IntentService A constructor is required and must call the super IntentService(String)

constructor with a name for the worker thread public HelloIntentService() super(HelloIntentService) The IntentService calls this method from the default worker thread with the intent that started the service When this method returns IntentService stops the service as appropriate Override protected void onHandleIntent(Intent intent) Normally we would do some work here like download a file For our sample we just sleep for 5 seconds long endTime = SystemcurrentTimeMillis() + 51000 while (SystemcurrentTimeMillis() lt endTime) synchronized (this) try wait(endTime - SystemcurrentTimeMillis()) catch (Exception e)

Thats all you need a constructor and an implementation of onHandleIntent()

If you decide to also override other callback methods such as onCreate() onStartCommand() or

onDestroy() be sure to call the super implementation so that the IntentService can properly handle

the life of the worker thread

For example onStartCommand() must return the default implementation (which is how the intent gets

delivered to onHandleIntent())

Override public int onStartCommand(Intent intent int flags int startId) ToastmakeText(this service starting ToastLENGTH_SHORT)show() return superonStartCommand(intentflagsstartId)

Besides onHandleIntent() the only method from which you dont need to call the super class is

onBind() (but you only need to implement that if your service allows binding)

In the next section youll see how the same kind of service is implemented when extending the base

Service class which is a lot more code but which might be appropriate if you need to handle

simultaneous start requests

Extending the Service class

As you saw in the previous section using IntentService makes your implementation of a started

service very simple If however you require your service to perform multi-threading (instead of

processing start requests through a work queue) then you can extend the Service class to handle

each intent

For comparison the following example code is an implementation of the Service class that performs

the exact same work as the example above using IntentService That is for each start request it uses

a worker thread to perform the job and processes only one request at a time

public class HelloService extends Service private Looper mServiceLooper private ServiceHandler mServiceHandler Handler that receives messages from the thread private final class ServiceHandler extends Handler public ServiceHandler(Looper looper) super(looper) Override public void handleMessage(Message msg) Normally we would do some work here like download a file For our sample we just sleep for 5 seconds long endTime = SystemcurrentTimeMillis() + 51000 while (SystemcurrentTimeMillis() lt endTime) synchronized (this) try wait(endTime - SystemcurrentTimeMillis()) catch (Exception e) Stop the service using the startId so that we dont stop the service in the middle of handling another job stopSelf(msgarg1) Override public void onCreate() Start up the thread running the service Note that we create a separate thread because the service normally runs in the processs main thread which we dont want to block We also make it background priority so CPU-intensive work will not disrupt our UI HandlerThread thread = new HandlerThread(ServiceStartArguments ProcessTHREAD_PRIORITY_BACKGROUND) threadstart() Get the HandlerThreads Looper and use it for our Handler

mServiceLooper = threadgetLooper() mServiceHandler = new ServiceHandler(mServiceLooper) Override public int onStartCommand(Intent intent int flags int startId) ToastmakeText(this service starting ToastLENGTH_SHORT)show() For each start request send a message to start a job and deliver the start ID so we know which request were stopping when we finish the job Message msg = mServiceHandlerobtainMessage() msgarg1 = startId mServiceHandlersendMessage(msg) If we get killed after returning from here restart return START_STICKY Override public IBinder onBind(Intent intent) We dont provide binding so return null return null Override public void onDestroy() ToastmakeText(this service done ToastLENGTH_SHORT)show()

As you can see its a lot more work than using IntentService

However because you handle each call to onStartCommand() yourself you can perform multiple

requests simultaneously Thats not what this example does but if thats what you want then you can

create a new thread for each request and run them right away (instead of waiting for the previous

request to finish)

Notice that the onStartCommand() method must return an integer The integer is a value that

describes how the system should continue the service in the event that the system kills it (as

discussed above the default implementation for IntentService handles this for you though you are

able to modify it) The return value from onStartCommand() must be one of the following constants

START_NOT_STICKY

If the system kills the service after onStartCommand() returns do not recreate the service

unless there are pending intents to deliver This is the safest option to avoid running your

service when not necessary and when your application can simply restart any unfinished jobs

START_STICKY

If the system kills the service after onStartCommand() returns recreate the service and call

onStartCommand() but do not redeliver the last intent Instead the system calls

onStartCommand() with a null intent unless there were pending intents to start the service in

which case those intents are delivered This is suitable for media players (or similar services)

that are not executing commands but running indefinitely and waiting for a job

START_REDELIVER_INTENT

If the system kills the service after onStartCommand() returns recreate the service and call

onStartCommand() with the last intent that was delivered to the service Any pending intents are

delivered in turn This is suitable for services that are actively performing a job that should be

immediately resumed such as downloading a file

For more details about these return values see the linked reference documentation for each constant

Starting a Service

You can start a service from an activity or other application component by passing an Intent (specifying

the service to start) to startService() The Android system calls the services onStartCommand()

method and passes it the Intent (You should never call onStartCommand() directly)

For example an activity can start the example service in the previous section (HelloSevice) using an

explicit intent with startService()

Intent intent = new Intent(this HelloServiceclass) startService(intent)

The startService() method returns immediately and the Android system calls the services

onStartCommand() method If the service is not already running the system first calls onCreate() then

calls onStartCommand()

If the service does not also provide binding the intent delivered with startService() is the only mode of

communication between the application component and the service However if you want the service

to send a result back then the client that starts the service can create a PendingIntent for a broadcast

(with getBroadcast()) and deliver it to the service in the Intent that starts the service The service can

then use the broadcast to deliver a result

Multiple requests to start the service result in multiple corresponding calls to the services

onStartCommand() However only one request to stop the service (with stopSelf() or stopService()) is

required to stop it

Stopping a service

A started service must manage its own lifecycle That is the system does not stop or destroy the

service unless it must recover system memory and the service continues to run after

onStartCommand() returns So the service must stop itself by calling stopSelf() or another component

can stop it by calling stopService()

Once requested to stop with stopSelf() or stopService() the system destroys the service as soon as

possible

However if your service handles multiple requests to onStartCommand() concurrently then you

shouldnt stop the service when youre done processing a start request because you might have since

received a new start request (stopping at the end of the first request would terminate the second one)

To avoid this problem you can use stopSelf(int) to ensure that your request to stop the service is

always based on the most recent start request That is when you call stopSelf(int) you pass the ID of

the start request (the startId delivered to onStartCommand()) to which your stop request corresponds

Then if the service received a new start request before you were able to call stopSelf(int) then the ID

will not match and the service will not stop

Caution Its important that your application stops its services when its done working to avoid

wasting system resources and consuming battery power If necessary other components can stop

the service by calling stopService() Even if you enable binding for the service you must always

stop the service yourself if it ever received a call to onStartCommand()

For more information about the lifecycle of a service see the section below about Managing the

Lifecycle of a Service

Creating a Bound Service

A bound service is one that allows application components to bind to it by calling bindService() in order

to create a long-standing connection (and generally does not allow components to start it by calling

startService())

You should create a bound service when you want to interact with the service from activities and other

components in your application or to expose some of your applications functionality to other

applications through interprocess communication (IPC)

To create a bound service you must implement the onBind() callback method to return an IBinder that

defines the interface for communication with the service Other application components can then call

bindService() to retrieve the interface and begin calling methods on the service The service lives only

to serve the application component that is bound to it so when there are no components bound to the

service the system destroys it (you do not need to stop a bound service in the way you must when the

service is started through onStartCommand())

To create a bound service the first thing you must do is define the interface that specifies how a client

can communicate with the service This interface between the service and a client must be an

implementation of IBinder and is what your service must return from the onBind() callback method

Once the client receives the IBinder it can begin interacting with the service through that interface

Multiple clients can bind to the service at once When a client is done interacting with the service it

calls unbindService() to unbind Once there are no clients bound to the service the system destroys

the service

There are multiple ways to implement a bound service and the implementation is more complicated

than a started service so the bound service discussion appears in a separate document about Bound

Services

Sending Notifications to the User

Once running a service can notify the user of events using Toast Notifications or Status Bar

Notifications

A toast notification is a message that appears on the surface of the current window for a moment then

disappears while a status bar notification provides an icon in the status bar with a message which the

user can select in order to take an action (such as start an activity)

Usually a status bar notification is the best technique when some background work has completed

(such as a file completed downloading) and the user can now act on it When the user selects the

notification from the expanded view the notification can start an activity (such as to view the

downloaded file)

See the Toast Notifications or Status Bar Notifications developer guides for more information

Running a Service in the Foreground

A foreground service is a service thats considered to be something the user is actively aware of and

thus not a candidate for the system to kill when low on memory A foreground service must provide a

notification for the status bar which is placed under the Ongoing heading which means that the

notification cannot be dismissed unless the service is either stopped or removed from the foreground

For example a music player that plays music from a service should be set to run in the foreground

because the user is explicitly aware of its operation The notification in the status bar might indicate the

current song and allow the user to launch an activity to interact with the music player

To request that your service run in the foreground call startForeground() This method takes two

parameters an integer that uniquely identifies the notification and the Notification for the status bar

For example

Notification notification = new Notification(Rdrawableicon getText(Rstringticker_text) SystemcurrentTimeMillis()) Intent notificationIntent = new Intent(this ExampleActivityclass) PendingIntent pendingIntent = PendingIntentgetActivity(this 0 notificationIntent 0) notificationsetLatestEventInfo(this getText(Rstringnotification_title) getText(Rstringnotification_message) pendingIntent) startForeground(ONGOING_NOTIFICATION notification)

To remove the service from the foreground call stopForeground() This method takes a boolean

indicating whether to remove the status bar notification as well This method does not stop the service

However if you stop the service while its still running in the foreground then the notification is also

removed

Note The methods startForeground() and stopForeground() were introduced in Android 20 (API

Level 5) In order to run your service in the foreground on older versions of the platform you must

use the previous setForeground() methodmdashsee the startForeground() documentation for

information about how to provide backward compatibility

For more information about notifications see Creating Status Bar Notifications

Managing the Lifecycle of a Service

The lifecycle of a service is much simpler than that of an activity However its even more important

that you pay close attention to how your service is created and destroyed because a service can run

in the background without the user being aware

The service lifecyclemdashfrom when its created to when its destroyedmdashcan follow two different paths

A started service

The service is created when another component calls startService() The service then runs indefinitely

and must stop itself by calling stopSelf() Another component can also stop the service by calling

stopService() When the service is stopped the system destroys it

A bound service

The service is created when another component (a client) calls bindService() The client then

communicates with the service through an IBinder interface The client can close the connection by

calling unbindService() Multiple clients can bind to the same service and when all of them unbind the

system destroys the service (The service does not need to stop itself)

These two paths are not entirely separate That is you can bind to a service that was already started

with startService() For example a background music service could be started by calling startService()

with an Intent that identifies the music to play Later possibly when the user wants to exercise some

control over the player or get information about the current song an activity can bind to the service by

calling bindService() In cases like this stopService() or stopSelf() does not actually stop the service

until all clients unbind

Implementing the lifecycle callbacks

Like an activity a service has lifecycle callback methods that you can implement to monitor changes in

the services state and perform work at the appropriate times The following skeleton service

demonstrates each of the lifecycle methods

Figure 2 The service lifecycle The diagram on the left shows the lifecycle when the service is created

with startService() and the diagram on the right shows the lifecycle when the service is created with

bindService()

public class ExampleService extends Service int mStartMode indicates how to behave if the service is killed IBinder mBinder interface for clients that bind boolean mAllowRebind indicates whether onRebind should be used Override public void onCreate() The service is being created Override public int onStartCommand(Intent intent int flags int startId) The service is starting due to a call to startService() return mStartMode Override public IBinder onBind(Intent intent) A client is binding to the service with bindService() return mBinder Override public boolean onUnbind(Intent intent) All clients have unbound with unbindService()

return mAllowRebind Override public void onRebind(Intent intent) A client is binding to the service with bindService() after onUnbind() has already been called Override public void onDestroy() The service is no longer used and is being destroyed

Note Unlike the activity lifecycle callback methods you are not required to call the superclass

implementation of these callback methods

By implementing these methods you can monitor two nested loops of the services lifecycle

The entire lifetime of a service happens between the time onCreate() is called and the time

onDestroy() returns Like an activity a service does its initial setup in onCreate() and releases all

remaining resources in onDestroy() For example a music playback service could create the thread

where the music will be played in onCreate() then stop the thread in onDestroy()

The onCreate() and onDestroy() methods are called for all services whether theyre created by

startService() or bindService()

The active lifetime of a service begins with a call to either onStartCommand() or onBind() Each

method is handed the Intent that was passed to either startService() or bindService() respectively

If the service is started the active lifetime ends the same time that the entire lifetime ends (the service

is still active even after onStartCommand() returns) If the service is bound the active lifetime ends

when onUnbind() returns

Note Although a started service is stopped by a call to either stopSelf() or stopService() there is

not a respective callback for the service (theres no onStop() callback) So unless the service is

bound to a client the system destroys it when the service is stoppedmdashonDestroy() is the only

callback received

Figure 2 illustrates the typical callback methods for a service Although the figure separates services

that are created by startService() from those created by bindService() keep in mind that any service

no matter how its started can potentially allow clients to bind to it So a service that was initially

started with onStartCommand() (by a client calling startService()) can still receive a call to onBind()

(when a client calls bindService())

For more information about creating a service that provides binding see the Bound Services

document which includes more information about the onRebind() callback method in the section about

Managing the Lifecycle of a Bound Service

Bound Services

A bound service is the server in a client-server interface A bound service allows components (such as

activities) to bind to the service send requests receive responses and even perform interprocess

communication (IPC) A bound service typically lives only while it serves another application

component and does not run in the background indefinitely

This document shows you how to create a bound service including how to bind to the service from

other application components However you should also refer to the Services document for additional

information about services in general such as how to deliver notifications from a service set the

service to run in the foreground and more

The Basics

A bound service is an implementation of the Service class that allows other applications to bind to it

and interact with it To provide binding for a service you must implement the onBind() callback

method This method returns an IBinder object that defines the programming interface that clients can

use to interact with the service

Binding to a Started Service

As discussed in the Services document you can create a service that is both started and bound That

is the service can be started by calling startService() which allows the service to run indefinitely and

also allow a client to bind to the service by calling bindService()

If you do allow your service to be started and bound then when the service has been started the

system does not destroy the service when all clients unbind Instead you must explicitly stop the

service by calling stopSelf() or stopService()

Although you should usually implement either onBind() or onStartCommand() its sometimes

necessary to implement both For example a music player might find it useful to allow its service to run

indefinitely and also provide binding This way an activity can start the service to play some music and

the music continues to play even if the user leaves the application Then when the user returns to the

application the activity can bind to the service to regain control of playback

Be sure to read the section about Managing the Lifecycle of a Bound Service for more information

about the service lifecycle when adding binding to a started service

A client can bind to the service by calling bindService() When it does it must provide an

implementation of ServiceConnection which monitors the connection with the service The

bindService() method returns immediately without a value but when the Android system creates the

connection between the client and service it calls onServiceConnected() on the ServiceConnection to

deliver the IBinder that the client can use to communicate with the service

Multiple clients can connect to the service at once However the system calls your services onBind()

method to retrieve the IBinder only when the first client binds The system then delivers the same

IBinder to any additional clients that bind without calling onBind() again

When the last client unbinds from the service the system destroys the service (unless the service was

also started by startService())

When you implement your bound service the most important part is defining the interface that your

onBind() callback method returns There are a few different ways you can define your services IBinder

interface and the following section discusses each technique

Creating a Bound Service

When creating a service that provides binding you must provide an IBinder that provides the

programming interface that clients can use to interact with the service There are three ways you can

define the interface

Extending the Binder class

If your service is private to your own application and runs in the same process as the client

(which is common) you should create your interface by extending the Binder class and

returning an instance of it from onBind() The client receives the Binder and can use it to directly

access public methods available in either the Binder implementation or even the Service

This is the preferred technique when your service is merely a background worker for your own

application The only reason you would not create your interface this way is because your

service is used by other applications or across separate processes

Using a Messenger

If you need your interface to work across different processes you can create an interface for the

service with a Messenger In this manner the service defines a Handler that responds to

different types of Message objects This Handler is the basis for a Messenger that can then

share an IBinder with the client allowing the client to send commands to the service using

Message objects Additionally the client can define a Messenger of its own so the service can

send messages back

This is the simplest way to perform interprocess communication (IPC) because the Messenger

queues all requests into a single thread so that you dont have to design your service to be

thread-safe

Using AIDL

AIDL (Android Interface Definition Language) performs all the work to decompose objects into

primitives that the operating system can understand and marshall them across processes to

perform IPC The previous technique using a Messenger is actually based on AIDL as its

underlying structure As mentioned above the Messenger creates a queue of all the client

requests in a single thread so the service receives requests one at a time If however you

want your service to handle multiple requests simultaneously then you can use AIDL directly In

this case your service must be capable of multi-threading and be built thread-safe

To use AIDL directly you must create an aidl file that defines the programming interface The

Android SDK tools use this file to generate an abstract class that implements the interface and

handles IPC which you can then extend within your service

Note Most applications should not use AIDL to create a bound service because it may require

multithreading capabilities and can result in a more complicated implementation As such AIDL is

not suitable for most applications and this document does not discuss how to use it for your

service If youre certain that you need to use AIDL directly see the AIDL document

Extending the Binder class

If your service is used only by the local application and does not need to work across processes then

you can implement your own Binder class that provides your client direct access to public methods in

the service

Note This works only if the client and service are in the same application and process which is

most common For example this would work well for a music application that needs to bind an

activity to its own service thats playing music in the background

Heres how to set it up

1 In your service create an instance of Binder that either

o contains public methods that the client can call

o returns the current Service instance which has public methods the client can call

o or returns an instance of another class hosted by the service with public methods the client can call

2 Return this instance of Binder from the onBind() callback method

3 In the client receive the Binder from the onServiceConnected() callback method and make calls to the

bound service using the methods provided

Note The reason the service and client must be in the same application is so the client can cast

the returned object and properly call its APIs The service and client must also be in the same

process because this technique does not perform any marshalling across processes

For example heres a service that provides clients access to methods in the service through a Binder

implementation

public class LocalService extends Service

Binder given to clients

private final IBinder mBinder = new LocalBinder()

Random number generator

private final Random mGenerator = new Random()

Class used for the client Binder Because we know this service always

runs in the same process as its clients we dont need to deal with IPC

public class LocalBinder extends Binder

LocalService getService()

Return this instance of LocalService so clients can call public methods

return LocalServicethis

Override

public IBinder onBind(Intent intent)

return mBinder

method for clients

public int getRandomNumber()

return mGeneratornextInt(100)

The LocalBinder provides the getService() method for clients to retrieve the current instance of

LocalService This allows clients to call public methods in the service For example clients can call

getRandomNumber() from the service

Heres an activity that binds to LocalService and calls getRandomNumber() when a button is clicked

public class BindingActivity extends Activity

LocalService mService

boolean mBound = false

Override

protected void onCreate(Bundle savedInstanceState)

superonCreate(savedInstanceState)

setContentView(Rlayoutmain)

Override

protected void onStart()

superonStart()

Bind to LocalService

Intent intent = new Intent(this LocalServiceclass)

bindService(intent mConnection ContextBIND_AUTO_CREATE)

Override

protected void onStop()

superonStop()

Unbind from the service

if (mBound)

unbindService(mConnection)

mBound = false

Called when a button is clicked (the button in the layout file attaches to

this method with the androidonClick attribute)

public void onButtonClick(View v)

if (mBound)

Call a method from the LocalService

However if this call were something that might hang then this request should

occur in a separate thread to avoid slowing down the activity performance

int num = mServicegetRandomNumber()

ToastmakeText(this number + num ToastLENGTH_SHORT)show()

Defines callbacks for service binding passed to bindService()

private ServiceConnection mConnection = new ServiceConnection()

Override

public void onServiceConnected(ComponentName className

IBinder service)

Weve bound to LocalService cast the IBinder and get LocalService instance

LocalBinder binder = (LocalBinder) service

mService = bindergetService()

mBound = true

Override

public void onServiceDisconnected(ComponentName arg0)

mBound = false

The above sample shows how the client binds to the service using an implementation of

ServiceConnection and the onServiceConnected() callback The next section provides more

information about this process of binding to the service

Note The example above doesnt explicitly unbind from the service but all clients should unbind

at an appropriate time (such as when the activity pauses)

For more sample code see the LocalServicejava class and the LocalServiceActivitiesjava class in

ApiDemos

Using a Messenger

Compared to AIDL

When you need to perform IPC using a Messenger for your interface is simpler than implementing it

with AIDL because Messenger queues all calls to the service whereas a pure AIDL interface sends

simultaneous requests to the service which must then handle multi-threading

For most applications the service doesnt need to perform multi-threading so using a Messenger

allows the service to handle one call at a time If its important that your service be multi-threaded then

you should use AIDL to define your interface

If you need your service to communicate with remote processes then you can use a Messenger to

provide the interface for your service This technique allows you to perform interprocess

communication (IPC) without the need to use AIDL

Heres a summary of how to use a Messenger

The service implements a Handler that receives a callback for each call from a client

The Handler is used to create a Messenger object (which is a reference to the Handler)

The Messenger creates an IBinder that the service returns to clients from onBind()

Clients use the IBinder to instantiate the Messenger (that references the services Handler) which the

client uses to send Message objects to the service

The service receives each Message in its Handlermdashspecifically in the handleMessage() method

In this way there are no methods for the client to call on the service Instead the client delivers

messages (Message objects) that the service receives in its Handler

Heres a simple example service that uses a Messenger interface

public class MessengerService extends Service Command to the service to display a message static final int MSG_SAY_HELLO = 1 Handler of incoming messages from clients class IncomingHandler extends Handler Override public void handleMessage(Message msg) switch (msgwhat) case MSG_SAY_HELLO ToastmakeText(getApplicationContext() hello ToastLENGTH_SHORT)show() break default superhandleMessage(msg) Target we publish for clients to send messages to IncomingHandler final Messenger mMessenger = new Messenger(new IncomingHandler()) When binding to the service we return an interface to our messenger for sending messages to the service Override public IBinder onBind(Intent intent) ToastmakeText(getApplicationContext() binding ToastLENGTH_SHORT)show() return mMessengergetBinder()

Notice that the handleMessage() method in the Handler is where the service receives the incoming

Message and decides what to do based on the what member

All that a client needs to do is create a Messenger based on the IBinder returned by the service and

send a message using send() For example heres a simple activity that binds to the service and

delivers the MSG_SAY_HELLO message to the service

public class ActivityMessenger extends Activity Messenger for communicating with the service Messenger mService = null Flag indicating whether we have called bind on the service boolean mBound Class for interacting with the main interface of the service private ServiceConnection mConnection = new ServiceConnection() public void onServiceConnected(ComponentName className IBinder service) This is called when the connection with the service has been established giving us the object we can use to interact with the service We are communicating with the service using a Messenger so here we get a client-side representation of that from the raw IBinder object mService = new Messenger(service) mBound = true public void onServiceDisconnected(ComponentName className) This is called when the connection with the service has been unexpectedly disconnected -- that is its process crashed mService = null mBound = false public void sayHello(View v) if (mBound) return Create and send a message to the service using a supported what value Message msg = Messageobtain(null MessengerServiceMSG_SAY_HELLO 0 0) try mServicesend(msg) catch (RemoteException e) eprintStackTrace() Override protected void onCreate(Bundle savedInstanceState) superonCreate(savedInstanceState) setContentView(Rlayoutmain)

Override protected void onStart() superonStart() Bind to the service bindService(new Intent(this MessengerServiceclass) mConnection ContextBIND_AUTO_CREATE) Override protected void onStop() superonStop() Unbind from the service if (mBound) unbindService(mConnection) mBound = false

Notice that this example does not show how the service can respond to the client If you want the

service to respond then you need to also create a Messenger in the client Then when the client

receives the onServiceConnected() callback it sends a Message to the service that includes the

clients Messenger in the replyTo parameter of the send() method

You can see an example of how to provide two-way messaging in the MessengerServicejava (service)

and MessengerServiceActivitiesjava (client) samples

Binding to a Service

Application components (clients) can bind to a service by calling bindService() The Android system

then calls the services onBind() method which returns an IBinder for interacting with the service

The binding is asynchronous bindService() returns immediately and does not return the IBinder to the

client To receive the IBinder the client must create an instance of ServiceConnection and pass it to

bindService() The ServiceConnection includes a callback method that the system calls to deliver the

IBinder

Note Only activities services and content providers can bind to a servicemdashyou cannot bind to a

service from a broadcast receiver

So to bind to a service from your client you must

1 Implement ServiceConnection

Your implementation must override two callback methods

onServiceConnected()

The system calls this to deliver the IBinder returned by the services onBind() method

onServiceDisconnected()

The Android system calls this when the connection to the service is unexpectedly lost such as

when the service has crashed or has been killed This is not called when the client unbinds

2 Call bindService() passing the ServiceConnection implementation

3 When the system calls your onServiceConnected() callback method you can begin making calls to the

service using the methods defined by the interface

4 To disconnect from the service call unbindService()

When your client is destroyed it will unbind from the service but you should always unbind when

youre done interacting with the service or when your activity pauses so that the service can shutdown

while its not being used (Appropriate times to bind and unbind is discussed more below)

For example the following snippet connects the client to the service created above by extending the

Binder class so all it must do is cast the returned IBinder to the LocalService class and request the

LocalService instance

LocalService mService private ServiceConnection mConnection = new ServiceConnection() Called when the connection with the service is established public void onServiceConnected(ComponentName className IBinder service) Because we have bound to an explicit service that is running in our own process we can cast its IBinder to a concrete class and directly access it LocalBinder binder = (LocalBinder) service mService = bindergetService() mBound = true Called when the connection with the service disconnects unexpectedly public void onServiceDisconnected(ComponentName className) Loge(TAG onServiceDisconnected) mBound = false

With this ServiceConnection the client can bind to a service by passing this it to bindService() For

example

Intent intent = new Intent(this LocalServiceclass) bindService(intent mConnection ContextBIND_AUTO_CREATE)

The first parameter of bindService() is an Intent that explicitly names the service to bind (thought the

intent could be implicit)

The second parameter is the ServiceConnection object

The third parameter is a flag indicating options for the binding It should usually be

BIND_AUTO_CREATE in order to create the service if its not already alive Other possible values are

BIND_DEBUG_UNBIND and BIND_NOT_FOREGROUND or 0 for none

Additional notes

Here are some important notes about binding to a service

You should always trap DeadObjectException exceptions which are thrown when the connection has

broken This is the only exception thrown by remote methods

Objects are reference counted across processes

You should usually pair the binding and unbinding during matching bring-up and tear-down moments

of the clients lifecycle For example

o If you only need to interact with the service while your activity is visible you should bind during

onStart() and unbind during onStop()

o If you want your activity to receive responses even while it is stopped in the background then you can

bind during onCreate() and unbind during onDestroy() Beware that this implies that your activity needs

to use the service the entire time its running (even in the background) so if the service is in another

process then you increase the weight of the process and it becomes more likely that the system will

kill it

Note You should usually not bind and unbind during your activitys onResume() and onPause()

because these callbacks occur at every lifecycle transition and you should keep the processing that

occurs at these transitions to a minimum Also if multiple activities in your application bind to the same

service and there is a transition between two of those activities the service may be destroyed and

recreated as the current activity unbinds (during pause) before the next one binds (during resume)

(This activity transition for how activities coordinate their lifecycles is described in the Activities

document)

For more sample code showing how to bind to a service see the RemoteServicejava class in

ApiDemos

Managing the Lifecycle of a Bound Service

Figure 1 The lifecycle for a service

that is started and also allows binding

When a service is unbound from all

clients the Android system destroys it

(unless it was also started with

onStartCommand()) As such you

dont have to manage the lifecycle of

your service if its purely a bound

servicemdashthe Android system manages

it for you based on whether it is bound

to any clients

However if you choose to implement

the onStartCommand() callback

method then you must explicitly stop

the service because the service is

now considered to be started In this

case the service runs until the service

stops itself with stopSelf() or another

component calls stopService()

regardless of whether it is bound to

any clients

Additionally if your service is started and accepts binding then when the system calls your onUnbind()

method you can optionally return true if you would like to receive a call to onRebind() the next time a

client binds to the service (instead of receiving a call to onBind()) onRebind() returns void but the

client still receives the IBinder in its onServiceConnected() callback Below figure 1 illustrates the logic

for this kind of lifecycle

For more information about the lifecycle of an started service see the Services document

Content Providers

Content providers store and retrieve data and make it accessible to all applications Theyre the only

way to share data across applications theres no common storage area that all Android packages can

access

Android ships with a number of content providers for common data types (audio video images

personal contact information and so on) You can see some of them listed in the androidprovider

package You can query these providers for the data they contain (although for some you must

acquire the proper permission to read the data)

If you want to make your own data public you have two options You can create your own content

provider (a ContentProvider subclass) or you can add the data to an existing provider mdash if theres one

that controls the same type of data and you have permission to write to it

This document is an introduction to using content providers After a brief discussion of the

fundamentals it explores how to query a content provider how to modify data controlled by a provider

and how to create a content provider of your own

Content Provider Basics

How a content provider actually stores its data under the covers is up to its designer But all content

providers implement a common interface for querying the provider and returning results mdash as well as

for adding altering and deleting data Its an interface that clients use indirectly most generally

through ContentResolver objects You get a ContentResolver by calling getContentResolver() from

within the implementation of an Activity or other application component

ContentResolver cr = getContentResolver()

You can then use the ContentResolvers methods to interact with whatever content providers youre

interested in When a query is initiated the Android system identifies the content provider thats the

target of the query and makes sure that it is up and running The system instantiates all

ContentProvider objects you never need to do it on your own In fact you never deal directly with

ContentProvider objects at all Typically theres just a single instance of each type of ContentProvider

But it can communicate with multiple ContentResolver objects in different applications and processes

The interaction between processes is handled by the ContentResolver and ContentProvider classes

The data model

Content providers expose their data as a simple table on a database model where each row is a

record and each column is data of a particular type and meaning For example information about

people and their phone numbers might be exposed as follows

_ID NUMBER NUMBER_KEY LABEL NAME TYPE

13 (425) 555 6677 425 555 6677 Kirkland office Bully Pulpit TYPE_WORK

44 (212) 555-1234 212 555 1234 NY apartment Alan Vain TYPE_HOME

45 (212) 555-6657 212 555 6657 Downtown office Alan Vain TYPE_MOBILE

53 2015554433 201 555 4433 Love Nest Rex Cars TYPE_HOME

Every record includes a numeric _ID field that uniquely identifies the record within the table IDs can be

used to match records in related tables mdash for example to find a persons phone number in one table

and pictures of that person in another

A query returns a Cursor object that can move from record to record and column to column to read the

contents of each field It has specialized methods for reading each type of data So to read a field you

must know what type of data the field contains (Theres more on query results and Cursor objects

later)

URIs

Each content provider exposes a public URI (wrapped as a Uri object) that uniquely identifies its data

set A content provider that controls multiple data sets (multiple tables) exposes a separate URI for

each one All URIs for providers begin with the string content The content scheme identifies the

data as being controlled by a content provider

If youre defining a content provider its a good idea to also define a constant for its URI to simplify

client code and make future updates cleaner Android defines CONTENT_URI constants for all the

providers that come with the platform For example the URI for the table that matches phone numbers

to people and the URI for the table that holds pictures of people (both controlled by the Contacts

content provider) are

androidproviderContactsPhonesCONTENT_URI

androidproviderContactsPhotosCONTENT_URI

The URI constant is used in all interactions with the content provider Every ContentResolver method

takes the URI as its first argument Its what identifies which provider the ContentResolver should talk

to and which table of the provider is being targeted

Querying a Content Provider

You need three pieces of information to query a content provider

The URI that identifies the provider

The names of the data fields you want to receive

The data types for those fields

If youre querying a particular record you also need the ID for that record

Making the query

To query a content provider you can use either the ContentResolverquery() method or the

ActivitymanagedQuery() method Both methods take the same set of arguments and both return a

Cursor object However managedQuery() causes the activity to manage the life cycle of the Cursor A

managed Cursor handles all of the niceties such as unloading itself when the activity pauses and

requerying itself when the activity restarts You can ask an Activity to begin managing an unmanaged

Cursor object for you by calling ActivitystartManagingCursor()

The first argument to either query() or managedQuery() is the provider URI mdash the CONTENT_URI

constant that identifies a particular ContentProvider and data set (see URIs earlier)

To restrict a query to just one record you can append the _ID value for that record to the URI mdash that

is place a string matching the ID as the last segment of the path part of the URI For example if the ID

is 23 the URI would be

content 23

There are some helper methods particularly ContentUriswithAppendedId() and

UriwithAppendedPath() that make it easy to append an ID to a URI Both are static methods that

return a Uri object with the ID added So for example if you were looking for record 23 in the database

of people contacts you might construct a query as follows

import androidproviderContactsPeople import androidcontentContentUris import androidnetUri import androiddatabaseCursor Use the ContentUris method to produce the base URI for the contact with _ID == 23 Uri myPerson = ContentUriswithAppendedId(PeopleCONTENT_URI 23) Alternatively use the Uri method to produce the base URI It takes a string rather than an integer Uri myPerson = UriwithAppendedPath(PeopleCONTENT_URI 23) Then query for this specific record Cursor cur = managedQuery(myPerson null null null null)

The other arguments to the query() and managedQuery() methods delimit the query in more detail

They are

The names of the data columns that should be returned A null value returns all columns Otherwise

only columns that are listed by name are returned All the content providers that come with the

platform define constants for their columns For example the androidproviderContactsPhones class

defines constants for the names of the columns in the phone table illustrated earlier ampmdash _ID

NUMBER NUMBER_KEY NAME and so on

A filter detailing which rows to return formatted as an SQL WHERE clause (excluding the WHERE

itself) A null value returns all rows (unless the URI limits the query to a single record)

Selection arguments

A sorting order for the rows that are returned formatted as an SQL ORDER BY clause (excluding the

ORDER BY itself) A null value returns the records in the default order for the table which may be

unordered

Lets look at an example query to retrieve a list of contact names and their primary phone numbers

import androidproviderContactsPeople import androiddatabaseCursor Form an array specifying which columns to return String[] projection = new String[] People_ID People_COUNT PeopleNAME PeopleNUMBER Get the base URI for the People table in the Contacts content provider Uri contacts = PeopleCONTENT_URI Make the query Cursor managedCursor = managedQuery(contacts projection Which columns to return null Which rows to return (all rows) null Selection arguments (none) Put the results in ascending order by name PeopleNAME + ASC)

This query retrieves data from the People table of the Contacts content provider It gets the name

primary phone number and unique record ID for each contact It also reports the number of records

that are returned as the _COUNT field of each record

The constants for the names of the columns are defined in various interfaces mdash _ID and _COUNT in

BaseColumns NAME in PeopleColumns and NUMBER in PhoneColumns The ContactsPeople

class implements each of these interfaces which is why the code example above could refer to them

using just the class name

What a query returns

A query returns a set of zero or more database records The names of the columns their default order

and their data types are specific to each content provider But every provider has an _ID column

which holds a unique numeric ID for each record Every provider can also report the number of records

returned as the _COUNT column its value is the same for all rows

Here is an example result set for the query in the previous section

_ID _COUNT NAME NUMBER

44 3 Alan Vain 212 555 1234

13 3 Bully Pulpit 425 555 6677

53 3 Rex Cars 201 555 4433

The retrieved data is exposed by a Cursor object that can be used to iterate backward or forward

through the result set You can use this object only to read the data To add modify or delete data

you must use a ContentResolver object

Reading retrieved data

The Cursor object returned by a query provides access to a recordset of results If you have queried

for a specific record by ID this set will contain only one value Otherwise it can contain multiple

values (If there are no matches it can also be empty) You can read data from specific fields in the

record but you must know the data type of the field because the Cursor object has a separate method

for reading each type of data mdash such as getString() getInt() and getFloat() (However for most types

if you call the method for reading strings the Cursor object will give you the String representation of

the data) The Cursor lets you request the column name from the index of the column or the index

number from the column name

The following snippet demonstrates reading names and phone numbers from the query illustrated

earlier

import androidproviderContactsPeople private void getColumnData(Cursor cur) if (curmoveToFirst()) String name String phoneNumber int nameColumn = curgetColumnIndex(PeopleNAME) int phoneColumn = curgetColumnIndex(PeopleNUMBER) String imagePath do Get the field values name = curgetString(nameColumn) phoneNumber = curgetString(phoneColumn) Do something with the values while (curmoveToNext())

If a query can return binary data such as an image or sound the data may be directly entered in the

table or the table entry for that data may be a string specifying a content URI that you can use to get

the data In general smaller amounts of data (say from 20 to 50K or less) are most often directly

entered in the table and can be read by calling CursorgetBlob() It returns a byte array

If the table entry is a content URI you should never try to open and read the file directly (for one thing

permissions problems can make this fail) Instead you should call ContentResolveropenInputStream()

to get an InputStream object that you can use to read the data

Modifying Data

Data kept by a content provider can be modified by

Adding new records

Adding new values to existing records

Batch updating existing records

Deleting records

All data modification is accomplished using ContentResolver methods Some content providers require

a more restrictive permission for writing data than they do for reading it If you dont have permission to

write to a content provider the ContentResolver methods will fail

Adding records

To add a new record to a content provider first set up a map of key-value pairs in a ContentValues

object where each key matches the name of a column in the content provider and the value is the

desired value for the new record in that column Then call ContentResolverinsert() and pass it the URI

of the provider and the ContentValues map This method returns the full URI of the new record mdash that

is the providers URI with the appended ID for the new record You can then use this URI to query and

get a Cursor over the new record and to further modify the record Heres an example

import androidproviderContactsPeople import androidcontentContentResolver import androidcontentContentValues ContentValues values = new ContentValues() Add Abraham Lincoln to contacts and make him a favorite valuesput(PeopleNAME Abraham Lincoln) 1 = the new contact is added to favorites 0 = the new contact is not added to favorites valuesput(PeopleSTARRED 1) Uri uri = getContentResolver()insert(PeopleCONTENT_URI values)

Adding new values

Once a record exists you can add new information to it or modify existing information For example

the next step in the example above would be to add contact information mdash like a phone number or an

IM or e-mail address mdash to the new entry

The best way to add to a record in the Contacts database is to append the name of the table where the

new data goes to the URI for the record then use the amended URI to add the new data values Each

Contacts table exposes a name for this purpose as a CONTENT_DIRECTORY constant The following

code continues the previous example by adding a phone number and e-mail address for the record

just created

Uri phoneUri = null Uri emailUri = null Add a phone number for Abraham Lincoln Begin with the URI for the new record just returned by insert() it ends with the _ID of the new record so we dont have to add the ID ourselves Then append the designation for the phone table to this URI and use the resulting URI to insert the phone number phoneUri = UriwithAppendedPath(uri PeoplePhonesCONTENT_DIRECTORY) valuesclear() valuesput(PeoplePhonesTYPE PeoplePhonesTYPE_MOBILE) valuesput(PeoplePhonesNUMBER 1233214567) getContentResolver()insert(phoneUri values) Now add an email address in the same way emailUri = UriwithAppendedPath(uri PeopleContactMethodsCONTENT_DIRECTORY) valuesclear() ContactMethodsKIND is used to distinguish different kinds of contact methods such as email IM etc valuesput(PeopleContactMethodsKIND ContactsKIND_EMAIL) valuesput(PeopleContactMethodsDATA testexamplecom) valuesput(PeopleContactMethodsTYPE PeopleContactMethodsTYPE_HOME) getContentResolver()insert(emailUri values)

You can place small amounts of binary data into a table by calling the version of ContentValuesput()

that takes a byte array That would work for a small icon-like image or a short audio clip for example

However if you have a large amount of binary data to add such as a photograph or a complete song

put a content URI for the data in the table and call ContentResolveropenOutputStream() with the files

URI (That causes the content provider to store the data in a file and record the file path in a hidden

field of the record)

In this regard the MediaStore content provider the main provider that dispenses image audio and

video data employs a special convention The same URI that is used with query() or managedQuery()

to get meta-information about the binary data (such as the caption of a photograph or the date it was

taken) is used with openInputStream() to get the data itself Similarly the same URI that is used with

insert() to put meta-information into a MediaStore record is used with openOutputStream() to place the

binary data there The following code snippet illustrates this convention

import androidproviderMediaStoreImagesMedia import androidcontentContentValues import javaioOutputStream Save the name and description of an image in a ContentValues map ContentValues values = new ContentValues(3) valuesput(MediaDISPLAY_NAME road_trip_1) valuesput(MediaDESCRIPTION Day 1 trip to Los Angeles) valuesput(MediaMIME_TYPE imagejpeg) Add a new record without the bitmap but with the values just set insert() returns the URI of the new record Uri uri = getContentResolver()insert(MediaEXTERNAL_CONTENT_URI values) Now get a handle to the file for that record and save the data into it Here sourceBitmap is a Bitmap object representing the file to save to the database try OutputStream outStream = getContentResolver()openOutputStream(uri) sourceBitmapcompress(BitmapCompressFormatJPEG 50 outStream) outStreamclose() catch (Exception e) Loge(TAG exception while writing image e)

Batch updating records

To batch update a group of records (for example to change NY to New York in all fields) call the

ContentResolverupdate() method with the columns and values to change

Deleting a record

To delete a single record call ContentResolverdelete() with the URI of a specific row

To delete multiple rows call ContentResolverdelete() with the URI of the type of record to delete (for

example androidproviderContactsPeopleCONTENT_URI) and an SQL WHERE clause defining

which rows to delete (Caution Be sure to include a valid WHERE clause if youre deleting a general

type or you risk deleting more records than you intended)

Creating a Content Provider

To create a content provider you must

Set up a system for storing the data Most content providers store their data using Androids file

storage methods or SQLite databases but you can store your data any way you want Android

provides the SQLiteOpenHelper class to help you create a database and SQLiteDatabase to manage

it

Extend the ContentProvider class to provide access to the data

Declare the content provider in the manifest file for your application (AndroidManifestxml)

The following sections have notes on the last two of these tasks

Extending the ContentProvider class

You define a ContentProvider subclass to expose your data to others using the conventions expected

by ContentResolver and Cursor objects Principally this means implementing six abstract methods

declared in the ContentProvider class

query()

insert()

update()

delete()

getType()

onCreate()

The query() method must return a Cursor object that can iterate over the requested data Cursor itself

is an interface but Android provides some ready-made Cursor objects that you can use For example

SQLiteCursor can iterate over data stored in an SQLite database You get the Cursor object by calling

any of the SQLiteDatabase classs query() methods There are other Cursor implementations mdash such

as MatrixCursor mdash for data not stored in a database

Because these ContentProvider methods can be called from various ContentResolver objects in

different processes and threads they must be implemented in a thread-safe manner

As a courtesy you might also want to call ContentResolvernotifyChange() to notify listeners when

there are modifications to the data

Beyond defining the subclass itself there are other steps you should take to simplify the work of clients

and make the class more accessible

Define a public static final Uri named CONTENT_URI This is the string that represents the full content

URI that your content provider handles You must define a unique string for this value The best

solution is to use the fully-qualified class name of the content provider (made lowercase) So for

example the URI for a TransportationProvider class could be defined as follows

public static final Uri CONTENT_URI = Uriparse(contentcomexamplecodelabtransportationprovider)

If the provider has subtables also define CONTENT_URI constants for each of the subtables These

URIs should all have the same authority (since that identifies the content provider) and be

distinguished only by their paths For example

contentcomexamplecodelabtransportationprovidertrain

contentcomexamplecodelabtransportationproviderairdomestic

contentcomexamplecodelabtransportationproviderairinternational

For an overview of content URIs see the Content URI Summary at the end of this document

Define the column names that the content provider will return to clients If you are using an underlying

database these column names are typically identical to the SQL database column names they

represent Also define public static String constants that clients can use to specify the columns in

queries and other instructions

Be sure to include an integer column named _id (with the constant _ID) for the IDs of the records

You should have this field whether or not you have another field (such as a URL) that is also unique

among all records If youre using the SQLite database the _ID field should be the following type

INTEGER PRIMARY KEY AUTOINCREMENT

The AUTOINCREMENT descriptor is optional But without it SQLite increments an ID counter field to

the next number above the largest existing number in the column If you delete the last row the next

row added will have the same ID as the deleted row AUTOINCREMENT avoids this by having SQLite

increment to the next largest value whether deleted or not

Carefully document the data type of each column Clients need this information to read the data

If you are handling a new data type you must define a new MIME type to return in your

implementation of ContentProvidergetType() The type depends in part on whether or not the content

URI submitted to getType() limits the request to a specific record Theres one form of the MIME type

for a single record and another for multiple records Use the Uri methods to help determine what is

being requested Here is the general format for each type

o For a single record vndandroidcursoritemvndyourcompanynamecontenttype

For example a request for train record 122 like this URI

contentcomexampletransportationprovidertrains122

might return this MIME type

vndandroidcursoritemvndexamplerail

o For multiple records vndandroidcursordirvndyourcompanynamecontenttype

For example a request for all train records like the following URI

contentcomexampletransportationprovidertrains

might return this MIME type

vndandroidcursordirvndexamplerail

If you are exposing byte data thats too big to put in the table itself mdash such as a large bitmap file mdash the

field that exposes the data to clients should actually contain a content URI string This is the field that

gives clients access to the data file The record should also have another field named _data that lists

the exact file path on the device for that file This field is not intended to be read by the client but by

the ContentResolver The client will call ContentResolveropenInputStream() on the user-facing field

holding the URI for the item The ContentResolver will request the _data field for that record and

because it has higher permissions than a client it should be able to access that file directly and return

a read wrapper for the file to the client

For an example of a private content provider implementation see the NodePadProvider class in the

Notepad sample application that ships with the SDK

Declaring the content provider

To let the Android system know about the content provider youve developed declare it with a

ltprovidergt element in the applications AndroidManifestxml file Content providers that are not

declared in the manifest are not visible to the Android system

The name attribute is the fully qualified name of the ContentProvider subclass The authorities attribute

is the authority part of the content URI that identifies the provider For example if the ContentProvider

subclass is AutoInfoProvider the ltprovidergt element might look like this

ltprovider androidname=comexampleautosAutoInfoProvider androidauthorities=comexampleautosautoinfoprovider gt ltprovidergt

Note that the authorities attribute omits the path part of a content URI For example if

AutoInfoProvider controlled subtables for different types of autos or different manufacturers

contentcomexampleautosautoinfoproviderhonda

contentcomexampleautosautoinfoprovidergmcompact

contentcomexampleautosautoinfoprovidergmsuv

those paths would not be declared in the manifest The authority is what identifies the provider not the

path your provider can interpret the path part of the URI in any way you choose

Other ltprovidergt attributes can set permissions to read and write data provide for an icon and text

that can be displayed to users enable and disable the provider and so on Set the multiprocess

attribute to true if data does not need to be synchronized between multiple running versions of the

content provider This permits an instance of the provider to be created in each client process

eliminating the need to perform IPC

Content URI Summary

Here is a recap of the important parts of a content URI

A Standard prefix indicating that the data is controlled by a content provider Its never modified

B The authority part of the URI it identifies the content provider For third-party applications this should

be a fully-qualified class name (reduced to lowercase) to ensure uniqueness The authority is declared

in the ltprovidergt elements authorities attribute

ltprovider androidname=TransportationProvider androidauthorities=comexampletransportationprovider gt

C The path that the content provider uses to determine what kind of data is being requested This can be

zero or more segments long If the content provider exposes only one type of data (only trains for

example) it can be absent If the provider exposes several types including subtypes it can be several

segments long mdash for example landbus landtrain seaship and seasubmarine to give four

possibilities

D The ID of the specific record being requested if any This is the _ID value of the requested record If

the request is not limited to a single record this segment and the trailing slash are omitted

contentcomexampletransportationprovidertrains

Intent and intent filters

Three of the core components of an application mdash activities services and broadcast receivers mdash 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 mdash 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 ContextstartActivity() or ActivitystartActivityForResult() to launch an

activity or get an existing activity to do something new (It can also be passed to ActivitysetResult() to

return information to the activity that called startActivityForResult())

An Intent object is passed to ContextstartService() to initiate a service or deliver new instructions to an

ongoing service Similarly an intent can be passed to ContextbindService() to establish a connection

between the calling component and a target service It can optionally initiate the service if its not

already running

Intent objects passed to any of the broadcast methods (such as ContextsendBroadcast()

ContextsendOrderedBroadcast() or ContextsendStickyBroadcast()) 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 mdash how it resolves which component should receive an intent message For

intents that dont explicitly name a target component this process involves testing the Intent object

against intent filters associated with potential targets

Intent Objects

An Intent object is a bundle of information It contains information of interest to the component that

receives the intent (such as the action to be taken and the data to act on) plus information of interest to

the Android system (such as the category of component that should handle the intent and instructions

on how to launch a target activity) Principally it can contain the following

Component name

The name of the component that should handle the intent This field is a ComponentName

object mdash a combination of the fully qualified class name of the target component (for example

comexampleprojectappFreneticActivity) and the package name set in the manifest file of the

application where the component resides (for example comexampleproject) The package

part of the component name and the package name set in the manifest do not necessarily have

to match

The component name is optional If it is set the Intent object is delivered to an instance of the

designated class If it is not set Android uses other information in the Intent object to locate a

suitable target mdash see Intent Resolution later in this document

The component name is set by setComponent() setClass() or setClassName() and read by

getComponent()

Action

A string naming the action to be performed mdash or in the case of broadcast intents the action

that took place and is being reported The Intent class defines a number of action constants

including these

Constant Target

component

Action

ACTION_CALL activity Initiate a phone call

ACTION_EDIT activity Display data for the user to edit

ACTION_MAIN activity Start up as the initial activity of a task

with no data input and no returned

output

ACTION_SYNC activity Synchronize data on a server with

data on the mobile device

ACTION_BATTERY_LOW broadcast

receiver

A warning that the battery is low

ACTION_HEADSET_PLUG broadcast

receiver

A headset has been plugged into the

device or unplugged from it

ACTION_SCREEN_ON broadcast

receiver

The screen has been turned on

ACTION_TIMEZONE_CHANGED broadcast

receiver

The setting for the time zone has

changed

See the Intent class description for a list of pre-defined constants for generic actions Other

actions are defined elsewhere in the Android API You can also define your own action strings

for activating the components in your application Those you invent should include the

application package as a prefix mdash for example comexampleprojectSHOW_COLOR

The action largely determines how the rest of the intent is structured mdash particularly the data and

extras fields mdash much as a method name determines a set of arguments and a return value For

this reason its a good idea to use action names that are as specific as possible and to couple

them tightly to the other fields of the intent In other words instead of defining an action in

isolation define an entire protocol for the Intent objects your components can handle

The action in an Intent object is set by the setAction() method and read by getAction()

Data

The URI of the data to be acted on and the MIME type of that data Different actions are paired

with different kinds of data specifications For example if the action field is ACTION_EDIT the

data field would contain the URI of the document to be displayed for editing If the action is

ACTION_CALL the data field would be a tel URI with the number to call Similarly if the action

is ACTION_VIEW and the data field is an http URI the receiving activity would be called upon

to download and display whatever data the URI refers to

When matching an intent to a component that is capable of handling the data its often

important to know the type of data (its MIME type) in addition to its URI For example a

component able to display image data should not be called upon to play an audio file

In many cases the data type can be inferred from the URI mdash particularly content URIs which

indicate that the data is located on the device and controlled by a content provider (see the

separate discussion on content providers) But the type can also be explicitly set in the Intent

object The setData() method specifies data only as a URI setType() specifies it only as a

MIME type and setDataAndType() specifies it as both a URI and a MIME type The URI is read

by getData() and the type by getType()

Category

A string containing additional information about the kind of component that should handle the

intent Any number of category descriptions can be placed in an Intent object As it does for

actions the Intent class defines several category constants including these

Constant Meaning

CATEGORY_BROWSABLE The target activity can be safely invoked by the browser to

display data referenced by a link mdash for example an image or

an e-mail message

CATEGORY_GADGET The activity can be embedded inside of another activity that

hosts gadgets

CATEGORY_HOME The activity displays the home screen the first screen the

user sees when the device is turned on or when the HOME

key is pressed

CATEGORY_LAUNCHER The activity can be the initial activity of a task and is listed in

the top-level application launcher

CATEGORY_PREFERENCE The target activity is a preference panel

See the Intent class description for the full list of categories

The addCategory() method places a category in an Intent object removeCategory() deletes a

category previously added and getCategories() gets the set of all categories currently in the

object

Extras

Key-value pairs for additional information that should be delivered to the component handling

the intent Just as some actions are paired with particular kinds of data URIs some are paired

with particular extras For example an ACTION_TIMEZONE_CHANGED intent has a time-

zone extra that identifies the new time zone and ACTION_HEADSET_PLUG has a state

extra indicating whether the headset is now plugged in or unplugged as well as a name extra

for the type of headset If you were to invent a SHOW_COLOR action the color value would be

set in an extra key-value pair

The Intent object has a series of put() methods for inserting various types of extra data and a

similar set of get() methods for reading the data These methods parallel those for Bundle

objects In fact the extras can be installed and read as a Bundle using the putExtras() and

getExtras() methods

Flags

Flags of various sorts Many instruct the Android system how to launch an activity (for example

which task the activity should belong to) and how to treat it after its launched (for example

whether it belongs in the list of recent activities) All these flags are defined in the Intent class

The Android system and the applications that come with the platform employ Intent objects both to

send out system-originated broadcasts and to activate system-defined components To see how to

structure an intent to activate a system component consult the list of intents in the reference

Intent Resolution

Intents can be divided into two groups

Explicit intents designate the target component by its name (the component name field mentioned

earlier has a value set) Since component names would generally not be known to developers of other

applications explicit intents are typically used for application-internal messages mdash such as an activity

starting a subordinate service or launching a sister activity

Implicit intents do not name a target (the field for the component name is blank) Implicit intents are

often used to activate components in other applications

Android delivers an explicit intent to an instance of the designated target class Nothing in the Intent

object other than the component name matters for determining which component should get the intent

A different strategy is needed for implicit intents In the absence of a designated target the Android

system must find the best component (or components) to handle the intent mdash a single activity or

service to perform the requested action or the set of broadcast receivers to respond to the broadcast

announcement It does so by comparing the contents of the Intent object to intent filters structures

associated with components that can potentially receive intents Filters advertise the capabilities of a

component and delimit the intents it can handle They open the component to the possibility of

receiving implicit intents of the advertised type If a component does not have any intent filters it can

receive only explicit intents A component with filters can receive both explicit and implicit intents

Only three aspects of an Intent object are consulted when the object is tested against an intent filter

action

data (both URI and data type)

category

The extras and flags play no part in resolving which component receives an intent

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 mdash but only unwanted implicit intents (those that dont 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

components 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 mdash 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 Pads filters are described in the Note Pad Example

section later)

Filters and security

An intent filter cannot be relied on for security While it opens a component to receiving only certain

kinds of implicit intents it does nothing to prevent explicit intents from targeting the component Even

though a filter restricts the intents a component will be asked to handle to certain actions and data

sources someone could always put together an explicit intent with a different action and data source

and name the component as the target

An intent filter is an instance of the IntentFilter class However since the Android system must know

about the capabilities of a component before it can launch that component intent filters are generally

not set up in Java code but in the applications manifest file (AndroidManifestxml) as ltintent-filtergt

elements (The one exception would be filters for broadcast receivers that are registered dynamically

by calling ContextregisterReceiver() they are directly created as IntentFilter objects)

A filter has fields that parallel the action data and category fields of an Intent object An implicit intent

is tested against the filter in all three areas To be delivered to the component that owns the filter it

must pass all three tests If it fails even one of them the Android system wont deliver it to the

component mdash at least not on the basis of that filter However since a component can have multiple

intent filters an intent that does not pass through one of a components filters might make it through on

another

Each of the three tests is described in detail below

Action test

An ltintent-filtergt element in the manifest file lists actions as ltactiongt subelements For

example

ltintent-filter gt ltaction androidname=comexampleprojectSHOW_CURRENT gt ltaction androidname=comexampleprojectSHOW_RECENT gt ltaction androidname=comexampleprojectSHOW_PENDING gt ltintent-filtergt

As the example shows while an Intent object names just a single action a filter may list more

than one The list cannot be empty a filter must contain at least one ltactiongt element or it will

block all intents

To pass this test the action specified in the Intent object must match one of the actions listed in

the filter If the object or the filter does not specify an action the results are as follows

If the filter fails to list any actions there is nothing for an intent to match so all intents fail the

test No intents can get through the filter

On the other hand an Intent object that doesnt specify an action automatically passes the test

mdash as long as the filter contains at least one action

Category test

An ltintent-filtergt element also lists categories as subelements For example

ltintent-filter gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryBROWSABLE gt ltintent-filtergt

Note that the constants described earlier for actions and categories are not used in the manifest

file The full string values are used instead For instance the

androidintentcategoryBROWSABLE string in the example above corresponds to the

CATEGORY_BROWSABLE constant mentioned earlier in this document Similarly the string

androidintentactionEDIT corresponds to the ACTION_EDIT constant

For an intent to pass the category test every category in the Intent object must match a

category in the filter The filter can list additional categories but it cannot omit any that are in the

intent

In principle therefore an Intent object with no categories should always pass this test

regardless of whats in the filter Thats mostly true However with one exception Android treats

all implicit intents passed to startActivity() as if they contained at least one category

androidintentcategoryDEFAULT (the CATEGORY_DEFAULT constant) Therefore activities

that are willing to receive implicit intents must include androidintentcategoryDEFAULT in

their intent filters (Filters with androidintentactionMAIN and

androidintentcategoryLAUNCHER settings are the exception They mark activities that begin

new tasks and that are represented on the launcher screen They can include

androidintentcategoryDEFAULT in the list of categories but dont need to) See Using intent

matching later for more on these filters)

Data test

Like the action and categories the data specification for an intent filter is contained in a

subelement And as in those cases the subelement can appear multiple times or not at all For

example

ltintent-filter gt ltdata androidmimeType=videompeg androidscheme=http gt ltdata androidmimeType=audiompeg androidscheme=http gt ltintent-filtergt

Each ltdatagt element can specify a URI and a data type (MIME media type) There are

separate attributes mdash scheme host port and path mdash for each part of the URI

schemehostportpath

For example in the following URI

contentcomexampleproject200foldersubfolderetc

the scheme is content the host is comexampleproject the port is 200 and the path is

foldersubfolderetc The host and port together constitute the URI authority if a host is not

specified the port is ignored

Each of these attributes is optional but they are not independent of each other For an authority

to be meaningful a scheme must also be specified For a path to be meaningful both a scheme

and an authority must be specified

When the URI in an Intent object is compared to a URI specification in a filter its compared

only to the parts of the URI actually mentioned in the filter For example if a filter specifies only

a scheme all URIs with that scheme match the filter If a filter specifies a scheme and an

authority but no path all URIs with the same scheme and authority match regardless of their

paths If a filter specifies a scheme an authority and a path only URIs with the same scheme

authority and path match However a path specification in the filter can contain wildcards to

require only a partial match of the path

The type attribute of a ltdatagt element specifies the MIME type of the data Its more common in

filters than a URI Both the Intent object and the filter can use a wildcard for the subtype field

mdash for example text or audio mdash indicating any subtype matches

The data test compares both the URI and the data type in the Intent object to a URI and data

type specified in the filter The rules are as follows

a An Intent object that contains neither a URI nor a data type passes the test only if the filter

likewise does not specify any URIs or data types

b An Intent object that contains a URI but no data type (and a type cannot be inferred from the

URI) passes the test only if its URI matches a URI in the filter and the filter likewise does not

specify a type This will be the case only for URIs like mailto and tel that do not refer to actual

data

c An Intent object that contains a data type but not a URI passes the test only if the filter lists the

same data type and similarly does not specify a URI

d An Intent object that contains both a URI and a data type (or a data type can be inferred from

the URI) passes the data type part of the test only if its type matches a type listed in the filter It

passes the URI part of the test either if its URI matches a URI in the filter or if it has a content

or file URI and the filter does not specify a URI In other words a component is presumed to

support content and file data if its filter lists only a data type

If an intent can pass through the filters of more than one activity or service the user may be asked

which component to activate An exception is raised if no target can be found

Common cases

The last rule shown above for the data test rule (d) reflects the expectation that components are able

to get local data from a file or content provider Therefore their filters can list just a data type and do

not need to explicitly name the content and file schemes This is a typical case A ltdatagt element like

the following for example tells Android that the component can get image data from a content

provider and display it

ltdata androidmimeType=image gt

Since most available data is dispensed by content providers filters that specify a data type but not a

URI are perhaps the most common

Another common configuration is filters with a scheme and a data type For example a ltdatagt

element like the following tells Android that the component can get video data from the network and

display it

ltdata androidscheme=http androidtype=video gt

Consider for example what the browser application does when the user follows a link on a web page

It first tries to display the data (as it could if the link was to an HTML page) If it cant display the data it

puts together an implicit intent with the scheme and data type and tries to start an activity that can do

the job If there are no takers it asks the download manager to download the data That puts it under

the control of a content provider so a potentially larger pool of activities (those with filters that just

name a data type) can respond

Most applications also have a way to start fresh without a reference to any particular data Activities

that can initiate applications have filters with androidintentactionMAIN specified as the action If

they are to be represented in the application launcher they also specify the

androidintentcategoryLAUNCHER category

ltintent-filter gt ltaction androidname=code androidintentactionMAIN gt ltcategory androidname=code androidintentcategoryLAUNCHER gt ltintent-filtergt

Using intent matching

Intents are matched against intent filters not only to discover a target component to activate but also

to discover something about the set of components on the device For example the Android system

populates the application launcher the top-level screen that shows the applications that are available

for the user to launch by finding all the activities with intent filters that specify the

androidintentactionMAIN action and androidintentcategoryLAUNCHER category (as illustrated

in the previous section) It then displays the icons and labels of those activities in the launcher

Similarly it discovers the home screen by looking for the activity with androidintentcategoryHOME

in its filter

Your application can use intent matching is a similar way The PackageManager has a set of query()

methods that return all components that can accept a particular intent and a similar series of

resolve() methods that determine the best component to respond to an intent For example

queryIntentActivities() returns a list of all activities that can perform the intent passed as an argument

and queryIntentServices() returns a similar list of services Neither method activates the components

they just list the ones that can respond Theres a similar method queryBroadcastReceivers() for

broadcast receivers

Note Pad Example

The Note Pad sample application enables users to browse through a list of notes view details about

individual items in the list edit the items and add a new item to the list This section looks at the intent

filters declared in its manifest file (If youre working offline in the SDK you can find all the source files

for this sample application including its manifest file at ltsdkgtsamplesNotePadindexhtml If youre

viewing the documentation online the source files are in the Tutorials and Sample Code section here)

In its manifest file the Note Pad application declares three activities each with at least one intent filter

It also declares a content provider that manages the note data Here is the manifest file in its entirety

ltmanifest xmlnsandroid=httpschemasandroidcomapkresandroid package=comexampleandroidnotepadgt ltapplication androidicon=drawableapp_notes androidlabel=stringapp_name gt ltprovider androidname=NotePadProvider androidauthorities=comgoogleproviderNotePad gt ltactivity androidname=NotesList androidlabel=stringtitle_notes_listgt ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltactivity androidname=NoteEditor androidtheme=androidstyleThemeLight androidlabel=stringtitle_note gt ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltactivitygt

ltactivity androidname=TitleEditor androidlabel=stringtitle_edit_title androidtheme=androidstyleThemeDialoggt ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltapplicationgt ltmanifestgt

The first activity NotesList is distinguished from the other activities by the fact that it operates on a

directory of notes (the note list) rather than on a single note It would generally serve as the initial user

interface into the application It can do three things as described by its three intent filters

1 ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt

This filter declares the main entry point into the Note Pad application The standard MAIN action is an

entry point that does not require any other information in the Intent (no data specification for example)

and the LAUNCHER category says that this entry point should be listed in the application launcher

2 ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

This filter declares the things that the activity can do on a directory of notes It can allow the user to

view or edit the directory (via the VIEW and EDIT actions) or to pick a particular note from the

directory (via the PICK action)

The mimeType attribute of the ltdatagt element specifies the kind of data that these actions operate on

It indicates that the activity can get a Cursor over zero or more items (vndandroidcursordir) from a

content provider that holds Note Pad data (vndgooglenote) The Intent object that launches the

activity would include a content URI specifying the exact data of this type that the activity should open

Note also the DEFAULT category supplied in this filter Its there because the ContextstartActivity()

and ActivitystartActivityForResult() methods treat all intents as if they contained the DEFAULT

category mdash with just two exceptions

o Intents that explicitly name the target activity

o Intents consisting of the MAIN action and LAUNCHER category

Therefore the DEFAULT category is required for all filters mdash except for those with the MAIN action

and LAUNCHER category (Intent filters are not consulted for explicit intents)

3 ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

This filter describes the activitys ability to return a note selected by the user without requiring any

specification of the directory the user should choose from The GET_CONTENT action is similar to the

PICK action In both cases the activity returns the URI for a note selected by the user (In each case

its returned to the activity that called startActivityForResult() to start the NoteList activity) Here

however the caller specifies the type of data desired instead of the directory of data the user will be

picking from

The data type vndandroidcursoritemvndgooglenote indicates the type of data the activity can

return mdash a URI for a single note From the returned URI the caller can get a Cursor for exactly one

item (vndandroidcursoritem) from the content provider that holds Note Pad data (vndgooglenote)

In other words for the PICK action in the previous filter the data type indicates the type of data the

activity could display to the user For the GET_CONTENT filter it indicates the type of data the activity

can return to the caller

Given these capabilities the following intents will resolve to the NotesList activity

action androidintentactionMAIN

Launches the activity with no data specified

action androidintentactionMAIN

category androidintentcategoryLAUNCHER

Launches the activity with no data selected specified This is the actual intent used by the

Launcher to populate its top-level list All activities with filters that match this action and

category are added to the list

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of all the notes under

contentcomgoogleproviderNotePadnotes The user can then browse through the list and

get information about the items in it

action androidintentactionPICK

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of the notes under

contentcomgoogleproviderNotePadnotes The user can then pick a note from the list and

the activity will return the URI for that item back to the activity that started the NoteList activity

action androidintentactionGET_CONTENT

data type vndandroidcursoritemvndgooglenote

Asks the activity to supply a single item of Note Pad data

The second activity NoteEditor shows users a single note entry and allows them to edit it It can do

two things as described by its two intent filters

1 ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The first primary purpose of this activity is to enable the user to interact with a single note ampmdash to

either VIEW the note or EDIT it (The EDIT_NOTE category is a synonym for EDIT) The intent would

contain the URI for data matching the MIME type vndandroidcursoritemvndgooglenote mdash that is

the URI for a single specific note It would typically be a URI that was returned by the PICK or

GET_CONTENT actions of the NoteList activity

As before this filter lists the DEFAULT category so that the activity can be launched by intents that

dont explicitly specify the NoteEditor class

2 ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

The secondary purpose of this activity is to enable the user to create a new note which it will INSERT

into an existing directory of notes The intent would contain the URI for data matching the MIME type

vndandroidcursordirvndgooglenote mdash that is the URI for the directory where the note should be

placed

Given these capabilities the following intents will resolve to the NoteEditor activity

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID (For details on how content

URIs specify individual members of a group see Content Providers)

action androidintentactionEDIT

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID and to let the user edit it If

the user saves the changes the activity updates the data for the note in the content provider

action androidintentactionINSERT

data contentcomgoogleproviderNotePadnotes

Asks the activity to create a new empty note in the notes list at

contentcomgoogleproviderNotePadnotes and allow the user to edit it If the user saves the

note its URI is returned to the caller

The last activity TitleEditor enables the user to edit the title of a note This could be implemented by

directly invoking the activity (by explicitly setting its component name in the Intent) without using an

intent filter But here we take the opportunity to show how to publish alternative operations on existing

data

ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The single intent filter for this activity uses a custom action called

comandroidnotepadactionEDIT_TITLE It must be invoked on a specific note (data type

vndandroidcursoritemvndgooglenote) like the previous VIEW and EDIT actions However here the

activity displays the title contained in the note data not the content of the note itself

In addition to supporting the usual DEFAULT category the title editor also supports two other standard

categories ALTERNATIVE and SELECTED_ALTERNATIVE These categories identify activities that

can be presented to users in a menu of options (much as the LAUNCHER category identifies activities

that should be presented to user in the application launcher) Note that the filter also supplies an

explicit label (via androidlabel=stringresolve_title) to better control what users see when

presented with this activity as an alternative action to the data they are currently viewing (For more

information on these categories and building options menus see the

PackageManagerqueryIntentActivityOptions() and MenuaddIntentOptions() methods)

Given these capabilities the following intent will resolve to the TitleEditor activity

action comandroidnotepadactionEDIT_TITLE

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the title associated with note ID and allow the user to edit the title

Processes and Threads

When an application component starts and the application does not have any other components

running the Android system starts a new Linux process for the application with a single thread of

execution By default all components of the same application run in the same process and thread

(called the main thread) If an application component starts and there already exists a process for

that application (because another component from the application exists) then the component is

started within that process and uses the same thread of execution However you can arrange for

different components in your application to run in separate processes and you can create additional

threads for any process

This document discusses how processes and threads work in an Android application

Processes

By default all components of the same application run in the same process and most applications

should not change this However if you find that you need to control which process a certain

component belongs to you can do so in the manifest file

The manifest entry for each type of component elementmdashltactivitygt ltservicegt ltreceivergt and

ltprovidergtmdashsupports an androidprocess attribute that can specify a process in which that component

should run You can set this attribute so that each component runs in its own process or so that some

components share a process while others do not You can also set androidprocess so that

components of different applications run in the same processmdashprovided that the applications share the

same Linux user ID and are signed with the same certificates

The ltapplicationgt element also supports an androidprocess attribute to set a default value that

applies to all components

Android might 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 thats killed are consequently destroyed A process is started again for those components

when theres again work for them to do

When deciding which processes to kill the Android system weighs their relative importance to the

user For example it more readily shuts down a process hosting activities that are no longer visible on

screen compared to a process hosting visible activities The decision whether to terminate a process

therefore depends on the state of the components running in that process The rules used to decide

which processes to terminate is discussed below

Process lifecycle

The Android system tries to maintain an application process for as long as possible but eventually

needs to remove old processes to reclaim memory for new or more important processes To determine

which processes to keep and which to kill the system places each process into an importance

hierarchy based on the components running in the process and the state of those components

Processes with the lowest importance are eliminated first then those with the next lowest importance

and so on as necessary to recover system resources

There are five levels in the importance hierarchy The following list presents the different types of

processes in order of importance (the first process is most important and is killed last)

1 Foreground process

A process that is required for what the user is currently doing A process is considered to be in the

foreground if any of the following conditions are true

o It hosts an Activity that the user is interacting with (the Activitys onResume() method has been called)

o It hosts a Service thats bound to the activity that the user is interacting with

o It hosts a Service thats running in the foregroundmdashthe service has called startForeground()

o It hosts a Service thats executing one of its lifecycle callbacks (onCreate() onStart() or onDestroy())

o It hosts a BroadcastReceiver thats executing its onReceive() method

Generally only a few foreground processes exist at any given time They are killed only as a last

resortmdashif memory is so low that they cannot all continue to run Generally at that point the device has

reached a memory paging state so killing some foreground processes is required to keep the user

interface responsive

2 Visible process

A process that doesnt have any foreground components but still can affect what the user sees on

screen A process is considered to be visible if either of the following conditions are true

o It hosts an Activity that is not in the foreground but is still visible to the user (its onPause() method has

been called) This might occur for example if the foreground activity started a dialog which allows the

previous activity to be seen behind it

o It hosts a Service thats bound to a visible (or foreground) activity

A visible process is considered extremely important and will not be killed unless doing so is required to

keep all foreground processes running

3 Service process

A process that is running a service that has been started with the startService() method and does not

fall into either of the two higher categories Although service processes are not directly tied to anything

the user sees they are generally doing things that the user cares about (such as playing music in the

background or downloading data on the network) so the system keeps them running unless theres

not enough memory to retain them along with all foreground and visible processes

4 Background process

A process holding an activity thats not currently visible to the user (the activitys onStop() method has

been called) These processes have no direct impact on the user experience and the system can kill

them at any time to reclaim memory for a foreground visible or service process Usually there are

many background processes running so they are kept in an LRU (least recently used) list to ensure

that the process with the activity that was most recently seen by the user is the last to be killed If an

activity implements its lifecycle methods correctly and saves its current state killing its process will not

have a visible effect on the user experience because when the user navigates back to the activity the

activity restores all of its visible state See the Activities document for information about saving and

restoring state

5 Empty process

A process that doesnt hold any active application components The only reason to keep this kind of

process alive is for caching purposes to improve startup time the next time a component needs to run

in it The system often kills these processes in order to balance overall system resources between

process caches and the underlying kernel caches

Android ranks a process at the highest level it can based upon the importance of the components

currently active in the process For example if a process hosts a service and a visible activity the

process is ranked as a visible process not a service process

In addition a processs ranking might be increased because other processes are dependent on itmdasha

process that is serving another process can never be ranked lower than the process it is serving For

example if a content provider in process A is serving a client in process B or if a service in process A

is bound to a component in process B process A is always considered at least as important as

process B

Because a process running a service is ranked higher than a process with background activities an

activity that initiates a long-running operation might do well to start a service for that operation rather

than simply create a worker threadmdashparticularly if the operation will likely outlast the activity For

example an activity thats uploading a picture to a web site should start a service to perform the

upload so that the upload can continue in the background even if the user leaves the activity Using a

service guarantees that the operation will have at least service process priority regardless of what

happens to the activity This is the same reason that broadcast receivers should employ services

rather than simply put time-consuming operations in a thread

Threads

When an application is launched the system creates a thread of execution for the application called

main This thread is very important because it is in charge of dispatching events to the appropriate

user interface widgets including drawing events It is also the thread in which your application interacts

with components from the Android UI toolkit (components from the androidwidget and androidview

packages) As such the main thread is also sometimes called the UI thread

The system does not create a separate thread for each instance of a component All components that

run in the same process are instantiated in the UI thread and system calls to each component are

dispatched from that thread Consequently methods that respond to system callbacks (such as

onKeyDown() to report user actions or a lifecycle callback method) always run in the UI thread of the

process

For instance when the user touches a button on the screen your apps UI thread dispatches the touch

event to the widget which in turn sets its pressed state and posts an invalidate request to the event

queue The UI thread dequeues the request and notifies the widget that it should redraw itself

When your app performs intensive work in response to user interaction this single thread model can

yield poor performance unless you implement your application properly Specifically if everything is

happening in the UI thread performing long operations such as network access or database queries

will block the whole UI When the thread is blocked no events can be dispatched including drawing

events From the users perspective the application appears to hang Even worse if the UI thread is

blocked for more than a few seconds (about 5 seconds currently) the user is presented with the

infamous application not responding (ANR) dialog The user might then decide to quit your

application and uninstall it if they are unhappy

Additionally the Andoid UI toolkit is not thread-safe So you must not manipulate your UI from a

worker threadmdashyou must do all manipulation to your user interface from the UI thread Thus there are

simply two rules to Androids single thread model

1 Do not block the UI thread

2 Do not access the Android UI toolkit from outside the UI thread

Worker threads

Because of the single thread model described above its vital to the responsiveness of your

applications UI that you do not block the UI thread If you have operations to perform that are not

instantaneous you should make sure to do them in separate threads (background or worker

threads)

For example below is some code for a click listener that downloads an image from a separate thread

and displays it in an ImageView

public void onClick(View v) new Thread(new Runnable() public void run() Bitmap b = loadImageFromNetwork(httpexamplecomimagepng) mImageViewsetImageBitmap(b) )start()

At first this seems to work fine because it creates a new thread to handle the network operation

However it violates the second rule of the single-threaded model do not access the Android UI toolkit

from outside the UI threadmdashthis sample modifies the ImageView from the worker thread instead of the

UI thread This can result in undefined and unexpected behavior which can be difficult and time-

consuming to track down

To fix this problem Android offers several ways to access the UI thread from other threads Here is a

list of methods that can help

ActivityrunOnUiThread(Runnable)

Viewpost(Runnable)

ViewpostDelayed(Runnable long)

For example you can fix the above code by using the Viewpost(Runnable) method

public void onClick(View v) new Thread(new Runnable() public void run() final Bitmap bitmap = loadImageFromNetwork(httpexamplecomimagepng) mImageViewpost(new Runnable() public void run() mImageViewsetImageBitmap(bitmap) ) )start()

Now this implementation is thread-safe the network operation is done from a separate thread while

the ImageView is manipulated from the UI thread

However as the complexity of the operation grows this kind of code can get complicated and difficult

to maintain To handle more complex interactions with a worker thread you might consider using a

Handler in your worker thread to process messages delivered from the UI thread Perhaps the best

solution though is to extend the AsyncTask class which simplifies the execution of worker thread

tasks that need to interact with the UI

Using AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface It performs the blocking

operations in a worker thread and then publishes the results on the UI thread without requiring you to

handle threads andor handlers yourself

To use it you must subclass AsyncTask and implement the doInBackground() callback method which

runs in a pool of background threads To update your UI you should implement onPostExecute()

which delivers the result from doInBackground() and runs in the UI thread so you can safely update

your UI You can then run the task by calling execute() from the UI thread

For example you can implement the previous example using AsyncTask this way

public void onClick(View v) new DownloadImageTask()execute(httpexamplecomimagepng) private class DownloadImageTask extends AsyncTaskltString Void Bitmapgt The system calls this to perform work in a worker thread and delivers it the parameters given to AsyncTaskexecute() protected Bitmap doInBackground(String urls) return loadImageFromNetwork(urls[0])

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 2: 03 services

The Basics

Should you use a service or a thread

A service is simply a component that can run in the background even when the user is not interacting

with your application Thus you should create a service only if that is what you need

If you need to perform work outside your main thread but only while the user is interacting with your

application then you should probably instead create a new thread and not a service For example if

you want to play some music but only while your activity is running you might create a thread in

onCreate() start running it in onStart() then stop it in onStop() Also consider using AsyncTask or

HandlerThread instead of the traditional Thread class See the Processes and Threading document

for more information about threads

Remember that if you do use a service it still runs in your applications main thread by default so you

should still create a new thread within the service if it performs intensive or blocking operations

To create a service you must create a subclass of Service (or one of its existing subclasses) In your

implementation you need to override some callback methods that handle key aspects of the service

lifecycle and provide a mechanism for components to bind to the service if appropriate The most

important callback methods you should override are

onStartCommand()

The system calls this method when another component such as an activity requests that the

service be started by calling startService() Once this method executes the service is started

and can run in the background indefinitely If you implement this it is your responsibility to stop

the service when its work is done by calling stopSelf() or stopService() (If you only want to

provide binding you dont need to implement this method)

onBind()

The system calls this method when another component wants to bind with the service (such as

to perform RPC) by calling bindService() In your implementation of this method you must

provide an interface that clients use to communicate with the service by returning an IBinder

You must always implement this method but if you dont want to allow binding then you should

return null

onCreate()

The system calls this method when the service is first created to perform one-time setup

procedures (before it calls either onStartCommand() or onBind()) If the service is already

running this method is not called

onDestroy()

The system calls this method when the service is no longer used and is being destroyed Your

service should implement this to clean up any resources such as threads registered listeners

receivers etc This is the last call the service receives

If a component starts the service by calling startService() (which results in a call to

onStartCommand()) then the service remains running until it stops itself with stopSelf() or another

component stops it by calling stopService()

If a component calls bindService() to create the service (and onStartCommand() is not called) then the

service runs only as long as the component is bound to it Once the service is unbound from all clients

the system destroys it

The Android system will force-stop a service only when memory is low and it must recover system

resources for the activity that has user focus If the service is bound to an activity that has user focus

then its less likely to be killed and if the service is declared to run in the foreground (discussed later)

then it will almost never be killed Otherwise if the service was started and is long-running then the

system will lower its position in the list of background tasks over time and the service will become

highly susceptible to killingmdashif your service is started then you must design it to gracefully handle

restarts by the system If the system kills your service it restarts it as soon as resources become

available again (though this also depends on the value you return from onStartCommand() as

discussed later) For more information about when the system might destroy a service see the

Processes and Threading document

In the following sections youll see how you can create each type of service and how to use it from

other application components

Declaring a service in the manifest

Like activities (and other components) you must declare all services in your applications manifest file

To declare your service add a ltservicegt element as a child of the ltapplicationgt element For

example

ltmanifest gt ltapplication gt ltservice androidname=ExampleService gt ltapplicationgt ltmanifestgt

There are other attributes you can include in the ltservicegt element to define properties such as

permissions required to start the service and the process in which the service should run The

androidname attribute is the only required attributemdashit specifies the class name of the service Once

you publish your application you should not change this name because if you do you might break

some functionality where explicit intents are used to reference your service (read the blog post Things

That Cannot Change)

See the ltservicegt element reference for more information about declaring your service in the manifest

Just like an activity a service can define intent filters that allow other components to invoke the service

using implicit intents By declaring intent filters components from any application installed on the

users device can potentially start your service if your service declares an intent filter that matches the

intent another application passes to startService()

If you plan on using your service only locally (other applications do not use it) then you dont need to

(and should not) supply any intent filters Without any intent filters you must start the service using an

intent that explicitly names the service class More information about starting a service is discussed

below

Additionally you can ensure that your service is private to your application only if you include the

androidexported attribute and set it to false This is effective even if your service supplies intent

filters

For more information about creating intent filters for your service see the Intents and Intent Filters

document

Creating a Started Service

Targeting Android 16 or lower

If youre building an application for Android 16 or lower you need to implement onStart() instead of

onStartCommand() (in Android 20 onStart() was deprecated in favor of onStartCommand())

For more information about providing compatibility with versions of Android older than 20 see the

onStartCommand() documentation

A started service is one that another component starts by calling startService() resulting in a call to the

services onStartCommand() method

When a service is started it has a lifecycle thats independent of the component that started it and the

service can run in the background indefinitely even if the component that started it is destroyed As

such the service should stop itself when its job is done by calling stopSelf() or another component

can stop it by calling stopService()

An application component such as an activity can start the service by calling startService() and

passing an Intent that specifies the service and includes any data for the service to use The service

receives this Intent in the onStartCommand() method

For instance suppose an activity needs to save some data to an online database The activity can

start a companion service and deliver it the data to save by passing an intent to startService() The

service receives the intent in onStartCommand() connects to the Internet and performs the database

transaction When the transaction is done the service stops itself and it is destroyed

Caution A services runs in the same process as the application in which it is declared and in the

main thread of that application by default So if your service performs intensive or blocking

operations while the user interacts with an activity from the same application the service will slow

down activity performance To avoid impacting application performance you should start a new

thread inside the service

Traditionally there are two classes you can extend to create a started service

Service

This is the base class for all services When you extend this class its important that you create

a new thread in which to do all the services work because the service uses your applications

main thread by default which could slow the performance of any activity your application is

running

IntentService

This is a subclass of Service that uses a worker thread to handle all start requests one at a

time This is the best option if you dont require that your service handle multiple requests

simultaneously All you need to do is implement onHandleIntent() which receives the intent for

each start request so you can do the background work

The following sections describe how you can implement your service using either one for these

classes

Extending the IntentService class

Because most started services dont need to handle multiple requests simultaneously (which can

actually be a dangerous multi-threading scenario) its probably best if you implement your service

using the IntentService class

The IntentService does the following

Creates a default worker thread that executes all intents delivered to onStartCommand() separate from

your applications main thread

Creates a work queue that passes one intent at a time to your onHandleIntent() implementation so

you never have to worry about multi-threading

Stops the service after all start requests have been handled so you never have to call stopSelf()

Provides default implementation of onBind() that returns null

Provides a default implementation of onStartCommand() that sends the intent to the work queue and

then to your onHandleIntent() implementation

All this adds up to the fact that all you need to do is implement onHandleIntent() to do the work

provided by the client (Though you also need to provide a small constructor for the service)

Heres an example implementation of IntentService

public class HelloIntentService extends IntentService A constructor is required and must call the super IntentService(String)

constructor with a name for the worker thread public HelloIntentService() super(HelloIntentService) The IntentService calls this method from the default worker thread with the intent that started the service When this method returns IntentService stops the service as appropriate Override protected void onHandleIntent(Intent intent) Normally we would do some work here like download a file For our sample we just sleep for 5 seconds long endTime = SystemcurrentTimeMillis() + 51000 while (SystemcurrentTimeMillis() lt endTime) synchronized (this) try wait(endTime - SystemcurrentTimeMillis()) catch (Exception e)

Thats all you need a constructor and an implementation of onHandleIntent()

If you decide to also override other callback methods such as onCreate() onStartCommand() or

onDestroy() be sure to call the super implementation so that the IntentService can properly handle

the life of the worker thread

For example onStartCommand() must return the default implementation (which is how the intent gets

delivered to onHandleIntent())

Override public int onStartCommand(Intent intent int flags int startId) ToastmakeText(this service starting ToastLENGTH_SHORT)show() return superonStartCommand(intentflagsstartId)

Besides onHandleIntent() the only method from which you dont need to call the super class is

onBind() (but you only need to implement that if your service allows binding)

In the next section youll see how the same kind of service is implemented when extending the base

Service class which is a lot more code but which might be appropriate if you need to handle

simultaneous start requests

Extending the Service class

As you saw in the previous section using IntentService makes your implementation of a started

service very simple If however you require your service to perform multi-threading (instead of

processing start requests through a work queue) then you can extend the Service class to handle

each intent

For comparison the following example code is an implementation of the Service class that performs

the exact same work as the example above using IntentService That is for each start request it uses

a worker thread to perform the job and processes only one request at a time

public class HelloService extends Service private Looper mServiceLooper private ServiceHandler mServiceHandler Handler that receives messages from the thread private final class ServiceHandler extends Handler public ServiceHandler(Looper looper) super(looper) Override public void handleMessage(Message msg) Normally we would do some work here like download a file For our sample we just sleep for 5 seconds long endTime = SystemcurrentTimeMillis() + 51000 while (SystemcurrentTimeMillis() lt endTime) synchronized (this) try wait(endTime - SystemcurrentTimeMillis()) catch (Exception e) Stop the service using the startId so that we dont stop the service in the middle of handling another job stopSelf(msgarg1) Override public void onCreate() Start up the thread running the service Note that we create a separate thread because the service normally runs in the processs main thread which we dont want to block We also make it background priority so CPU-intensive work will not disrupt our UI HandlerThread thread = new HandlerThread(ServiceStartArguments ProcessTHREAD_PRIORITY_BACKGROUND) threadstart() Get the HandlerThreads Looper and use it for our Handler

mServiceLooper = threadgetLooper() mServiceHandler = new ServiceHandler(mServiceLooper) Override public int onStartCommand(Intent intent int flags int startId) ToastmakeText(this service starting ToastLENGTH_SHORT)show() For each start request send a message to start a job and deliver the start ID so we know which request were stopping when we finish the job Message msg = mServiceHandlerobtainMessage() msgarg1 = startId mServiceHandlersendMessage(msg) If we get killed after returning from here restart return START_STICKY Override public IBinder onBind(Intent intent) We dont provide binding so return null return null Override public void onDestroy() ToastmakeText(this service done ToastLENGTH_SHORT)show()

As you can see its a lot more work than using IntentService

However because you handle each call to onStartCommand() yourself you can perform multiple

requests simultaneously Thats not what this example does but if thats what you want then you can

create a new thread for each request and run them right away (instead of waiting for the previous

request to finish)

Notice that the onStartCommand() method must return an integer The integer is a value that

describes how the system should continue the service in the event that the system kills it (as

discussed above the default implementation for IntentService handles this for you though you are

able to modify it) The return value from onStartCommand() must be one of the following constants

START_NOT_STICKY

If the system kills the service after onStartCommand() returns do not recreate the service

unless there are pending intents to deliver This is the safest option to avoid running your

service when not necessary and when your application can simply restart any unfinished jobs

START_STICKY

If the system kills the service after onStartCommand() returns recreate the service and call

onStartCommand() but do not redeliver the last intent Instead the system calls

onStartCommand() with a null intent unless there were pending intents to start the service in

which case those intents are delivered This is suitable for media players (or similar services)

that are not executing commands but running indefinitely and waiting for a job

START_REDELIVER_INTENT

If the system kills the service after onStartCommand() returns recreate the service and call

onStartCommand() with the last intent that was delivered to the service Any pending intents are

delivered in turn This is suitable for services that are actively performing a job that should be

immediately resumed such as downloading a file

For more details about these return values see the linked reference documentation for each constant

Starting a Service

You can start a service from an activity or other application component by passing an Intent (specifying

the service to start) to startService() The Android system calls the services onStartCommand()

method and passes it the Intent (You should never call onStartCommand() directly)

For example an activity can start the example service in the previous section (HelloSevice) using an

explicit intent with startService()

Intent intent = new Intent(this HelloServiceclass) startService(intent)

The startService() method returns immediately and the Android system calls the services

onStartCommand() method If the service is not already running the system first calls onCreate() then

calls onStartCommand()

If the service does not also provide binding the intent delivered with startService() is the only mode of

communication between the application component and the service However if you want the service

to send a result back then the client that starts the service can create a PendingIntent for a broadcast

(with getBroadcast()) and deliver it to the service in the Intent that starts the service The service can

then use the broadcast to deliver a result

Multiple requests to start the service result in multiple corresponding calls to the services

onStartCommand() However only one request to stop the service (with stopSelf() or stopService()) is

required to stop it

Stopping a service

A started service must manage its own lifecycle That is the system does not stop or destroy the

service unless it must recover system memory and the service continues to run after

onStartCommand() returns So the service must stop itself by calling stopSelf() or another component

can stop it by calling stopService()

Once requested to stop with stopSelf() or stopService() the system destroys the service as soon as

possible

However if your service handles multiple requests to onStartCommand() concurrently then you

shouldnt stop the service when youre done processing a start request because you might have since

received a new start request (stopping at the end of the first request would terminate the second one)

To avoid this problem you can use stopSelf(int) to ensure that your request to stop the service is

always based on the most recent start request That is when you call stopSelf(int) you pass the ID of

the start request (the startId delivered to onStartCommand()) to which your stop request corresponds

Then if the service received a new start request before you were able to call stopSelf(int) then the ID

will not match and the service will not stop

Caution Its important that your application stops its services when its done working to avoid

wasting system resources and consuming battery power If necessary other components can stop

the service by calling stopService() Even if you enable binding for the service you must always

stop the service yourself if it ever received a call to onStartCommand()

For more information about the lifecycle of a service see the section below about Managing the

Lifecycle of a Service

Creating a Bound Service

A bound service is one that allows application components to bind to it by calling bindService() in order

to create a long-standing connection (and generally does not allow components to start it by calling

startService())

You should create a bound service when you want to interact with the service from activities and other

components in your application or to expose some of your applications functionality to other

applications through interprocess communication (IPC)

To create a bound service you must implement the onBind() callback method to return an IBinder that

defines the interface for communication with the service Other application components can then call

bindService() to retrieve the interface and begin calling methods on the service The service lives only

to serve the application component that is bound to it so when there are no components bound to the

service the system destroys it (you do not need to stop a bound service in the way you must when the

service is started through onStartCommand())

To create a bound service the first thing you must do is define the interface that specifies how a client

can communicate with the service This interface between the service and a client must be an

implementation of IBinder and is what your service must return from the onBind() callback method

Once the client receives the IBinder it can begin interacting with the service through that interface

Multiple clients can bind to the service at once When a client is done interacting with the service it

calls unbindService() to unbind Once there are no clients bound to the service the system destroys

the service

There are multiple ways to implement a bound service and the implementation is more complicated

than a started service so the bound service discussion appears in a separate document about Bound

Services

Sending Notifications to the User

Once running a service can notify the user of events using Toast Notifications or Status Bar

Notifications

A toast notification is a message that appears on the surface of the current window for a moment then

disappears while a status bar notification provides an icon in the status bar with a message which the

user can select in order to take an action (such as start an activity)

Usually a status bar notification is the best technique when some background work has completed

(such as a file completed downloading) and the user can now act on it When the user selects the

notification from the expanded view the notification can start an activity (such as to view the

downloaded file)

See the Toast Notifications or Status Bar Notifications developer guides for more information

Running a Service in the Foreground

A foreground service is a service thats considered to be something the user is actively aware of and

thus not a candidate for the system to kill when low on memory A foreground service must provide a

notification for the status bar which is placed under the Ongoing heading which means that the

notification cannot be dismissed unless the service is either stopped or removed from the foreground

For example a music player that plays music from a service should be set to run in the foreground

because the user is explicitly aware of its operation The notification in the status bar might indicate the

current song and allow the user to launch an activity to interact with the music player

To request that your service run in the foreground call startForeground() This method takes two

parameters an integer that uniquely identifies the notification and the Notification for the status bar

For example

Notification notification = new Notification(Rdrawableicon getText(Rstringticker_text) SystemcurrentTimeMillis()) Intent notificationIntent = new Intent(this ExampleActivityclass) PendingIntent pendingIntent = PendingIntentgetActivity(this 0 notificationIntent 0) notificationsetLatestEventInfo(this getText(Rstringnotification_title) getText(Rstringnotification_message) pendingIntent) startForeground(ONGOING_NOTIFICATION notification)

To remove the service from the foreground call stopForeground() This method takes a boolean

indicating whether to remove the status bar notification as well This method does not stop the service

However if you stop the service while its still running in the foreground then the notification is also

removed

Note The methods startForeground() and stopForeground() were introduced in Android 20 (API

Level 5) In order to run your service in the foreground on older versions of the platform you must

use the previous setForeground() methodmdashsee the startForeground() documentation for

information about how to provide backward compatibility

For more information about notifications see Creating Status Bar Notifications

Managing the Lifecycle of a Service

The lifecycle of a service is much simpler than that of an activity However its even more important

that you pay close attention to how your service is created and destroyed because a service can run

in the background without the user being aware

The service lifecyclemdashfrom when its created to when its destroyedmdashcan follow two different paths

A started service

The service is created when another component calls startService() The service then runs indefinitely

and must stop itself by calling stopSelf() Another component can also stop the service by calling

stopService() When the service is stopped the system destroys it

A bound service

The service is created when another component (a client) calls bindService() The client then

communicates with the service through an IBinder interface The client can close the connection by

calling unbindService() Multiple clients can bind to the same service and when all of them unbind the

system destroys the service (The service does not need to stop itself)

These two paths are not entirely separate That is you can bind to a service that was already started

with startService() For example a background music service could be started by calling startService()

with an Intent that identifies the music to play Later possibly when the user wants to exercise some

control over the player or get information about the current song an activity can bind to the service by

calling bindService() In cases like this stopService() or stopSelf() does not actually stop the service

until all clients unbind

Implementing the lifecycle callbacks

Like an activity a service has lifecycle callback methods that you can implement to monitor changes in

the services state and perform work at the appropriate times The following skeleton service

demonstrates each of the lifecycle methods

Figure 2 The service lifecycle The diagram on the left shows the lifecycle when the service is created

with startService() and the diagram on the right shows the lifecycle when the service is created with

bindService()

public class ExampleService extends Service int mStartMode indicates how to behave if the service is killed IBinder mBinder interface for clients that bind boolean mAllowRebind indicates whether onRebind should be used Override public void onCreate() The service is being created Override public int onStartCommand(Intent intent int flags int startId) The service is starting due to a call to startService() return mStartMode Override public IBinder onBind(Intent intent) A client is binding to the service with bindService() return mBinder Override public boolean onUnbind(Intent intent) All clients have unbound with unbindService()

return mAllowRebind Override public void onRebind(Intent intent) A client is binding to the service with bindService() after onUnbind() has already been called Override public void onDestroy() The service is no longer used and is being destroyed

Note Unlike the activity lifecycle callback methods you are not required to call the superclass

implementation of these callback methods

By implementing these methods you can monitor two nested loops of the services lifecycle

The entire lifetime of a service happens between the time onCreate() is called and the time

onDestroy() returns Like an activity a service does its initial setup in onCreate() and releases all

remaining resources in onDestroy() For example a music playback service could create the thread

where the music will be played in onCreate() then stop the thread in onDestroy()

The onCreate() and onDestroy() methods are called for all services whether theyre created by

startService() or bindService()

The active lifetime of a service begins with a call to either onStartCommand() or onBind() Each

method is handed the Intent that was passed to either startService() or bindService() respectively

If the service is started the active lifetime ends the same time that the entire lifetime ends (the service

is still active even after onStartCommand() returns) If the service is bound the active lifetime ends

when onUnbind() returns

Note Although a started service is stopped by a call to either stopSelf() or stopService() there is

not a respective callback for the service (theres no onStop() callback) So unless the service is

bound to a client the system destroys it when the service is stoppedmdashonDestroy() is the only

callback received

Figure 2 illustrates the typical callback methods for a service Although the figure separates services

that are created by startService() from those created by bindService() keep in mind that any service

no matter how its started can potentially allow clients to bind to it So a service that was initially

started with onStartCommand() (by a client calling startService()) can still receive a call to onBind()

(when a client calls bindService())

For more information about creating a service that provides binding see the Bound Services

document which includes more information about the onRebind() callback method in the section about

Managing the Lifecycle of a Bound Service

Bound Services

A bound service is the server in a client-server interface A bound service allows components (such as

activities) to bind to the service send requests receive responses and even perform interprocess

communication (IPC) A bound service typically lives only while it serves another application

component and does not run in the background indefinitely

This document shows you how to create a bound service including how to bind to the service from

other application components However you should also refer to the Services document for additional

information about services in general such as how to deliver notifications from a service set the

service to run in the foreground and more

The Basics

A bound service is an implementation of the Service class that allows other applications to bind to it

and interact with it To provide binding for a service you must implement the onBind() callback

method This method returns an IBinder object that defines the programming interface that clients can

use to interact with the service

Binding to a Started Service

As discussed in the Services document you can create a service that is both started and bound That

is the service can be started by calling startService() which allows the service to run indefinitely and

also allow a client to bind to the service by calling bindService()

If you do allow your service to be started and bound then when the service has been started the

system does not destroy the service when all clients unbind Instead you must explicitly stop the

service by calling stopSelf() or stopService()

Although you should usually implement either onBind() or onStartCommand() its sometimes

necessary to implement both For example a music player might find it useful to allow its service to run

indefinitely and also provide binding This way an activity can start the service to play some music and

the music continues to play even if the user leaves the application Then when the user returns to the

application the activity can bind to the service to regain control of playback

Be sure to read the section about Managing the Lifecycle of a Bound Service for more information

about the service lifecycle when adding binding to a started service

A client can bind to the service by calling bindService() When it does it must provide an

implementation of ServiceConnection which monitors the connection with the service The

bindService() method returns immediately without a value but when the Android system creates the

connection between the client and service it calls onServiceConnected() on the ServiceConnection to

deliver the IBinder that the client can use to communicate with the service

Multiple clients can connect to the service at once However the system calls your services onBind()

method to retrieve the IBinder only when the first client binds The system then delivers the same

IBinder to any additional clients that bind without calling onBind() again

When the last client unbinds from the service the system destroys the service (unless the service was

also started by startService())

When you implement your bound service the most important part is defining the interface that your

onBind() callback method returns There are a few different ways you can define your services IBinder

interface and the following section discusses each technique

Creating a Bound Service

When creating a service that provides binding you must provide an IBinder that provides the

programming interface that clients can use to interact with the service There are three ways you can

define the interface

Extending the Binder class

If your service is private to your own application and runs in the same process as the client

(which is common) you should create your interface by extending the Binder class and

returning an instance of it from onBind() The client receives the Binder and can use it to directly

access public methods available in either the Binder implementation or even the Service

This is the preferred technique when your service is merely a background worker for your own

application The only reason you would not create your interface this way is because your

service is used by other applications or across separate processes

Using a Messenger

If you need your interface to work across different processes you can create an interface for the

service with a Messenger In this manner the service defines a Handler that responds to

different types of Message objects This Handler is the basis for a Messenger that can then

share an IBinder with the client allowing the client to send commands to the service using

Message objects Additionally the client can define a Messenger of its own so the service can

send messages back

This is the simplest way to perform interprocess communication (IPC) because the Messenger

queues all requests into a single thread so that you dont have to design your service to be

thread-safe

Using AIDL

AIDL (Android Interface Definition Language) performs all the work to decompose objects into

primitives that the operating system can understand and marshall them across processes to

perform IPC The previous technique using a Messenger is actually based on AIDL as its

underlying structure As mentioned above the Messenger creates a queue of all the client

requests in a single thread so the service receives requests one at a time If however you

want your service to handle multiple requests simultaneously then you can use AIDL directly In

this case your service must be capable of multi-threading and be built thread-safe

To use AIDL directly you must create an aidl file that defines the programming interface The

Android SDK tools use this file to generate an abstract class that implements the interface and

handles IPC which you can then extend within your service

Note Most applications should not use AIDL to create a bound service because it may require

multithreading capabilities and can result in a more complicated implementation As such AIDL is

not suitable for most applications and this document does not discuss how to use it for your

service If youre certain that you need to use AIDL directly see the AIDL document

Extending the Binder class

If your service is used only by the local application and does not need to work across processes then

you can implement your own Binder class that provides your client direct access to public methods in

the service

Note This works only if the client and service are in the same application and process which is

most common For example this would work well for a music application that needs to bind an

activity to its own service thats playing music in the background

Heres how to set it up

1 In your service create an instance of Binder that either

o contains public methods that the client can call

o returns the current Service instance which has public methods the client can call

o or returns an instance of another class hosted by the service with public methods the client can call

2 Return this instance of Binder from the onBind() callback method

3 In the client receive the Binder from the onServiceConnected() callback method and make calls to the

bound service using the methods provided

Note The reason the service and client must be in the same application is so the client can cast

the returned object and properly call its APIs The service and client must also be in the same

process because this technique does not perform any marshalling across processes

For example heres a service that provides clients access to methods in the service through a Binder

implementation

public class LocalService extends Service

Binder given to clients

private final IBinder mBinder = new LocalBinder()

Random number generator

private final Random mGenerator = new Random()

Class used for the client Binder Because we know this service always

runs in the same process as its clients we dont need to deal with IPC

public class LocalBinder extends Binder

LocalService getService()

Return this instance of LocalService so clients can call public methods

return LocalServicethis

Override

public IBinder onBind(Intent intent)

return mBinder

method for clients

public int getRandomNumber()

return mGeneratornextInt(100)

The LocalBinder provides the getService() method for clients to retrieve the current instance of

LocalService This allows clients to call public methods in the service For example clients can call

getRandomNumber() from the service

Heres an activity that binds to LocalService and calls getRandomNumber() when a button is clicked

public class BindingActivity extends Activity

LocalService mService

boolean mBound = false

Override

protected void onCreate(Bundle savedInstanceState)

superonCreate(savedInstanceState)

setContentView(Rlayoutmain)

Override

protected void onStart()

superonStart()

Bind to LocalService

Intent intent = new Intent(this LocalServiceclass)

bindService(intent mConnection ContextBIND_AUTO_CREATE)

Override

protected void onStop()

superonStop()

Unbind from the service

if (mBound)

unbindService(mConnection)

mBound = false

Called when a button is clicked (the button in the layout file attaches to

this method with the androidonClick attribute)

public void onButtonClick(View v)

if (mBound)

Call a method from the LocalService

However if this call were something that might hang then this request should

occur in a separate thread to avoid slowing down the activity performance

int num = mServicegetRandomNumber()

ToastmakeText(this number + num ToastLENGTH_SHORT)show()

Defines callbacks for service binding passed to bindService()

private ServiceConnection mConnection = new ServiceConnection()

Override

public void onServiceConnected(ComponentName className

IBinder service)

Weve bound to LocalService cast the IBinder and get LocalService instance

LocalBinder binder = (LocalBinder) service

mService = bindergetService()

mBound = true

Override

public void onServiceDisconnected(ComponentName arg0)

mBound = false

The above sample shows how the client binds to the service using an implementation of

ServiceConnection and the onServiceConnected() callback The next section provides more

information about this process of binding to the service

Note The example above doesnt explicitly unbind from the service but all clients should unbind

at an appropriate time (such as when the activity pauses)

For more sample code see the LocalServicejava class and the LocalServiceActivitiesjava class in

ApiDemos

Using a Messenger

Compared to AIDL

When you need to perform IPC using a Messenger for your interface is simpler than implementing it

with AIDL because Messenger queues all calls to the service whereas a pure AIDL interface sends

simultaneous requests to the service which must then handle multi-threading

For most applications the service doesnt need to perform multi-threading so using a Messenger

allows the service to handle one call at a time If its important that your service be multi-threaded then

you should use AIDL to define your interface

If you need your service to communicate with remote processes then you can use a Messenger to

provide the interface for your service This technique allows you to perform interprocess

communication (IPC) without the need to use AIDL

Heres a summary of how to use a Messenger

The service implements a Handler that receives a callback for each call from a client

The Handler is used to create a Messenger object (which is a reference to the Handler)

The Messenger creates an IBinder that the service returns to clients from onBind()

Clients use the IBinder to instantiate the Messenger (that references the services Handler) which the

client uses to send Message objects to the service

The service receives each Message in its Handlermdashspecifically in the handleMessage() method

In this way there are no methods for the client to call on the service Instead the client delivers

messages (Message objects) that the service receives in its Handler

Heres a simple example service that uses a Messenger interface

public class MessengerService extends Service Command to the service to display a message static final int MSG_SAY_HELLO = 1 Handler of incoming messages from clients class IncomingHandler extends Handler Override public void handleMessage(Message msg) switch (msgwhat) case MSG_SAY_HELLO ToastmakeText(getApplicationContext() hello ToastLENGTH_SHORT)show() break default superhandleMessage(msg) Target we publish for clients to send messages to IncomingHandler final Messenger mMessenger = new Messenger(new IncomingHandler()) When binding to the service we return an interface to our messenger for sending messages to the service Override public IBinder onBind(Intent intent) ToastmakeText(getApplicationContext() binding ToastLENGTH_SHORT)show() return mMessengergetBinder()

Notice that the handleMessage() method in the Handler is where the service receives the incoming

Message and decides what to do based on the what member

All that a client needs to do is create a Messenger based on the IBinder returned by the service and

send a message using send() For example heres a simple activity that binds to the service and

delivers the MSG_SAY_HELLO message to the service

public class ActivityMessenger extends Activity Messenger for communicating with the service Messenger mService = null Flag indicating whether we have called bind on the service boolean mBound Class for interacting with the main interface of the service private ServiceConnection mConnection = new ServiceConnection() public void onServiceConnected(ComponentName className IBinder service) This is called when the connection with the service has been established giving us the object we can use to interact with the service We are communicating with the service using a Messenger so here we get a client-side representation of that from the raw IBinder object mService = new Messenger(service) mBound = true public void onServiceDisconnected(ComponentName className) This is called when the connection with the service has been unexpectedly disconnected -- that is its process crashed mService = null mBound = false public void sayHello(View v) if (mBound) return Create and send a message to the service using a supported what value Message msg = Messageobtain(null MessengerServiceMSG_SAY_HELLO 0 0) try mServicesend(msg) catch (RemoteException e) eprintStackTrace() Override protected void onCreate(Bundle savedInstanceState) superonCreate(savedInstanceState) setContentView(Rlayoutmain)

Override protected void onStart() superonStart() Bind to the service bindService(new Intent(this MessengerServiceclass) mConnection ContextBIND_AUTO_CREATE) Override protected void onStop() superonStop() Unbind from the service if (mBound) unbindService(mConnection) mBound = false

Notice that this example does not show how the service can respond to the client If you want the

service to respond then you need to also create a Messenger in the client Then when the client

receives the onServiceConnected() callback it sends a Message to the service that includes the

clients Messenger in the replyTo parameter of the send() method

You can see an example of how to provide two-way messaging in the MessengerServicejava (service)

and MessengerServiceActivitiesjava (client) samples

Binding to a Service

Application components (clients) can bind to a service by calling bindService() The Android system

then calls the services onBind() method which returns an IBinder for interacting with the service

The binding is asynchronous bindService() returns immediately and does not return the IBinder to the

client To receive the IBinder the client must create an instance of ServiceConnection and pass it to

bindService() The ServiceConnection includes a callback method that the system calls to deliver the

IBinder

Note Only activities services and content providers can bind to a servicemdashyou cannot bind to a

service from a broadcast receiver

So to bind to a service from your client you must

1 Implement ServiceConnection

Your implementation must override two callback methods

onServiceConnected()

The system calls this to deliver the IBinder returned by the services onBind() method

onServiceDisconnected()

The Android system calls this when the connection to the service is unexpectedly lost such as

when the service has crashed or has been killed This is not called when the client unbinds

2 Call bindService() passing the ServiceConnection implementation

3 When the system calls your onServiceConnected() callback method you can begin making calls to the

service using the methods defined by the interface

4 To disconnect from the service call unbindService()

When your client is destroyed it will unbind from the service but you should always unbind when

youre done interacting with the service or when your activity pauses so that the service can shutdown

while its not being used (Appropriate times to bind and unbind is discussed more below)

For example the following snippet connects the client to the service created above by extending the

Binder class so all it must do is cast the returned IBinder to the LocalService class and request the

LocalService instance

LocalService mService private ServiceConnection mConnection = new ServiceConnection() Called when the connection with the service is established public void onServiceConnected(ComponentName className IBinder service) Because we have bound to an explicit service that is running in our own process we can cast its IBinder to a concrete class and directly access it LocalBinder binder = (LocalBinder) service mService = bindergetService() mBound = true Called when the connection with the service disconnects unexpectedly public void onServiceDisconnected(ComponentName className) Loge(TAG onServiceDisconnected) mBound = false

With this ServiceConnection the client can bind to a service by passing this it to bindService() For

example

Intent intent = new Intent(this LocalServiceclass) bindService(intent mConnection ContextBIND_AUTO_CREATE)

The first parameter of bindService() is an Intent that explicitly names the service to bind (thought the

intent could be implicit)

The second parameter is the ServiceConnection object

The third parameter is a flag indicating options for the binding It should usually be

BIND_AUTO_CREATE in order to create the service if its not already alive Other possible values are

BIND_DEBUG_UNBIND and BIND_NOT_FOREGROUND or 0 for none

Additional notes

Here are some important notes about binding to a service

You should always trap DeadObjectException exceptions which are thrown when the connection has

broken This is the only exception thrown by remote methods

Objects are reference counted across processes

You should usually pair the binding and unbinding during matching bring-up and tear-down moments

of the clients lifecycle For example

o If you only need to interact with the service while your activity is visible you should bind during

onStart() and unbind during onStop()

o If you want your activity to receive responses even while it is stopped in the background then you can

bind during onCreate() and unbind during onDestroy() Beware that this implies that your activity needs

to use the service the entire time its running (even in the background) so if the service is in another

process then you increase the weight of the process and it becomes more likely that the system will

kill it

Note You should usually not bind and unbind during your activitys onResume() and onPause()

because these callbacks occur at every lifecycle transition and you should keep the processing that

occurs at these transitions to a minimum Also if multiple activities in your application bind to the same

service and there is a transition between two of those activities the service may be destroyed and

recreated as the current activity unbinds (during pause) before the next one binds (during resume)

(This activity transition for how activities coordinate their lifecycles is described in the Activities

document)

For more sample code showing how to bind to a service see the RemoteServicejava class in

ApiDemos

Managing the Lifecycle of a Bound Service

Figure 1 The lifecycle for a service

that is started and also allows binding

When a service is unbound from all

clients the Android system destroys it

(unless it was also started with

onStartCommand()) As such you

dont have to manage the lifecycle of

your service if its purely a bound

servicemdashthe Android system manages

it for you based on whether it is bound

to any clients

However if you choose to implement

the onStartCommand() callback

method then you must explicitly stop

the service because the service is

now considered to be started In this

case the service runs until the service

stops itself with stopSelf() or another

component calls stopService()

regardless of whether it is bound to

any clients

Additionally if your service is started and accepts binding then when the system calls your onUnbind()

method you can optionally return true if you would like to receive a call to onRebind() the next time a

client binds to the service (instead of receiving a call to onBind()) onRebind() returns void but the

client still receives the IBinder in its onServiceConnected() callback Below figure 1 illustrates the logic

for this kind of lifecycle

For more information about the lifecycle of an started service see the Services document

Content Providers

Content providers store and retrieve data and make it accessible to all applications Theyre the only

way to share data across applications theres no common storage area that all Android packages can

access

Android ships with a number of content providers for common data types (audio video images

personal contact information and so on) You can see some of them listed in the androidprovider

package You can query these providers for the data they contain (although for some you must

acquire the proper permission to read the data)

If you want to make your own data public you have two options You can create your own content

provider (a ContentProvider subclass) or you can add the data to an existing provider mdash if theres one

that controls the same type of data and you have permission to write to it

This document is an introduction to using content providers After a brief discussion of the

fundamentals it explores how to query a content provider how to modify data controlled by a provider

and how to create a content provider of your own

Content Provider Basics

How a content provider actually stores its data under the covers is up to its designer But all content

providers implement a common interface for querying the provider and returning results mdash as well as

for adding altering and deleting data Its an interface that clients use indirectly most generally

through ContentResolver objects You get a ContentResolver by calling getContentResolver() from

within the implementation of an Activity or other application component

ContentResolver cr = getContentResolver()

You can then use the ContentResolvers methods to interact with whatever content providers youre

interested in When a query is initiated the Android system identifies the content provider thats the

target of the query and makes sure that it is up and running The system instantiates all

ContentProvider objects you never need to do it on your own In fact you never deal directly with

ContentProvider objects at all Typically theres just a single instance of each type of ContentProvider

But it can communicate with multiple ContentResolver objects in different applications and processes

The interaction between processes is handled by the ContentResolver and ContentProvider classes

The data model

Content providers expose their data as a simple table on a database model where each row is a

record and each column is data of a particular type and meaning For example information about

people and their phone numbers might be exposed as follows

_ID NUMBER NUMBER_KEY LABEL NAME TYPE

13 (425) 555 6677 425 555 6677 Kirkland office Bully Pulpit TYPE_WORK

44 (212) 555-1234 212 555 1234 NY apartment Alan Vain TYPE_HOME

45 (212) 555-6657 212 555 6657 Downtown office Alan Vain TYPE_MOBILE

53 2015554433 201 555 4433 Love Nest Rex Cars TYPE_HOME

Every record includes a numeric _ID field that uniquely identifies the record within the table IDs can be

used to match records in related tables mdash for example to find a persons phone number in one table

and pictures of that person in another

A query returns a Cursor object that can move from record to record and column to column to read the

contents of each field It has specialized methods for reading each type of data So to read a field you

must know what type of data the field contains (Theres more on query results and Cursor objects

later)

URIs

Each content provider exposes a public URI (wrapped as a Uri object) that uniquely identifies its data

set A content provider that controls multiple data sets (multiple tables) exposes a separate URI for

each one All URIs for providers begin with the string content The content scheme identifies the

data as being controlled by a content provider

If youre defining a content provider its a good idea to also define a constant for its URI to simplify

client code and make future updates cleaner Android defines CONTENT_URI constants for all the

providers that come with the platform For example the URI for the table that matches phone numbers

to people and the URI for the table that holds pictures of people (both controlled by the Contacts

content provider) are

androidproviderContactsPhonesCONTENT_URI

androidproviderContactsPhotosCONTENT_URI

The URI constant is used in all interactions with the content provider Every ContentResolver method

takes the URI as its first argument Its what identifies which provider the ContentResolver should talk

to and which table of the provider is being targeted

Querying a Content Provider

You need three pieces of information to query a content provider

The URI that identifies the provider

The names of the data fields you want to receive

The data types for those fields

If youre querying a particular record you also need the ID for that record

Making the query

To query a content provider you can use either the ContentResolverquery() method or the

ActivitymanagedQuery() method Both methods take the same set of arguments and both return a

Cursor object However managedQuery() causes the activity to manage the life cycle of the Cursor A

managed Cursor handles all of the niceties such as unloading itself when the activity pauses and

requerying itself when the activity restarts You can ask an Activity to begin managing an unmanaged

Cursor object for you by calling ActivitystartManagingCursor()

The first argument to either query() or managedQuery() is the provider URI mdash the CONTENT_URI

constant that identifies a particular ContentProvider and data set (see URIs earlier)

To restrict a query to just one record you can append the _ID value for that record to the URI mdash that

is place a string matching the ID as the last segment of the path part of the URI For example if the ID

is 23 the URI would be

content 23

There are some helper methods particularly ContentUriswithAppendedId() and

UriwithAppendedPath() that make it easy to append an ID to a URI Both are static methods that

return a Uri object with the ID added So for example if you were looking for record 23 in the database

of people contacts you might construct a query as follows

import androidproviderContactsPeople import androidcontentContentUris import androidnetUri import androiddatabaseCursor Use the ContentUris method to produce the base URI for the contact with _ID == 23 Uri myPerson = ContentUriswithAppendedId(PeopleCONTENT_URI 23) Alternatively use the Uri method to produce the base URI It takes a string rather than an integer Uri myPerson = UriwithAppendedPath(PeopleCONTENT_URI 23) Then query for this specific record Cursor cur = managedQuery(myPerson null null null null)

The other arguments to the query() and managedQuery() methods delimit the query in more detail

They are

The names of the data columns that should be returned A null value returns all columns Otherwise

only columns that are listed by name are returned All the content providers that come with the

platform define constants for their columns For example the androidproviderContactsPhones class

defines constants for the names of the columns in the phone table illustrated earlier ampmdash _ID

NUMBER NUMBER_KEY NAME and so on

A filter detailing which rows to return formatted as an SQL WHERE clause (excluding the WHERE

itself) A null value returns all rows (unless the URI limits the query to a single record)

Selection arguments

A sorting order for the rows that are returned formatted as an SQL ORDER BY clause (excluding the

ORDER BY itself) A null value returns the records in the default order for the table which may be

unordered

Lets look at an example query to retrieve a list of contact names and their primary phone numbers

import androidproviderContactsPeople import androiddatabaseCursor Form an array specifying which columns to return String[] projection = new String[] People_ID People_COUNT PeopleNAME PeopleNUMBER Get the base URI for the People table in the Contacts content provider Uri contacts = PeopleCONTENT_URI Make the query Cursor managedCursor = managedQuery(contacts projection Which columns to return null Which rows to return (all rows) null Selection arguments (none) Put the results in ascending order by name PeopleNAME + ASC)

This query retrieves data from the People table of the Contacts content provider It gets the name

primary phone number and unique record ID for each contact It also reports the number of records

that are returned as the _COUNT field of each record

The constants for the names of the columns are defined in various interfaces mdash _ID and _COUNT in

BaseColumns NAME in PeopleColumns and NUMBER in PhoneColumns The ContactsPeople

class implements each of these interfaces which is why the code example above could refer to them

using just the class name

What a query returns

A query returns a set of zero or more database records The names of the columns their default order

and their data types are specific to each content provider But every provider has an _ID column

which holds a unique numeric ID for each record Every provider can also report the number of records

returned as the _COUNT column its value is the same for all rows

Here is an example result set for the query in the previous section

_ID _COUNT NAME NUMBER

44 3 Alan Vain 212 555 1234

13 3 Bully Pulpit 425 555 6677

53 3 Rex Cars 201 555 4433

The retrieved data is exposed by a Cursor object that can be used to iterate backward or forward

through the result set You can use this object only to read the data To add modify or delete data

you must use a ContentResolver object

Reading retrieved data

The Cursor object returned by a query provides access to a recordset of results If you have queried

for a specific record by ID this set will contain only one value Otherwise it can contain multiple

values (If there are no matches it can also be empty) You can read data from specific fields in the

record but you must know the data type of the field because the Cursor object has a separate method

for reading each type of data mdash such as getString() getInt() and getFloat() (However for most types

if you call the method for reading strings the Cursor object will give you the String representation of

the data) The Cursor lets you request the column name from the index of the column or the index

number from the column name

The following snippet demonstrates reading names and phone numbers from the query illustrated

earlier

import androidproviderContactsPeople private void getColumnData(Cursor cur) if (curmoveToFirst()) String name String phoneNumber int nameColumn = curgetColumnIndex(PeopleNAME) int phoneColumn = curgetColumnIndex(PeopleNUMBER) String imagePath do Get the field values name = curgetString(nameColumn) phoneNumber = curgetString(phoneColumn) Do something with the values while (curmoveToNext())

If a query can return binary data such as an image or sound the data may be directly entered in the

table or the table entry for that data may be a string specifying a content URI that you can use to get

the data In general smaller amounts of data (say from 20 to 50K or less) are most often directly

entered in the table and can be read by calling CursorgetBlob() It returns a byte array

If the table entry is a content URI you should never try to open and read the file directly (for one thing

permissions problems can make this fail) Instead you should call ContentResolveropenInputStream()

to get an InputStream object that you can use to read the data

Modifying Data

Data kept by a content provider can be modified by

Adding new records

Adding new values to existing records

Batch updating existing records

Deleting records

All data modification is accomplished using ContentResolver methods Some content providers require

a more restrictive permission for writing data than they do for reading it If you dont have permission to

write to a content provider the ContentResolver methods will fail

Adding records

To add a new record to a content provider first set up a map of key-value pairs in a ContentValues

object where each key matches the name of a column in the content provider and the value is the

desired value for the new record in that column Then call ContentResolverinsert() and pass it the URI

of the provider and the ContentValues map This method returns the full URI of the new record mdash that

is the providers URI with the appended ID for the new record You can then use this URI to query and

get a Cursor over the new record and to further modify the record Heres an example

import androidproviderContactsPeople import androidcontentContentResolver import androidcontentContentValues ContentValues values = new ContentValues() Add Abraham Lincoln to contacts and make him a favorite valuesput(PeopleNAME Abraham Lincoln) 1 = the new contact is added to favorites 0 = the new contact is not added to favorites valuesput(PeopleSTARRED 1) Uri uri = getContentResolver()insert(PeopleCONTENT_URI values)

Adding new values

Once a record exists you can add new information to it or modify existing information For example

the next step in the example above would be to add contact information mdash like a phone number or an

IM or e-mail address mdash to the new entry

The best way to add to a record in the Contacts database is to append the name of the table where the

new data goes to the URI for the record then use the amended URI to add the new data values Each

Contacts table exposes a name for this purpose as a CONTENT_DIRECTORY constant The following

code continues the previous example by adding a phone number and e-mail address for the record

just created

Uri phoneUri = null Uri emailUri = null Add a phone number for Abraham Lincoln Begin with the URI for the new record just returned by insert() it ends with the _ID of the new record so we dont have to add the ID ourselves Then append the designation for the phone table to this URI and use the resulting URI to insert the phone number phoneUri = UriwithAppendedPath(uri PeoplePhonesCONTENT_DIRECTORY) valuesclear() valuesput(PeoplePhonesTYPE PeoplePhonesTYPE_MOBILE) valuesput(PeoplePhonesNUMBER 1233214567) getContentResolver()insert(phoneUri values) Now add an email address in the same way emailUri = UriwithAppendedPath(uri PeopleContactMethodsCONTENT_DIRECTORY) valuesclear() ContactMethodsKIND is used to distinguish different kinds of contact methods such as email IM etc valuesput(PeopleContactMethodsKIND ContactsKIND_EMAIL) valuesput(PeopleContactMethodsDATA testexamplecom) valuesput(PeopleContactMethodsTYPE PeopleContactMethodsTYPE_HOME) getContentResolver()insert(emailUri values)

You can place small amounts of binary data into a table by calling the version of ContentValuesput()

that takes a byte array That would work for a small icon-like image or a short audio clip for example

However if you have a large amount of binary data to add such as a photograph or a complete song

put a content URI for the data in the table and call ContentResolveropenOutputStream() with the files

URI (That causes the content provider to store the data in a file and record the file path in a hidden

field of the record)

In this regard the MediaStore content provider the main provider that dispenses image audio and

video data employs a special convention The same URI that is used with query() or managedQuery()

to get meta-information about the binary data (such as the caption of a photograph or the date it was

taken) is used with openInputStream() to get the data itself Similarly the same URI that is used with

insert() to put meta-information into a MediaStore record is used with openOutputStream() to place the

binary data there The following code snippet illustrates this convention

import androidproviderMediaStoreImagesMedia import androidcontentContentValues import javaioOutputStream Save the name and description of an image in a ContentValues map ContentValues values = new ContentValues(3) valuesput(MediaDISPLAY_NAME road_trip_1) valuesput(MediaDESCRIPTION Day 1 trip to Los Angeles) valuesput(MediaMIME_TYPE imagejpeg) Add a new record without the bitmap but with the values just set insert() returns the URI of the new record Uri uri = getContentResolver()insert(MediaEXTERNAL_CONTENT_URI values) Now get a handle to the file for that record and save the data into it Here sourceBitmap is a Bitmap object representing the file to save to the database try OutputStream outStream = getContentResolver()openOutputStream(uri) sourceBitmapcompress(BitmapCompressFormatJPEG 50 outStream) outStreamclose() catch (Exception e) Loge(TAG exception while writing image e)

Batch updating records

To batch update a group of records (for example to change NY to New York in all fields) call the

ContentResolverupdate() method with the columns and values to change

Deleting a record

To delete a single record call ContentResolverdelete() with the URI of a specific row

To delete multiple rows call ContentResolverdelete() with the URI of the type of record to delete (for

example androidproviderContactsPeopleCONTENT_URI) and an SQL WHERE clause defining

which rows to delete (Caution Be sure to include a valid WHERE clause if youre deleting a general

type or you risk deleting more records than you intended)

Creating a Content Provider

To create a content provider you must

Set up a system for storing the data Most content providers store their data using Androids file

storage methods or SQLite databases but you can store your data any way you want Android

provides the SQLiteOpenHelper class to help you create a database and SQLiteDatabase to manage

it

Extend the ContentProvider class to provide access to the data

Declare the content provider in the manifest file for your application (AndroidManifestxml)

The following sections have notes on the last two of these tasks

Extending the ContentProvider class

You define a ContentProvider subclass to expose your data to others using the conventions expected

by ContentResolver and Cursor objects Principally this means implementing six abstract methods

declared in the ContentProvider class

query()

insert()

update()

delete()

getType()

onCreate()

The query() method must return a Cursor object that can iterate over the requested data Cursor itself

is an interface but Android provides some ready-made Cursor objects that you can use For example

SQLiteCursor can iterate over data stored in an SQLite database You get the Cursor object by calling

any of the SQLiteDatabase classs query() methods There are other Cursor implementations mdash such

as MatrixCursor mdash for data not stored in a database

Because these ContentProvider methods can be called from various ContentResolver objects in

different processes and threads they must be implemented in a thread-safe manner

As a courtesy you might also want to call ContentResolvernotifyChange() to notify listeners when

there are modifications to the data

Beyond defining the subclass itself there are other steps you should take to simplify the work of clients

and make the class more accessible

Define a public static final Uri named CONTENT_URI This is the string that represents the full content

URI that your content provider handles You must define a unique string for this value The best

solution is to use the fully-qualified class name of the content provider (made lowercase) So for

example the URI for a TransportationProvider class could be defined as follows

public static final Uri CONTENT_URI = Uriparse(contentcomexamplecodelabtransportationprovider)

If the provider has subtables also define CONTENT_URI constants for each of the subtables These

URIs should all have the same authority (since that identifies the content provider) and be

distinguished only by their paths For example

contentcomexamplecodelabtransportationprovidertrain

contentcomexamplecodelabtransportationproviderairdomestic

contentcomexamplecodelabtransportationproviderairinternational

For an overview of content URIs see the Content URI Summary at the end of this document

Define the column names that the content provider will return to clients If you are using an underlying

database these column names are typically identical to the SQL database column names they

represent Also define public static String constants that clients can use to specify the columns in

queries and other instructions

Be sure to include an integer column named _id (with the constant _ID) for the IDs of the records

You should have this field whether or not you have another field (such as a URL) that is also unique

among all records If youre using the SQLite database the _ID field should be the following type

INTEGER PRIMARY KEY AUTOINCREMENT

The AUTOINCREMENT descriptor is optional But without it SQLite increments an ID counter field to

the next number above the largest existing number in the column If you delete the last row the next

row added will have the same ID as the deleted row AUTOINCREMENT avoids this by having SQLite

increment to the next largest value whether deleted or not

Carefully document the data type of each column Clients need this information to read the data

If you are handling a new data type you must define a new MIME type to return in your

implementation of ContentProvidergetType() The type depends in part on whether or not the content

URI submitted to getType() limits the request to a specific record Theres one form of the MIME type

for a single record and another for multiple records Use the Uri methods to help determine what is

being requested Here is the general format for each type

o For a single record vndandroidcursoritemvndyourcompanynamecontenttype

For example a request for train record 122 like this URI

contentcomexampletransportationprovidertrains122

might return this MIME type

vndandroidcursoritemvndexamplerail

o For multiple records vndandroidcursordirvndyourcompanynamecontenttype

For example a request for all train records like the following URI

contentcomexampletransportationprovidertrains

might return this MIME type

vndandroidcursordirvndexamplerail

If you are exposing byte data thats too big to put in the table itself mdash such as a large bitmap file mdash the

field that exposes the data to clients should actually contain a content URI string This is the field that

gives clients access to the data file The record should also have another field named _data that lists

the exact file path on the device for that file This field is not intended to be read by the client but by

the ContentResolver The client will call ContentResolveropenInputStream() on the user-facing field

holding the URI for the item The ContentResolver will request the _data field for that record and

because it has higher permissions than a client it should be able to access that file directly and return

a read wrapper for the file to the client

For an example of a private content provider implementation see the NodePadProvider class in the

Notepad sample application that ships with the SDK

Declaring the content provider

To let the Android system know about the content provider youve developed declare it with a

ltprovidergt element in the applications AndroidManifestxml file Content providers that are not

declared in the manifest are not visible to the Android system

The name attribute is the fully qualified name of the ContentProvider subclass The authorities attribute

is the authority part of the content URI that identifies the provider For example if the ContentProvider

subclass is AutoInfoProvider the ltprovidergt element might look like this

ltprovider androidname=comexampleautosAutoInfoProvider androidauthorities=comexampleautosautoinfoprovider gt ltprovidergt

Note that the authorities attribute omits the path part of a content URI For example if

AutoInfoProvider controlled subtables for different types of autos or different manufacturers

contentcomexampleautosautoinfoproviderhonda

contentcomexampleautosautoinfoprovidergmcompact

contentcomexampleautosautoinfoprovidergmsuv

those paths would not be declared in the manifest The authority is what identifies the provider not the

path your provider can interpret the path part of the URI in any way you choose

Other ltprovidergt attributes can set permissions to read and write data provide for an icon and text

that can be displayed to users enable and disable the provider and so on Set the multiprocess

attribute to true if data does not need to be synchronized between multiple running versions of the

content provider This permits an instance of the provider to be created in each client process

eliminating the need to perform IPC

Content URI Summary

Here is a recap of the important parts of a content URI

A Standard prefix indicating that the data is controlled by a content provider Its never modified

B The authority part of the URI it identifies the content provider For third-party applications this should

be a fully-qualified class name (reduced to lowercase) to ensure uniqueness The authority is declared

in the ltprovidergt elements authorities attribute

ltprovider androidname=TransportationProvider androidauthorities=comexampletransportationprovider gt

C The path that the content provider uses to determine what kind of data is being requested This can be

zero or more segments long If the content provider exposes only one type of data (only trains for

example) it can be absent If the provider exposes several types including subtypes it can be several

segments long mdash for example landbus landtrain seaship and seasubmarine to give four

possibilities

D The ID of the specific record being requested if any This is the _ID value of the requested record If

the request is not limited to a single record this segment and the trailing slash are omitted

contentcomexampletransportationprovidertrains

Intent and intent filters

Three of the core components of an application mdash activities services and broadcast receivers mdash 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 mdash 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 ContextstartActivity() or ActivitystartActivityForResult() to launch an

activity or get an existing activity to do something new (It can also be passed to ActivitysetResult() to

return information to the activity that called startActivityForResult())

An Intent object is passed to ContextstartService() to initiate a service or deliver new instructions to an

ongoing service Similarly an intent can be passed to ContextbindService() to establish a connection

between the calling component and a target service It can optionally initiate the service if its not

already running

Intent objects passed to any of the broadcast methods (such as ContextsendBroadcast()

ContextsendOrderedBroadcast() or ContextsendStickyBroadcast()) 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 mdash how it resolves which component should receive an intent message For

intents that dont explicitly name a target component this process involves testing the Intent object

against intent filters associated with potential targets

Intent Objects

An Intent object is a bundle of information It contains information of interest to the component that

receives the intent (such as the action to be taken and the data to act on) plus information of interest to

the Android system (such as the category of component that should handle the intent and instructions

on how to launch a target activity) Principally it can contain the following

Component name

The name of the component that should handle the intent This field is a ComponentName

object mdash a combination of the fully qualified class name of the target component (for example

comexampleprojectappFreneticActivity) and the package name set in the manifest file of the

application where the component resides (for example comexampleproject) The package

part of the component name and the package name set in the manifest do not necessarily have

to match

The component name is optional If it is set the Intent object is delivered to an instance of the

designated class If it is not set Android uses other information in the Intent object to locate a

suitable target mdash see Intent Resolution later in this document

The component name is set by setComponent() setClass() or setClassName() and read by

getComponent()

Action

A string naming the action to be performed mdash or in the case of broadcast intents the action

that took place and is being reported The Intent class defines a number of action constants

including these

Constant Target

component

Action

ACTION_CALL activity Initiate a phone call

ACTION_EDIT activity Display data for the user to edit

ACTION_MAIN activity Start up as the initial activity of a task

with no data input and no returned

output

ACTION_SYNC activity Synchronize data on a server with

data on the mobile device

ACTION_BATTERY_LOW broadcast

receiver

A warning that the battery is low

ACTION_HEADSET_PLUG broadcast

receiver

A headset has been plugged into the

device or unplugged from it

ACTION_SCREEN_ON broadcast

receiver

The screen has been turned on

ACTION_TIMEZONE_CHANGED broadcast

receiver

The setting for the time zone has

changed

See the Intent class description for a list of pre-defined constants for generic actions Other

actions are defined elsewhere in the Android API You can also define your own action strings

for activating the components in your application Those you invent should include the

application package as a prefix mdash for example comexampleprojectSHOW_COLOR

The action largely determines how the rest of the intent is structured mdash particularly the data and

extras fields mdash much as a method name determines a set of arguments and a return value For

this reason its a good idea to use action names that are as specific as possible and to couple

them tightly to the other fields of the intent In other words instead of defining an action in

isolation define an entire protocol for the Intent objects your components can handle

The action in an Intent object is set by the setAction() method and read by getAction()

Data

The URI of the data to be acted on and the MIME type of that data Different actions are paired

with different kinds of data specifications For example if the action field is ACTION_EDIT the

data field would contain the URI of the document to be displayed for editing If the action is

ACTION_CALL the data field would be a tel URI with the number to call Similarly if the action

is ACTION_VIEW and the data field is an http URI the receiving activity would be called upon

to download and display whatever data the URI refers to

When matching an intent to a component that is capable of handling the data its often

important to know the type of data (its MIME type) in addition to its URI For example a

component able to display image data should not be called upon to play an audio file

In many cases the data type can be inferred from the URI mdash particularly content URIs which

indicate that the data is located on the device and controlled by a content provider (see the

separate discussion on content providers) But the type can also be explicitly set in the Intent

object The setData() method specifies data only as a URI setType() specifies it only as a

MIME type and setDataAndType() specifies it as both a URI and a MIME type The URI is read

by getData() and the type by getType()

Category

A string containing additional information about the kind of component that should handle the

intent Any number of category descriptions can be placed in an Intent object As it does for

actions the Intent class defines several category constants including these

Constant Meaning

CATEGORY_BROWSABLE The target activity can be safely invoked by the browser to

display data referenced by a link mdash for example an image or

an e-mail message

CATEGORY_GADGET The activity can be embedded inside of another activity that

hosts gadgets

CATEGORY_HOME The activity displays the home screen the first screen the

user sees when the device is turned on or when the HOME

key is pressed

CATEGORY_LAUNCHER The activity can be the initial activity of a task and is listed in

the top-level application launcher

CATEGORY_PREFERENCE The target activity is a preference panel

See the Intent class description for the full list of categories

The addCategory() method places a category in an Intent object removeCategory() deletes a

category previously added and getCategories() gets the set of all categories currently in the

object

Extras

Key-value pairs for additional information that should be delivered to the component handling

the intent Just as some actions are paired with particular kinds of data URIs some are paired

with particular extras For example an ACTION_TIMEZONE_CHANGED intent has a time-

zone extra that identifies the new time zone and ACTION_HEADSET_PLUG has a state

extra indicating whether the headset is now plugged in or unplugged as well as a name extra

for the type of headset If you were to invent a SHOW_COLOR action the color value would be

set in an extra key-value pair

The Intent object has a series of put() methods for inserting various types of extra data and a

similar set of get() methods for reading the data These methods parallel those for Bundle

objects In fact the extras can be installed and read as a Bundle using the putExtras() and

getExtras() methods

Flags

Flags of various sorts Many instruct the Android system how to launch an activity (for example

which task the activity should belong to) and how to treat it after its launched (for example

whether it belongs in the list of recent activities) All these flags are defined in the Intent class

The Android system and the applications that come with the platform employ Intent objects both to

send out system-originated broadcasts and to activate system-defined components To see how to

structure an intent to activate a system component consult the list of intents in the reference

Intent Resolution

Intents can be divided into two groups

Explicit intents designate the target component by its name (the component name field mentioned

earlier has a value set) Since component names would generally not be known to developers of other

applications explicit intents are typically used for application-internal messages mdash such as an activity

starting a subordinate service or launching a sister activity

Implicit intents do not name a target (the field for the component name is blank) Implicit intents are

often used to activate components in other applications

Android delivers an explicit intent to an instance of the designated target class Nothing in the Intent

object other than the component name matters for determining which component should get the intent

A different strategy is needed for implicit intents In the absence of a designated target the Android

system must find the best component (or components) to handle the intent mdash a single activity or

service to perform the requested action or the set of broadcast receivers to respond to the broadcast

announcement It does so by comparing the contents of the Intent object to intent filters structures

associated with components that can potentially receive intents Filters advertise the capabilities of a

component and delimit the intents it can handle They open the component to the possibility of

receiving implicit intents of the advertised type If a component does not have any intent filters it can

receive only explicit intents A component with filters can receive both explicit and implicit intents

Only three aspects of an Intent object are consulted when the object is tested against an intent filter

action

data (both URI and data type)

category

The extras and flags play no part in resolving which component receives an intent

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 mdash but only unwanted implicit intents (those that dont 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

components 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 mdash 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 Pads filters are described in the Note Pad Example

section later)

Filters and security

An intent filter cannot be relied on for security While it opens a component to receiving only certain

kinds of implicit intents it does nothing to prevent explicit intents from targeting the component Even

though a filter restricts the intents a component will be asked to handle to certain actions and data

sources someone could always put together an explicit intent with a different action and data source

and name the component as the target

An intent filter is an instance of the IntentFilter class However since the Android system must know

about the capabilities of a component before it can launch that component intent filters are generally

not set up in Java code but in the applications manifest file (AndroidManifestxml) as ltintent-filtergt

elements (The one exception would be filters for broadcast receivers that are registered dynamically

by calling ContextregisterReceiver() they are directly created as IntentFilter objects)

A filter has fields that parallel the action data and category fields of an Intent object An implicit intent

is tested against the filter in all three areas To be delivered to the component that owns the filter it

must pass all three tests If it fails even one of them the Android system wont deliver it to the

component mdash at least not on the basis of that filter However since a component can have multiple

intent filters an intent that does not pass through one of a components filters might make it through on

another

Each of the three tests is described in detail below

Action test

An ltintent-filtergt element in the manifest file lists actions as ltactiongt subelements For

example

ltintent-filter gt ltaction androidname=comexampleprojectSHOW_CURRENT gt ltaction androidname=comexampleprojectSHOW_RECENT gt ltaction androidname=comexampleprojectSHOW_PENDING gt ltintent-filtergt

As the example shows while an Intent object names just a single action a filter may list more

than one The list cannot be empty a filter must contain at least one ltactiongt element or it will

block all intents

To pass this test the action specified in the Intent object must match one of the actions listed in

the filter If the object or the filter does not specify an action the results are as follows

If the filter fails to list any actions there is nothing for an intent to match so all intents fail the

test No intents can get through the filter

On the other hand an Intent object that doesnt specify an action automatically passes the test

mdash as long as the filter contains at least one action

Category test

An ltintent-filtergt element also lists categories as subelements For example

ltintent-filter gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryBROWSABLE gt ltintent-filtergt

Note that the constants described earlier for actions and categories are not used in the manifest

file The full string values are used instead For instance the

androidintentcategoryBROWSABLE string in the example above corresponds to the

CATEGORY_BROWSABLE constant mentioned earlier in this document Similarly the string

androidintentactionEDIT corresponds to the ACTION_EDIT constant

For an intent to pass the category test every category in the Intent object must match a

category in the filter The filter can list additional categories but it cannot omit any that are in the

intent

In principle therefore an Intent object with no categories should always pass this test

regardless of whats in the filter Thats mostly true However with one exception Android treats

all implicit intents passed to startActivity() as if they contained at least one category

androidintentcategoryDEFAULT (the CATEGORY_DEFAULT constant) Therefore activities

that are willing to receive implicit intents must include androidintentcategoryDEFAULT in

their intent filters (Filters with androidintentactionMAIN and

androidintentcategoryLAUNCHER settings are the exception They mark activities that begin

new tasks and that are represented on the launcher screen They can include

androidintentcategoryDEFAULT in the list of categories but dont need to) See Using intent

matching later for more on these filters)

Data test

Like the action and categories the data specification for an intent filter is contained in a

subelement And as in those cases the subelement can appear multiple times or not at all For

example

ltintent-filter gt ltdata androidmimeType=videompeg androidscheme=http gt ltdata androidmimeType=audiompeg androidscheme=http gt ltintent-filtergt

Each ltdatagt element can specify a URI and a data type (MIME media type) There are

separate attributes mdash scheme host port and path mdash for each part of the URI

schemehostportpath

For example in the following URI

contentcomexampleproject200foldersubfolderetc

the scheme is content the host is comexampleproject the port is 200 and the path is

foldersubfolderetc The host and port together constitute the URI authority if a host is not

specified the port is ignored

Each of these attributes is optional but they are not independent of each other For an authority

to be meaningful a scheme must also be specified For a path to be meaningful both a scheme

and an authority must be specified

When the URI in an Intent object is compared to a URI specification in a filter its compared

only to the parts of the URI actually mentioned in the filter For example if a filter specifies only

a scheme all URIs with that scheme match the filter If a filter specifies a scheme and an

authority but no path all URIs with the same scheme and authority match regardless of their

paths If a filter specifies a scheme an authority and a path only URIs with the same scheme

authority and path match However a path specification in the filter can contain wildcards to

require only a partial match of the path

The type attribute of a ltdatagt element specifies the MIME type of the data Its more common in

filters than a URI Both the Intent object and the filter can use a wildcard for the subtype field

mdash for example text or audio mdash indicating any subtype matches

The data test compares both the URI and the data type in the Intent object to a URI and data

type specified in the filter The rules are as follows

a An Intent object that contains neither a URI nor a data type passes the test only if the filter

likewise does not specify any URIs or data types

b An Intent object that contains a URI but no data type (and a type cannot be inferred from the

URI) passes the test only if its URI matches a URI in the filter and the filter likewise does not

specify a type This will be the case only for URIs like mailto and tel that do not refer to actual

data

c An Intent object that contains a data type but not a URI passes the test only if the filter lists the

same data type and similarly does not specify a URI

d An Intent object that contains both a URI and a data type (or a data type can be inferred from

the URI) passes the data type part of the test only if its type matches a type listed in the filter It

passes the URI part of the test either if its URI matches a URI in the filter or if it has a content

or file URI and the filter does not specify a URI In other words a component is presumed to

support content and file data if its filter lists only a data type

If an intent can pass through the filters of more than one activity or service the user may be asked

which component to activate An exception is raised if no target can be found

Common cases

The last rule shown above for the data test rule (d) reflects the expectation that components are able

to get local data from a file or content provider Therefore their filters can list just a data type and do

not need to explicitly name the content and file schemes This is a typical case A ltdatagt element like

the following for example tells Android that the component can get image data from a content

provider and display it

ltdata androidmimeType=image gt

Since most available data is dispensed by content providers filters that specify a data type but not a

URI are perhaps the most common

Another common configuration is filters with a scheme and a data type For example a ltdatagt

element like the following tells Android that the component can get video data from the network and

display it

ltdata androidscheme=http androidtype=video gt

Consider for example what the browser application does when the user follows a link on a web page

It first tries to display the data (as it could if the link was to an HTML page) If it cant display the data it

puts together an implicit intent with the scheme and data type and tries to start an activity that can do

the job If there are no takers it asks the download manager to download the data That puts it under

the control of a content provider so a potentially larger pool of activities (those with filters that just

name a data type) can respond

Most applications also have a way to start fresh without a reference to any particular data Activities

that can initiate applications have filters with androidintentactionMAIN specified as the action If

they are to be represented in the application launcher they also specify the

androidintentcategoryLAUNCHER category

ltintent-filter gt ltaction androidname=code androidintentactionMAIN gt ltcategory androidname=code androidintentcategoryLAUNCHER gt ltintent-filtergt

Using intent matching

Intents are matched against intent filters not only to discover a target component to activate but also

to discover something about the set of components on the device For example the Android system

populates the application launcher the top-level screen that shows the applications that are available

for the user to launch by finding all the activities with intent filters that specify the

androidintentactionMAIN action and androidintentcategoryLAUNCHER category (as illustrated

in the previous section) It then displays the icons and labels of those activities in the launcher

Similarly it discovers the home screen by looking for the activity with androidintentcategoryHOME

in its filter

Your application can use intent matching is a similar way The PackageManager has a set of query()

methods that return all components that can accept a particular intent and a similar series of

resolve() methods that determine the best component to respond to an intent For example

queryIntentActivities() returns a list of all activities that can perform the intent passed as an argument

and queryIntentServices() returns a similar list of services Neither method activates the components

they just list the ones that can respond Theres a similar method queryBroadcastReceivers() for

broadcast receivers

Note Pad Example

The Note Pad sample application enables users to browse through a list of notes view details about

individual items in the list edit the items and add a new item to the list This section looks at the intent

filters declared in its manifest file (If youre working offline in the SDK you can find all the source files

for this sample application including its manifest file at ltsdkgtsamplesNotePadindexhtml If youre

viewing the documentation online the source files are in the Tutorials and Sample Code section here)

In its manifest file the Note Pad application declares three activities each with at least one intent filter

It also declares a content provider that manages the note data Here is the manifest file in its entirety

ltmanifest xmlnsandroid=httpschemasandroidcomapkresandroid package=comexampleandroidnotepadgt ltapplication androidicon=drawableapp_notes androidlabel=stringapp_name gt ltprovider androidname=NotePadProvider androidauthorities=comgoogleproviderNotePad gt ltactivity androidname=NotesList androidlabel=stringtitle_notes_listgt ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltactivity androidname=NoteEditor androidtheme=androidstyleThemeLight androidlabel=stringtitle_note gt ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltactivitygt

ltactivity androidname=TitleEditor androidlabel=stringtitle_edit_title androidtheme=androidstyleThemeDialoggt ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltapplicationgt ltmanifestgt

The first activity NotesList is distinguished from the other activities by the fact that it operates on a

directory of notes (the note list) rather than on a single note It would generally serve as the initial user

interface into the application It can do three things as described by its three intent filters

1 ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt

This filter declares the main entry point into the Note Pad application The standard MAIN action is an

entry point that does not require any other information in the Intent (no data specification for example)

and the LAUNCHER category says that this entry point should be listed in the application launcher

2 ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

This filter declares the things that the activity can do on a directory of notes It can allow the user to

view or edit the directory (via the VIEW and EDIT actions) or to pick a particular note from the

directory (via the PICK action)

The mimeType attribute of the ltdatagt element specifies the kind of data that these actions operate on

It indicates that the activity can get a Cursor over zero or more items (vndandroidcursordir) from a

content provider that holds Note Pad data (vndgooglenote) The Intent object that launches the

activity would include a content URI specifying the exact data of this type that the activity should open

Note also the DEFAULT category supplied in this filter Its there because the ContextstartActivity()

and ActivitystartActivityForResult() methods treat all intents as if they contained the DEFAULT

category mdash with just two exceptions

o Intents that explicitly name the target activity

o Intents consisting of the MAIN action and LAUNCHER category

Therefore the DEFAULT category is required for all filters mdash except for those with the MAIN action

and LAUNCHER category (Intent filters are not consulted for explicit intents)

3 ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

This filter describes the activitys ability to return a note selected by the user without requiring any

specification of the directory the user should choose from The GET_CONTENT action is similar to the

PICK action In both cases the activity returns the URI for a note selected by the user (In each case

its returned to the activity that called startActivityForResult() to start the NoteList activity) Here

however the caller specifies the type of data desired instead of the directory of data the user will be

picking from

The data type vndandroidcursoritemvndgooglenote indicates the type of data the activity can

return mdash a URI for a single note From the returned URI the caller can get a Cursor for exactly one

item (vndandroidcursoritem) from the content provider that holds Note Pad data (vndgooglenote)

In other words for the PICK action in the previous filter the data type indicates the type of data the

activity could display to the user For the GET_CONTENT filter it indicates the type of data the activity

can return to the caller

Given these capabilities the following intents will resolve to the NotesList activity

action androidintentactionMAIN

Launches the activity with no data specified

action androidintentactionMAIN

category androidintentcategoryLAUNCHER

Launches the activity with no data selected specified This is the actual intent used by the

Launcher to populate its top-level list All activities with filters that match this action and

category are added to the list

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of all the notes under

contentcomgoogleproviderNotePadnotes The user can then browse through the list and

get information about the items in it

action androidintentactionPICK

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of the notes under

contentcomgoogleproviderNotePadnotes The user can then pick a note from the list and

the activity will return the URI for that item back to the activity that started the NoteList activity

action androidintentactionGET_CONTENT

data type vndandroidcursoritemvndgooglenote

Asks the activity to supply a single item of Note Pad data

The second activity NoteEditor shows users a single note entry and allows them to edit it It can do

two things as described by its two intent filters

1 ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The first primary purpose of this activity is to enable the user to interact with a single note ampmdash to

either VIEW the note or EDIT it (The EDIT_NOTE category is a synonym for EDIT) The intent would

contain the URI for data matching the MIME type vndandroidcursoritemvndgooglenote mdash that is

the URI for a single specific note It would typically be a URI that was returned by the PICK or

GET_CONTENT actions of the NoteList activity

As before this filter lists the DEFAULT category so that the activity can be launched by intents that

dont explicitly specify the NoteEditor class

2 ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

The secondary purpose of this activity is to enable the user to create a new note which it will INSERT

into an existing directory of notes The intent would contain the URI for data matching the MIME type

vndandroidcursordirvndgooglenote mdash that is the URI for the directory where the note should be

placed

Given these capabilities the following intents will resolve to the NoteEditor activity

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID (For details on how content

URIs specify individual members of a group see Content Providers)

action androidintentactionEDIT

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID and to let the user edit it If

the user saves the changes the activity updates the data for the note in the content provider

action androidintentactionINSERT

data contentcomgoogleproviderNotePadnotes

Asks the activity to create a new empty note in the notes list at

contentcomgoogleproviderNotePadnotes and allow the user to edit it If the user saves the

note its URI is returned to the caller

The last activity TitleEditor enables the user to edit the title of a note This could be implemented by

directly invoking the activity (by explicitly setting its component name in the Intent) without using an

intent filter But here we take the opportunity to show how to publish alternative operations on existing

data

ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The single intent filter for this activity uses a custom action called

comandroidnotepadactionEDIT_TITLE It must be invoked on a specific note (data type

vndandroidcursoritemvndgooglenote) like the previous VIEW and EDIT actions However here the

activity displays the title contained in the note data not the content of the note itself

In addition to supporting the usual DEFAULT category the title editor also supports two other standard

categories ALTERNATIVE and SELECTED_ALTERNATIVE These categories identify activities that

can be presented to users in a menu of options (much as the LAUNCHER category identifies activities

that should be presented to user in the application launcher) Note that the filter also supplies an

explicit label (via androidlabel=stringresolve_title) to better control what users see when

presented with this activity as an alternative action to the data they are currently viewing (For more

information on these categories and building options menus see the

PackageManagerqueryIntentActivityOptions() and MenuaddIntentOptions() methods)

Given these capabilities the following intent will resolve to the TitleEditor activity

action comandroidnotepadactionEDIT_TITLE

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the title associated with note ID and allow the user to edit the title

Processes and Threads

When an application component starts and the application does not have any other components

running the Android system starts a new Linux process for the application with a single thread of

execution By default all components of the same application run in the same process and thread

(called the main thread) If an application component starts and there already exists a process for

that application (because another component from the application exists) then the component is

started within that process and uses the same thread of execution However you can arrange for

different components in your application to run in separate processes and you can create additional

threads for any process

This document discusses how processes and threads work in an Android application

Processes

By default all components of the same application run in the same process and most applications

should not change this However if you find that you need to control which process a certain

component belongs to you can do so in the manifest file

The manifest entry for each type of component elementmdashltactivitygt ltservicegt ltreceivergt and

ltprovidergtmdashsupports an androidprocess attribute that can specify a process in which that component

should run You can set this attribute so that each component runs in its own process or so that some

components share a process while others do not You can also set androidprocess so that

components of different applications run in the same processmdashprovided that the applications share the

same Linux user ID and are signed with the same certificates

The ltapplicationgt element also supports an androidprocess attribute to set a default value that

applies to all components

Android might 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 thats killed are consequently destroyed A process is started again for those components

when theres again work for them to do

When deciding which processes to kill the Android system weighs their relative importance to the

user For example it more readily shuts down a process hosting activities that are no longer visible on

screen compared to a process hosting visible activities The decision whether to terminate a process

therefore depends on the state of the components running in that process The rules used to decide

which processes to terminate is discussed below

Process lifecycle

The Android system tries to maintain an application process for as long as possible but eventually

needs to remove old processes to reclaim memory for new or more important processes To determine

which processes to keep and which to kill the system places each process into an importance

hierarchy based on the components running in the process and the state of those components

Processes with the lowest importance are eliminated first then those with the next lowest importance

and so on as necessary to recover system resources

There are five levels in the importance hierarchy The following list presents the different types of

processes in order of importance (the first process is most important and is killed last)

1 Foreground process

A process that is required for what the user is currently doing A process is considered to be in the

foreground if any of the following conditions are true

o It hosts an Activity that the user is interacting with (the Activitys onResume() method has been called)

o It hosts a Service thats bound to the activity that the user is interacting with

o It hosts a Service thats running in the foregroundmdashthe service has called startForeground()

o It hosts a Service thats executing one of its lifecycle callbacks (onCreate() onStart() or onDestroy())

o It hosts a BroadcastReceiver thats executing its onReceive() method

Generally only a few foreground processes exist at any given time They are killed only as a last

resortmdashif memory is so low that they cannot all continue to run Generally at that point the device has

reached a memory paging state so killing some foreground processes is required to keep the user

interface responsive

2 Visible process

A process that doesnt have any foreground components but still can affect what the user sees on

screen A process is considered to be visible if either of the following conditions are true

o It hosts an Activity that is not in the foreground but is still visible to the user (its onPause() method has

been called) This might occur for example if the foreground activity started a dialog which allows the

previous activity to be seen behind it

o It hosts a Service thats bound to a visible (or foreground) activity

A visible process is considered extremely important and will not be killed unless doing so is required to

keep all foreground processes running

3 Service process

A process that is running a service that has been started with the startService() method and does not

fall into either of the two higher categories Although service processes are not directly tied to anything

the user sees they are generally doing things that the user cares about (such as playing music in the

background or downloading data on the network) so the system keeps them running unless theres

not enough memory to retain them along with all foreground and visible processes

4 Background process

A process holding an activity thats not currently visible to the user (the activitys onStop() method has

been called) These processes have no direct impact on the user experience and the system can kill

them at any time to reclaim memory for a foreground visible or service process Usually there are

many background processes running so they are kept in an LRU (least recently used) list to ensure

that the process with the activity that was most recently seen by the user is the last to be killed If an

activity implements its lifecycle methods correctly and saves its current state killing its process will not

have a visible effect on the user experience because when the user navigates back to the activity the

activity restores all of its visible state See the Activities document for information about saving and

restoring state

5 Empty process

A process that doesnt hold any active application components The only reason to keep this kind of

process alive is for caching purposes to improve startup time the next time a component needs to run

in it The system often kills these processes in order to balance overall system resources between

process caches and the underlying kernel caches

Android ranks a process at the highest level it can based upon the importance of the components

currently active in the process For example if a process hosts a service and a visible activity the

process is ranked as a visible process not a service process

In addition a processs ranking might be increased because other processes are dependent on itmdasha

process that is serving another process can never be ranked lower than the process it is serving For

example if a content provider in process A is serving a client in process B or if a service in process A

is bound to a component in process B process A is always considered at least as important as

process B

Because a process running a service is ranked higher than a process with background activities an

activity that initiates a long-running operation might do well to start a service for that operation rather

than simply create a worker threadmdashparticularly if the operation will likely outlast the activity For

example an activity thats uploading a picture to a web site should start a service to perform the

upload so that the upload can continue in the background even if the user leaves the activity Using a

service guarantees that the operation will have at least service process priority regardless of what

happens to the activity This is the same reason that broadcast receivers should employ services

rather than simply put time-consuming operations in a thread

Threads

When an application is launched the system creates a thread of execution for the application called

main This thread is very important because it is in charge of dispatching events to the appropriate

user interface widgets including drawing events It is also the thread in which your application interacts

with components from the Android UI toolkit (components from the androidwidget and androidview

packages) As such the main thread is also sometimes called the UI thread

The system does not create a separate thread for each instance of a component All components that

run in the same process are instantiated in the UI thread and system calls to each component are

dispatched from that thread Consequently methods that respond to system callbacks (such as

onKeyDown() to report user actions or a lifecycle callback method) always run in the UI thread of the

process

For instance when the user touches a button on the screen your apps UI thread dispatches the touch

event to the widget which in turn sets its pressed state and posts an invalidate request to the event

queue The UI thread dequeues the request and notifies the widget that it should redraw itself

When your app performs intensive work in response to user interaction this single thread model can

yield poor performance unless you implement your application properly Specifically if everything is

happening in the UI thread performing long operations such as network access or database queries

will block the whole UI When the thread is blocked no events can be dispatched including drawing

events From the users perspective the application appears to hang Even worse if the UI thread is

blocked for more than a few seconds (about 5 seconds currently) the user is presented with the

infamous application not responding (ANR) dialog The user might then decide to quit your

application and uninstall it if they are unhappy

Additionally the Andoid UI toolkit is not thread-safe So you must not manipulate your UI from a

worker threadmdashyou must do all manipulation to your user interface from the UI thread Thus there are

simply two rules to Androids single thread model

1 Do not block the UI thread

2 Do not access the Android UI toolkit from outside the UI thread

Worker threads

Because of the single thread model described above its vital to the responsiveness of your

applications UI that you do not block the UI thread If you have operations to perform that are not

instantaneous you should make sure to do them in separate threads (background or worker

threads)

For example below is some code for a click listener that downloads an image from a separate thread

and displays it in an ImageView

public void onClick(View v) new Thread(new Runnable() public void run() Bitmap b = loadImageFromNetwork(httpexamplecomimagepng) mImageViewsetImageBitmap(b) )start()

At first this seems to work fine because it creates a new thread to handle the network operation

However it violates the second rule of the single-threaded model do not access the Android UI toolkit

from outside the UI threadmdashthis sample modifies the ImageView from the worker thread instead of the

UI thread This can result in undefined and unexpected behavior which can be difficult and time-

consuming to track down

To fix this problem Android offers several ways to access the UI thread from other threads Here is a

list of methods that can help

ActivityrunOnUiThread(Runnable)

Viewpost(Runnable)

ViewpostDelayed(Runnable long)

For example you can fix the above code by using the Viewpost(Runnable) method

public void onClick(View v) new Thread(new Runnable() public void run() final Bitmap bitmap = loadImageFromNetwork(httpexamplecomimagepng) mImageViewpost(new Runnable() public void run() mImageViewsetImageBitmap(bitmap) ) )start()

Now this implementation is thread-safe the network operation is done from a separate thread while

the ImageView is manipulated from the UI thread

However as the complexity of the operation grows this kind of code can get complicated and difficult

to maintain To handle more complex interactions with a worker thread you might consider using a

Handler in your worker thread to process messages delivered from the UI thread Perhaps the best

solution though is to extend the AsyncTask class which simplifies the execution of worker thread

tasks that need to interact with the UI

Using AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface It performs the blocking

operations in a worker thread and then publishes the results on the UI thread without requiring you to

handle threads andor handlers yourself

To use it you must subclass AsyncTask and implement the doInBackground() callback method which

runs in a pool of background threads To update your UI you should implement onPostExecute()

which delivers the result from doInBackground() and runs in the UI thread so you can safely update

your UI You can then run the task by calling execute() from the UI thread

For example you can implement the previous example using AsyncTask this way

public void onClick(View v) new DownloadImageTask()execute(httpexamplecomimagepng) private class DownloadImageTask extends AsyncTaskltString Void Bitmapgt The system calls this to perform work in a worker thread and delivers it the parameters given to AsyncTaskexecute() protected Bitmap doInBackground(String urls) return loadImageFromNetwork(urls[0])

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 3: 03 services

If a component starts the service by calling startService() (which results in a call to

onStartCommand()) then the service remains running until it stops itself with stopSelf() or another

component stops it by calling stopService()

If a component calls bindService() to create the service (and onStartCommand() is not called) then the

service runs only as long as the component is bound to it Once the service is unbound from all clients

the system destroys it

The Android system will force-stop a service only when memory is low and it must recover system

resources for the activity that has user focus If the service is bound to an activity that has user focus

then its less likely to be killed and if the service is declared to run in the foreground (discussed later)

then it will almost never be killed Otherwise if the service was started and is long-running then the

system will lower its position in the list of background tasks over time and the service will become

highly susceptible to killingmdashif your service is started then you must design it to gracefully handle

restarts by the system If the system kills your service it restarts it as soon as resources become

available again (though this also depends on the value you return from onStartCommand() as

discussed later) For more information about when the system might destroy a service see the

Processes and Threading document

In the following sections youll see how you can create each type of service and how to use it from

other application components

Declaring a service in the manifest

Like activities (and other components) you must declare all services in your applications manifest file

To declare your service add a ltservicegt element as a child of the ltapplicationgt element For

example

ltmanifest gt ltapplication gt ltservice androidname=ExampleService gt ltapplicationgt ltmanifestgt

There are other attributes you can include in the ltservicegt element to define properties such as

permissions required to start the service and the process in which the service should run The

androidname attribute is the only required attributemdashit specifies the class name of the service Once

you publish your application you should not change this name because if you do you might break

some functionality where explicit intents are used to reference your service (read the blog post Things

That Cannot Change)

See the ltservicegt element reference for more information about declaring your service in the manifest

Just like an activity a service can define intent filters that allow other components to invoke the service

using implicit intents By declaring intent filters components from any application installed on the

users device can potentially start your service if your service declares an intent filter that matches the

intent another application passes to startService()

If you plan on using your service only locally (other applications do not use it) then you dont need to

(and should not) supply any intent filters Without any intent filters you must start the service using an

intent that explicitly names the service class More information about starting a service is discussed

below

Additionally you can ensure that your service is private to your application only if you include the

androidexported attribute and set it to false This is effective even if your service supplies intent

filters

For more information about creating intent filters for your service see the Intents and Intent Filters

document

Creating a Started Service

Targeting Android 16 or lower

If youre building an application for Android 16 or lower you need to implement onStart() instead of

onStartCommand() (in Android 20 onStart() was deprecated in favor of onStartCommand())

For more information about providing compatibility with versions of Android older than 20 see the

onStartCommand() documentation

A started service is one that another component starts by calling startService() resulting in a call to the

services onStartCommand() method

When a service is started it has a lifecycle thats independent of the component that started it and the

service can run in the background indefinitely even if the component that started it is destroyed As

such the service should stop itself when its job is done by calling stopSelf() or another component

can stop it by calling stopService()

An application component such as an activity can start the service by calling startService() and

passing an Intent that specifies the service and includes any data for the service to use The service

receives this Intent in the onStartCommand() method

For instance suppose an activity needs to save some data to an online database The activity can

start a companion service and deliver it the data to save by passing an intent to startService() The

service receives the intent in onStartCommand() connects to the Internet and performs the database

transaction When the transaction is done the service stops itself and it is destroyed

Caution A services runs in the same process as the application in which it is declared and in the

main thread of that application by default So if your service performs intensive or blocking

operations while the user interacts with an activity from the same application the service will slow

down activity performance To avoid impacting application performance you should start a new

thread inside the service

Traditionally there are two classes you can extend to create a started service

Service

This is the base class for all services When you extend this class its important that you create

a new thread in which to do all the services work because the service uses your applications

main thread by default which could slow the performance of any activity your application is

running

IntentService

This is a subclass of Service that uses a worker thread to handle all start requests one at a

time This is the best option if you dont require that your service handle multiple requests

simultaneously All you need to do is implement onHandleIntent() which receives the intent for

each start request so you can do the background work

The following sections describe how you can implement your service using either one for these

classes

Extending the IntentService class

Because most started services dont need to handle multiple requests simultaneously (which can

actually be a dangerous multi-threading scenario) its probably best if you implement your service

using the IntentService class

The IntentService does the following

Creates a default worker thread that executes all intents delivered to onStartCommand() separate from

your applications main thread

Creates a work queue that passes one intent at a time to your onHandleIntent() implementation so

you never have to worry about multi-threading

Stops the service after all start requests have been handled so you never have to call stopSelf()

Provides default implementation of onBind() that returns null

Provides a default implementation of onStartCommand() that sends the intent to the work queue and

then to your onHandleIntent() implementation

All this adds up to the fact that all you need to do is implement onHandleIntent() to do the work

provided by the client (Though you also need to provide a small constructor for the service)

Heres an example implementation of IntentService

public class HelloIntentService extends IntentService A constructor is required and must call the super IntentService(String)

constructor with a name for the worker thread public HelloIntentService() super(HelloIntentService) The IntentService calls this method from the default worker thread with the intent that started the service When this method returns IntentService stops the service as appropriate Override protected void onHandleIntent(Intent intent) Normally we would do some work here like download a file For our sample we just sleep for 5 seconds long endTime = SystemcurrentTimeMillis() + 51000 while (SystemcurrentTimeMillis() lt endTime) synchronized (this) try wait(endTime - SystemcurrentTimeMillis()) catch (Exception e)

Thats all you need a constructor and an implementation of onHandleIntent()

If you decide to also override other callback methods such as onCreate() onStartCommand() or

onDestroy() be sure to call the super implementation so that the IntentService can properly handle

the life of the worker thread

For example onStartCommand() must return the default implementation (which is how the intent gets

delivered to onHandleIntent())

Override public int onStartCommand(Intent intent int flags int startId) ToastmakeText(this service starting ToastLENGTH_SHORT)show() return superonStartCommand(intentflagsstartId)

Besides onHandleIntent() the only method from which you dont need to call the super class is

onBind() (but you only need to implement that if your service allows binding)

In the next section youll see how the same kind of service is implemented when extending the base

Service class which is a lot more code but which might be appropriate if you need to handle

simultaneous start requests

Extending the Service class

As you saw in the previous section using IntentService makes your implementation of a started

service very simple If however you require your service to perform multi-threading (instead of

processing start requests through a work queue) then you can extend the Service class to handle

each intent

For comparison the following example code is an implementation of the Service class that performs

the exact same work as the example above using IntentService That is for each start request it uses

a worker thread to perform the job and processes only one request at a time

public class HelloService extends Service private Looper mServiceLooper private ServiceHandler mServiceHandler Handler that receives messages from the thread private final class ServiceHandler extends Handler public ServiceHandler(Looper looper) super(looper) Override public void handleMessage(Message msg) Normally we would do some work here like download a file For our sample we just sleep for 5 seconds long endTime = SystemcurrentTimeMillis() + 51000 while (SystemcurrentTimeMillis() lt endTime) synchronized (this) try wait(endTime - SystemcurrentTimeMillis()) catch (Exception e) Stop the service using the startId so that we dont stop the service in the middle of handling another job stopSelf(msgarg1) Override public void onCreate() Start up the thread running the service Note that we create a separate thread because the service normally runs in the processs main thread which we dont want to block We also make it background priority so CPU-intensive work will not disrupt our UI HandlerThread thread = new HandlerThread(ServiceStartArguments ProcessTHREAD_PRIORITY_BACKGROUND) threadstart() Get the HandlerThreads Looper and use it for our Handler

mServiceLooper = threadgetLooper() mServiceHandler = new ServiceHandler(mServiceLooper) Override public int onStartCommand(Intent intent int flags int startId) ToastmakeText(this service starting ToastLENGTH_SHORT)show() For each start request send a message to start a job and deliver the start ID so we know which request were stopping when we finish the job Message msg = mServiceHandlerobtainMessage() msgarg1 = startId mServiceHandlersendMessage(msg) If we get killed after returning from here restart return START_STICKY Override public IBinder onBind(Intent intent) We dont provide binding so return null return null Override public void onDestroy() ToastmakeText(this service done ToastLENGTH_SHORT)show()

As you can see its a lot more work than using IntentService

However because you handle each call to onStartCommand() yourself you can perform multiple

requests simultaneously Thats not what this example does but if thats what you want then you can

create a new thread for each request and run them right away (instead of waiting for the previous

request to finish)

Notice that the onStartCommand() method must return an integer The integer is a value that

describes how the system should continue the service in the event that the system kills it (as

discussed above the default implementation for IntentService handles this for you though you are

able to modify it) The return value from onStartCommand() must be one of the following constants

START_NOT_STICKY

If the system kills the service after onStartCommand() returns do not recreate the service

unless there are pending intents to deliver This is the safest option to avoid running your

service when not necessary and when your application can simply restart any unfinished jobs

START_STICKY

If the system kills the service after onStartCommand() returns recreate the service and call

onStartCommand() but do not redeliver the last intent Instead the system calls

onStartCommand() with a null intent unless there were pending intents to start the service in

which case those intents are delivered This is suitable for media players (or similar services)

that are not executing commands but running indefinitely and waiting for a job

START_REDELIVER_INTENT

If the system kills the service after onStartCommand() returns recreate the service and call

onStartCommand() with the last intent that was delivered to the service Any pending intents are

delivered in turn This is suitable for services that are actively performing a job that should be

immediately resumed such as downloading a file

For more details about these return values see the linked reference documentation for each constant

Starting a Service

You can start a service from an activity or other application component by passing an Intent (specifying

the service to start) to startService() The Android system calls the services onStartCommand()

method and passes it the Intent (You should never call onStartCommand() directly)

For example an activity can start the example service in the previous section (HelloSevice) using an

explicit intent with startService()

Intent intent = new Intent(this HelloServiceclass) startService(intent)

The startService() method returns immediately and the Android system calls the services

onStartCommand() method If the service is not already running the system first calls onCreate() then

calls onStartCommand()

If the service does not also provide binding the intent delivered with startService() is the only mode of

communication between the application component and the service However if you want the service

to send a result back then the client that starts the service can create a PendingIntent for a broadcast

(with getBroadcast()) and deliver it to the service in the Intent that starts the service The service can

then use the broadcast to deliver a result

Multiple requests to start the service result in multiple corresponding calls to the services

onStartCommand() However only one request to stop the service (with stopSelf() or stopService()) is

required to stop it

Stopping a service

A started service must manage its own lifecycle That is the system does not stop or destroy the

service unless it must recover system memory and the service continues to run after

onStartCommand() returns So the service must stop itself by calling stopSelf() or another component

can stop it by calling stopService()

Once requested to stop with stopSelf() or stopService() the system destroys the service as soon as

possible

However if your service handles multiple requests to onStartCommand() concurrently then you

shouldnt stop the service when youre done processing a start request because you might have since

received a new start request (stopping at the end of the first request would terminate the second one)

To avoid this problem you can use stopSelf(int) to ensure that your request to stop the service is

always based on the most recent start request That is when you call stopSelf(int) you pass the ID of

the start request (the startId delivered to onStartCommand()) to which your stop request corresponds

Then if the service received a new start request before you were able to call stopSelf(int) then the ID

will not match and the service will not stop

Caution Its important that your application stops its services when its done working to avoid

wasting system resources and consuming battery power If necessary other components can stop

the service by calling stopService() Even if you enable binding for the service you must always

stop the service yourself if it ever received a call to onStartCommand()

For more information about the lifecycle of a service see the section below about Managing the

Lifecycle of a Service

Creating a Bound Service

A bound service is one that allows application components to bind to it by calling bindService() in order

to create a long-standing connection (and generally does not allow components to start it by calling

startService())

You should create a bound service when you want to interact with the service from activities and other

components in your application or to expose some of your applications functionality to other

applications through interprocess communication (IPC)

To create a bound service you must implement the onBind() callback method to return an IBinder that

defines the interface for communication with the service Other application components can then call

bindService() to retrieve the interface and begin calling methods on the service The service lives only

to serve the application component that is bound to it so when there are no components bound to the

service the system destroys it (you do not need to stop a bound service in the way you must when the

service is started through onStartCommand())

To create a bound service the first thing you must do is define the interface that specifies how a client

can communicate with the service This interface between the service and a client must be an

implementation of IBinder and is what your service must return from the onBind() callback method

Once the client receives the IBinder it can begin interacting with the service through that interface

Multiple clients can bind to the service at once When a client is done interacting with the service it

calls unbindService() to unbind Once there are no clients bound to the service the system destroys

the service

There are multiple ways to implement a bound service and the implementation is more complicated

than a started service so the bound service discussion appears in a separate document about Bound

Services

Sending Notifications to the User

Once running a service can notify the user of events using Toast Notifications or Status Bar

Notifications

A toast notification is a message that appears on the surface of the current window for a moment then

disappears while a status bar notification provides an icon in the status bar with a message which the

user can select in order to take an action (such as start an activity)

Usually a status bar notification is the best technique when some background work has completed

(such as a file completed downloading) and the user can now act on it When the user selects the

notification from the expanded view the notification can start an activity (such as to view the

downloaded file)

See the Toast Notifications or Status Bar Notifications developer guides for more information

Running a Service in the Foreground

A foreground service is a service thats considered to be something the user is actively aware of and

thus not a candidate for the system to kill when low on memory A foreground service must provide a

notification for the status bar which is placed under the Ongoing heading which means that the

notification cannot be dismissed unless the service is either stopped or removed from the foreground

For example a music player that plays music from a service should be set to run in the foreground

because the user is explicitly aware of its operation The notification in the status bar might indicate the

current song and allow the user to launch an activity to interact with the music player

To request that your service run in the foreground call startForeground() This method takes two

parameters an integer that uniquely identifies the notification and the Notification for the status bar

For example

Notification notification = new Notification(Rdrawableicon getText(Rstringticker_text) SystemcurrentTimeMillis()) Intent notificationIntent = new Intent(this ExampleActivityclass) PendingIntent pendingIntent = PendingIntentgetActivity(this 0 notificationIntent 0) notificationsetLatestEventInfo(this getText(Rstringnotification_title) getText(Rstringnotification_message) pendingIntent) startForeground(ONGOING_NOTIFICATION notification)

To remove the service from the foreground call stopForeground() This method takes a boolean

indicating whether to remove the status bar notification as well This method does not stop the service

However if you stop the service while its still running in the foreground then the notification is also

removed

Note The methods startForeground() and stopForeground() were introduced in Android 20 (API

Level 5) In order to run your service in the foreground on older versions of the platform you must

use the previous setForeground() methodmdashsee the startForeground() documentation for

information about how to provide backward compatibility

For more information about notifications see Creating Status Bar Notifications

Managing the Lifecycle of a Service

The lifecycle of a service is much simpler than that of an activity However its even more important

that you pay close attention to how your service is created and destroyed because a service can run

in the background without the user being aware

The service lifecyclemdashfrom when its created to when its destroyedmdashcan follow two different paths

A started service

The service is created when another component calls startService() The service then runs indefinitely

and must stop itself by calling stopSelf() Another component can also stop the service by calling

stopService() When the service is stopped the system destroys it

A bound service

The service is created when another component (a client) calls bindService() The client then

communicates with the service through an IBinder interface The client can close the connection by

calling unbindService() Multiple clients can bind to the same service and when all of them unbind the

system destroys the service (The service does not need to stop itself)

These two paths are not entirely separate That is you can bind to a service that was already started

with startService() For example a background music service could be started by calling startService()

with an Intent that identifies the music to play Later possibly when the user wants to exercise some

control over the player or get information about the current song an activity can bind to the service by

calling bindService() In cases like this stopService() or stopSelf() does not actually stop the service

until all clients unbind

Implementing the lifecycle callbacks

Like an activity a service has lifecycle callback methods that you can implement to monitor changes in

the services state and perform work at the appropriate times The following skeleton service

demonstrates each of the lifecycle methods

Figure 2 The service lifecycle The diagram on the left shows the lifecycle when the service is created

with startService() and the diagram on the right shows the lifecycle when the service is created with

bindService()

public class ExampleService extends Service int mStartMode indicates how to behave if the service is killed IBinder mBinder interface for clients that bind boolean mAllowRebind indicates whether onRebind should be used Override public void onCreate() The service is being created Override public int onStartCommand(Intent intent int flags int startId) The service is starting due to a call to startService() return mStartMode Override public IBinder onBind(Intent intent) A client is binding to the service with bindService() return mBinder Override public boolean onUnbind(Intent intent) All clients have unbound with unbindService()

return mAllowRebind Override public void onRebind(Intent intent) A client is binding to the service with bindService() after onUnbind() has already been called Override public void onDestroy() The service is no longer used and is being destroyed

Note Unlike the activity lifecycle callback methods you are not required to call the superclass

implementation of these callback methods

By implementing these methods you can monitor two nested loops of the services lifecycle

The entire lifetime of a service happens between the time onCreate() is called and the time

onDestroy() returns Like an activity a service does its initial setup in onCreate() and releases all

remaining resources in onDestroy() For example a music playback service could create the thread

where the music will be played in onCreate() then stop the thread in onDestroy()

The onCreate() and onDestroy() methods are called for all services whether theyre created by

startService() or bindService()

The active lifetime of a service begins with a call to either onStartCommand() or onBind() Each

method is handed the Intent that was passed to either startService() or bindService() respectively

If the service is started the active lifetime ends the same time that the entire lifetime ends (the service

is still active even after onStartCommand() returns) If the service is bound the active lifetime ends

when onUnbind() returns

Note Although a started service is stopped by a call to either stopSelf() or stopService() there is

not a respective callback for the service (theres no onStop() callback) So unless the service is

bound to a client the system destroys it when the service is stoppedmdashonDestroy() is the only

callback received

Figure 2 illustrates the typical callback methods for a service Although the figure separates services

that are created by startService() from those created by bindService() keep in mind that any service

no matter how its started can potentially allow clients to bind to it So a service that was initially

started with onStartCommand() (by a client calling startService()) can still receive a call to onBind()

(when a client calls bindService())

For more information about creating a service that provides binding see the Bound Services

document which includes more information about the onRebind() callback method in the section about

Managing the Lifecycle of a Bound Service

Bound Services

A bound service is the server in a client-server interface A bound service allows components (such as

activities) to bind to the service send requests receive responses and even perform interprocess

communication (IPC) A bound service typically lives only while it serves another application

component and does not run in the background indefinitely

This document shows you how to create a bound service including how to bind to the service from

other application components However you should also refer to the Services document for additional

information about services in general such as how to deliver notifications from a service set the

service to run in the foreground and more

The Basics

A bound service is an implementation of the Service class that allows other applications to bind to it

and interact with it To provide binding for a service you must implement the onBind() callback

method This method returns an IBinder object that defines the programming interface that clients can

use to interact with the service

Binding to a Started Service

As discussed in the Services document you can create a service that is both started and bound That

is the service can be started by calling startService() which allows the service to run indefinitely and

also allow a client to bind to the service by calling bindService()

If you do allow your service to be started and bound then when the service has been started the

system does not destroy the service when all clients unbind Instead you must explicitly stop the

service by calling stopSelf() or stopService()

Although you should usually implement either onBind() or onStartCommand() its sometimes

necessary to implement both For example a music player might find it useful to allow its service to run

indefinitely and also provide binding This way an activity can start the service to play some music and

the music continues to play even if the user leaves the application Then when the user returns to the

application the activity can bind to the service to regain control of playback

Be sure to read the section about Managing the Lifecycle of a Bound Service for more information

about the service lifecycle when adding binding to a started service

A client can bind to the service by calling bindService() When it does it must provide an

implementation of ServiceConnection which monitors the connection with the service The

bindService() method returns immediately without a value but when the Android system creates the

connection between the client and service it calls onServiceConnected() on the ServiceConnection to

deliver the IBinder that the client can use to communicate with the service

Multiple clients can connect to the service at once However the system calls your services onBind()

method to retrieve the IBinder only when the first client binds The system then delivers the same

IBinder to any additional clients that bind without calling onBind() again

When the last client unbinds from the service the system destroys the service (unless the service was

also started by startService())

When you implement your bound service the most important part is defining the interface that your

onBind() callback method returns There are a few different ways you can define your services IBinder

interface and the following section discusses each technique

Creating a Bound Service

When creating a service that provides binding you must provide an IBinder that provides the

programming interface that clients can use to interact with the service There are three ways you can

define the interface

Extending the Binder class

If your service is private to your own application and runs in the same process as the client

(which is common) you should create your interface by extending the Binder class and

returning an instance of it from onBind() The client receives the Binder and can use it to directly

access public methods available in either the Binder implementation or even the Service

This is the preferred technique when your service is merely a background worker for your own

application The only reason you would not create your interface this way is because your

service is used by other applications or across separate processes

Using a Messenger

If you need your interface to work across different processes you can create an interface for the

service with a Messenger In this manner the service defines a Handler that responds to

different types of Message objects This Handler is the basis for a Messenger that can then

share an IBinder with the client allowing the client to send commands to the service using

Message objects Additionally the client can define a Messenger of its own so the service can

send messages back

This is the simplest way to perform interprocess communication (IPC) because the Messenger

queues all requests into a single thread so that you dont have to design your service to be

thread-safe

Using AIDL

AIDL (Android Interface Definition Language) performs all the work to decompose objects into

primitives that the operating system can understand and marshall them across processes to

perform IPC The previous technique using a Messenger is actually based on AIDL as its

underlying structure As mentioned above the Messenger creates a queue of all the client

requests in a single thread so the service receives requests one at a time If however you

want your service to handle multiple requests simultaneously then you can use AIDL directly In

this case your service must be capable of multi-threading and be built thread-safe

To use AIDL directly you must create an aidl file that defines the programming interface The

Android SDK tools use this file to generate an abstract class that implements the interface and

handles IPC which you can then extend within your service

Note Most applications should not use AIDL to create a bound service because it may require

multithreading capabilities and can result in a more complicated implementation As such AIDL is

not suitable for most applications and this document does not discuss how to use it for your

service If youre certain that you need to use AIDL directly see the AIDL document

Extending the Binder class

If your service is used only by the local application and does not need to work across processes then

you can implement your own Binder class that provides your client direct access to public methods in

the service

Note This works only if the client and service are in the same application and process which is

most common For example this would work well for a music application that needs to bind an

activity to its own service thats playing music in the background

Heres how to set it up

1 In your service create an instance of Binder that either

o contains public methods that the client can call

o returns the current Service instance which has public methods the client can call

o or returns an instance of another class hosted by the service with public methods the client can call

2 Return this instance of Binder from the onBind() callback method

3 In the client receive the Binder from the onServiceConnected() callback method and make calls to the

bound service using the methods provided

Note The reason the service and client must be in the same application is so the client can cast

the returned object and properly call its APIs The service and client must also be in the same

process because this technique does not perform any marshalling across processes

For example heres a service that provides clients access to methods in the service through a Binder

implementation

public class LocalService extends Service

Binder given to clients

private final IBinder mBinder = new LocalBinder()

Random number generator

private final Random mGenerator = new Random()

Class used for the client Binder Because we know this service always

runs in the same process as its clients we dont need to deal with IPC

public class LocalBinder extends Binder

LocalService getService()

Return this instance of LocalService so clients can call public methods

return LocalServicethis

Override

public IBinder onBind(Intent intent)

return mBinder

method for clients

public int getRandomNumber()

return mGeneratornextInt(100)

The LocalBinder provides the getService() method for clients to retrieve the current instance of

LocalService This allows clients to call public methods in the service For example clients can call

getRandomNumber() from the service

Heres an activity that binds to LocalService and calls getRandomNumber() when a button is clicked

public class BindingActivity extends Activity

LocalService mService

boolean mBound = false

Override

protected void onCreate(Bundle savedInstanceState)

superonCreate(savedInstanceState)

setContentView(Rlayoutmain)

Override

protected void onStart()

superonStart()

Bind to LocalService

Intent intent = new Intent(this LocalServiceclass)

bindService(intent mConnection ContextBIND_AUTO_CREATE)

Override

protected void onStop()

superonStop()

Unbind from the service

if (mBound)

unbindService(mConnection)

mBound = false

Called when a button is clicked (the button in the layout file attaches to

this method with the androidonClick attribute)

public void onButtonClick(View v)

if (mBound)

Call a method from the LocalService

However if this call were something that might hang then this request should

occur in a separate thread to avoid slowing down the activity performance

int num = mServicegetRandomNumber()

ToastmakeText(this number + num ToastLENGTH_SHORT)show()

Defines callbacks for service binding passed to bindService()

private ServiceConnection mConnection = new ServiceConnection()

Override

public void onServiceConnected(ComponentName className

IBinder service)

Weve bound to LocalService cast the IBinder and get LocalService instance

LocalBinder binder = (LocalBinder) service

mService = bindergetService()

mBound = true

Override

public void onServiceDisconnected(ComponentName arg0)

mBound = false

The above sample shows how the client binds to the service using an implementation of

ServiceConnection and the onServiceConnected() callback The next section provides more

information about this process of binding to the service

Note The example above doesnt explicitly unbind from the service but all clients should unbind

at an appropriate time (such as when the activity pauses)

For more sample code see the LocalServicejava class and the LocalServiceActivitiesjava class in

ApiDemos

Using a Messenger

Compared to AIDL

When you need to perform IPC using a Messenger for your interface is simpler than implementing it

with AIDL because Messenger queues all calls to the service whereas a pure AIDL interface sends

simultaneous requests to the service which must then handle multi-threading

For most applications the service doesnt need to perform multi-threading so using a Messenger

allows the service to handle one call at a time If its important that your service be multi-threaded then

you should use AIDL to define your interface

If you need your service to communicate with remote processes then you can use a Messenger to

provide the interface for your service This technique allows you to perform interprocess

communication (IPC) without the need to use AIDL

Heres a summary of how to use a Messenger

The service implements a Handler that receives a callback for each call from a client

The Handler is used to create a Messenger object (which is a reference to the Handler)

The Messenger creates an IBinder that the service returns to clients from onBind()

Clients use the IBinder to instantiate the Messenger (that references the services Handler) which the

client uses to send Message objects to the service

The service receives each Message in its Handlermdashspecifically in the handleMessage() method

In this way there are no methods for the client to call on the service Instead the client delivers

messages (Message objects) that the service receives in its Handler

Heres a simple example service that uses a Messenger interface

public class MessengerService extends Service Command to the service to display a message static final int MSG_SAY_HELLO = 1 Handler of incoming messages from clients class IncomingHandler extends Handler Override public void handleMessage(Message msg) switch (msgwhat) case MSG_SAY_HELLO ToastmakeText(getApplicationContext() hello ToastLENGTH_SHORT)show() break default superhandleMessage(msg) Target we publish for clients to send messages to IncomingHandler final Messenger mMessenger = new Messenger(new IncomingHandler()) When binding to the service we return an interface to our messenger for sending messages to the service Override public IBinder onBind(Intent intent) ToastmakeText(getApplicationContext() binding ToastLENGTH_SHORT)show() return mMessengergetBinder()

Notice that the handleMessage() method in the Handler is where the service receives the incoming

Message and decides what to do based on the what member

All that a client needs to do is create a Messenger based on the IBinder returned by the service and

send a message using send() For example heres a simple activity that binds to the service and

delivers the MSG_SAY_HELLO message to the service

public class ActivityMessenger extends Activity Messenger for communicating with the service Messenger mService = null Flag indicating whether we have called bind on the service boolean mBound Class for interacting with the main interface of the service private ServiceConnection mConnection = new ServiceConnection() public void onServiceConnected(ComponentName className IBinder service) This is called when the connection with the service has been established giving us the object we can use to interact with the service We are communicating with the service using a Messenger so here we get a client-side representation of that from the raw IBinder object mService = new Messenger(service) mBound = true public void onServiceDisconnected(ComponentName className) This is called when the connection with the service has been unexpectedly disconnected -- that is its process crashed mService = null mBound = false public void sayHello(View v) if (mBound) return Create and send a message to the service using a supported what value Message msg = Messageobtain(null MessengerServiceMSG_SAY_HELLO 0 0) try mServicesend(msg) catch (RemoteException e) eprintStackTrace() Override protected void onCreate(Bundle savedInstanceState) superonCreate(savedInstanceState) setContentView(Rlayoutmain)

Override protected void onStart() superonStart() Bind to the service bindService(new Intent(this MessengerServiceclass) mConnection ContextBIND_AUTO_CREATE) Override protected void onStop() superonStop() Unbind from the service if (mBound) unbindService(mConnection) mBound = false

Notice that this example does not show how the service can respond to the client If you want the

service to respond then you need to also create a Messenger in the client Then when the client

receives the onServiceConnected() callback it sends a Message to the service that includes the

clients Messenger in the replyTo parameter of the send() method

You can see an example of how to provide two-way messaging in the MessengerServicejava (service)

and MessengerServiceActivitiesjava (client) samples

Binding to a Service

Application components (clients) can bind to a service by calling bindService() The Android system

then calls the services onBind() method which returns an IBinder for interacting with the service

The binding is asynchronous bindService() returns immediately and does not return the IBinder to the

client To receive the IBinder the client must create an instance of ServiceConnection and pass it to

bindService() The ServiceConnection includes a callback method that the system calls to deliver the

IBinder

Note Only activities services and content providers can bind to a servicemdashyou cannot bind to a

service from a broadcast receiver

So to bind to a service from your client you must

1 Implement ServiceConnection

Your implementation must override two callback methods

onServiceConnected()

The system calls this to deliver the IBinder returned by the services onBind() method

onServiceDisconnected()

The Android system calls this when the connection to the service is unexpectedly lost such as

when the service has crashed or has been killed This is not called when the client unbinds

2 Call bindService() passing the ServiceConnection implementation

3 When the system calls your onServiceConnected() callback method you can begin making calls to the

service using the methods defined by the interface

4 To disconnect from the service call unbindService()

When your client is destroyed it will unbind from the service but you should always unbind when

youre done interacting with the service or when your activity pauses so that the service can shutdown

while its not being used (Appropriate times to bind and unbind is discussed more below)

For example the following snippet connects the client to the service created above by extending the

Binder class so all it must do is cast the returned IBinder to the LocalService class and request the

LocalService instance

LocalService mService private ServiceConnection mConnection = new ServiceConnection() Called when the connection with the service is established public void onServiceConnected(ComponentName className IBinder service) Because we have bound to an explicit service that is running in our own process we can cast its IBinder to a concrete class and directly access it LocalBinder binder = (LocalBinder) service mService = bindergetService() mBound = true Called when the connection with the service disconnects unexpectedly public void onServiceDisconnected(ComponentName className) Loge(TAG onServiceDisconnected) mBound = false

With this ServiceConnection the client can bind to a service by passing this it to bindService() For

example

Intent intent = new Intent(this LocalServiceclass) bindService(intent mConnection ContextBIND_AUTO_CREATE)

The first parameter of bindService() is an Intent that explicitly names the service to bind (thought the

intent could be implicit)

The second parameter is the ServiceConnection object

The third parameter is a flag indicating options for the binding It should usually be

BIND_AUTO_CREATE in order to create the service if its not already alive Other possible values are

BIND_DEBUG_UNBIND and BIND_NOT_FOREGROUND or 0 for none

Additional notes

Here are some important notes about binding to a service

You should always trap DeadObjectException exceptions which are thrown when the connection has

broken This is the only exception thrown by remote methods

Objects are reference counted across processes

You should usually pair the binding and unbinding during matching bring-up and tear-down moments

of the clients lifecycle For example

o If you only need to interact with the service while your activity is visible you should bind during

onStart() and unbind during onStop()

o If you want your activity to receive responses even while it is stopped in the background then you can

bind during onCreate() and unbind during onDestroy() Beware that this implies that your activity needs

to use the service the entire time its running (even in the background) so if the service is in another

process then you increase the weight of the process and it becomes more likely that the system will

kill it

Note You should usually not bind and unbind during your activitys onResume() and onPause()

because these callbacks occur at every lifecycle transition and you should keep the processing that

occurs at these transitions to a minimum Also if multiple activities in your application bind to the same

service and there is a transition between two of those activities the service may be destroyed and

recreated as the current activity unbinds (during pause) before the next one binds (during resume)

(This activity transition for how activities coordinate their lifecycles is described in the Activities

document)

For more sample code showing how to bind to a service see the RemoteServicejava class in

ApiDemos

Managing the Lifecycle of a Bound Service

Figure 1 The lifecycle for a service

that is started and also allows binding

When a service is unbound from all

clients the Android system destroys it

(unless it was also started with

onStartCommand()) As such you

dont have to manage the lifecycle of

your service if its purely a bound

servicemdashthe Android system manages

it for you based on whether it is bound

to any clients

However if you choose to implement

the onStartCommand() callback

method then you must explicitly stop

the service because the service is

now considered to be started In this

case the service runs until the service

stops itself with stopSelf() or another

component calls stopService()

regardless of whether it is bound to

any clients

Additionally if your service is started and accepts binding then when the system calls your onUnbind()

method you can optionally return true if you would like to receive a call to onRebind() the next time a

client binds to the service (instead of receiving a call to onBind()) onRebind() returns void but the

client still receives the IBinder in its onServiceConnected() callback Below figure 1 illustrates the logic

for this kind of lifecycle

For more information about the lifecycle of an started service see the Services document

Content Providers

Content providers store and retrieve data and make it accessible to all applications Theyre the only

way to share data across applications theres no common storage area that all Android packages can

access

Android ships with a number of content providers for common data types (audio video images

personal contact information and so on) You can see some of them listed in the androidprovider

package You can query these providers for the data they contain (although for some you must

acquire the proper permission to read the data)

If you want to make your own data public you have two options You can create your own content

provider (a ContentProvider subclass) or you can add the data to an existing provider mdash if theres one

that controls the same type of data and you have permission to write to it

This document is an introduction to using content providers After a brief discussion of the

fundamentals it explores how to query a content provider how to modify data controlled by a provider

and how to create a content provider of your own

Content Provider Basics

How a content provider actually stores its data under the covers is up to its designer But all content

providers implement a common interface for querying the provider and returning results mdash as well as

for adding altering and deleting data Its an interface that clients use indirectly most generally

through ContentResolver objects You get a ContentResolver by calling getContentResolver() from

within the implementation of an Activity or other application component

ContentResolver cr = getContentResolver()

You can then use the ContentResolvers methods to interact with whatever content providers youre

interested in When a query is initiated the Android system identifies the content provider thats the

target of the query and makes sure that it is up and running The system instantiates all

ContentProvider objects you never need to do it on your own In fact you never deal directly with

ContentProvider objects at all Typically theres just a single instance of each type of ContentProvider

But it can communicate with multiple ContentResolver objects in different applications and processes

The interaction between processes is handled by the ContentResolver and ContentProvider classes

The data model

Content providers expose their data as a simple table on a database model where each row is a

record and each column is data of a particular type and meaning For example information about

people and their phone numbers might be exposed as follows

_ID NUMBER NUMBER_KEY LABEL NAME TYPE

13 (425) 555 6677 425 555 6677 Kirkland office Bully Pulpit TYPE_WORK

44 (212) 555-1234 212 555 1234 NY apartment Alan Vain TYPE_HOME

45 (212) 555-6657 212 555 6657 Downtown office Alan Vain TYPE_MOBILE

53 2015554433 201 555 4433 Love Nest Rex Cars TYPE_HOME

Every record includes a numeric _ID field that uniquely identifies the record within the table IDs can be

used to match records in related tables mdash for example to find a persons phone number in one table

and pictures of that person in another

A query returns a Cursor object that can move from record to record and column to column to read the

contents of each field It has specialized methods for reading each type of data So to read a field you

must know what type of data the field contains (Theres more on query results and Cursor objects

later)

URIs

Each content provider exposes a public URI (wrapped as a Uri object) that uniquely identifies its data

set A content provider that controls multiple data sets (multiple tables) exposes a separate URI for

each one All URIs for providers begin with the string content The content scheme identifies the

data as being controlled by a content provider

If youre defining a content provider its a good idea to also define a constant for its URI to simplify

client code and make future updates cleaner Android defines CONTENT_URI constants for all the

providers that come with the platform For example the URI for the table that matches phone numbers

to people and the URI for the table that holds pictures of people (both controlled by the Contacts

content provider) are

androidproviderContactsPhonesCONTENT_URI

androidproviderContactsPhotosCONTENT_URI

The URI constant is used in all interactions with the content provider Every ContentResolver method

takes the URI as its first argument Its what identifies which provider the ContentResolver should talk

to and which table of the provider is being targeted

Querying a Content Provider

You need three pieces of information to query a content provider

The URI that identifies the provider

The names of the data fields you want to receive

The data types for those fields

If youre querying a particular record you also need the ID for that record

Making the query

To query a content provider you can use either the ContentResolverquery() method or the

ActivitymanagedQuery() method Both methods take the same set of arguments and both return a

Cursor object However managedQuery() causes the activity to manage the life cycle of the Cursor A

managed Cursor handles all of the niceties such as unloading itself when the activity pauses and

requerying itself when the activity restarts You can ask an Activity to begin managing an unmanaged

Cursor object for you by calling ActivitystartManagingCursor()

The first argument to either query() or managedQuery() is the provider URI mdash the CONTENT_URI

constant that identifies a particular ContentProvider and data set (see URIs earlier)

To restrict a query to just one record you can append the _ID value for that record to the URI mdash that

is place a string matching the ID as the last segment of the path part of the URI For example if the ID

is 23 the URI would be

content 23

There are some helper methods particularly ContentUriswithAppendedId() and

UriwithAppendedPath() that make it easy to append an ID to a URI Both are static methods that

return a Uri object with the ID added So for example if you were looking for record 23 in the database

of people contacts you might construct a query as follows

import androidproviderContactsPeople import androidcontentContentUris import androidnetUri import androiddatabaseCursor Use the ContentUris method to produce the base URI for the contact with _ID == 23 Uri myPerson = ContentUriswithAppendedId(PeopleCONTENT_URI 23) Alternatively use the Uri method to produce the base URI It takes a string rather than an integer Uri myPerson = UriwithAppendedPath(PeopleCONTENT_URI 23) Then query for this specific record Cursor cur = managedQuery(myPerson null null null null)

The other arguments to the query() and managedQuery() methods delimit the query in more detail

They are

The names of the data columns that should be returned A null value returns all columns Otherwise

only columns that are listed by name are returned All the content providers that come with the

platform define constants for their columns For example the androidproviderContactsPhones class

defines constants for the names of the columns in the phone table illustrated earlier ampmdash _ID

NUMBER NUMBER_KEY NAME and so on

A filter detailing which rows to return formatted as an SQL WHERE clause (excluding the WHERE

itself) A null value returns all rows (unless the URI limits the query to a single record)

Selection arguments

A sorting order for the rows that are returned formatted as an SQL ORDER BY clause (excluding the

ORDER BY itself) A null value returns the records in the default order for the table which may be

unordered

Lets look at an example query to retrieve a list of contact names and their primary phone numbers

import androidproviderContactsPeople import androiddatabaseCursor Form an array specifying which columns to return String[] projection = new String[] People_ID People_COUNT PeopleNAME PeopleNUMBER Get the base URI for the People table in the Contacts content provider Uri contacts = PeopleCONTENT_URI Make the query Cursor managedCursor = managedQuery(contacts projection Which columns to return null Which rows to return (all rows) null Selection arguments (none) Put the results in ascending order by name PeopleNAME + ASC)

This query retrieves data from the People table of the Contacts content provider It gets the name

primary phone number and unique record ID for each contact It also reports the number of records

that are returned as the _COUNT field of each record

The constants for the names of the columns are defined in various interfaces mdash _ID and _COUNT in

BaseColumns NAME in PeopleColumns and NUMBER in PhoneColumns The ContactsPeople

class implements each of these interfaces which is why the code example above could refer to them

using just the class name

What a query returns

A query returns a set of zero or more database records The names of the columns their default order

and their data types are specific to each content provider But every provider has an _ID column

which holds a unique numeric ID for each record Every provider can also report the number of records

returned as the _COUNT column its value is the same for all rows

Here is an example result set for the query in the previous section

_ID _COUNT NAME NUMBER

44 3 Alan Vain 212 555 1234

13 3 Bully Pulpit 425 555 6677

53 3 Rex Cars 201 555 4433

The retrieved data is exposed by a Cursor object that can be used to iterate backward or forward

through the result set You can use this object only to read the data To add modify or delete data

you must use a ContentResolver object

Reading retrieved data

The Cursor object returned by a query provides access to a recordset of results If you have queried

for a specific record by ID this set will contain only one value Otherwise it can contain multiple

values (If there are no matches it can also be empty) You can read data from specific fields in the

record but you must know the data type of the field because the Cursor object has a separate method

for reading each type of data mdash such as getString() getInt() and getFloat() (However for most types

if you call the method for reading strings the Cursor object will give you the String representation of

the data) The Cursor lets you request the column name from the index of the column or the index

number from the column name

The following snippet demonstrates reading names and phone numbers from the query illustrated

earlier

import androidproviderContactsPeople private void getColumnData(Cursor cur) if (curmoveToFirst()) String name String phoneNumber int nameColumn = curgetColumnIndex(PeopleNAME) int phoneColumn = curgetColumnIndex(PeopleNUMBER) String imagePath do Get the field values name = curgetString(nameColumn) phoneNumber = curgetString(phoneColumn) Do something with the values while (curmoveToNext())

If a query can return binary data such as an image or sound the data may be directly entered in the

table or the table entry for that data may be a string specifying a content URI that you can use to get

the data In general smaller amounts of data (say from 20 to 50K or less) are most often directly

entered in the table and can be read by calling CursorgetBlob() It returns a byte array

If the table entry is a content URI you should never try to open and read the file directly (for one thing

permissions problems can make this fail) Instead you should call ContentResolveropenInputStream()

to get an InputStream object that you can use to read the data

Modifying Data

Data kept by a content provider can be modified by

Adding new records

Adding new values to existing records

Batch updating existing records

Deleting records

All data modification is accomplished using ContentResolver methods Some content providers require

a more restrictive permission for writing data than they do for reading it If you dont have permission to

write to a content provider the ContentResolver methods will fail

Adding records

To add a new record to a content provider first set up a map of key-value pairs in a ContentValues

object where each key matches the name of a column in the content provider and the value is the

desired value for the new record in that column Then call ContentResolverinsert() and pass it the URI

of the provider and the ContentValues map This method returns the full URI of the new record mdash that

is the providers URI with the appended ID for the new record You can then use this URI to query and

get a Cursor over the new record and to further modify the record Heres an example

import androidproviderContactsPeople import androidcontentContentResolver import androidcontentContentValues ContentValues values = new ContentValues() Add Abraham Lincoln to contacts and make him a favorite valuesput(PeopleNAME Abraham Lincoln) 1 = the new contact is added to favorites 0 = the new contact is not added to favorites valuesput(PeopleSTARRED 1) Uri uri = getContentResolver()insert(PeopleCONTENT_URI values)

Adding new values

Once a record exists you can add new information to it or modify existing information For example

the next step in the example above would be to add contact information mdash like a phone number or an

IM or e-mail address mdash to the new entry

The best way to add to a record in the Contacts database is to append the name of the table where the

new data goes to the URI for the record then use the amended URI to add the new data values Each

Contacts table exposes a name for this purpose as a CONTENT_DIRECTORY constant The following

code continues the previous example by adding a phone number and e-mail address for the record

just created

Uri phoneUri = null Uri emailUri = null Add a phone number for Abraham Lincoln Begin with the URI for the new record just returned by insert() it ends with the _ID of the new record so we dont have to add the ID ourselves Then append the designation for the phone table to this URI and use the resulting URI to insert the phone number phoneUri = UriwithAppendedPath(uri PeoplePhonesCONTENT_DIRECTORY) valuesclear() valuesput(PeoplePhonesTYPE PeoplePhonesTYPE_MOBILE) valuesput(PeoplePhonesNUMBER 1233214567) getContentResolver()insert(phoneUri values) Now add an email address in the same way emailUri = UriwithAppendedPath(uri PeopleContactMethodsCONTENT_DIRECTORY) valuesclear() ContactMethodsKIND is used to distinguish different kinds of contact methods such as email IM etc valuesput(PeopleContactMethodsKIND ContactsKIND_EMAIL) valuesput(PeopleContactMethodsDATA testexamplecom) valuesput(PeopleContactMethodsTYPE PeopleContactMethodsTYPE_HOME) getContentResolver()insert(emailUri values)

You can place small amounts of binary data into a table by calling the version of ContentValuesput()

that takes a byte array That would work for a small icon-like image or a short audio clip for example

However if you have a large amount of binary data to add such as a photograph or a complete song

put a content URI for the data in the table and call ContentResolveropenOutputStream() with the files

URI (That causes the content provider to store the data in a file and record the file path in a hidden

field of the record)

In this regard the MediaStore content provider the main provider that dispenses image audio and

video data employs a special convention The same URI that is used with query() or managedQuery()

to get meta-information about the binary data (such as the caption of a photograph or the date it was

taken) is used with openInputStream() to get the data itself Similarly the same URI that is used with

insert() to put meta-information into a MediaStore record is used with openOutputStream() to place the

binary data there The following code snippet illustrates this convention

import androidproviderMediaStoreImagesMedia import androidcontentContentValues import javaioOutputStream Save the name and description of an image in a ContentValues map ContentValues values = new ContentValues(3) valuesput(MediaDISPLAY_NAME road_trip_1) valuesput(MediaDESCRIPTION Day 1 trip to Los Angeles) valuesput(MediaMIME_TYPE imagejpeg) Add a new record without the bitmap but with the values just set insert() returns the URI of the new record Uri uri = getContentResolver()insert(MediaEXTERNAL_CONTENT_URI values) Now get a handle to the file for that record and save the data into it Here sourceBitmap is a Bitmap object representing the file to save to the database try OutputStream outStream = getContentResolver()openOutputStream(uri) sourceBitmapcompress(BitmapCompressFormatJPEG 50 outStream) outStreamclose() catch (Exception e) Loge(TAG exception while writing image e)

Batch updating records

To batch update a group of records (for example to change NY to New York in all fields) call the

ContentResolverupdate() method with the columns and values to change

Deleting a record

To delete a single record call ContentResolverdelete() with the URI of a specific row

To delete multiple rows call ContentResolverdelete() with the URI of the type of record to delete (for

example androidproviderContactsPeopleCONTENT_URI) and an SQL WHERE clause defining

which rows to delete (Caution Be sure to include a valid WHERE clause if youre deleting a general

type or you risk deleting more records than you intended)

Creating a Content Provider

To create a content provider you must

Set up a system for storing the data Most content providers store their data using Androids file

storage methods or SQLite databases but you can store your data any way you want Android

provides the SQLiteOpenHelper class to help you create a database and SQLiteDatabase to manage

it

Extend the ContentProvider class to provide access to the data

Declare the content provider in the manifest file for your application (AndroidManifestxml)

The following sections have notes on the last two of these tasks

Extending the ContentProvider class

You define a ContentProvider subclass to expose your data to others using the conventions expected

by ContentResolver and Cursor objects Principally this means implementing six abstract methods

declared in the ContentProvider class

query()

insert()

update()

delete()

getType()

onCreate()

The query() method must return a Cursor object that can iterate over the requested data Cursor itself

is an interface but Android provides some ready-made Cursor objects that you can use For example

SQLiteCursor can iterate over data stored in an SQLite database You get the Cursor object by calling

any of the SQLiteDatabase classs query() methods There are other Cursor implementations mdash such

as MatrixCursor mdash for data not stored in a database

Because these ContentProvider methods can be called from various ContentResolver objects in

different processes and threads they must be implemented in a thread-safe manner

As a courtesy you might also want to call ContentResolvernotifyChange() to notify listeners when

there are modifications to the data

Beyond defining the subclass itself there are other steps you should take to simplify the work of clients

and make the class more accessible

Define a public static final Uri named CONTENT_URI This is the string that represents the full content

URI that your content provider handles You must define a unique string for this value The best

solution is to use the fully-qualified class name of the content provider (made lowercase) So for

example the URI for a TransportationProvider class could be defined as follows

public static final Uri CONTENT_URI = Uriparse(contentcomexamplecodelabtransportationprovider)

If the provider has subtables also define CONTENT_URI constants for each of the subtables These

URIs should all have the same authority (since that identifies the content provider) and be

distinguished only by their paths For example

contentcomexamplecodelabtransportationprovidertrain

contentcomexamplecodelabtransportationproviderairdomestic

contentcomexamplecodelabtransportationproviderairinternational

For an overview of content URIs see the Content URI Summary at the end of this document

Define the column names that the content provider will return to clients If you are using an underlying

database these column names are typically identical to the SQL database column names they

represent Also define public static String constants that clients can use to specify the columns in

queries and other instructions

Be sure to include an integer column named _id (with the constant _ID) for the IDs of the records

You should have this field whether or not you have another field (such as a URL) that is also unique

among all records If youre using the SQLite database the _ID field should be the following type

INTEGER PRIMARY KEY AUTOINCREMENT

The AUTOINCREMENT descriptor is optional But without it SQLite increments an ID counter field to

the next number above the largest existing number in the column If you delete the last row the next

row added will have the same ID as the deleted row AUTOINCREMENT avoids this by having SQLite

increment to the next largest value whether deleted or not

Carefully document the data type of each column Clients need this information to read the data

If you are handling a new data type you must define a new MIME type to return in your

implementation of ContentProvidergetType() The type depends in part on whether or not the content

URI submitted to getType() limits the request to a specific record Theres one form of the MIME type

for a single record and another for multiple records Use the Uri methods to help determine what is

being requested Here is the general format for each type

o For a single record vndandroidcursoritemvndyourcompanynamecontenttype

For example a request for train record 122 like this URI

contentcomexampletransportationprovidertrains122

might return this MIME type

vndandroidcursoritemvndexamplerail

o For multiple records vndandroidcursordirvndyourcompanynamecontenttype

For example a request for all train records like the following URI

contentcomexampletransportationprovidertrains

might return this MIME type

vndandroidcursordirvndexamplerail

If you are exposing byte data thats too big to put in the table itself mdash such as a large bitmap file mdash the

field that exposes the data to clients should actually contain a content URI string This is the field that

gives clients access to the data file The record should also have another field named _data that lists

the exact file path on the device for that file This field is not intended to be read by the client but by

the ContentResolver The client will call ContentResolveropenInputStream() on the user-facing field

holding the URI for the item The ContentResolver will request the _data field for that record and

because it has higher permissions than a client it should be able to access that file directly and return

a read wrapper for the file to the client

For an example of a private content provider implementation see the NodePadProvider class in the

Notepad sample application that ships with the SDK

Declaring the content provider

To let the Android system know about the content provider youve developed declare it with a

ltprovidergt element in the applications AndroidManifestxml file Content providers that are not

declared in the manifest are not visible to the Android system

The name attribute is the fully qualified name of the ContentProvider subclass The authorities attribute

is the authority part of the content URI that identifies the provider For example if the ContentProvider

subclass is AutoInfoProvider the ltprovidergt element might look like this

ltprovider androidname=comexampleautosAutoInfoProvider androidauthorities=comexampleautosautoinfoprovider gt ltprovidergt

Note that the authorities attribute omits the path part of a content URI For example if

AutoInfoProvider controlled subtables for different types of autos or different manufacturers

contentcomexampleautosautoinfoproviderhonda

contentcomexampleautosautoinfoprovidergmcompact

contentcomexampleautosautoinfoprovidergmsuv

those paths would not be declared in the manifest The authority is what identifies the provider not the

path your provider can interpret the path part of the URI in any way you choose

Other ltprovidergt attributes can set permissions to read and write data provide for an icon and text

that can be displayed to users enable and disable the provider and so on Set the multiprocess

attribute to true if data does not need to be synchronized between multiple running versions of the

content provider This permits an instance of the provider to be created in each client process

eliminating the need to perform IPC

Content URI Summary

Here is a recap of the important parts of a content URI

A Standard prefix indicating that the data is controlled by a content provider Its never modified

B The authority part of the URI it identifies the content provider For third-party applications this should

be a fully-qualified class name (reduced to lowercase) to ensure uniqueness The authority is declared

in the ltprovidergt elements authorities attribute

ltprovider androidname=TransportationProvider androidauthorities=comexampletransportationprovider gt

C The path that the content provider uses to determine what kind of data is being requested This can be

zero or more segments long If the content provider exposes only one type of data (only trains for

example) it can be absent If the provider exposes several types including subtypes it can be several

segments long mdash for example landbus landtrain seaship and seasubmarine to give four

possibilities

D The ID of the specific record being requested if any This is the _ID value of the requested record If

the request is not limited to a single record this segment and the trailing slash are omitted

contentcomexampletransportationprovidertrains

Intent and intent filters

Three of the core components of an application mdash activities services and broadcast receivers mdash 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 mdash 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 ContextstartActivity() or ActivitystartActivityForResult() to launch an

activity or get an existing activity to do something new (It can also be passed to ActivitysetResult() to

return information to the activity that called startActivityForResult())

An Intent object is passed to ContextstartService() to initiate a service or deliver new instructions to an

ongoing service Similarly an intent can be passed to ContextbindService() to establish a connection

between the calling component and a target service It can optionally initiate the service if its not

already running

Intent objects passed to any of the broadcast methods (such as ContextsendBroadcast()

ContextsendOrderedBroadcast() or ContextsendStickyBroadcast()) 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 mdash how it resolves which component should receive an intent message For

intents that dont explicitly name a target component this process involves testing the Intent object

against intent filters associated with potential targets

Intent Objects

An Intent object is a bundle of information It contains information of interest to the component that

receives the intent (such as the action to be taken and the data to act on) plus information of interest to

the Android system (such as the category of component that should handle the intent and instructions

on how to launch a target activity) Principally it can contain the following

Component name

The name of the component that should handle the intent This field is a ComponentName

object mdash a combination of the fully qualified class name of the target component (for example

comexampleprojectappFreneticActivity) and the package name set in the manifest file of the

application where the component resides (for example comexampleproject) The package

part of the component name and the package name set in the manifest do not necessarily have

to match

The component name is optional If it is set the Intent object is delivered to an instance of the

designated class If it is not set Android uses other information in the Intent object to locate a

suitable target mdash see Intent Resolution later in this document

The component name is set by setComponent() setClass() or setClassName() and read by

getComponent()

Action

A string naming the action to be performed mdash or in the case of broadcast intents the action

that took place and is being reported The Intent class defines a number of action constants

including these

Constant Target

component

Action

ACTION_CALL activity Initiate a phone call

ACTION_EDIT activity Display data for the user to edit

ACTION_MAIN activity Start up as the initial activity of a task

with no data input and no returned

output

ACTION_SYNC activity Synchronize data on a server with

data on the mobile device

ACTION_BATTERY_LOW broadcast

receiver

A warning that the battery is low

ACTION_HEADSET_PLUG broadcast

receiver

A headset has been plugged into the

device or unplugged from it

ACTION_SCREEN_ON broadcast

receiver

The screen has been turned on

ACTION_TIMEZONE_CHANGED broadcast

receiver

The setting for the time zone has

changed

See the Intent class description for a list of pre-defined constants for generic actions Other

actions are defined elsewhere in the Android API You can also define your own action strings

for activating the components in your application Those you invent should include the

application package as a prefix mdash for example comexampleprojectSHOW_COLOR

The action largely determines how the rest of the intent is structured mdash particularly the data and

extras fields mdash much as a method name determines a set of arguments and a return value For

this reason its a good idea to use action names that are as specific as possible and to couple

them tightly to the other fields of the intent In other words instead of defining an action in

isolation define an entire protocol for the Intent objects your components can handle

The action in an Intent object is set by the setAction() method and read by getAction()

Data

The URI of the data to be acted on and the MIME type of that data Different actions are paired

with different kinds of data specifications For example if the action field is ACTION_EDIT the

data field would contain the URI of the document to be displayed for editing If the action is

ACTION_CALL the data field would be a tel URI with the number to call Similarly if the action

is ACTION_VIEW and the data field is an http URI the receiving activity would be called upon

to download and display whatever data the URI refers to

When matching an intent to a component that is capable of handling the data its often

important to know the type of data (its MIME type) in addition to its URI For example a

component able to display image data should not be called upon to play an audio file

In many cases the data type can be inferred from the URI mdash particularly content URIs which

indicate that the data is located on the device and controlled by a content provider (see the

separate discussion on content providers) But the type can also be explicitly set in the Intent

object The setData() method specifies data only as a URI setType() specifies it only as a

MIME type and setDataAndType() specifies it as both a URI and a MIME type The URI is read

by getData() and the type by getType()

Category

A string containing additional information about the kind of component that should handle the

intent Any number of category descriptions can be placed in an Intent object As it does for

actions the Intent class defines several category constants including these

Constant Meaning

CATEGORY_BROWSABLE The target activity can be safely invoked by the browser to

display data referenced by a link mdash for example an image or

an e-mail message

CATEGORY_GADGET The activity can be embedded inside of another activity that

hosts gadgets

CATEGORY_HOME The activity displays the home screen the first screen the

user sees when the device is turned on or when the HOME

key is pressed

CATEGORY_LAUNCHER The activity can be the initial activity of a task and is listed in

the top-level application launcher

CATEGORY_PREFERENCE The target activity is a preference panel

See the Intent class description for the full list of categories

The addCategory() method places a category in an Intent object removeCategory() deletes a

category previously added and getCategories() gets the set of all categories currently in the

object

Extras

Key-value pairs for additional information that should be delivered to the component handling

the intent Just as some actions are paired with particular kinds of data URIs some are paired

with particular extras For example an ACTION_TIMEZONE_CHANGED intent has a time-

zone extra that identifies the new time zone and ACTION_HEADSET_PLUG has a state

extra indicating whether the headset is now plugged in or unplugged as well as a name extra

for the type of headset If you were to invent a SHOW_COLOR action the color value would be

set in an extra key-value pair

The Intent object has a series of put() methods for inserting various types of extra data and a

similar set of get() methods for reading the data These methods parallel those for Bundle

objects In fact the extras can be installed and read as a Bundle using the putExtras() and

getExtras() methods

Flags

Flags of various sorts Many instruct the Android system how to launch an activity (for example

which task the activity should belong to) and how to treat it after its launched (for example

whether it belongs in the list of recent activities) All these flags are defined in the Intent class

The Android system and the applications that come with the platform employ Intent objects both to

send out system-originated broadcasts and to activate system-defined components To see how to

structure an intent to activate a system component consult the list of intents in the reference

Intent Resolution

Intents can be divided into two groups

Explicit intents designate the target component by its name (the component name field mentioned

earlier has a value set) Since component names would generally not be known to developers of other

applications explicit intents are typically used for application-internal messages mdash such as an activity

starting a subordinate service or launching a sister activity

Implicit intents do not name a target (the field for the component name is blank) Implicit intents are

often used to activate components in other applications

Android delivers an explicit intent to an instance of the designated target class Nothing in the Intent

object other than the component name matters for determining which component should get the intent

A different strategy is needed for implicit intents In the absence of a designated target the Android

system must find the best component (or components) to handle the intent mdash a single activity or

service to perform the requested action or the set of broadcast receivers to respond to the broadcast

announcement It does so by comparing the contents of the Intent object to intent filters structures

associated with components that can potentially receive intents Filters advertise the capabilities of a

component and delimit the intents it can handle They open the component to the possibility of

receiving implicit intents of the advertised type If a component does not have any intent filters it can

receive only explicit intents A component with filters can receive both explicit and implicit intents

Only three aspects of an Intent object are consulted when the object is tested against an intent filter

action

data (both URI and data type)

category

The extras and flags play no part in resolving which component receives an intent

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 mdash but only unwanted implicit intents (those that dont 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

components 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 mdash 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 Pads filters are described in the Note Pad Example

section later)

Filters and security

An intent filter cannot be relied on for security While it opens a component to receiving only certain

kinds of implicit intents it does nothing to prevent explicit intents from targeting the component Even

though a filter restricts the intents a component will be asked to handle to certain actions and data

sources someone could always put together an explicit intent with a different action and data source

and name the component as the target

An intent filter is an instance of the IntentFilter class However since the Android system must know

about the capabilities of a component before it can launch that component intent filters are generally

not set up in Java code but in the applications manifest file (AndroidManifestxml) as ltintent-filtergt

elements (The one exception would be filters for broadcast receivers that are registered dynamically

by calling ContextregisterReceiver() they are directly created as IntentFilter objects)

A filter has fields that parallel the action data and category fields of an Intent object An implicit intent

is tested against the filter in all three areas To be delivered to the component that owns the filter it

must pass all three tests If it fails even one of them the Android system wont deliver it to the

component mdash at least not on the basis of that filter However since a component can have multiple

intent filters an intent that does not pass through one of a components filters might make it through on

another

Each of the three tests is described in detail below

Action test

An ltintent-filtergt element in the manifest file lists actions as ltactiongt subelements For

example

ltintent-filter gt ltaction androidname=comexampleprojectSHOW_CURRENT gt ltaction androidname=comexampleprojectSHOW_RECENT gt ltaction androidname=comexampleprojectSHOW_PENDING gt ltintent-filtergt

As the example shows while an Intent object names just a single action a filter may list more

than one The list cannot be empty a filter must contain at least one ltactiongt element or it will

block all intents

To pass this test the action specified in the Intent object must match one of the actions listed in

the filter If the object or the filter does not specify an action the results are as follows

If the filter fails to list any actions there is nothing for an intent to match so all intents fail the

test No intents can get through the filter

On the other hand an Intent object that doesnt specify an action automatically passes the test

mdash as long as the filter contains at least one action

Category test

An ltintent-filtergt element also lists categories as subelements For example

ltintent-filter gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryBROWSABLE gt ltintent-filtergt

Note that the constants described earlier for actions and categories are not used in the manifest

file The full string values are used instead For instance the

androidintentcategoryBROWSABLE string in the example above corresponds to the

CATEGORY_BROWSABLE constant mentioned earlier in this document Similarly the string

androidintentactionEDIT corresponds to the ACTION_EDIT constant

For an intent to pass the category test every category in the Intent object must match a

category in the filter The filter can list additional categories but it cannot omit any that are in the

intent

In principle therefore an Intent object with no categories should always pass this test

regardless of whats in the filter Thats mostly true However with one exception Android treats

all implicit intents passed to startActivity() as if they contained at least one category

androidintentcategoryDEFAULT (the CATEGORY_DEFAULT constant) Therefore activities

that are willing to receive implicit intents must include androidintentcategoryDEFAULT in

their intent filters (Filters with androidintentactionMAIN and

androidintentcategoryLAUNCHER settings are the exception They mark activities that begin

new tasks and that are represented on the launcher screen They can include

androidintentcategoryDEFAULT in the list of categories but dont need to) See Using intent

matching later for more on these filters)

Data test

Like the action and categories the data specification for an intent filter is contained in a

subelement And as in those cases the subelement can appear multiple times or not at all For

example

ltintent-filter gt ltdata androidmimeType=videompeg androidscheme=http gt ltdata androidmimeType=audiompeg androidscheme=http gt ltintent-filtergt

Each ltdatagt element can specify a URI and a data type (MIME media type) There are

separate attributes mdash scheme host port and path mdash for each part of the URI

schemehostportpath

For example in the following URI

contentcomexampleproject200foldersubfolderetc

the scheme is content the host is comexampleproject the port is 200 and the path is

foldersubfolderetc The host and port together constitute the URI authority if a host is not

specified the port is ignored

Each of these attributes is optional but they are not independent of each other For an authority

to be meaningful a scheme must also be specified For a path to be meaningful both a scheme

and an authority must be specified

When the URI in an Intent object is compared to a URI specification in a filter its compared

only to the parts of the URI actually mentioned in the filter For example if a filter specifies only

a scheme all URIs with that scheme match the filter If a filter specifies a scheme and an

authority but no path all URIs with the same scheme and authority match regardless of their

paths If a filter specifies a scheme an authority and a path only URIs with the same scheme

authority and path match However a path specification in the filter can contain wildcards to

require only a partial match of the path

The type attribute of a ltdatagt element specifies the MIME type of the data Its more common in

filters than a URI Both the Intent object and the filter can use a wildcard for the subtype field

mdash for example text or audio mdash indicating any subtype matches

The data test compares both the URI and the data type in the Intent object to a URI and data

type specified in the filter The rules are as follows

a An Intent object that contains neither a URI nor a data type passes the test only if the filter

likewise does not specify any URIs or data types

b An Intent object that contains a URI but no data type (and a type cannot be inferred from the

URI) passes the test only if its URI matches a URI in the filter and the filter likewise does not

specify a type This will be the case only for URIs like mailto and tel that do not refer to actual

data

c An Intent object that contains a data type but not a URI passes the test only if the filter lists the

same data type and similarly does not specify a URI

d An Intent object that contains both a URI and a data type (or a data type can be inferred from

the URI) passes the data type part of the test only if its type matches a type listed in the filter It

passes the URI part of the test either if its URI matches a URI in the filter or if it has a content

or file URI and the filter does not specify a URI In other words a component is presumed to

support content and file data if its filter lists only a data type

If an intent can pass through the filters of more than one activity or service the user may be asked

which component to activate An exception is raised if no target can be found

Common cases

The last rule shown above for the data test rule (d) reflects the expectation that components are able

to get local data from a file or content provider Therefore their filters can list just a data type and do

not need to explicitly name the content and file schemes This is a typical case A ltdatagt element like

the following for example tells Android that the component can get image data from a content

provider and display it

ltdata androidmimeType=image gt

Since most available data is dispensed by content providers filters that specify a data type but not a

URI are perhaps the most common

Another common configuration is filters with a scheme and a data type For example a ltdatagt

element like the following tells Android that the component can get video data from the network and

display it

ltdata androidscheme=http androidtype=video gt

Consider for example what the browser application does when the user follows a link on a web page

It first tries to display the data (as it could if the link was to an HTML page) If it cant display the data it

puts together an implicit intent with the scheme and data type and tries to start an activity that can do

the job If there are no takers it asks the download manager to download the data That puts it under

the control of a content provider so a potentially larger pool of activities (those with filters that just

name a data type) can respond

Most applications also have a way to start fresh without a reference to any particular data Activities

that can initiate applications have filters with androidintentactionMAIN specified as the action If

they are to be represented in the application launcher they also specify the

androidintentcategoryLAUNCHER category

ltintent-filter gt ltaction androidname=code androidintentactionMAIN gt ltcategory androidname=code androidintentcategoryLAUNCHER gt ltintent-filtergt

Using intent matching

Intents are matched against intent filters not only to discover a target component to activate but also

to discover something about the set of components on the device For example the Android system

populates the application launcher the top-level screen that shows the applications that are available

for the user to launch by finding all the activities with intent filters that specify the

androidintentactionMAIN action and androidintentcategoryLAUNCHER category (as illustrated

in the previous section) It then displays the icons and labels of those activities in the launcher

Similarly it discovers the home screen by looking for the activity with androidintentcategoryHOME

in its filter

Your application can use intent matching is a similar way The PackageManager has a set of query()

methods that return all components that can accept a particular intent and a similar series of

resolve() methods that determine the best component to respond to an intent For example

queryIntentActivities() returns a list of all activities that can perform the intent passed as an argument

and queryIntentServices() returns a similar list of services Neither method activates the components

they just list the ones that can respond Theres a similar method queryBroadcastReceivers() for

broadcast receivers

Note Pad Example

The Note Pad sample application enables users to browse through a list of notes view details about

individual items in the list edit the items and add a new item to the list This section looks at the intent

filters declared in its manifest file (If youre working offline in the SDK you can find all the source files

for this sample application including its manifest file at ltsdkgtsamplesNotePadindexhtml If youre

viewing the documentation online the source files are in the Tutorials and Sample Code section here)

In its manifest file the Note Pad application declares three activities each with at least one intent filter

It also declares a content provider that manages the note data Here is the manifest file in its entirety

ltmanifest xmlnsandroid=httpschemasandroidcomapkresandroid package=comexampleandroidnotepadgt ltapplication androidicon=drawableapp_notes androidlabel=stringapp_name gt ltprovider androidname=NotePadProvider androidauthorities=comgoogleproviderNotePad gt ltactivity androidname=NotesList androidlabel=stringtitle_notes_listgt ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltactivity androidname=NoteEditor androidtheme=androidstyleThemeLight androidlabel=stringtitle_note gt ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltactivitygt

ltactivity androidname=TitleEditor androidlabel=stringtitle_edit_title androidtheme=androidstyleThemeDialoggt ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltapplicationgt ltmanifestgt

The first activity NotesList is distinguished from the other activities by the fact that it operates on a

directory of notes (the note list) rather than on a single note It would generally serve as the initial user

interface into the application It can do three things as described by its three intent filters

1 ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt

This filter declares the main entry point into the Note Pad application The standard MAIN action is an

entry point that does not require any other information in the Intent (no data specification for example)

and the LAUNCHER category says that this entry point should be listed in the application launcher

2 ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

This filter declares the things that the activity can do on a directory of notes It can allow the user to

view or edit the directory (via the VIEW and EDIT actions) or to pick a particular note from the

directory (via the PICK action)

The mimeType attribute of the ltdatagt element specifies the kind of data that these actions operate on

It indicates that the activity can get a Cursor over zero or more items (vndandroidcursordir) from a

content provider that holds Note Pad data (vndgooglenote) The Intent object that launches the

activity would include a content URI specifying the exact data of this type that the activity should open

Note also the DEFAULT category supplied in this filter Its there because the ContextstartActivity()

and ActivitystartActivityForResult() methods treat all intents as if they contained the DEFAULT

category mdash with just two exceptions

o Intents that explicitly name the target activity

o Intents consisting of the MAIN action and LAUNCHER category

Therefore the DEFAULT category is required for all filters mdash except for those with the MAIN action

and LAUNCHER category (Intent filters are not consulted for explicit intents)

3 ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

This filter describes the activitys ability to return a note selected by the user without requiring any

specification of the directory the user should choose from The GET_CONTENT action is similar to the

PICK action In both cases the activity returns the URI for a note selected by the user (In each case

its returned to the activity that called startActivityForResult() to start the NoteList activity) Here

however the caller specifies the type of data desired instead of the directory of data the user will be

picking from

The data type vndandroidcursoritemvndgooglenote indicates the type of data the activity can

return mdash a URI for a single note From the returned URI the caller can get a Cursor for exactly one

item (vndandroidcursoritem) from the content provider that holds Note Pad data (vndgooglenote)

In other words for the PICK action in the previous filter the data type indicates the type of data the

activity could display to the user For the GET_CONTENT filter it indicates the type of data the activity

can return to the caller

Given these capabilities the following intents will resolve to the NotesList activity

action androidintentactionMAIN

Launches the activity with no data specified

action androidintentactionMAIN

category androidintentcategoryLAUNCHER

Launches the activity with no data selected specified This is the actual intent used by the

Launcher to populate its top-level list All activities with filters that match this action and

category are added to the list

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of all the notes under

contentcomgoogleproviderNotePadnotes The user can then browse through the list and

get information about the items in it

action androidintentactionPICK

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of the notes under

contentcomgoogleproviderNotePadnotes The user can then pick a note from the list and

the activity will return the URI for that item back to the activity that started the NoteList activity

action androidintentactionGET_CONTENT

data type vndandroidcursoritemvndgooglenote

Asks the activity to supply a single item of Note Pad data

The second activity NoteEditor shows users a single note entry and allows them to edit it It can do

two things as described by its two intent filters

1 ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The first primary purpose of this activity is to enable the user to interact with a single note ampmdash to

either VIEW the note or EDIT it (The EDIT_NOTE category is a synonym for EDIT) The intent would

contain the URI for data matching the MIME type vndandroidcursoritemvndgooglenote mdash that is

the URI for a single specific note It would typically be a URI that was returned by the PICK or

GET_CONTENT actions of the NoteList activity

As before this filter lists the DEFAULT category so that the activity can be launched by intents that

dont explicitly specify the NoteEditor class

2 ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

The secondary purpose of this activity is to enable the user to create a new note which it will INSERT

into an existing directory of notes The intent would contain the URI for data matching the MIME type

vndandroidcursordirvndgooglenote mdash that is the URI for the directory where the note should be

placed

Given these capabilities the following intents will resolve to the NoteEditor activity

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID (For details on how content

URIs specify individual members of a group see Content Providers)

action androidintentactionEDIT

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID and to let the user edit it If

the user saves the changes the activity updates the data for the note in the content provider

action androidintentactionINSERT

data contentcomgoogleproviderNotePadnotes

Asks the activity to create a new empty note in the notes list at

contentcomgoogleproviderNotePadnotes and allow the user to edit it If the user saves the

note its URI is returned to the caller

The last activity TitleEditor enables the user to edit the title of a note This could be implemented by

directly invoking the activity (by explicitly setting its component name in the Intent) without using an

intent filter But here we take the opportunity to show how to publish alternative operations on existing

data

ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The single intent filter for this activity uses a custom action called

comandroidnotepadactionEDIT_TITLE It must be invoked on a specific note (data type

vndandroidcursoritemvndgooglenote) like the previous VIEW and EDIT actions However here the

activity displays the title contained in the note data not the content of the note itself

In addition to supporting the usual DEFAULT category the title editor also supports two other standard

categories ALTERNATIVE and SELECTED_ALTERNATIVE These categories identify activities that

can be presented to users in a menu of options (much as the LAUNCHER category identifies activities

that should be presented to user in the application launcher) Note that the filter also supplies an

explicit label (via androidlabel=stringresolve_title) to better control what users see when

presented with this activity as an alternative action to the data they are currently viewing (For more

information on these categories and building options menus see the

PackageManagerqueryIntentActivityOptions() and MenuaddIntentOptions() methods)

Given these capabilities the following intent will resolve to the TitleEditor activity

action comandroidnotepadactionEDIT_TITLE

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the title associated with note ID and allow the user to edit the title

Processes and Threads

When an application component starts and the application does not have any other components

running the Android system starts a new Linux process for the application with a single thread of

execution By default all components of the same application run in the same process and thread

(called the main thread) If an application component starts and there already exists a process for

that application (because another component from the application exists) then the component is

started within that process and uses the same thread of execution However you can arrange for

different components in your application to run in separate processes and you can create additional

threads for any process

This document discusses how processes and threads work in an Android application

Processes

By default all components of the same application run in the same process and most applications

should not change this However if you find that you need to control which process a certain

component belongs to you can do so in the manifest file

The manifest entry for each type of component elementmdashltactivitygt ltservicegt ltreceivergt and

ltprovidergtmdashsupports an androidprocess attribute that can specify a process in which that component

should run You can set this attribute so that each component runs in its own process or so that some

components share a process while others do not You can also set androidprocess so that

components of different applications run in the same processmdashprovided that the applications share the

same Linux user ID and are signed with the same certificates

The ltapplicationgt element also supports an androidprocess attribute to set a default value that

applies to all components

Android might 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 thats killed are consequently destroyed A process is started again for those components

when theres again work for them to do

When deciding which processes to kill the Android system weighs their relative importance to the

user For example it more readily shuts down a process hosting activities that are no longer visible on

screen compared to a process hosting visible activities The decision whether to terminate a process

therefore depends on the state of the components running in that process The rules used to decide

which processes to terminate is discussed below

Process lifecycle

The Android system tries to maintain an application process for as long as possible but eventually

needs to remove old processes to reclaim memory for new or more important processes To determine

which processes to keep and which to kill the system places each process into an importance

hierarchy based on the components running in the process and the state of those components

Processes with the lowest importance are eliminated first then those with the next lowest importance

and so on as necessary to recover system resources

There are five levels in the importance hierarchy The following list presents the different types of

processes in order of importance (the first process is most important and is killed last)

1 Foreground process

A process that is required for what the user is currently doing A process is considered to be in the

foreground if any of the following conditions are true

o It hosts an Activity that the user is interacting with (the Activitys onResume() method has been called)

o It hosts a Service thats bound to the activity that the user is interacting with

o It hosts a Service thats running in the foregroundmdashthe service has called startForeground()

o It hosts a Service thats executing one of its lifecycle callbacks (onCreate() onStart() or onDestroy())

o It hosts a BroadcastReceiver thats executing its onReceive() method

Generally only a few foreground processes exist at any given time They are killed only as a last

resortmdashif memory is so low that they cannot all continue to run Generally at that point the device has

reached a memory paging state so killing some foreground processes is required to keep the user

interface responsive

2 Visible process

A process that doesnt have any foreground components but still can affect what the user sees on

screen A process is considered to be visible if either of the following conditions are true

o It hosts an Activity that is not in the foreground but is still visible to the user (its onPause() method has

been called) This might occur for example if the foreground activity started a dialog which allows the

previous activity to be seen behind it

o It hosts a Service thats bound to a visible (or foreground) activity

A visible process is considered extremely important and will not be killed unless doing so is required to

keep all foreground processes running

3 Service process

A process that is running a service that has been started with the startService() method and does not

fall into either of the two higher categories Although service processes are not directly tied to anything

the user sees they are generally doing things that the user cares about (such as playing music in the

background or downloading data on the network) so the system keeps them running unless theres

not enough memory to retain them along with all foreground and visible processes

4 Background process

A process holding an activity thats not currently visible to the user (the activitys onStop() method has

been called) These processes have no direct impact on the user experience and the system can kill

them at any time to reclaim memory for a foreground visible or service process Usually there are

many background processes running so they are kept in an LRU (least recently used) list to ensure

that the process with the activity that was most recently seen by the user is the last to be killed If an

activity implements its lifecycle methods correctly and saves its current state killing its process will not

have a visible effect on the user experience because when the user navigates back to the activity the

activity restores all of its visible state See the Activities document for information about saving and

restoring state

5 Empty process

A process that doesnt hold any active application components The only reason to keep this kind of

process alive is for caching purposes to improve startup time the next time a component needs to run

in it The system often kills these processes in order to balance overall system resources between

process caches and the underlying kernel caches

Android ranks a process at the highest level it can based upon the importance of the components

currently active in the process For example if a process hosts a service and a visible activity the

process is ranked as a visible process not a service process

In addition a processs ranking might be increased because other processes are dependent on itmdasha

process that is serving another process can never be ranked lower than the process it is serving For

example if a content provider in process A is serving a client in process B or if a service in process A

is bound to a component in process B process A is always considered at least as important as

process B

Because a process running a service is ranked higher than a process with background activities an

activity that initiates a long-running operation might do well to start a service for that operation rather

than simply create a worker threadmdashparticularly if the operation will likely outlast the activity For

example an activity thats uploading a picture to a web site should start a service to perform the

upload so that the upload can continue in the background even if the user leaves the activity Using a

service guarantees that the operation will have at least service process priority regardless of what

happens to the activity This is the same reason that broadcast receivers should employ services

rather than simply put time-consuming operations in a thread

Threads

When an application is launched the system creates a thread of execution for the application called

main This thread is very important because it is in charge of dispatching events to the appropriate

user interface widgets including drawing events It is also the thread in which your application interacts

with components from the Android UI toolkit (components from the androidwidget and androidview

packages) As such the main thread is also sometimes called the UI thread

The system does not create a separate thread for each instance of a component All components that

run in the same process are instantiated in the UI thread and system calls to each component are

dispatched from that thread Consequently methods that respond to system callbacks (such as

onKeyDown() to report user actions or a lifecycle callback method) always run in the UI thread of the

process

For instance when the user touches a button on the screen your apps UI thread dispatches the touch

event to the widget which in turn sets its pressed state and posts an invalidate request to the event

queue The UI thread dequeues the request and notifies the widget that it should redraw itself

When your app performs intensive work in response to user interaction this single thread model can

yield poor performance unless you implement your application properly Specifically if everything is

happening in the UI thread performing long operations such as network access or database queries

will block the whole UI When the thread is blocked no events can be dispatched including drawing

events From the users perspective the application appears to hang Even worse if the UI thread is

blocked for more than a few seconds (about 5 seconds currently) the user is presented with the

infamous application not responding (ANR) dialog The user might then decide to quit your

application and uninstall it if they are unhappy

Additionally the Andoid UI toolkit is not thread-safe So you must not manipulate your UI from a

worker threadmdashyou must do all manipulation to your user interface from the UI thread Thus there are

simply two rules to Androids single thread model

1 Do not block the UI thread

2 Do not access the Android UI toolkit from outside the UI thread

Worker threads

Because of the single thread model described above its vital to the responsiveness of your

applications UI that you do not block the UI thread If you have operations to perform that are not

instantaneous you should make sure to do them in separate threads (background or worker

threads)

For example below is some code for a click listener that downloads an image from a separate thread

and displays it in an ImageView

public void onClick(View v) new Thread(new Runnable() public void run() Bitmap b = loadImageFromNetwork(httpexamplecomimagepng) mImageViewsetImageBitmap(b) )start()

At first this seems to work fine because it creates a new thread to handle the network operation

However it violates the second rule of the single-threaded model do not access the Android UI toolkit

from outside the UI threadmdashthis sample modifies the ImageView from the worker thread instead of the

UI thread This can result in undefined and unexpected behavior which can be difficult and time-

consuming to track down

To fix this problem Android offers several ways to access the UI thread from other threads Here is a

list of methods that can help

ActivityrunOnUiThread(Runnable)

Viewpost(Runnable)

ViewpostDelayed(Runnable long)

For example you can fix the above code by using the Viewpost(Runnable) method

public void onClick(View v) new Thread(new Runnable() public void run() final Bitmap bitmap = loadImageFromNetwork(httpexamplecomimagepng) mImageViewpost(new Runnable() public void run() mImageViewsetImageBitmap(bitmap) ) )start()

Now this implementation is thread-safe the network operation is done from a separate thread while

the ImageView is manipulated from the UI thread

However as the complexity of the operation grows this kind of code can get complicated and difficult

to maintain To handle more complex interactions with a worker thread you might consider using a

Handler in your worker thread to process messages delivered from the UI thread Perhaps the best

solution though is to extend the AsyncTask class which simplifies the execution of worker thread

tasks that need to interact with the UI

Using AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface It performs the blocking

operations in a worker thread and then publishes the results on the UI thread without requiring you to

handle threads andor handlers yourself

To use it you must subclass AsyncTask and implement the doInBackground() callback method which

runs in a pool of background threads To update your UI you should implement onPostExecute()

which delivers the result from doInBackground() and runs in the UI thread so you can safely update

your UI You can then run the task by calling execute() from the UI thread

For example you can implement the previous example using AsyncTask this way

public void onClick(View v) new DownloadImageTask()execute(httpexamplecomimagepng) private class DownloadImageTask extends AsyncTaskltString Void Bitmapgt The system calls this to perform work in a worker thread and delivers it the parameters given to AsyncTaskexecute() protected Bitmap doInBackground(String urls) return loadImageFromNetwork(urls[0])

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 4: 03 services

Just like an activity a service can define intent filters that allow other components to invoke the service

using implicit intents By declaring intent filters components from any application installed on the

users device can potentially start your service if your service declares an intent filter that matches the

intent another application passes to startService()

If you plan on using your service only locally (other applications do not use it) then you dont need to

(and should not) supply any intent filters Without any intent filters you must start the service using an

intent that explicitly names the service class More information about starting a service is discussed

below

Additionally you can ensure that your service is private to your application only if you include the

androidexported attribute and set it to false This is effective even if your service supplies intent

filters

For more information about creating intent filters for your service see the Intents and Intent Filters

document

Creating a Started Service

Targeting Android 16 or lower

If youre building an application for Android 16 or lower you need to implement onStart() instead of

onStartCommand() (in Android 20 onStart() was deprecated in favor of onStartCommand())

For more information about providing compatibility with versions of Android older than 20 see the

onStartCommand() documentation

A started service is one that another component starts by calling startService() resulting in a call to the

services onStartCommand() method

When a service is started it has a lifecycle thats independent of the component that started it and the

service can run in the background indefinitely even if the component that started it is destroyed As

such the service should stop itself when its job is done by calling stopSelf() or another component

can stop it by calling stopService()

An application component such as an activity can start the service by calling startService() and

passing an Intent that specifies the service and includes any data for the service to use The service

receives this Intent in the onStartCommand() method

For instance suppose an activity needs to save some data to an online database The activity can

start a companion service and deliver it the data to save by passing an intent to startService() The

service receives the intent in onStartCommand() connects to the Internet and performs the database

transaction When the transaction is done the service stops itself and it is destroyed

Caution A services runs in the same process as the application in which it is declared and in the

main thread of that application by default So if your service performs intensive or blocking

operations while the user interacts with an activity from the same application the service will slow

down activity performance To avoid impacting application performance you should start a new

thread inside the service

Traditionally there are two classes you can extend to create a started service

Service

This is the base class for all services When you extend this class its important that you create

a new thread in which to do all the services work because the service uses your applications

main thread by default which could slow the performance of any activity your application is

running

IntentService

This is a subclass of Service that uses a worker thread to handle all start requests one at a

time This is the best option if you dont require that your service handle multiple requests

simultaneously All you need to do is implement onHandleIntent() which receives the intent for

each start request so you can do the background work

The following sections describe how you can implement your service using either one for these

classes

Extending the IntentService class

Because most started services dont need to handle multiple requests simultaneously (which can

actually be a dangerous multi-threading scenario) its probably best if you implement your service

using the IntentService class

The IntentService does the following

Creates a default worker thread that executes all intents delivered to onStartCommand() separate from

your applications main thread

Creates a work queue that passes one intent at a time to your onHandleIntent() implementation so

you never have to worry about multi-threading

Stops the service after all start requests have been handled so you never have to call stopSelf()

Provides default implementation of onBind() that returns null

Provides a default implementation of onStartCommand() that sends the intent to the work queue and

then to your onHandleIntent() implementation

All this adds up to the fact that all you need to do is implement onHandleIntent() to do the work

provided by the client (Though you also need to provide a small constructor for the service)

Heres an example implementation of IntentService

public class HelloIntentService extends IntentService A constructor is required and must call the super IntentService(String)

constructor with a name for the worker thread public HelloIntentService() super(HelloIntentService) The IntentService calls this method from the default worker thread with the intent that started the service When this method returns IntentService stops the service as appropriate Override protected void onHandleIntent(Intent intent) Normally we would do some work here like download a file For our sample we just sleep for 5 seconds long endTime = SystemcurrentTimeMillis() + 51000 while (SystemcurrentTimeMillis() lt endTime) synchronized (this) try wait(endTime - SystemcurrentTimeMillis()) catch (Exception e)

Thats all you need a constructor and an implementation of onHandleIntent()

If you decide to also override other callback methods such as onCreate() onStartCommand() or

onDestroy() be sure to call the super implementation so that the IntentService can properly handle

the life of the worker thread

For example onStartCommand() must return the default implementation (which is how the intent gets

delivered to onHandleIntent())

Override public int onStartCommand(Intent intent int flags int startId) ToastmakeText(this service starting ToastLENGTH_SHORT)show() return superonStartCommand(intentflagsstartId)

Besides onHandleIntent() the only method from which you dont need to call the super class is

onBind() (but you only need to implement that if your service allows binding)

In the next section youll see how the same kind of service is implemented when extending the base

Service class which is a lot more code but which might be appropriate if you need to handle

simultaneous start requests

Extending the Service class

As you saw in the previous section using IntentService makes your implementation of a started

service very simple If however you require your service to perform multi-threading (instead of

processing start requests through a work queue) then you can extend the Service class to handle

each intent

For comparison the following example code is an implementation of the Service class that performs

the exact same work as the example above using IntentService That is for each start request it uses

a worker thread to perform the job and processes only one request at a time

public class HelloService extends Service private Looper mServiceLooper private ServiceHandler mServiceHandler Handler that receives messages from the thread private final class ServiceHandler extends Handler public ServiceHandler(Looper looper) super(looper) Override public void handleMessage(Message msg) Normally we would do some work here like download a file For our sample we just sleep for 5 seconds long endTime = SystemcurrentTimeMillis() + 51000 while (SystemcurrentTimeMillis() lt endTime) synchronized (this) try wait(endTime - SystemcurrentTimeMillis()) catch (Exception e) Stop the service using the startId so that we dont stop the service in the middle of handling another job stopSelf(msgarg1) Override public void onCreate() Start up the thread running the service Note that we create a separate thread because the service normally runs in the processs main thread which we dont want to block We also make it background priority so CPU-intensive work will not disrupt our UI HandlerThread thread = new HandlerThread(ServiceStartArguments ProcessTHREAD_PRIORITY_BACKGROUND) threadstart() Get the HandlerThreads Looper and use it for our Handler

mServiceLooper = threadgetLooper() mServiceHandler = new ServiceHandler(mServiceLooper) Override public int onStartCommand(Intent intent int flags int startId) ToastmakeText(this service starting ToastLENGTH_SHORT)show() For each start request send a message to start a job and deliver the start ID so we know which request were stopping when we finish the job Message msg = mServiceHandlerobtainMessage() msgarg1 = startId mServiceHandlersendMessage(msg) If we get killed after returning from here restart return START_STICKY Override public IBinder onBind(Intent intent) We dont provide binding so return null return null Override public void onDestroy() ToastmakeText(this service done ToastLENGTH_SHORT)show()

As you can see its a lot more work than using IntentService

However because you handle each call to onStartCommand() yourself you can perform multiple

requests simultaneously Thats not what this example does but if thats what you want then you can

create a new thread for each request and run them right away (instead of waiting for the previous

request to finish)

Notice that the onStartCommand() method must return an integer The integer is a value that

describes how the system should continue the service in the event that the system kills it (as

discussed above the default implementation for IntentService handles this for you though you are

able to modify it) The return value from onStartCommand() must be one of the following constants

START_NOT_STICKY

If the system kills the service after onStartCommand() returns do not recreate the service

unless there are pending intents to deliver This is the safest option to avoid running your

service when not necessary and when your application can simply restart any unfinished jobs

START_STICKY

If the system kills the service after onStartCommand() returns recreate the service and call

onStartCommand() but do not redeliver the last intent Instead the system calls

onStartCommand() with a null intent unless there were pending intents to start the service in

which case those intents are delivered This is suitable for media players (or similar services)

that are not executing commands but running indefinitely and waiting for a job

START_REDELIVER_INTENT

If the system kills the service after onStartCommand() returns recreate the service and call

onStartCommand() with the last intent that was delivered to the service Any pending intents are

delivered in turn This is suitable for services that are actively performing a job that should be

immediately resumed such as downloading a file

For more details about these return values see the linked reference documentation for each constant

Starting a Service

You can start a service from an activity or other application component by passing an Intent (specifying

the service to start) to startService() The Android system calls the services onStartCommand()

method and passes it the Intent (You should never call onStartCommand() directly)

For example an activity can start the example service in the previous section (HelloSevice) using an

explicit intent with startService()

Intent intent = new Intent(this HelloServiceclass) startService(intent)

The startService() method returns immediately and the Android system calls the services

onStartCommand() method If the service is not already running the system first calls onCreate() then

calls onStartCommand()

If the service does not also provide binding the intent delivered with startService() is the only mode of

communication between the application component and the service However if you want the service

to send a result back then the client that starts the service can create a PendingIntent for a broadcast

(with getBroadcast()) and deliver it to the service in the Intent that starts the service The service can

then use the broadcast to deliver a result

Multiple requests to start the service result in multiple corresponding calls to the services

onStartCommand() However only one request to stop the service (with stopSelf() or stopService()) is

required to stop it

Stopping a service

A started service must manage its own lifecycle That is the system does not stop or destroy the

service unless it must recover system memory and the service continues to run after

onStartCommand() returns So the service must stop itself by calling stopSelf() or another component

can stop it by calling stopService()

Once requested to stop with stopSelf() or stopService() the system destroys the service as soon as

possible

However if your service handles multiple requests to onStartCommand() concurrently then you

shouldnt stop the service when youre done processing a start request because you might have since

received a new start request (stopping at the end of the first request would terminate the second one)

To avoid this problem you can use stopSelf(int) to ensure that your request to stop the service is

always based on the most recent start request That is when you call stopSelf(int) you pass the ID of

the start request (the startId delivered to onStartCommand()) to which your stop request corresponds

Then if the service received a new start request before you were able to call stopSelf(int) then the ID

will not match and the service will not stop

Caution Its important that your application stops its services when its done working to avoid

wasting system resources and consuming battery power If necessary other components can stop

the service by calling stopService() Even if you enable binding for the service you must always

stop the service yourself if it ever received a call to onStartCommand()

For more information about the lifecycle of a service see the section below about Managing the

Lifecycle of a Service

Creating a Bound Service

A bound service is one that allows application components to bind to it by calling bindService() in order

to create a long-standing connection (and generally does not allow components to start it by calling

startService())

You should create a bound service when you want to interact with the service from activities and other

components in your application or to expose some of your applications functionality to other

applications through interprocess communication (IPC)

To create a bound service you must implement the onBind() callback method to return an IBinder that

defines the interface for communication with the service Other application components can then call

bindService() to retrieve the interface and begin calling methods on the service The service lives only

to serve the application component that is bound to it so when there are no components bound to the

service the system destroys it (you do not need to stop a bound service in the way you must when the

service is started through onStartCommand())

To create a bound service the first thing you must do is define the interface that specifies how a client

can communicate with the service This interface between the service and a client must be an

implementation of IBinder and is what your service must return from the onBind() callback method

Once the client receives the IBinder it can begin interacting with the service through that interface

Multiple clients can bind to the service at once When a client is done interacting with the service it

calls unbindService() to unbind Once there are no clients bound to the service the system destroys

the service

There are multiple ways to implement a bound service and the implementation is more complicated

than a started service so the bound service discussion appears in a separate document about Bound

Services

Sending Notifications to the User

Once running a service can notify the user of events using Toast Notifications or Status Bar

Notifications

A toast notification is a message that appears on the surface of the current window for a moment then

disappears while a status bar notification provides an icon in the status bar with a message which the

user can select in order to take an action (such as start an activity)

Usually a status bar notification is the best technique when some background work has completed

(such as a file completed downloading) and the user can now act on it When the user selects the

notification from the expanded view the notification can start an activity (such as to view the

downloaded file)

See the Toast Notifications or Status Bar Notifications developer guides for more information

Running a Service in the Foreground

A foreground service is a service thats considered to be something the user is actively aware of and

thus not a candidate for the system to kill when low on memory A foreground service must provide a

notification for the status bar which is placed under the Ongoing heading which means that the

notification cannot be dismissed unless the service is either stopped or removed from the foreground

For example a music player that plays music from a service should be set to run in the foreground

because the user is explicitly aware of its operation The notification in the status bar might indicate the

current song and allow the user to launch an activity to interact with the music player

To request that your service run in the foreground call startForeground() This method takes two

parameters an integer that uniquely identifies the notification and the Notification for the status bar

For example

Notification notification = new Notification(Rdrawableicon getText(Rstringticker_text) SystemcurrentTimeMillis()) Intent notificationIntent = new Intent(this ExampleActivityclass) PendingIntent pendingIntent = PendingIntentgetActivity(this 0 notificationIntent 0) notificationsetLatestEventInfo(this getText(Rstringnotification_title) getText(Rstringnotification_message) pendingIntent) startForeground(ONGOING_NOTIFICATION notification)

To remove the service from the foreground call stopForeground() This method takes a boolean

indicating whether to remove the status bar notification as well This method does not stop the service

However if you stop the service while its still running in the foreground then the notification is also

removed

Note The methods startForeground() and stopForeground() were introduced in Android 20 (API

Level 5) In order to run your service in the foreground on older versions of the platform you must

use the previous setForeground() methodmdashsee the startForeground() documentation for

information about how to provide backward compatibility

For more information about notifications see Creating Status Bar Notifications

Managing the Lifecycle of a Service

The lifecycle of a service is much simpler than that of an activity However its even more important

that you pay close attention to how your service is created and destroyed because a service can run

in the background without the user being aware

The service lifecyclemdashfrom when its created to when its destroyedmdashcan follow two different paths

A started service

The service is created when another component calls startService() The service then runs indefinitely

and must stop itself by calling stopSelf() Another component can also stop the service by calling

stopService() When the service is stopped the system destroys it

A bound service

The service is created when another component (a client) calls bindService() The client then

communicates with the service through an IBinder interface The client can close the connection by

calling unbindService() Multiple clients can bind to the same service and when all of them unbind the

system destroys the service (The service does not need to stop itself)

These two paths are not entirely separate That is you can bind to a service that was already started

with startService() For example a background music service could be started by calling startService()

with an Intent that identifies the music to play Later possibly when the user wants to exercise some

control over the player or get information about the current song an activity can bind to the service by

calling bindService() In cases like this stopService() or stopSelf() does not actually stop the service

until all clients unbind

Implementing the lifecycle callbacks

Like an activity a service has lifecycle callback methods that you can implement to monitor changes in

the services state and perform work at the appropriate times The following skeleton service

demonstrates each of the lifecycle methods

Figure 2 The service lifecycle The diagram on the left shows the lifecycle when the service is created

with startService() and the diagram on the right shows the lifecycle when the service is created with

bindService()

public class ExampleService extends Service int mStartMode indicates how to behave if the service is killed IBinder mBinder interface for clients that bind boolean mAllowRebind indicates whether onRebind should be used Override public void onCreate() The service is being created Override public int onStartCommand(Intent intent int flags int startId) The service is starting due to a call to startService() return mStartMode Override public IBinder onBind(Intent intent) A client is binding to the service with bindService() return mBinder Override public boolean onUnbind(Intent intent) All clients have unbound with unbindService()

return mAllowRebind Override public void onRebind(Intent intent) A client is binding to the service with bindService() after onUnbind() has already been called Override public void onDestroy() The service is no longer used and is being destroyed

Note Unlike the activity lifecycle callback methods you are not required to call the superclass

implementation of these callback methods

By implementing these methods you can monitor two nested loops of the services lifecycle

The entire lifetime of a service happens between the time onCreate() is called and the time

onDestroy() returns Like an activity a service does its initial setup in onCreate() and releases all

remaining resources in onDestroy() For example a music playback service could create the thread

where the music will be played in onCreate() then stop the thread in onDestroy()

The onCreate() and onDestroy() methods are called for all services whether theyre created by

startService() or bindService()

The active lifetime of a service begins with a call to either onStartCommand() or onBind() Each

method is handed the Intent that was passed to either startService() or bindService() respectively

If the service is started the active lifetime ends the same time that the entire lifetime ends (the service

is still active even after onStartCommand() returns) If the service is bound the active lifetime ends

when onUnbind() returns

Note Although a started service is stopped by a call to either stopSelf() or stopService() there is

not a respective callback for the service (theres no onStop() callback) So unless the service is

bound to a client the system destroys it when the service is stoppedmdashonDestroy() is the only

callback received

Figure 2 illustrates the typical callback methods for a service Although the figure separates services

that are created by startService() from those created by bindService() keep in mind that any service

no matter how its started can potentially allow clients to bind to it So a service that was initially

started with onStartCommand() (by a client calling startService()) can still receive a call to onBind()

(when a client calls bindService())

For more information about creating a service that provides binding see the Bound Services

document which includes more information about the onRebind() callback method in the section about

Managing the Lifecycle of a Bound Service

Bound Services

A bound service is the server in a client-server interface A bound service allows components (such as

activities) to bind to the service send requests receive responses and even perform interprocess

communication (IPC) A bound service typically lives only while it serves another application

component and does not run in the background indefinitely

This document shows you how to create a bound service including how to bind to the service from

other application components However you should also refer to the Services document for additional

information about services in general such as how to deliver notifications from a service set the

service to run in the foreground and more

The Basics

A bound service is an implementation of the Service class that allows other applications to bind to it

and interact with it To provide binding for a service you must implement the onBind() callback

method This method returns an IBinder object that defines the programming interface that clients can

use to interact with the service

Binding to a Started Service

As discussed in the Services document you can create a service that is both started and bound That

is the service can be started by calling startService() which allows the service to run indefinitely and

also allow a client to bind to the service by calling bindService()

If you do allow your service to be started and bound then when the service has been started the

system does not destroy the service when all clients unbind Instead you must explicitly stop the

service by calling stopSelf() or stopService()

Although you should usually implement either onBind() or onStartCommand() its sometimes

necessary to implement both For example a music player might find it useful to allow its service to run

indefinitely and also provide binding This way an activity can start the service to play some music and

the music continues to play even if the user leaves the application Then when the user returns to the

application the activity can bind to the service to regain control of playback

Be sure to read the section about Managing the Lifecycle of a Bound Service for more information

about the service lifecycle when adding binding to a started service

A client can bind to the service by calling bindService() When it does it must provide an

implementation of ServiceConnection which monitors the connection with the service The

bindService() method returns immediately without a value but when the Android system creates the

connection between the client and service it calls onServiceConnected() on the ServiceConnection to

deliver the IBinder that the client can use to communicate with the service

Multiple clients can connect to the service at once However the system calls your services onBind()

method to retrieve the IBinder only when the first client binds The system then delivers the same

IBinder to any additional clients that bind without calling onBind() again

When the last client unbinds from the service the system destroys the service (unless the service was

also started by startService())

When you implement your bound service the most important part is defining the interface that your

onBind() callback method returns There are a few different ways you can define your services IBinder

interface and the following section discusses each technique

Creating a Bound Service

When creating a service that provides binding you must provide an IBinder that provides the

programming interface that clients can use to interact with the service There are three ways you can

define the interface

Extending the Binder class

If your service is private to your own application and runs in the same process as the client

(which is common) you should create your interface by extending the Binder class and

returning an instance of it from onBind() The client receives the Binder and can use it to directly

access public methods available in either the Binder implementation or even the Service

This is the preferred technique when your service is merely a background worker for your own

application The only reason you would not create your interface this way is because your

service is used by other applications or across separate processes

Using a Messenger

If you need your interface to work across different processes you can create an interface for the

service with a Messenger In this manner the service defines a Handler that responds to

different types of Message objects This Handler is the basis for a Messenger that can then

share an IBinder with the client allowing the client to send commands to the service using

Message objects Additionally the client can define a Messenger of its own so the service can

send messages back

This is the simplest way to perform interprocess communication (IPC) because the Messenger

queues all requests into a single thread so that you dont have to design your service to be

thread-safe

Using AIDL

AIDL (Android Interface Definition Language) performs all the work to decompose objects into

primitives that the operating system can understand and marshall them across processes to

perform IPC The previous technique using a Messenger is actually based on AIDL as its

underlying structure As mentioned above the Messenger creates a queue of all the client

requests in a single thread so the service receives requests one at a time If however you

want your service to handle multiple requests simultaneously then you can use AIDL directly In

this case your service must be capable of multi-threading and be built thread-safe

To use AIDL directly you must create an aidl file that defines the programming interface The

Android SDK tools use this file to generate an abstract class that implements the interface and

handles IPC which you can then extend within your service

Note Most applications should not use AIDL to create a bound service because it may require

multithreading capabilities and can result in a more complicated implementation As such AIDL is

not suitable for most applications and this document does not discuss how to use it for your

service If youre certain that you need to use AIDL directly see the AIDL document

Extending the Binder class

If your service is used only by the local application and does not need to work across processes then

you can implement your own Binder class that provides your client direct access to public methods in

the service

Note This works only if the client and service are in the same application and process which is

most common For example this would work well for a music application that needs to bind an

activity to its own service thats playing music in the background

Heres how to set it up

1 In your service create an instance of Binder that either

o contains public methods that the client can call

o returns the current Service instance which has public methods the client can call

o or returns an instance of another class hosted by the service with public methods the client can call

2 Return this instance of Binder from the onBind() callback method

3 In the client receive the Binder from the onServiceConnected() callback method and make calls to the

bound service using the methods provided

Note The reason the service and client must be in the same application is so the client can cast

the returned object and properly call its APIs The service and client must also be in the same

process because this technique does not perform any marshalling across processes

For example heres a service that provides clients access to methods in the service through a Binder

implementation

public class LocalService extends Service

Binder given to clients

private final IBinder mBinder = new LocalBinder()

Random number generator

private final Random mGenerator = new Random()

Class used for the client Binder Because we know this service always

runs in the same process as its clients we dont need to deal with IPC

public class LocalBinder extends Binder

LocalService getService()

Return this instance of LocalService so clients can call public methods

return LocalServicethis

Override

public IBinder onBind(Intent intent)

return mBinder

method for clients

public int getRandomNumber()

return mGeneratornextInt(100)

The LocalBinder provides the getService() method for clients to retrieve the current instance of

LocalService This allows clients to call public methods in the service For example clients can call

getRandomNumber() from the service

Heres an activity that binds to LocalService and calls getRandomNumber() when a button is clicked

public class BindingActivity extends Activity

LocalService mService

boolean mBound = false

Override

protected void onCreate(Bundle savedInstanceState)

superonCreate(savedInstanceState)

setContentView(Rlayoutmain)

Override

protected void onStart()

superonStart()

Bind to LocalService

Intent intent = new Intent(this LocalServiceclass)

bindService(intent mConnection ContextBIND_AUTO_CREATE)

Override

protected void onStop()

superonStop()

Unbind from the service

if (mBound)

unbindService(mConnection)

mBound = false

Called when a button is clicked (the button in the layout file attaches to

this method with the androidonClick attribute)

public void onButtonClick(View v)

if (mBound)

Call a method from the LocalService

However if this call were something that might hang then this request should

occur in a separate thread to avoid slowing down the activity performance

int num = mServicegetRandomNumber()

ToastmakeText(this number + num ToastLENGTH_SHORT)show()

Defines callbacks for service binding passed to bindService()

private ServiceConnection mConnection = new ServiceConnection()

Override

public void onServiceConnected(ComponentName className

IBinder service)

Weve bound to LocalService cast the IBinder and get LocalService instance

LocalBinder binder = (LocalBinder) service

mService = bindergetService()

mBound = true

Override

public void onServiceDisconnected(ComponentName arg0)

mBound = false

The above sample shows how the client binds to the service using an implementation of

ServiceConnection and the onServiceConnected() callback The next section provides more

information about this process of binding to the service

Note The example above doesnt explicitly unbind from the service but all clients should unbind

at an appropriate time (such as when the activity pauses)

For more sample code see the LocalServicejava class and the LocalServiceActivitiesjava class in

ApiDemos

Using a Messenger

Compared to AIDL

When you need to perform IPC using a Messenger for your interface is simpler than implementing it

with AIDL because Messenger queues all calls to the service whereas a pure AIDL interface sends

simultaneous requests to the service which must then handle multi-threading

For most applications the service doesnt need to perform multi-threading so using a Messenger

allows the service to handle one call at a time If its important that your service be multi-threaded then

you should use AIDL to define your interface

If you need your service to communicate with remote processes then you can use a Messenger to

provide the interface for your service This technique allows you to perform interprocess

communication (IPC) without the need to use AIDL

Heres a summary of how to use a Messenger

The service implements a Handler that receives a callback for each call from a client

The Handler is used to create a Messenger object (which is a reference to the Handler)

The Messenger creates an IBinder that the service returns to clients from onBind()

Clients use the IBinder to instantiate the Messenger (that references the services Handler) which the

client uses to send Message objects to the service

The service receives each Message in its Handlermdashspecifically in the handleMessage() method

In this way there are no methods for the client to call on the service Instead the client delivers

messages (Message objects) that the service receives in its Handler

Heres a simple example service that uses a Messenger interface

public class MessengerService extends Service Command to the service to display a message static final int MSG_SAY_HELLO = 1 Handler of incoming messages from clients class IncomingHandler extends Handler Override public void handleMessage(Message msg) switch (msgwhat) case MSG_SAY_HELLO ToastmakeText(getApplicationContext() hello ToastLENGTH_SHORT)show() break default superhandleMessage(msg) Target we publish for clients to send messages to IncomingHandler final Messenger mMessenger = new Messenger(new IncomingHandler()) When binding to the service we return an interface to our messenger for sending messages to the service Override public IBinder onBind(Intent intent) ToastmakeText(getApplicationContext() binding ToastLENGTH_SHORT)show() return mMessengergetBinder()

Notice that the handleMessage() method in the Handler is where the service receives the incoming

Message and decides what to do based on the what member

All that a client needs to do is create a Messenger based on the IBinder returned by the service and

send a message using send() For example heres a simple activity that binds to the service and

delivers the MSG_SAY_HELLO message to the service

public class ActivityMessenger extends Activity Messenger for communicating with the service Messenger mService = null Flag indicating whether we have called bind on the service boolean mBound Class for interacting with the main interface of the service private ServiceConnection mConnection = new ServiceConnection() public void onServiceConnected(ComponentName className IBinder service) This is called when the connection with the service has been established giving us the object we can use to interact with the service We are communicating with the service using a Messenger so here we get a client-side representation of that from the raw IBinder object mService = new Messenger(service) mBound = true public void onServiceDisconnected(ComponentName className) This is called when the connection with the service has been unexpectedly disconnected -- that is its process crashed mService = null mBound = false public void sayHello(View v) if (mBound) return Create and send a message to the service using a supported what value Message msg = Messageobtain(null MessengerServiceMSG_SAY_HELLO 0 0) try mServicesend(msg) catch (RemoteException e) eprintStackTrace() Override protected void onCreate(Bundle savedInstanceState) superonCreate(savedInstanceState) setContentView(Rlayoutmain)

Override protected void onStart() superonStart() Bind to the service bindService(new Intent(this MessengerServiceclass) mConnection ContextBIND_AUTO_CREATE) Override protected void onStop() superonStop() Unbind from the service if (mBound) unbindService(mConnection) mBound = false

Notice that this example does not show how the service can respond to the client If you want the

service to respond then you need to also create a Messenger in the client Then when the client

receives the onServiceConnected() callback it sends a Message to the service that includes the

clients Messenger in the replyTo parameter of the send() method

You can see an example of how to provide two-way messaging in the MessengerServicejava (service)

and MessengerServiceActivitiesjava (client) samples

Binding to a Service

Application components (clients) can bind to a service by calling bindService() The Android system

then calls the services onBind() method which returns an IBinder for interacting with the service

The binding is asynchronous bindService() returns immediately and does not return the IBinder to the

client To receive the IBinder the client must create an instance of ServiceConnection and pass it to

bindService() The ServiceConnection includes a callback method that the system calls to deliver the

IBinder

Note Only activities services and content providers can bind to a servicemdashyou cannot bind to a

service from a broadcast receiver

So to bind to a service from your client you must

1 Implement ServiceConnection

Your implementation must override two callback methods

onServiceConnected()

The system calls this to deliver the IBinder returned by the services onBind() method

onServiceDisconnected()

The Android system calls this when the connection to the service is unexpectedly lost such as

when the service has crashed or has been killed This is not called when the client unbinds

2 Call bindService() passing the ServiceConnection implementation

3 When the system calls your onServiceConnected() callback method you can begin making calls to the

service using the methods defined by the interface

4 To disconnect from the service call unbindService()

When your client is destroyed it will unbind from the service but you should always unbind when

youre done interacting with the service or when your activity pauses so that the service can shutdown

while its not being used (Appropriate times to bind and unbind is discussed more below)

For example the following snippet connects the client to the service created above by extending the

Binder class so all it must do is cast the returned IBinder to the LocalService class and request the

LocalService instance

LocalService mService private ServiceConnection mConnection = new ServiceConnection() Called when the connection with the service is established public void onServiceConnected(ComponentName className IBinder service) Because we have bound to an explicit service that is running in our own process we can cast its IBinder to a concrete class and directly access it LocalBinder binder = (LocalBinder) service mService = bindergetService() mBound = true Called when the connection with the service disconnects unexpectedly public void onServiceDisconnected(ComponentName className) Loge(TAG onServiceDisconnected) mBound = false

With this ServiceConnection the client can bind to a service by passing this it to bindService() For

example

Intent intent = new Intent(this LocalServiceclass) bindService(intent mConnection ContextBIND_AUTO_CREATE)

The first parameter of bindService() is an Intent that explicitly names the service to bind (thought the

intent could be implicit)

The second parameter is the ServiceConnection object

The third parameter is a flag indicating options for the binding It should usually be

BIND_AUTO_CREATE in order to create the service if its not already alive Other possible values are

BIND_DEBUG_UNBIND and BIND_NOT_FOREGROUND or 0 for none

Additional notes

Here are some important notes about binding to a service

You should always trap DeadObjectException exceptions which are thrown when the connection has

broken This is the only exception thrown by remote methods

Objects are reference counted across processes

You should usually pair the binding and unbinding during matching bring-up and tear-down moments

of the clients lifecycle For example

o If you only need to interact with the service while your activity is visible you should bind during

onStart() and unbind during onStop()

o If you want your activity to receive responses even while it is stopped in the background then you can

bind during onCreate() and unbind during onDestroy() Beware that this implies that your activity needs

to use the service the entire time its running (even in the background) so if the service is in another

process then you increase the weight of the process and it becomes more likely that the system will

kill it

Note You should usually not bind and unbind during your activitys onResume() and onPause()

because these callbacks occur at every lifecycle transition and you should keep the processing that

occurs at these transitions to a minimum Also if multiple activities in your application bind to the same

service and there is a transition between two of those activities the service may be destroyed and

recreated as the current activity unbinds (during pause) before the next one binds (during resume)

(This activity transition for how activities coordinate their lifecycles is described in the Activities

document)

For more sample code showing how to bind to a service see the RemoteServicejava class in

ApiDemos

Managing the Lifecycle of a Bound Service

Figure 1 The lifecycle for a service

that is started and also allows binding

When a service is unbound from all

clients the Android system destroys it

(unless it was also started with

onStartCommand()) As such you

dont have to manage the lifecycle of

your service if its purely a bound

servicemdashthe Android system manages

it for you based on whether it is bound

to any clients

However if you choose to implement

the onStartCommand() callback

method then you must explicitly stop

the service because the service is

now considered to be started In this

case the service runs until the service

stops itself with stopSelf() or another

component calls stopService()

regardless of whether it is bound to

any clients

Additionally if your service is started and accepts binding then when the system calls your onUnbind()

method you can optionally return true if you would like to receive a call to onRebind() the next time a

client binds to the service (instead of receiving a call to onBind()) onRebind() returns void but the

client still receives the IBinder in its onServiceConnected() callback Below figure 1 illustrates the logic

for this kind of lifecycle

For more information about the lifecycle of an started service see the Services document

Content Providers

Content providers store and retrieve data and make it accessible to all applications Theyre the only

way to share data across applications theres no common storage area that all Android packages can

access

Android ships with a number of content providers for common data types (audio video images

personal contact information and so on) You can see some of them listed in the androidprovider

package You can query these providers for the data they contain (although for some you must

acquire the proper permission to read the data)

If you want to make your own data public you have two options You can create your own content

provider (a ContentProvider subclass) or you can add the data to an existing provider mdash if theres one

that controls the same type of data and you have permission to write to it

This document is an introduction to using content providers After a brief discussion of the

fundamentals it explores how to query a content provider how to modify data controlled by a provider

and how to create a content provider of your own

Content Provider Basics

How a content provider actually stores its data under the covers is up to its designer But all content

providers implement a common interface for querying the provider and returning results mdash as well as

for adding altering and deleting data Its an interface that clients use indirectly most generally

through ContentResolver objects You get a ContentResolver by calling getContentResolver() from

within the implementation of an Activity or other application component

ContentResolver cr = getContentResolver()

You can then use the ContentResolvers methods to interact with whatever content providers youre

interested in When a query is initiated the Android system identifies the content provider thats the

target of the query and makes sure that it is up and running The system instantiates all

ContentProvider objects you never need to do it on your own In fact you never deal directly with

ContentProvider objects at all Typically theres just a single instance of each type of ContentProvider

But it can communicate with multiple ContentResolver objects in different applications and processes

The interaction between processes is handled by the ContentResolver and ContentProvider classes

The data model

Content providers expose their data as a simple table on a database model where each row is a

record and each column is data of a particular type and meaning For example information about

people and their phone numbers might be exposed as follows

_ID NUMBER NUMBER_KEY LABEL NAME TYPE

13 (425) 555 6677 425 555 6677 Kirkland office Bully Pulpit TYPE_WORK

44 (212) 555-1234 212 555 1234 NY apartment Alan Vain TYPE_HOME

45 (212) 555-6657 212 555 6657 Downtown office Alan Vain TYPE_MOBILE

53 2015554433 201 555 4433 Love Nest Rex Cars TYPE_HOME

Every record includes a numeric _ID field that uniquely identifies the record within the table IDs can be

used to match records in related tables mdash for example to find a persons phone number in one table

and pictures of that person in another

A query returns a Cursor object that can move from record to record and column to column to read the

contents of each field It has specialized methods for reading each type of data So to read a field you

must know what type of data the field contains (Theres more on query results and Cursor objects

later)

URIs

Each content provider exposes a public URI (wrapped as a Uri object) that uniquely identifies its data

set A content provider that controls multiple data sets (multiple tables) exposes a separate URI for

each one All URIs for providers begin with the string content The content scheme identifies the

data as being controlled by a content provider

If youre defining a content provider its a good idea to also define a constant for its URI to simplify

client code and make future updates cleaner Android defines CONTENT_URI constants for all the

providers that come with the platform For example the URI for the table that matches phone numbers

to people and the URI for the table that holds pictures of people (both controlled by the Contacts

content provider) are

androidproviderContactsPhonesCONTENT_URI

androidproviderContactsPhotosCONTENT_URI

The URI constant is used in all interactions with the content provider Every ContentResolver method

takes the URI as its first argument Its what identifies which provider the ContentResolver should talk

to and which table of the provider is being targeted

Querying a Content Provider

You need three pieces of information to query a content provider

The URI that identifies the provider

The names of the data fields you want to receive

The data types for those fields

If youre querying a particular record you also need the ID for that record

Making the query

To query a content provider you can use either the ContentResolverquery() method or the

ActivitymanagedQuery() method Both methods take the same set of arguments and both return a

Cursor object However managedQuery() causes the activity to manage the life cycle of the Cursor A

managed Cursor handles all of the niceties such as unloading itself when the activity pauses and

requerying itself when the activity restarts You can ask an Activity to begin managing an unmanaged

Cursor object for you by calling ActivitystartManagingCursor()

The first argument to either query() or managedQuery() is the provider URI mdash the CONTENT_URI

constant that identifies a particular ContentProvider and data set (see URIs earlier)

To restrict a query to just one record you can append the _ID value for that record to the URI mdash that

is place a string matching the ID as the last segment of the path part of the URI For example if the ID

is 23 the URI would be

content 23

There are some helper methods particularly ContentUriswithAppendedId() and

UriwithAppendedPath() that make it easy to append an ID to a URI Both are static methods that

return a Uri object with the ID added So for example if you were looking for record 23 in the database

of people contacts you might construct a query as follows

import androidproviderContactsPeople import androidcontentContentUris import androidnetUri import androiddatabaseCursor Use the ContentUris method to produce the base URI for the contact with _ID == 23 Uri myPerson = ContentUriswithAppendedId(PeopleCONTENT_URI 23) Alternatively use the Uri method to produce the base URI It takes a string rather than an integer Uri myPerson = UriwithAppendedPath(PeopleCONTENT_URI 23) Then query for this specific record Cursor cur = managedQuery(myPerson null null null null)

The other arguments to the query() and managedQuery() methods delimit the query in more detail

They are

The names of the data columns that should be returned A null value returns all columns Otherwise

only columns that are listed by name are returned All the content providers that come with the

platform define constants for their columns For example the androidproviderContactsPhones class

defines constants for the names of the columns in the phone table illustrated earlier ampmdash _ID

NUMBER NUMBER_KEY NAME and so on

A filter detailing which rows to return formatted as an SQL WHERE clause (excluding the WHERE

itself) A null value returns all rows (unless the URI limits the query to a single record)

Selection arguments

A sorting order for the rows that are returned formatted as an SQL ORDER BY clause (excluding the

ORDER BY itself) A null value returns the records in the default order for the table which may be

unordered

Lets look at an example query to retrieve a list of contact names and their primary phone numbers

import androidproviderContactsPeople import androiddatabaseCursor Form an array specifying which columns to return String[] projection = new String[] People_ID People_COUNT PeopleNAME PeopleNUMBER Get the base URI for the People table in the Contacts content provider Uri contacts = PeopleCONTENT_URI Make the query Cursor managedCursor = managedQuery(contacts projection Which columns to return null Which rows to return (all rows) null Selection arguments (none) Put the results in ascending order by name PeopleNAME + ASC)

This query retrieves data from the People table of the Contacts content provider It gets the name

primary phone number and unique record ID for each contact It also reports the number of records

that are returned as the _COUNT field of each record

The constants for the names of the columns are defined in various interfaces mdash _ID and _COUNT in

BaseColumns NAME in PeopleColumns and NUMBER in PhoneColumns The ContactsPeople

class implements each of these interfaces which is why the code example above could refer to them

using just the class name

What a query returns

A query returns a set of zero or more database records The names of the columns their default order

and their data types are specific to each content provider But every provider has an _ID column

which holds a unique numeric ID for each record Every provider can also report the number of records

returned as the _COUNT column its value is the same for all rows

Here is an example result set for the query in the previous section

_ID _COUNT NAME NUMBER

44 3 Alan Vain 212 555 1234

13 3 Bully Pulpit 425 555 6677

53 3 Rex Cars 201 555 4433

The retrieved data is exposed by a Cursor object that can be used to iterate backward or forward

through the result set You can use this object only to read the data To add modify or delete data

you must use a ContentResolver object

Reading retrieved data

The Cursor object returned by a query provides access to a recordset of results If you have queried

for a specific record by ID this set will contain only one value Otherwise it can contain multiple

values (If there are no matches it can also be empty) You can read data from specific fields in the

record but you must know the data type of the field because the Cursor object has a separate method

for reading each type of data mdash such as getString() getInt() and getFloat() (However for most types

if you call the method for reading strings the Cursor object will give you the String representation of

the data) The Cursor lets you request the column name from the index of the column or the index

number from the column name

The following snippet demonstrates reading names and phone numbers from the query illustrated

earlier

import androidproviderContactsPeople private void getColumnData(Cursor cur) if (curmoveToFirst()) String name String phoneNumber int nameColumn = curgetColumnIndex(PeopleNAME) int phoneColumn = curgetColumnIndex(PeopleNUMBER) String imagePath do Get the field values name = curgetString(nameColumn) phoneNumber = curgetString(phoneColumn) Do something with the values while (curmoveToNext())

If a query can return binary data such as an image or sound the data may be directly entered in the

table or the table entry for that data may be a string specifying a content URI that you can use to get

the data In general smaller amounts of data (say from 20 to 50K or less) are most often directly

entered in the table and can be read by calling CursorgetBlob() It returns a byte array

If the table entry is a content URI you should never try to open and read the file directly (for one thing

permissions problems can make this fail) Instead you should call ContentResolveropenInputStream()

to get an InputStream object that you can use to read the data

Modifying Data

Data kept by a content provider can be modified by

Adding new records

Adding new values to existing records

Batch updating existing records

Deleting records

All data modification is accomplished using ContentResolver methods Some content providers require

a more restrictive permission for writing data than they do for reading it If you dont have permission to

write to a content provider the ContentResolver methods will fail

Adding records

To add a new record to a content provider first set up a map of key-value pairs in a ContentValues

object where each key matches the name of a column in the content provider and the value is the

desired value for the new record in that column Then call ContentResolverinsert() and pass it the URI

of the provider and the ContentValues map This method returns the full URI of the new record mdash that

is the providers URI with the appended ID for the new record You can then use this URI to query and

get a Cursor over the new record and to further modify the record Heres an example

import androidproviderContactsPeople import androidcontentContentResolver import androidcontentContentValues ContentValues values = new ContentValues() Add Abraham Lincoln to contacts and make him a favorite valuesput(PeopleNAME Abraham Lincoln) 1 = the new contact is added to favorites 0 = the new contact is not added to favorites valuesput(PeopleSTARRED 1) Uri uri = getContentResolver()insert(PeopleCONTENT_URI values)

Adding new values

Once a record exists you can add new information to it or modify existing information For example

the next step in the example above would be to add contact information mdash like a phone number or an

IM or e-mail address mdash to the new entry

The best way to add to a record in the Contacts database is to append the name of the table where the

new data goes to the URI for the record then use the amended URI to add the new data values Each

Contacts table exposes a name for this purpose as a CONTENT_DIRECTORY constant The following

code continues the previous example by adding a phone number and e-mail address for the record

just created

Uri phoneUri = null Uri emailUri = null Add a phone number for Abraham Lincoln Begin with the URI for the new record just returned by insert() it ends with the _ID of the new record so we dont have to add the ID ourselves Then append the designation for the phone table to this URI and use the resulting URI to insert the phone number phoneUri = UriwithAppendedPath(uri PeoplePhonesCONTENT_DIRECTORY) valuesclear() valuesput(PeoplePhonesTYPE PeoplePhonesTYPE_MOBILE) valuesput(PeoplePhonesNUMBER 1233214567) getContentResolver()insert(phoneUri values) Now add an email address in the same way emailUri = UriwithAppendedPath(uri PeopleContactMethodsCONTENT_DIRECTORY) valuesclear() ContactMethodsKIND is used to distinguish different kinds of contact methods such as email IM etc valuesput(PeopleContactMethodsKIND ContactsKIND_EMAIL) valuesput(PeopleContactMethodsDATA testexamplecom) valuesput(PeopleContactMethodsTYPE PeopleContactMethodsTYPE_HOME) getContentResolver()insert(emailUri values)

You can place small amounts of binary data into a table by calling the version of ContentValuesput()

that takes a byte array That would work for a small icon-like image or a short audio clip for example

However if you have a large amount of binary data to add such as a photograph or a complete song

put a content URI for the data in the table and call ContentResolveropenOutputStream() with the files

URI (That causes the content provider to store the data in a file and record the file path in a hidden

field of the record)

In this regard the MediaStore content provider the main provider that dispenses image audio and

video data employs a special convention The same URI that is used with query() or managedQuery()

to get meta-information about the binary data (such as the caption of a photograph or the date it was

taken) is used with openInputStream() to get the data itself Similarly the same URI that is used with

insert() to put meta-information into a MediaStore record is used with openOutputStream() to place the

binary data there The following code snippet illustrates this convention

import androidproviderMediaStoreImagesMedia import androidcontentContentValues import javaioOutputStream Save the name and description of an image in a ContentValues map ContentValues values = new ContentValues(3) valuesput(MediaDISPLAY_NAME road_trip_1) valuesput(MediaDESCRIPTION Day 1 trip to Los Angeles) valuesput(MediaMIME_TYPE imagejpeg) Add a new record without the bitmap but with the values just set insert() returns the URI of the new record Uri uri = getContentResolver()insert(MediaEXTERNAL_CONTENT_URI values) Now get a handle to the file for that record and save the data into it Here sourceBitmap is a Bitmap object representing the file to save to the database try OutputStream outStream = getContentResolver()openOutputStream(uri) sourceBitmapcompress(BitmapCompressFormatJPEG 50 outStream) outStreamclose() catch (Exception e) Loge(TAG exception while writing image e)

Batch updating records

To batch update a group of records (for example to change NY to New York in all fields) call the

ContentResolverupdate() method with the columns and values to change

Deleting a record

To delete a single record call ContentResolverdelete() with the URI of a specific row

To delete multiple rows call ContentResolverdelete() with the URI of the type of record to delete (for

example androidproviderContactsPeopleCONTENT_URI) and an SQL WHERE clause defining

which rows to delete (Caution Be sure to include a valid WHERE clause if youre deleting a general

type or you risk deleting more records than you intended)

Creating a Content Provider

To create a content provider you must

Set up a system for storing the data Most content providers store their data using Androids file

storage methods or SQLite databases but you can store your data any way you want Android

provides the SQLiteOpenHelper class to help you create a database and SQLiteDatabase to manage

it

Extend the ContentProvider class to provide access to the data

Declare the content provider in the manifest file for your application (AndroidManifestxml)

The following sections have notes on the last two of these tasks

Extending the ContentProvider class

You define a ContentProvider subclass to expose your data to others using the conventions expected

by ContentResolver and Cursor objects Principally this means implementing six abstract methods

declared in the ContentProvider class

query()

insert()

update()

delete()

getType()

onCreate()

The query() method must return a Cursor object that can iterate over the requested data Cursor itself

is an interface but Android provides some ready-made Cursor objects that you can use For example

SQLiteCursor can iterate over data stored in an SQLite database You get the Cursor object by calling

any of the SQLiteDatabase classs query() methods There are other Cursor implementations mdash such

as MatrixCursor mdash for data not stored in a database

Because these ContentProvider methods can be called from various ContentResolver objects in

different processes and threads they must be implemented in a thread-safe manner

As a courtesy you might also want to call ContentResolvernotifyChange() to notify listeners when

there are modifications to the data

Beyond defining the subclass itself there are other steps you should take to simplify the work of clients

and make the class more accessible

Define a public static final Uri named CONTENT_URI This is the string that represents the full content

URI that your content provider handles You must define a unique string for this value The best

solution is to use the fully-qualified class name of the content provider (made lowercase) So for

example the URI for a TransportationProvider class could be defined as follows

public static final Uri CONTENT_URI = Uriparse(contentcomexamplecodelabtransportationprovider)

If the provider has subtables also define CONTENT_URI constants for each of the subtables These

URIs should all have the same authority (since that identifies the content provider) and be

distinguished only by their paths For example

contentcomexamplecodelabtransportationprovidertrain

contentcomexamplecodelabtransportationproviderairdomestic

contentcomexamplecodelabtransportationproviderairinternational

For an overview of content URIs see the Content URI Summary at the end of this document

Define the column names that the content provider will return to clients If you are using an underlying

database these column names are typically identical to the SQL database column names they

represent Also define public static String constants that clients can use to specify the columns in

queries and other instructions

Be sure to include an integer column named _id (with the constant _ID) for the IDs of the records

You should have this field whether or not you have another field (such as a URL) that is also unique

among all records If youre using the SQLite database the _ID field should be the following type

INTEGER PRIMARY KEY AUTOINCREMENT

The AUTOINCREMENT descriptor is optional But without it SQLite increments an ID counter field to

the next number above the largest existing number in the column If you delete the last row the next

row added will have the same ID as the deleted row AUTOINCREMENT avoids this by having SQLite

increment to the next largest value whether deleted or not

Carefully document the data type of each column Clients need this information to read the data

If you are handling a new data type you must define a new MIME type to return in your

implementation of ContentProvidergetType() The type depends in part on whether or not the content

URI submitted to getType() limits the request to a specific record Theres one form of the MIME type

for a single record and another for multiple records Use the Uri methods to help determine what is

being requested Here is the general format for each type

o For a single record vndandroidcursoritemvndyourcompanynamecontenttype

For example a request for train record 122 like this URI

contentcomexampletransportationprovidertrains122

might return this MIME type

vndandroidcursoritemvndexamplerail

o For multiple records vndandroidcursordirvndyourcompanynamecontenttype

For example a request for all train records like the following URI

contentcomexampletransportationprovidertrains

might return this MIME type

vndandroidcursordirvndexamplerail

If you are exposing byte data thats too big to put in the table itself mdash such as a large bitmap file mdash the

field that exposes the data to clients should actually contain a content URI string This is the field that

gives clients access to the data file The record should also have another field named _data that lists

the exact file path on the device for that file This field is not intended to be read by the client but by

the ContentResolver The client will call ContentResolveropenInputStream() on the user-facing field

holding the URI for the item The ContentResolver will request the _data field for that record and

because it has higher permissions than a client it should be able to access that file directly and return

a read wrapper for the file to the client

For an example of a private content provider implementation see the NodePadProvider class in the

Notepad sample application that ships with the SDK

Declaring the content provider

To let the Android system know about the content provider youve developed declare it with a

ltprovidergt element in the applications AndroidManifestxml file Content providers that are not

declared in the manifest are not visible to the Android system

The name attribute is the fully qualified name of the ContentProvider subclass The authorities attribute

is the authority part of the content URI that identifies the provider For example if the ContentProvider

subclass is AutoInfoProvider the ltprovidergt element might look like this

ltprovider androidname=comexampleautosAutoInfoProvider androidauthorities=comexampleautosautoinfoprovider gt ltprovidergt

Note that the authorities attribute omits the path part of a content URI For example if

AutoInfoProvider controlled subtables for different types of autos or different manufacturers

contentcomexampleautosautoinfoproviderhonda

contentcomexampleautosautoinfoprovidergmcompact

contentcomexampleautosautoinfoprovidergmsuv

those paths would not be declared in the manifest The authority is what identifies the provider not the

path your provider can interpret the path part of the URI in any way you choose

Other ltprovidergt attributes can set permissions to read and write data provide for an icon and text

that can be displayed to users enable and disable the provider and so on Set the multiprocess

attribute to true if data does not need to be synchronized between multiple running versions of the

content provider This permits an instance of the provider to be created in each client process

eliminating the need to perform IPC

Content URI Summary

Here is a recap of the important parts of a content URI

A Standard prefix indicating that the data is controlled by a content provider Its never modified

B The authority part of the URI it identifies the content provider For third-party applications this should

be a fully-qualified class name (reduced to lowercase) to ensure uniqueness The authority is declared

in the ltprovidergt elements authorities attribute

ltprovider androidname=TransportationProvider androidauthorities=comexampletransportationprovider gt

C The path that the content provider uses to determine what kind of data is being requested This can be

zero or more segments long If the content provider exposes only one type of data (only trains for

example) it can be absent If the provider exposes several types including subtypes it can be several

segments long mdash for example landbus landtrain seaship and seasubmarine to give four

possibilities

D The ID of the specific record being requested if any This is the _ID value of the requested record If

the request is not limited to a single record this segment and the trailing slash are omitted

contentcomexampletransportationprovidertrains

Intent and intent filters

Three of the core components of an application mdash activities services and broadcast receivers mdash 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 mdash 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 ContextstartActivity() or ActivitystartActivityForResult() to launch an

activity or get an existing activity to do something new (It can also be passed to ActivitysetResult() to

return information to the activity that called startActivityForResult())

An Intent object is passed to ContextstartService() to initiate a service or deliver new instructions to an

ongoing service Similarly an intent can be passed to ContextbindService() to establish a connection

between the calling component and a target service It can optionally initiate the service if its not

already running

Intent objects passed to any of the broadcast methods (such as ContextsendBroadcast()

ContextsendOrderedBroadcast() or ContextsendStickyBroadcast()) 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 mdash how it resolves which component should receive an intent message For

intents that dont explicitly name a target component this process involves testing the Intent object

against intent filters associated with potential targets

Intent Objects

An Intent object is a bundle of information It contains information of interest to the component that

receives the intent (such as the action to be taken and the data to act on) plus information of interest to

the Android system (such as the category of component that should handle the intent and instructions

on how to launch a target activity) Principally it can contain the following

Component name

The name of the component that should handle the intent This field is a ComponentName

object mdash a combination of the fully qualified class name of the target component (for example

comexampleprojectappFreneticActivity) and the package name set in the manifest file of the

application where the component resides (for example comexampleproject) The package

part of the component name and the package name set in the manifest do not necessarily have

to match

The component name is optional If it is set the Intent object is delivered to an instance of the

designated class If it is not set Android uses other information in the Intent object to locate a

suitable target mdash see Intent Resolution later in this document

The component name is set by setComponent() setClass() or setClassName() and read by

getComponent()

Action

A string naming the action to be performed mdash or in the case of broadcast intents the action

that took place and is being reported The Intent class defines a number of action constants

including these

Constant Target

component

Action

ACTION_CALL activity Initiate a phone call

ACTION_EDIT activity Display data for the user to edit

ACTION_MAIN activity Start up as the initial activity of a task

with no data input and no returned

output

ACTION_SYNC activity Synchronize data on a server with

data on the mobile device

ACTION_BATTERY_LOW broadcast

receiver

A warning that the battery is low

ACTION_HEADSET_PLUG broadcast

receiver

A headset has been plugged into the

device or unplugged from it

ACTION_SCREEN_ON broadcast

receiver

The screen has been turned on

ACTION_TIMEZONE_CHANGED broadcast

receiver

The setting for the time zone has

changed

See the Intent class description for a list of pre-defined constants for generic actions Other

actions are defined elsewhere in the Android API You can also define your own action strings

for activating the components in your application Those you invent should include the

application package as a prefix mdash for example comexampleprojectSHOW_COLOR

The action largely determines how the rest of the intent is structured mdash particularly the data and

extras fields mdash much as a method name determines a set of arguments and a return value For

this reason its a good idea to use action names that are as specific as possible and to couple

them tightly to the other fields of the intent In other words instead of defining an action in

isolation define an entire protocol for the Intent objects your components can handle

The action in an Intent object is set by the setAction() method and read by getAction()

Data

The URI of the data to be acted on and the MIME type of that data Different actions are paired

with different kinds of data specifications For example if the action field is ACTION_EDIT the

data field would contain the URI of the document to be displayed for editing If the action is

ACTION_CALL the data field would be a tel URI with the number to call Similarly if the action

is ACTION_VIEW and the data field is an http URI the receiving activity would be called upon

to download and display whatever data the URI refers to

When matching an intent to a component that is capable of handling the data its often

important to know the type of data (its MIME type) in addition to its URI For example a

component able to display image data should not be called upon to play an audio file

In many cases the data type can be inferred from the URI mdash particularly content URIs which

indicate that the data is located on the device and controlled by a content provider (see the

separate discussion on content providers) But the type can also be explicitly set in the Intent

object The setData() method specifies data only as a URI setType() specifies it only as a

MIME type and setDataAndType() specifies it as both a URI and a MIME type The URI is read

by getData() and the type by getType()

Category

A string containing additional information about the kind of component that should handle the

intent Any number of category descriptions can be placed in an Intent object As it does for

actions the Intent class defines several category constants including these

Constant Meaning

CATEGORY_BROWSABLE The target activity can be safely invoked by the browser to

display data referenced by a link mdash for example an image or

an e-mail message

CATEGORY_GADGET The activity can be embedded inside of another activity that

hosts gadgets

CATEGORY_HOME The activity displays the home screen the first screen the

user sees when the device is turned on or when the HOME

key is pressed

CATEGORY_LAUNCHER The activity can be the initial activity of a task and is listed in

the top-level application launcher

CATEGORY_PREFERENCE The target activity is a preference panel

See the Intent class description for the full list of categories

The addCategory() method places a category in an Intent object removeCategory() deletes a

category previously added and getCategories() gets the set of all categories currently in the

object

Extras

Key-value pairs for additional information that should be delivered to the component handling

the intent Just as some actions are paired with particular kinds of data URIs some are paired

with particular extras For example an ACTION_TIMEZONE_CHANGED intent has a time-

zone extra that identifies the new time zone and ACTION_HEADSET_PLUG has a state

extra indicating whether the headset is now plugged in or unplugged as well as a name extra

for the type of headset If you were to invent a SHOW_COLOR action the color value would be

set in an extra key-value pair

The Intent object has a series of put() methods for inserting various types of extra data and a

similar set of get() methods for reading the data These methods parallel those for Bundle

objects In fact the extras can be installed and read as a Bundle using the putExtras() and

getExtras() methods

Flags

Flags of various sorts Many instruct the Android system how to launch an activity (for example

which task the activity should belong to) and how to treat it after its launched (for example

whether it belongs in the list of recent activities) All these flags are defined in the Intent class

The Android system and the applications that come with the platform employ Intent objects both to

send out system-originated broadcasts and to activate system-defined components To see how to

structure an intent to activate a system component consult the list of intents in the reference

Intent Resolution

Intents can be divided into two groups

Explicit intents designate the target component by its name (the component name field mentioned

earlier has a value set) Since component names would generally not be known to developers of other

applications explicit intents are typically used for application-internal messages mdash such as an activity

starting a subordinate service or launching a sister activity

Implicit intents do not name a target (the field for the component name is blank) Implicit intents are

often used to activate components in other applications

Android delivers an explicit intent to an instance of the designated target class Nothing in the Intent

object other than the component name matters for determining which component should get the intent

A different strategy is needed for implicit intents In the absence of a designated target the Android

system must find the best component (or components) to handle the intent mdash a single activity or

service to perform the requested action or the set of broadcast receivers to respond to the broadcast

announcement It does so by comparing the contents of the Intent object to intent filters structures

associated with components that can potentially receive intents Filters advertise the capabilities of a

component and delimit the intents it can handle They open the component to the possibility of

receiving implicit intents of the advertised type If a component does not have any intent filters it can

receive only explicit intents A component with filters can receive both explicit and implicit intents

Only three aspects of an Intent object are consulted when the object is tested against an intent filter

action

data (both URI and data type)

category

The extras and flags play no part in resolving which component receives an intent

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 mdash but only unwanted implicit intents (those that dont 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

components 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 mdash 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 Pads filters are described in the Note Pad Example

section later)

Filters and security

An intent filter cannot be relied on for security While it opens a component to receiving only certain

kinds of implicit intents it does nothing to prevent explicit intents from targeting the component Even

though a filter restricts the intents a component will be asked to handle to certain actions and data

sources someone could always put together an explicit intent with a different action and data source

and name the component as the target

An intent filter is an instance of the IntentFilter class However since the Android system must know

about the capabilities of a component before it can launch that component intent filters are generally

not set up in Java code but in the applications manifest file (AndroidManifestxml) as ltintent-filtergt

elements (The one exception would be filters for broadcast receivers that are registered dynamically

by calling ContextregisterReceiver() they are directly created as IntentFilter objects)

A filter has fields that parallel the action data and category fields of an Intent object An implicit intent

is tested against the filter in all three areas To be delivered to the component that owns the filter it

must pass all three tests If it fails even one of them the Android system wont deliver it to the

component mdash at least not on the basis of that filter However since a component can have multiple

intent filters an intent that does not pass through one of a components filters might make it through on

another

Each of the three tests is described in detail below

Action test

An ltintent-filtergt element in the manifest file lists actions as ltactiongt subelements For

example

ltintent-filter gt ltaction androidname=comexampleprojectSHOW_CURRENT gt ltaction androidname=comexampleprojectSHOW_RECENT gt ltaction androidname=comexampleprojectSHOW_PENDING gt ltintent-filtergt

As the example shows while an Intent object names just a single action a filter may list more

than one The list cannot be empty a filter must contain at least one ltactiongt element or it will

block all intents

To pass this test the action specified in the Intent object must match one of the actions listed in

the filter If the object or the filter does not specify an action the results are as follows

If the filter fails to list any actions there is nothing for an intent to match so all intents fail the

test No intents can get through the filter

On the other hand an Intent object that doesnt specify an action automatically passes the test

mdash as long as the filter contains at least one action

Category test

An ltintent-filtergt element also lists categories as subelements For example

ltintent-filter gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryBROWSABLE gt ltintent-filtergt

Note that the constants described earlier for actions and categories are not used in the manifest

file The full string values are used instead For instance the

androidintentcategoryBROWSABLE string in the example above corresponds to the

CATEGORY_BROWSABLE constant mentioned earlier in this document Similarly the string

androidintentactionEDIT corresponds to the ACTION_EDIT constant

For an intent to pass the category test every category in the Intent object must match a

category in the filter The filter can list additional categories but it cannot omit any that are in the

intent

In principle therefore an Intent object with no categories should always pass this test

regardless of whats in the filter Thats mostly true However with one exception Android treats

all implicit intents passed to startActivity() as if they contained at least one category

androidintentcategoryDEFAULT (the CATEGORY_DEFAULT constant) Therefore activities

that are willing to receive implicit intents must include androidintentcategoryDEFAULT in

their intent filters (Filters with androidintentactionMAIN and

androidintentcategoryLAUNCHER settings are the exception They mark activities that begin

new tasks and that are represented on the launcher screen They can include

androidintentcategoryDEFAULT in the list of categories but dont need to) See Using intent

matching later for more on these filters)

Data test

Like the action and categories the data specification for an intent filter is contained in a

subelement And as in those cases the subelement can appear multiple times or not at all For

example

ltintent-filter gt ltdata androidmimeType=videompeg androidscheme=http gt ltdata androidmimeType=audiompeg androidscheme=http gt ltintent-filtergt

Each ltdatagt element can specify a URI and a data type (MIME media type) There are

separate attributes mdash scheme host port and path mdash for each part of the URI

schemehostportpath

For example in the following URI

contentcomexampleproject200foldersubfolderetc

the scheme is content the host is comexampleproject the port is 200 and the path is

foldersubfolderetc The host and port together constitute the URI authority if a host is not

specified the port is ignored

Each of these attributes is optional but they are not independent of each other For an authority

to be meaningful a scheme must also be specified For a path to be meaningful both a scheme

and an authority must be specified

When the URI in an Intent object is compared to a URI specification in a filter its compared

only to the parts of the URI actually mentioned in the filter For example if a filter specifies only

a scheme all URIs with that scheme match the filter If a filter specifies a scheme and an

authority but no path all URIs with the same scheme and authority match regardless of their

paths If a filter specifies a scheme an authority and a path only URIs with the same scheme

authority and path match However a path specification in the filter can contain wildcards to

require only a partial match of the path

The type attribute of a ltdatagt element specifies the MIME type of the data Its more common in

filters than a URI Both the Intent object and the filter can use a wildcard for the subtype field

mdash for example text or audio mdash indicating any subtype matches

The data test compares both the URI and the data type in the Intent object to a URI and data

type specified in the filter The rules are as follows

a An Intent object that contains neither a URI nor a data type passes the test only if the filter

likewise does not specify any URIs or data types

b An Intent object that contains a URI but no data type (and a type cannot be inferred from the

URI) passes the test only if its URI matches a URI in the filter and the filter likewise does not

specify a type This will be the case only for URIs like mailto and tel that do not refer to actual

data

c An Intent object that contains a data type but not a URI passes the test only if the filter lists the

same data type and similarly does not specify a URI

d An Intent object that contains both a URI and a data type (or a data type can be inferred from

the URI) passes the data type part of the test only if its type matches a type listed in the filter It

passes the URI part of the test either if its URI matches a URI in the filter or if it has a content

or file URI and the filter does not specify a URI In other words a component is presumed to

support content and file data if its filter lists only a data type

If an intent can pass through the filters of more than one activity or service the user may be asked

which component to activate An exception is raised if no target can be found

Common cases

The last rule shown above for the data test rule (d) reflects the expectation that components are able

to get local data from a file or content provider Therefore their filters can list just a data type and do

not need to explicitly name the content and file schemes This is a typical case A ltdatagt element like

the following for example tells Android that the component can get image data from a content

provider and display it

ltdata androidmimeType=image gt

Since most available data is dispensed by content providers filters that specify a data type but not a

URI are perhaps the most common

Another common configuration is filters with a scheme and a data type For example a ltdatagt

element like the following tells Android that the component can get video data from the network and

display it

ltdata androidscheme=http androidtype=video gt

Consider for example what the browser application does when the user follows a link on a web page

It first tries to display the data (as it could if the link was to an HTML page) If it cant display the data it

puts together an implicit intent with the scheme and data type and tries to start an activity that can do

the job If there are no takers it asks the download manager to download the data That puts it under

the control of a content provider so a potentially larger pool of activities (those with filters that just

name a data type) can respond

Most applications also have a way to start fresh without a reference to any particular data Activities

that can initiate applications have filters with androidintentactionMAIN specified as the action If

they are to be represented in the application launcher they also specify the

androidintentcategoryLAUNCHER category

ltintent-filter gt ltaction androidname=code androidintentactionMAIN gt ltcategory androidname=code androidintentcategoryLAUNCHER gt ltintent-filtergt

Using intent matching

Intents are matched against intent filters not only to discover a target component to activate but also

to discover something about the set of components on the device For example the Android system

populates the application launcher the top-level screen that shows the applications that are available

for the user to launch by finding all the activities with intent filters that specify the

androidintentactionMAIN action and androidintentcategoryLAUNCHER category (as illustrated

in the previous section) It then displays the icons and labels of those activities in the launcher

Similarly it discovers the home screen by looking for the activity with androidintentcategoryHOME

in its filter

Your application can use intent matching is a similar way The PackageManager has a set of query()

methods that return all components that can accept a particular intent and a similar series of

resolve() methods that determine the best component to respond to an intent For example

queryIntentActivities() returns a list of all activities that can perform the intent passed as an argument

and queryIntentServices() returns a similar list of services Neither method activates the components

they just list the ones that can respond Theres a similar method queryBroadcastReceivers() for

broadcast receivers

Note Pad Example

The Note Pad sample application enables users to browse through a list of notes view details about

individual items in the list edit the items and add a new item to the list This section looks at the intent

filters declared in its manifest file (If youre working offline in the SDK you can find all the source files

for this sample application including its manifest file at ltsdkgtsamplesNotePadindexhtml If youre

viewing the documentation online the source files are in the Tutorials and Sample Code section here)

In its manifest file the Note Pad application declares three activities each with at least one intent filter

It also declares a content provider that manages the note data Here is the manifest file in its entirety

ltmanifest xmlnsandroid=httpschemasandroidcomapkresandroid package=comexampleandroidnotepadgt ltapplication androidicon=drawableapp_notes androidlabel=stringapp_name gt ltprovider androidname=NotePadProvider androidauthorities=comgoogleproviderNotePad gt ltactivity androidname=NotesList androidlabel=stringtitle_notes_listgt ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltactivity androidname=NoteEditor androidtheme=androidstyleThemeLight androidlabel=stringtitle_note gt ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltactivitygt

ltactivity androidname=TitleEditor androidlabel=stringtitle_edit_title androidtheme=androidstyleThemeDialoggt ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltapplicationgt ltmanifestgt

The first activity NotesList is distinguished from the other activities by the fact that it operates on a

directory of notes (the note list) rather than on a single note It would generally serve as the initial user

interface into the application It can do three things as described by its three intent filters

1 ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt

This filter declares the main entry point into the Note Pad application The standard MAIN action is an

entry point that does not require any other information in the Intent (no data specification for example)

and the LAUNCHER category says that this entry point should be listed in the application launcher

2 ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

This filter declares the things that the activity can do on a directory of notes It can allow the user to

view or edit the directory (via the VIEW and EDIT actions) or to pick a particular note from the

directory (via the PICK action)

The mimeType attribute of the ltdatagt element specifies the kind of data that these actions operate on

It indicates that the activity can get a Cursor over zero or more items (vndandroidcursordir) from a

content provider that holds Note Pad data (vndgooglenote) The Intent object that launches the

activity would include a content URI specifying the exact data of this type that the activity should open

Note also the DEFAULT category supplied in this filter Its there because the ContextstartActivity()

and ActivitystartActivityForResult() methods treat all intents as if they contained the DEFAULT

category mdash with just two exceptions

o Intents that explicitly name the target activity

o Intents consisting of the MAIN action and LAUNCHER category

Therefore the DEFAULT category is required for all filters mdash except for those with the MAIN action

and LAUNCHER category (Intent filters are not consulted for explicit intents)

3 ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

This filter describes the activitys ability to return a note selected by the user without requiring any

specification of the directory the user should choose from The GET_CONTENT action is similar to the

PICK action In both cases the activity returns the URI for a note selected by the user (In each case

its returned to the activity that called startActivityForResult() to start the NoteList activity) Here

however the caller specifies the type of data desired instead of the directory of data the user will be

picking from

The data type vndandroidcursoritemvndgooglenote indicates the type of data the activity can

return mdash a URI for a single note From the returned URI the caller can get a Cursor for exactly one

item (vndandroidcursoritem) from the content provider that holds Note Pad data (vndgooglenote)

In other words for the PICK action in the previous filter the data type indicates the type of data the

activity could display to the user For the GET_CONTENT filter it indicates the type of data the activity

can return to the caller

Given these capabilities the following intents will resolve to the NotesList activity

action androidintentactionMAIN

Launches the activity with no data specified

action androidintentactionMAIN

category androidintentcategoryLAUNCHER

Launches the activity with no data selected specified This is the actual intent used by the

Launcher to populate its top-level list All activities with filters that match this action and

category are added to the list

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of all the notes under

contentcomgoogleproviderNotePadnotes The user can then browse through the list and

get information about the items in it

action androidintentactionPICK

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of the notes under

contentcomgoogleproviderNotePadnotes The user can then pick a note from the list and

the activity will return the URI for that item back to the activity that started the NoteList activity

action androidintentactionGET_CONTENT

data type vndandroidcursoritemvndgooglenote

Asks the activity to supply a single item of Note Pad data

The second activity NoteEditor shows users a single note entry and allows them to edit it It can do

two things as described by its two intent filters

1 ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The first primary purpose of this activity is to enable the user to interact with a single note ampmdash to

either VIEW the note or EDIT it (The EDIT_NOTE category is a synonym for EDIT) The intent would

contain the URI for data matching the MIME type vndandroidcursoritemvndgooglenote mdash that is

the URI for a single specific note It would typically be a URI that was returned by the PICK or

GET_CONTENT actions of the NoteList activity

As before this filter lists the DEFAULT category so that the activity can be launched by intents that

dont explicitly specify the NoteEditor class

2 ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

The secondary purpose of this activity is to enable the user to create a new note which it will INSERT

into an existing directory of notes The intent would contain the URI for data matching the MIME type

vndandroidcursordirvndgooglenote mdash that is the URI for the directory where the note should be

placed

Given these capabilities the following intents will resolve to the NoteEditor activity

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID (For details on how content

URIs specify individual members of a group see Content Providers)

action androidintentactionEDIT

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID and to let the user edit it If

the user saves the changes the activity updates the data for the note in the content provider

action androidintentactionINSERT

data contentcomgoogleproviderNotePadnotes

Asks the activity to create a new empty note in the notes list at

contentcomgoogleproviderNotePadnotes and allow the user to edit it If the user saves the

note its URI is returned to the caller

The last activity TitleEditor enables the user to edit the title of a note This could be implemented by

directly invoking the activity (by explicitly setting its component name in the Intent) without using an

intent filter But here we take the opportunity to show how to publish alternative operations on existing

data

ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The single intent filter for this activity uses a custom action called

comandroidnotepadactionEDIT_TITLE It must be invoked on a specific note (data type

vndandroidcursoritemvndgooglenote) like the previous VIEW and EDIT actions However here the

activity displays the title contained in the note data not the content of the note itself

In addition to supporting the usual DEFAULT category the title editor also supports two other standard

categories ALTERNATIVE and SELECTED_ALTERNATIVE These categories identify activities that

can be presented to users in a menu of options (much as the LAUNCHER category identifies activities

that should be presented to user in the application launcher) Note that the filter also supplies an

explicit label (via androidlabel=stringresolve_title) to better control what users see when

presented with this activity as an alternative action to the data they are currently viewing (For more

information on these categories and building options menus see the

PackageManagerqueryIntentActivityOptions() and MenuaddIntentOptions() methods)

Given these capabilities the following intent will resolve to the TitleEditor activity

action comandroidnotepadactionEDIT_TITLE

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the title associated with note ID and allow the user to edit the title

Processes and Threads

When an application component starts and the application does not have any other components

running the Android system starts a new Linux process for the application with a single thread of

execution By default all components of the same application run in the same process and thread

(called the main thread) If an application component starts and there already exists a process for

that application (because another component from the application exists) then the component is

started within that process and uses the same thread of execution However you can arrange for

different components in your application to run in separate processes and you can create additional

threads for any process

This document discusses how processes and threads work in an Android application

Processes

By default all components of the same application run in the same process and most applications

should not change this However if you find that you need to control which process a certain

component belongs to you can do so in the manifest file

The manifest entry for each type of component elementmdashltactivitygt ltservicegt ltreceivergt and

ltprovidergtmdashsupports an androidprocess attribute that can specify a process in which that component

should run You can set this attribute so that each component runs in its own process or so that some

components share a process while others do not You can also set androidprocess so that

components of different applications run in the same processmdashprovided that the applications share the

same Linux user ID and are signed with the same certificates

The ltapplicationgt element also supports an androidprocess attribute to set a default value that

applies to all components

Android might 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 thats killed are consequently destroyed A process is started again for those components

when theres again work for them to do

When deciding which processes to kill the Android system weighs their relative importance to the

user For example it more readily shuts down a process hosting activities that are no longer visible on

screen compared to a process hosting visible activities The decision whether to terminate a process

therefore depends on the state of the components running in that process The rules used to decide

which processes to terminate is discussed below

Process lifecycle

The Android system tries to maintain an application process for as long as possible but eventually

needs to remove old processes to reclaim memory for new or more important processes To determine

which processes to keep and which to kill the system places each process into an importance

hierarchy based on the components running in the process and the state of those components

Processes with the lowest importance are eliminated first then those with the next lowest importance

and so on as necessary to recover system resources

There are five levels in the importance hierarchy The following list presents the different types of

processes in order of importance (the first process is most important and is killed last)

1 Foreground process

A process that is required for what the user is currently doing A process is considered to be in the

foreground if any of the following conditions are true

o It hosts an Activity that the user is interacting with (the Activitys onResume() method has been called)

o It hosts a Service thats bound to the activity that the user is interacting with

o It hosts a Service thats running in the foregroundmdashthe service has called startForeground()

o It hosts a Service thats executing one of its lifecycle callbacks (onCreate() onStart() or onDestroy())

o It hosts a BroadcastReceiver thats executing its onReceive() method

Generally only a few foreground processes exist at any given time They are killed only as a last

resortmdashif memory is so low that they cannot all continue to run Generally at that point the device has

reached a memory paging state so killing some foreground processes is required to keep the user

interface responsive

2 Visible process

A process that doesnt have any foreground components but still can affect what the user sees on

screen A process is considered to be visible if either of the following conditions are true

o It hosts an Activity that is not in the foreground but is still visible to the user (its onPause() method has

been called) This might occur for example if the foreground activity started a dialog which allows the

previous activity to be seen behind it

o It hosts a Service thats bound to a visible (or foreground) activity

A visible process is considered extremely important and will not be killed unless doing so is required to

keep all foreground processes running

3 Service process

A process that is running a service that has been started with the startService() method and does not

fall into either of the two higher categories Although service processes are not directly tied to anything

the user sees they are generally doing things that the user cares about (such as playing music in the

background or downloading data on the network) so the system keeps them running unless theres

not enough memory to retain them along with all foreground and visible processes

4 Background process

A process holding an activity thats not currently visible to the user (the activitys onStop() method has

been called) These processes have no direct impact on the user experience and the system can kill

them at any time to reclaim memory for a foreground visible or service process Usually there are

many background processes running so they are kept in an LRU (least recently used) list to ensure

that the process with the activity that was most recently seen by the user is the last to be killed If an

activity implements its lifecycle methods correctly and saves its current state killing its process will not

have a visible effect on the user experience because when the user navigates back to the activity the

activity restores all of its visible state See the Activities document for information about saving and

restoring state

5 Empty process

A process that doesnt hold any active application components The only reason to keep this kind of

process alive is for caching purposes to improve startup time the next time a component needs to run

in it The system often kills these processes in order to balance overall system resources between

process caches and the underlying kernel caches

Android ranks a process at the highest level it can based upon the importance of the components

currently active in the process For example if a process hosts a service and a visible activity the

process is ranked as a visible process not a service process

In addition a processs ranking might be increased because other processes are dependent on itmdasha

process that is serving another process can never be ranked lower than the process it is serving For

example if a content provider in process A is serving a client in process B or if a service in process A

is bound to a component in process B process A is always considered at least as important as

process B

Because a process running a service is ranked higher than a process with background activities an

activity that initiates a long-running operation might do well to start a service for that operation rather

than simply create a worker threadmdashparticularly if the operation will likely outlast the activity For

example an activity thats uploading a picture to a web site should start a service to perform the

upload so that the upload can continue in the background even if the user leaves the activity Using a

service guarantees that the operation will have at least service process priority regardless of what

happens to the activity This is the same reason that broadcast receivers should employ services

rather than simply put time-consuming operations in a thread

Threads

When an application is launched the system creates a thread of execution for the application called

main This thread is very important because it is in charge of dispatching events to the appropriate

user interface widgets including drawing events It is also the thread in which your application interacts

with components from the Android UI toolkit (components from the androidwidget and androidview

packages) As such the main thread is also sometimes called the UI thread

The system does not create a separate thread for each instance of a component All components that

run in the same process are instantiated in the UI thread and system calls to each component are

dispatched from that thread Consequently methods that respond to system callbacks (such as

onKeyDown() to report user actions or a lifecycle callback method) always run in the UI thread of the

process

For instance when the user touches a button on the screen your apps UI thread dispatches the touch

event to the widget which in turn sets its pressed state and posts an invalidate request to the event

queue The UI thread dequeues the request and notifies the widget that it should redraw itself

When your app performs intensive work in response to user interaction this single thread model can

yield poor performance unless you implement your application properly Specifically if everything is

happening in the UI thread performing long operations such as network access or database queries

will block the whole UI When the thread is blocked no events can be dispatched including drawing

events From the users perspective the application appears to hang Even worse if the UI thread is

blocked for more than a few seconds (about 5 seconds currently) the user is presented with the

infamous application not responding (ANR) dialog The user might then decide to quit your

application and uninstall it if they are unhappy

Additionally the Andoid UI toolkit is not thread-safe So you must not manipulate your UI from a

worker threadmdashyou must do all manipulation to your user interface from the UI thread Thus there are

simply two rules to Androids single thread model

1 Do not block the UI thread

2 Do not access the Android UI toolkit from outside the UI thread

Worker threads

Because of the single thread model described above its vital to the responsiveness of your

applications UI that you do not block the UI thread If you have operations to perform that are not

instantaneous you should make sure to do them in separate threads (background or worker

threads)

For example below is some code for a click listener that downloads an image from a separate thread

and displays it in an ImageView

public void onClick(View v) new Thread(new Runnable() public void run() Bitmap b = loadImageFromNetwork(httpexamplecomimagepng) mImageViewsetImageBitmap(b) )start()

At first this seems to work fine because it creates a new thread to handle the network operation

However it violates the second rule of the single-threaded model do not access the Android UI toolkit

from outside the UI threadmdashthis sample modifies the ImageView from the worker thread instead of the

UI thread This can result in undefined and unexpected behavior which can be difficult and time-

consuming to track down

To fix this problem Android offers several ways to access the UI thread from other threads Here is a

list of methods that can help

ActivityrunOnUiThread(Runnable)

Viewpost(Runnable)

ViewpostDelayed(Runnable long)

For example you can fix the above code by using the Viewpost(Runnable) method

public void onClick(View v) new Thread(new Runnable() public void run() final Bitmap bitmap = loadImageFromNetwork(httpexamplecomimagepng) mImageViewpost(new Runnable() public void run() mImageViewsetImageBitmap(bitmap) ) )start()

Now this implementation is thread-safe the network operation is done from a separate thread while

the ImageView is manipulated from the UI thread

However as the complexity of the operation grows this kind of code can get complicated and difficult

to maintain To handle more complex interactions with a worker thread you might consider using a

Handler in your worker thread to process messages delivered from the UI thread Perhaps the best

solution though is to extend the AsyncTask class which simplifies the execution of worker thread

tasks that need to interact with the UI

Using AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface It performs the blocking

operations in a worker thread and then publishes the results on the UI thread without requiring you to

handle threads andor handlers yourself

To use it you must subclass AsyncTask and implement the doInBackground() callback method which

runs in a pool of background threads To update your UI you should implement onPostExecute()

which delivers the result from doInBackground() and runs in the UI thread so you can safely update

your UI You can then run the task by calling execute() from the UI thread

For example you can implement the previous example using AsyncTask this way

public void onClick(View v) new DownloadImageTask()execute(httpexamplecomimagepng) private class DownloadImageTask extends AsyncTaskltString Void Bitmapgt The system calls this to perform work in a worker thread and delivers it the parameters given to AsyncTaskexecute() protected Bitmap doInBackground(String urls) return loadImageFromNetwork(urls[0])

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 5: 03 services

down activity performance To avoid impacting application performance you should start a new

thread inside the service

Traditionally there are two classes you can extend to create a started service

Service

This is the base class for all services When you extend this class its important that you create

a new thread in which to do all the services work because the service uses your applications

main thread by default which could slow the performance of any activity your application is

running

IntentService

This is a subclass of Service that uses a worker thread to handle all start requests one at a

time This is the best option if you dont require that your service handle multiple requests

simultaneously All you need to do is implement onHandleIntent() which receives the intent for

each start request so you can do the background work

The following sections describe how you can implement your service using either one for these

classes

Extending the IntentService class

Because most started services dont need to handle multiple requests simultaneously (which can

actually be a dangerous multi-threading scenario) its probably best if you implement your service

using the IntentService class

The IntentService does the following

Creates a default worker thread that executes all intents delivered to onStartCommand() separate from

your applications main thread

Creates a work queue that passes one intent at a time to your onHandleIntent() implementation so

you never have to worry about multi-threading

Stops the service after all start requests have been handled so you never have to call stopSelf()

Provides default implementation of onBind() that returns null

Provides a default implementation of onStartCommand() that sends the intent to the work queue and

then to your onHandleIntent() implementation

All this adds up to the fact that all you need to do is implement onHandleIntent() to do the work

provided by the client (Though you also need to provide a small constructor for the service)

Heres an example implementation of IntentService

public class HelloIntentService extends IntentService A constructor is required and must call the super IntentService(String)

constructor with a name for the worker thread public HelloIntentService() super(HelloIntentService) The IntentService calls this method from the default worker thread with the intent that started the service When this method returns IntentService stops the service as appropriate Override protected void onHandleIntent(Intent intent) Normally we would do some work here like download a file For our sample we just sleep for 5 seconds long endTime = SystemcurrentTimeMillis() + 51000 while (SystemcurrentTimeMillis() lt endTime) synchronized (this) try wait(endTime - SystemcurrentTimeMillis()) catch (Exception e)

Thats all you need a constructor and an implementation of onHandleIntent()

If you decide to also override other callback methods such as onCreate() onStartCommand() or

onDestroy() be sure to call the super implementation so that the IntentService can properly handle

the life of the worker thread

For example onStartCommand() must return the default implementation (which is how the intent gets

delivered to onHandleIntent())

Override public int onStartCommand(Intent intent int flags int startId) ToastmakeText(this service starting ToastLENGTH_SHORT)show() return superonStartCommand(intentflagsstartId)

Besides onHandleIntent() the only method from which you dont need to call the super class is

onBind() (but you only need to implement that if your service allows binding)

In the next section youll see how the same kind of service is implemented when extending the base

Service class which is a lot more code but which might be appropriate if you need to handle

simultaneous start requests

Extending the Service class

As you saw in the previous section using IntentService makes your implementation of a started

service very simple If however you require your service to perform multi-threading (instead of

processing start requests through a work queue) then you can extend the Service class to handle

each intent

For comparison the following example code is an implementation of the Service class that performs

the exact same work as the example above using IntentService That is for each start request it uses

a worker thread to perform the job and processes only one request at a time

public class HelloService extends Service private Looper mServiceLooper private ServiceHandler mServiceHandler Handler that receives messages from the thread private final class ServiceHandler extends Handler public ServiceHandler(Looper looper) super(looper) Override public void handleMessage(Message msg) Normally we would do some work here like download a file For our sample we just sleep for 5 seconds long endTime = SystemcurrentTimeMillis() + 51000 while (SystemcurrentTimeMillis() lt endTime) synchronized (this) try wait(endTime - SystemcurrentTimeMillis()) catch (Exception e) Stop the service using the startId so that we dont stop the service in the middle of handling another job stopSelf(msgarg1) Override public void onCreate() Start up the thread running the service Note that we create a separate thread because the service normally runs in the processs main thread which we dont want to block We also make it background priority so CPU-intensive work will not disrupt our UI HandlerThread thread = new HandlerThread(ServiceStartArguments ProcessTHREAD_PRIORITY_BACKGROUND) threadstart() Get the HandlerThreads Looper and use it for our Handler

mServiceLooper = threadgetLooper() mServiceHandler = new ServiceHandler(mServiceLooper) Override public int onStartCommand(Intent intent int flags int startId) ToastmakeText(this service starting ToastLENGTH_SHORT)show() For each start request send a message to start a job and deliver the start ID so we know which request were stopping when we finish the job Message msg = mServiceHandlerobtainMessage() msgarg1 = startId mServiceHandlersendMessage(msg) If we get killed after returning from here restart return START_STICKY Override public IBinder onBind(Intent intent) We dont provide binding so return null return null Override public void onDestroy() ToastmakeText(this service done ToastLENGTH_SHORT)show()

As you can see its a lot more work than using IntentService

However because you handle each call to onStartCommand() yourself you can perform multiple

requests simultaneously Thats not what this example does but if thats what you want then you can

create a new thread for each request and run them right away (instead of waiting for the previous

request to finish)

Notice that the onStartCommand() method must return an integer The integer is a value that

describes how the system should continue the service in the event that the system kills it (as

discussed above the default implementation for IntentService handles this for you though you are

able to modify it) The return value from onStartCommand() must be one of the following constants

START_NOT_STICKY

If the system kills the service after onStartCommand() returns do not recreate the service

unless there are pending intents to deliver This is the safest option to avoid running your

service when not necessary and when your application can simply restart any unfinished jobs

START_STICKY

If the system kills the service after onStartCommand() returns recreate the service and call

onStartCommand() but do not redeliver the last intent Instead the system calls

onStartCommand() with a null intent unless there were pending intents to start the service in

which case those intents are delivered This is suitable for media players (or similar services)

that are not executing commands but running indefinitely and waiting for a job

START_REDELIVER_INTENT

If the system kills the service after onStartCommand() returns recreate the service and call

onStartCommand() with the last intent that was delivered to the service Any pending intents are

delivered in turn This is suitable for services that are actively performing a job that should be

immediately resumed such as downloading a file

For more details about these return values see the linked reference documentation for each constant

Starting a Service

You can start a service from an activity or other application component by passing an Intent (specifying

the service to start) to startService() The Android system calls the services onStartCommand()

method and passes it the Intent (You should never call onStartCommand() directly)

For example an activity can start the example service in the previous section (HelloSevice) using an

explicit intent with startService()

Intent intent = new Intent(this HelloServiceclass) startService(intent)

The startService() method returns immediately and the Android system calls the services

onStartCommand() method If the service is not already running the system first calls onCreate() then

calls onStartCommand()

If the service does not also provide binding the intent delivered with startService() is the only mode of

communication between the application component and the service However if you want the service

to send a result back then the client that starts the service can create a PendingIntent for a broadcast

(with getBroadcast()) and deliver it to the service in the Intent that starts the service The service can

then use the broadcast to deliver a result

Multiple requests to start the service result in multiple corresponding calls to the services

onStartCommand() However only one request to stop the service (with stopSelf() or stopService()) is

required to stop it

Stopping a service

A started service must manage its own lifecycle That is the system does not stop or destroy the

service unless it must recover system memory and the service continues to run after

onStartCommand() returns So the service must stop itself by calling stopSelf() or another component

can stop it by calling stopService()

Once requested to stop with stopSelf() or stopService() the system destroys the service as soon as

possible

However if your service handles multiple requests to onStartCommand() concurrently then you

shouldnt stop the service when youre done processing a start request because you might have since

received a new start request (stopping at the end of the first request would terminate the second one)

To avoid this problem you can use stopSelf(int) to ensure that your request to stop the service is

always based on the most recent start request That is when you call stopSelf(int) you pass the ID of

the start request (the startId delivered to onStartCommand()) to which your stop request corresponds

Then if the service received a new start request before you were able to call stopSelf(int) then the ID

will not match and the service will not stop

Caution Its important that your application stops its services when its done working to avoid

wasting system resources and consuming battery power If necessary other components can stop

the service by calling stopService() Even if you enable binding for the service you must always

stop the service yourself if it ever received a call to onStartCommand()

For more information about the lifecycle of a service see the section below about Managing the

Lifecycle of a Service

Creating a Bound Service

A bound service is one that allows application components to bind to it by calling bindService() in order

to create a long-standing connection (and generally does not allow components to start it by calling

startService())

You should create a bound service when you want to interact with the service from activities and other

components in your application or to expose some of your applications functionality to other

applications through interprocess communication (IPC)

To create a bound service you must implement the onBind() callback method to return an IBinder that

defines the interface for communication with the service Other application components can then call

bindService() to retrieve the interface and begin calling methods on the service The service lives only

to serve the application component that is bound to it so when there are no components bound to the

service the system destroys it (you do not need to stop a bound service in the way you must when the

service is started through onStartCommand())

To create a bound service the first thing you must do is define the interface that specifies how a client

can communicate with the service This interface between the service and a client must be an

implementation of IBinder and is what your service must return from the onBind() callback method

Once the client receives the IBinder it can begin interacting with the service through that interface

Multiple clients can bind to the service at once When a client is done interacting with the service it

calls unbindService() to unbind Once there are no clients bound to the service the system destroys

the service

There are multiple ways to implement a bound service and the implementation is more complicated

than a started service so the bound service discussion appears in a separate document about Bound

Services

Sending Notifications to the User

Once running a service can notify the user of events using Toast Notifications or Status Bar

Notifications

A toast notification is a message that appears on the surface of the current window for a moment then

disappears while a status bar notification provides an icon in the status bar with a message which the

user can select in order to take an action (such as start an activity)

Usually a status bar notification is the best technique when some background work has completed

(such as a file completed downloading) and the user can now act on it When the user selects the

notification from the expanded view the notification can start an activity (such as to view the

downloaded file)

See the Toast Notifications or Status Bar Notifications developer guides for more information

Running a Service in the Foreground

A foreground service is a service thats considered to be something the user is actively aware of and

thus not a candidate for the system to kill when low on memory A foreground service must provide a

notification for the status bar which is placed under the Ongoing heading which means that the

notification cannot be dismissed unless the service is either stopped or removed from the foreground

For example a music player that plays music from a service should be set to run in the foreground

because the user is explicitly aware of its operation The notification in the status bar might indicate the

current song and allow the user to launch an activity to interact with the music player

To request that your service run in the foreground call startForeground() This method takes two

parameters an integer that uniquely identifies the notification and the Notification for the status bar

For example

Notification notification = new Notification(Rdrawableicon getText(Rstringticker_text) SystemcurrentTimeMillis()) Intent notificationIntent = new Intent(this ExampleActivityclass) PendingIntent pendingIntent = PendingIntentgetActivity(this 0 notificationIntent 0) notificationsetLatestEventInfo(this getText(Rstringnotification_title) getText(Rstringnotification_message) pendingIntent) startForeground(ONGOING_NOTIFICATION notification)

To remove the service from the foreground call stopForeground() This method takes a boolean

indicating whether to remove the status bar notification as well This method does not stop the service

However if you stop the service while its still running in the foreground then the notification is also

removed

Note The methods startForeground() and stopForeground() were introduced in Android 20 (API

Level 5) In order to run your service in the foreground on older versions of the platform you must

use the previous setForeground() methodmdashsee the startForeground() documentation for

information about how to provide backward compatibility

For more information about notifications see Creating Status Bar Notifications

Managing the Lifecycle of a Service

The lifecycle of a service is much simpler than that of an activity However its even more important

that you pay close attention to how your service is created and destroyed because a service can run

in the background without the user being aware

The service lifecyclemdashfrom when its created to when its destroyedmdashcan follow two different paths

A started service

The service is created when another component calls startService() The service then runs indefinitely

and must stop itself by calling stopSelf() Another component can also stop the service by calling

stopService() When the service is stopped the system destroys it

A bound service

The service is created when another component (a client) calls bindService() The client then

communicates with the service through an IBinder interface The client can close the connection by

calling unbindService() Multiple clients can bind to the same service and when all of them unbind the

system destroys the service (The service does not need to stop itself)

These two paths are not entirely separate That is you can bind to a service that was already started

with startService() For example a background music service could be started by calling startService()

with an Intent that identifies the music to play Later possibly when the user wants to exercise some

control over the player or get information about the current song an activity can bind to the service by

calling bindService() In cases like this stopService() or stopSelf() does not actually stop the service

until all clients unbind

Implementing the lifecycle callbacks

Like an activity a service has lifecycle callback methods that you can implement to monitor changes in

the services state and perform work at the appropriate times The following skeleton service

demonstrates each of the lifecycle methods

Figure 2 The service lifecycle The diagram on the left shows the lifecycle when the service is created

with startService() and the diagram on the right shows the lifecycle when the service is created with

bindService()

public class ExampleService extends Service int mStartMode indicates how to behave if the service is killed IBinder mBinder interface for clients that bind boolean mAllowRebind indicates whether onRebind should be used Override public void onCreate() The service is being created Override public int onStartCommand(Intent intent int flags int startId) The service is starting due to a call to startService() return mStartMode Override public IBinder onBind(Intent intent) A client is binding to the service with bindService() return mBinder Override public boolean onUnbind(Intent intent) All clients have unbound with unbindService()

return mAllowRebind Override public void onRebind(Intent intent) A client is binding to the service with bindService() after onUnbind() has already been called Override public void onDestroy() The service is no longer used and is being destroyed

Note Unlike the activity lifecycle callback methods you are not required to call the superclass

implementation of these callback methods

By implementing these methods you can monitor two nested loops of the services lifecycle

The entire lifetime of a service happens between the time onCreate() is called and the time

onDestroy() returns Like an activity a service does its initial setup in onCreate() and releases all

remaining resources in onDestroy() For example a music playback service could create the thread

where the music will be played in onCreate() then stop the thread in onDestroy()

The onCreate() and onDestroy() methods are called for all services whether theyre created by

startService() or bindService()

The active lifetime of a service begins with a call to either onStartCommand() or onBind() Each

method is handed the Intent that was passed to either startService() or bindService() respectively

If the service is started the active lifetime ends the same time that the entire lifetime ends (the service

is still active even after onStartCommand() returns) If the service is bound the active lifetime ends

when onUnbind() returns

Note Although a started service is stopped by a call to either stopSelf() or stopService() there is

not a respective callback for the service (theres no onStop() callback) So unless the service is

bound to a client the system destroys it when the service is stoppedmdashonDestroy() is the only

callback received

Figure 2 illustrates the typical callback methods for a service Although the figure separates services

that are created by startService() from those created by bindService() keep in mind that any service

no matter how its started can potentially allow clients to bind to it So a service that was initially

started with onStartCommand() (by a client calling startService()) can still receive a call to onBind()

(when a client calls bindService())

For more information about creating a service that provides binding see the Bound Services

document which includes more information about the onRebind() callback method in the section about

Managing the Lifecycle of a Bound Service

Bound Services

A bound service is the server in a client-server interface A bound service allows components (such as

activities) to bind to the service send requests receive responses and even perform interprocess

communication (IPC) A bound service typically lives only while it serves another application

component and does not run in the background indefinitely

This document shows you how to create a bound service including how to bind to the service from

other application components However you should also refer to the Services document for additional

information about services in general such as how to deliver notifications from a service set the

service to run in the foreground and more

The Basics

A bound service is an implementation of the Service class that allows other applications to bind to it

and interact with it To provide binding for a service you must implement the onBind() callback

method This method returns an IBinder object that defines the programming interface that clients can

use to interact with the service

Binding to a Started Service

As discussed in the Services document you can create a service that is both started and bound That

is the service can be started by calling startService() which allows the service to run indefinitely and

also allow a client to bind to the service by calling bindService()

If you do allow your service to be started and bound then when the service has been started the

system does not destroy the service when all clients unbind Instead you must explicitly stop the

service by calling stopSelf() or stopService()

Although you should usually implement either onBind() or onStartCommand() its sometimes

necessary to implement both For example a music player might find it useful to allow its service to run

indefinitely and also provide binding This way an activity can start the service to play some music and

the music continues to play even if the user leaves the application Then when the user returns to the

application the activity can bind to the service to regain control of playback

Be sure to read the section about Managing the Lifecycle of a Bound Service for more information

about the service lifecycle when adding binding to a started service

A client can bind to the service by calling bindService() When it does it must provide an

implementation of ServiceConnection which monitors the connection with the service The

bindService() method returns immediately without a value but when the Android system creates the

connection between the client and service it calls onServiceConnected() on the ServiceConnection to

deliver the IBinder that the client can use to communicate with the service

Multiple clients can connect to the service at once However the system calls your services onBind()

method to retrieve the IBinder only when the first client binds The system then delivers the same

IBinder to any additional clients that bind without calling onBind() again

When the last client unbinds from the service the system destroys the service (unless the service was

also started by startService())

When you implement your bound service the most important part is defining the interface that your

onBind() callback method returns There are a few different ways you can define your services IBinder

interface and the following section discusses each technique

Creating a Bound Service

When creating a service that provides binding you must provide an IBinder that provides the

programming interface that clients can use to interact with the service There are three ways you can

define the interface

Extending the Binder class

If your service is private to your own application and runs in the same process as the client

(which is common) you should create your interface by extending the Binder class and

returning an instance of it from onBind() The client receives the Binder and can use it to directly

access public methods available in either the Binder implementation or even the Service

This is the preferred technique when your service is merely a background worker for your own

application The only reason you would not create your interface this way is because your

service is used by other applications or across separate processes

Using a Messenger

If you need your interface to work across different processes you can create an interface for the

service with a Messenger In this manner the service defines a Handler that responds to

different types of Message objects This Handler is the basis for a Messenger that can then

share an IBinder with the client allowing the client to send commands to the service using

Message objects Additionally the client can define a Messenger of its own so the service can

send messages back

This is the simplest way to perform interprocess communication (IPC) because the Messenger

queues all requests into a single thread so that you dont have to design your service to be

thread-safe

Using AIDL

AIDL (Android Interface Definition Language) performs all the work to decompose objects into

primitives that the operating system can understand and marshall them across processes to

perform IPC The previous technique using a Messenger is actually based on AIDL as its

underlying structure As mentioned above the Messenger creates a queue of all the client

requests in a single thread so the service receives requests one at a time If however you

want your service to handle multiple requests simultaneously then you can use AIDL directly In

this case your service must be capable of multi-threading and be built thread-safe

To use AIDL directly you must create an aidl file that defines the programming interface The

Android SDK tools use this file to generate an abstract class that implements the interface and

handles IPC which you can then extend within your service

Note Most applications should not use AIDL to create a bound service because it may require

multithreading capabilities and can result in a more complicated implementation As such AIDL is

not suitable for most applications and this document does not discuss how to use it for your

service If youre certain that you need to use AIDL directly see the AIDL document

Extending the Binder class

If your service is used only by the local application and does not need to work across processes then

you can implement your own Binder class that provides your client direct access to public methods in

the service

Note This works only if the client and service are in the same application and process which is

most common For example this would work well for a music application that needs to bind an

activity to its own service thats playing music in the background

Heres how to set it up

1 In your service create an instance of Binder that either

o contains public methods that the client can call

o returns the current Service instance which has public methods the client can call

o or returns an instance of another class hosted by the service with public methods the client can call

2 Return this instance of Binder from the onBind() callback method

3 In the client receive the Binder from the onServiceConnected() callback method and make calls to the

bound service using the methods provided

Note The reason the service and client must be in the same application is so the client can cast

the returned object and properly call its APIs The service and client must also be in the same

process because this technique does not perform any marshalling across processes

For example heres a service that provides clients access to methods in the service through a Binder

implementation

public class LocalService extends Service

Binder given to clients

private final IBinder mBinder = new LocalBinder()

Random number generator

private final Random mGenerator = new Random()

Class used for the client Binder Because we know this service always

runs in the same process as its clients we dont need to deal with IPC

public class LocalBinder extends Binder

LocalService getService()

Return this instance of LocalService so clients can call public methods

return LocalServicethis

Override

public IBinder onBind(Intent intent)

return mBinder

method for clients

public int getRandomNumber()

return mGeneratornextInt(100)

The LocalBinder provides the getService() method for clients to retrieve the current instance of

LocalService This allows clients to call public methods in the service For example clients can call

getRandomNumber() from the service

Heres an activity that binds to LocalService and calls getRandomNumber() when a button is clicked

public class BindingActivity extends Activity

LocalService mService

boolean mBound = false

Override

protected void onCreate(Bundle savedInstanceState)

superonCreate(savedInstanceState)

setContentView(Rlayoutmain)

Override

protected void onStart()

superonStart()

Bind to LocalService

Intent intent = new Intent(this LocalServiceclass)

bindService(intent mConnection ContextBIND_AUTO_CREATE)

Override

protected void onStop()

superonStop()

Unbind from the service

if (mBound)

unbindService(mConnection)

mBound = false

Called when a button is clicked (the button in the layout file attaches to

this method with the androidonClick attribute)

public void onButtonClick(View v)

if (mBound)

Call a method from the LocalService

However if this call were something that might hang then this request should

occur in a separate thread to avoid slowing down the activity performance

int num = mServicegetRandomNumber()

ToastmakeText(this number + num ToastLENGTH_SHORT)show()

Defines callbacks for service binding passed to bindService()

private ServiceConnection mConnection = new ServiceConnection()

Override

public void onServiceConnected(ComponentName className

IBinder service)

Weve bound to LocalService cast the IBinder and get LocalService instance

LocalBinder binder = (LocalBinder) service

mService = bindergetService()

mBound = true

Override

public void onServiceDisconnected(ComponentName arg0)

mBound = false

The above sample shows how the client binds to the service using an implementation of

ServiceConnection and the onServiceConnected() callback The next section provides more

information about this process of binding to the service

Note The example above doesnt explicitly unbind from the service but all clients should unbind

at an appropriate time (such as when the activity pauses)

For more sample code see the LocalServicejava class and the LocalServiceActivitiesjava class in

ApiDemos

Using a Messenger

Compared to AIDL

When you need to perform IPC using a Messenger for your interface is simpler than implementing it

with AIDL because Messenger queues all calls to the service whereas a pure AIDL interface sends

simultaneous requests to the service which must then handle multi-threading

For most applications the service doesnt need to perform multi-threading so using a Messenger

allows the service to handle one call at a time If its important that your service be multi-threaded then

you should use AIDL to define your interface

If you need your service to communicate with remote processes then you can use a Messenger to

provide the interface for your service This technique allows you to perform interprocess

communication (IPC) without the need to use AIDL

Heres a summary of how to use a Messenger

The service implements a Handler that receives a callback for each call from a client

The Handler is used to create a Messenger object (which is a reference to the Handler)

The Messenger creates an IBinder that the service returns to clients from onBind()

Clients use the IBinder to instantiate the Messenger (that references the services Handler) which the

client uses to send Message objects to the service

The service receives each Message in its Handlermdashspecifically in the handleMessage() method

In this way there are no methods for the client to call on the service Instead the client delivers

messages (Message objects) that the service receives in its Handler

Heres a simple example service that uses a Messenger interface

public class MessengerService extends Service Command to the service to display a message static final int MSG_SAY_HELLO = 1 Handler of incoming messages from clients class IncomingHandler extends Handler Override public void handleMessage(Message msg) switch (msgwhat) case MSG_SAY_HELLO ToastmakeText(getApplicationContext() hello ToastLENGTH_SHORT)show() break default superhandleMessage(msg) Target we publish for clients to send messages to IncomingHandler final Messenger mMessenger = new Messenger(new IncomingHandler()) When binding to the service we return an interface to our messenger for sending messages to the service Override public IBinder onBind(Intent intent) ToastmakeText(getApplicationContext() binding ToastLENGTH_SHORT)show() return mMessengergetBinder()

Notice that the handleMessage() method in the Handler is where the service receives the incoming

Message and decides what to do based on the what member

All that a client needs to do is create a Messenger based on the IBinder returned by the service and

send a message using send() For example heres a simple activity that binds to the service and

delivers the MSG_SAY_HELLO message to the service

public class ActivityMessenger extends Activity Messenger for communicating with the service Messenger mService = null Flag indicating whether we have called bind on the service boolean mBound Class for interacting with the main interface of the service private ServiceConnection mConnection = new ServiceConnection() public void onServiceConnected(ComponentName className IBinder service) This is called when the connection with the service has been established giving us the object we can use to interact with the service We are communicating with the service using a Messenger so here we get a client-side representation of that from the raw IBinder object mService = new Messenger(service) mBound = true public void onServiceDisconnected(ComponentName className) This is called when the connection with the service has been unexpectedly disconnected -- that is its process crashed mService = null mBound = false public void sayHello(View v) if (mBound) return Create and send a message to the service using a supported what value Message msg = Messageobtain(null MessengerServiceMSG_SAY_HELLO 0 0) try mServicesend(msg) catch (RemoteException e) eprintStackTrace() Override protected void onCreate(Bundle savedInstanceState) superonCreate(savedInstanceState) setContentView(Rlayoutmain)

Override protected void onStart() superonStart() Bind to the service bindService(new Intent(this MessengerServiceclass) mConnection ContextBIND_AUTO_CREATE) Override protected void onStop() superonStop() Unbind from the service if (mBound) unbindService(mConnection) mBound = false

Notice that this example does not show how the service can respond to the client If you want the

service to respond then you need to also create a Messenger in the client Then when the client

receives the onServiceConnected() callback it sends a Message to the service that includes the

clients Messenger in the replyTo parameter of the send() method

You can see an example of how to provide two-way messaging in the MessengerServicejava (service)

and MessengerServiceActivitiesjava (client) samples

Binding to a Service

Application components (clients) can bind to a service by calling bindService() The Android system

then calls the services onBind() method which returns an IBinder for interacting with the service

The binding is asynchronous bindService() returns immediately and does not return the IBinder to the

client To receive the IBinder the client must create an instance of ServiceConnection and pass it to

bindService() The ServiceConnection includes a callback method that the system calls to deliver the

IBinder

Note Only activities services and content providers can bind to a servicemdashyou cannot bind to a

service from a broadcast receiver

So to bind to a service from your client you must

1 Implement ServiceConnection

Your implementation must override two callback methods

onServiceConnected()

The system calls this to deliver the IBinder returned by the services onBind() method

onServiceDisconnected()

The Android system calls this when the connection to the service is unexpectedly lost such as

when the service has crashed or has been killed This is not called when the client unbinds

2 Call bindService() passing the ServiceConnection implementation

3 When the system calls your onServiceConnected() callback method you can begin making calls to the

service using the methods defined by the interface

4 To disconnect from the service call unbindService()

When your client is destroyed it will unbind from the service but you should always unbind when

youre done interacting with the service or when your activity pauses so that the service can shutdown

while its not being used (Appropriate times to bind and unbind is discussed more below)

For example the following snippet connects the client to the service created above by extending the

Binder class so all it must do is cast the returned IBinder to the LocalService class and request the

LocalService instance

LocalService mService private ServiceConnection mConnection = new ServiceConnection() Called when the connection with the service is established public void onServiceConnected(ComponentName className IBinder service) Because we have bound to an explicit service that is running in our own process we can cast its IBinder to a concrete class and directly access it LocalBinder binder = (LocalBinder) service mService = bindergetService() mBound = true Called when the connection with the service disconnects unexpectedly public void onServiceDisconnected(ComponentName className) Loge(TAG onServiceDisconnected) mBound = false

With this ServiceConnection the client can bind to a service by passing this it to bindService() For

example

Intent intent = new Intent(this LocalServiceclass) bindService(intent mConnection ContextBIND_AUTO_CREATE)

The first parameter of bindService() is an Intent that explicitly names the service to bind (thought the

intent could be implicit)

The second parameter is the ServiceConnection object

The third parameter is a flag indicating options for the binding It should usually be

BIND_AUTO_CREATE in order to create the service if its not already alive Other possible values are

BIND_DEBUG_UNBIND and BIND_NOT_FOREGROUND or 0 for none

Additional notes

Here are some important notes about binding to a service

You should always trap DeadObjectException exceptions which are thrown when the connection has

broken This is the only exception thrown by remote methods

Objects are reference counted across processes

You should usually pair the binding and unbinding during matching bring-up and tear-down moments

of the clients lifecycle For example

o If you only need to interact with the service while your activity is visible you should bind during

onStart() and unbind during onStop()

o If you want your activity to receive responses even while it is stopped in the background then you can

bind during onCreate() and unbind during onDestroy() Beware that this implies that your activity needs

to use the service the entire time its running (even in the background) so if the service is in another

process then you increase the weight of the process and it becomes more likely that the system will

kill it

Note You should usually not bind and unbind during your activitys onResume() and onPause()

because these callbacks occur at every lifecycle transition and you should keep the processing that

occurs at these transitions to a minimum Also if multiple activities in your application bind to the same

service and there is a transition between two of those activities the service may be destroyed and

recreated as the current activity unbinds (during pause) before the next one binds (during resume)

(This activity transition for how activities coordinate their lifecycles is described in the Activities

document)

For more sample code showing how to bind to a service see the RemoteServicejava class in

ApiDemos

Managing the Lifecycle of a Bound Service

Figure 1 The lifecycle for a service

that is started and also allows binding

When a service is unbound from all

clients the Android system destroys it

(unless it was also started with

onStartCommand()) As such you

dont have to manage the lifecycle of

your service if its purely a bound

servicemdashthe Android system manages

it for you based on whether it is bound

to any clients

However if you choose to implement

the onStartCommand() callback

method then you must explicitly stop

the service because the service is

now considered to be started In this

case the service runs until the service

stops itself with stopSelf() or another

component calls stopService()

regardless of whether it is bound to

any clients

Additionally if your service is started and accepts binding then when the system calls your onUnbind()

method you can optionally return true if you would like to receive a call to onRebind() the next time a

client binds to the service (instead of receiving a call to onBind()) onRebind() returns void but the

client still receives the IBinder in its onServiceConnected() callback Below figure 1 illustrates the logic

for this kind of lifecycle

For more information about the lifecycle of an started service see the Services document

Content Providers

Content providers store and retrieve data and make it accessible to all applications Theyre the only

way to share data across applications theres no common storage area that all Android packages can

access

Android ships with a number of content providers for common data types (audio video images

personal contact information and so on) You can see some of them listed in the androidprovider

package You can query these providers for the data they contain (although for some you must

acquire the proper permission to read the data)

If you want to make your own data public you have two options You can create your own content

provider (a ContentProvider subclass) or you can add the data to an existing provider mdash if theres one

that controls the same type of data and you have permission to write to it

This document is an introduction to using content providers After a brief discussion of the

fundamentals it explores how to query a content provider how to modify data controlled by a provider

and how to create a content provider of your own

Content Provider Basics

How a content provider actually stores its data under the covers is up to its designer But all content

providers implement a common interface for querying the provider and returning results mdash as well as

for adding altering and deleting data Its an interface that clients use indirectly most generally

through ContentResolver objects You get a ContentResolver by calling getContentResolver() from

within the implementation of an Activity or other application component

ContentResolver cr = getContentResolver()

You can then use the ContentResolvers methods to interact with whatever content providers youre

interested in When a query is initiated the Android system identifies the content provider thats the

target of the query and makes sure that it is up and running The system instantiates all

ContentProvider objects you never need to do it on your own In fact you never deal directly with

ContentProvider objects at all Typically theres just a single instance of each type of ContentProvider

But it can communicate with multiple ContentResolver objects in different applications and processes

The interaction between processes is handled by the ContentResolver and ContentProvider classes

The data model

Content providers expose their data as a simple table on a database model where each row is a

record and each column is data of a particular type and meaning For example information about

people and their phone numbers might be exposed as follows

_ID NUMBER NUMBER_KEY LABEL NAME TYPE

13 (425) 555 6677 425 555 6677 Kirkland office Bully Pulpit TYPE_WORK

44 (212) 555-1234 212 555 1234 NY apartment Alan Vain TYPE_HOME

45 (212) 555-6657 212 555 6657 Downtown office Alan Vain TYPE_MOBILE

53 2015554433 201 555 4433 Love Nest Rex Cars TYPE_HOME

Every record includes a numeric _ID field that uniquely identifies the record within the table IDs can be

used to match records in related tables mdash for example to find a persons phone number in one table

and pictures of that person in another

A query returns a Cursor object that can move from record to record and column to column to read the

contents of each field It has specialized methods for reading each type of data So to read a field you

must know what type of data the field contains (Theres more on query results and Cursor objects

later)

URIs

Each content provider exposes a public URI (wrapped as a Uri object) that uniquely identifies its data

set A content provider that controls multiple data sets (multiple tables) exposes a separate URI for

each one All URIs for providers begin with the string content The content scheme identifies the

data as being controlled by a content provider

If youre defining a content provider its a good idea to also define a constant for its URI to simplify

client code and make future updates cleaner Android defines CONTENT_URI constants for all the

providers that come with the platform For example the URI for the table that matches phone numbers

to people and the URI for the table that holds pictures of people (both controlled by the Contacts

content provider) are

androidproviderContactsPhonesCONTENT_URI

androidproviderContactsPhotosCONTENT_URI

The URI constant is used in all interactions with the content provider Every ContentResolver method

takes the URI as its first argument Its what identifies which provider the ContentResolver should talk

to and which table of the provider is being targeted

Querying a Content Provider

You need three pieces of information to query a content provider

The URI that identifies the provider

The names of the data fields you want to receive

The data types for those fields

If youre querying a particular record you also need the ID for that record

Making the query

To query a content provider you can use either the ContentResolverquery() method or the

ActivitymanagedQuery() method Both methods take the same set of arguments and both return a

Cursor object However managedQuery() causes the activity to manage the life cycle of the Cursor A

managed Cursor handles all of the niceties such as unloading itself when the activity pauses and

requerying itself when the activity restarts You can ask an Activity to begin managing an unmanaged

Cursor object for you by calling ActivitystartManagingCursor()

The first argument to either query() or managedQuery() is the provider URI mdash the CONTENT_URI

constant that identifies a particular ContentProvider and data set (see URIs earlier)

To restrict a query to just one record you can append the _ID value for that record to the URI mdash that

is place a string matching the ID as the last segment of the path part of the URI For example if the ID

is 23 the URI would be

content 23

There are some helper methods particularly ContentUriswithAppendedId() and

UriwithAppendedPath() that make it easy to append an ID to a URI Both are static methods that

return a Uri object with the ID added So for example if you were looking for record 23 in the database

of people contacts you might construct a query as follows

import androidproviderContactsPeople import androidcontentContentUris import androidnetUri import androiddatabaseCursor Use the ContentUris method to produce the base URI for the contact with _ID == 23 Uri myPerson = ContentUriswithAppendedId(PeopleCONTENT_URI 23) Alternatively use the Uri method to produce the base URI It takes a string rather than an integer Uri myPerson = UriwithAppendedPath(PeopleCONTENT_URI 23) Then query for this specific record Cursor cur = managedQuery(myPerson null null null null)

The other arguments to the query() and managedQuery() methods delimit the query in more detail

They are

The names of the data columns that should be returned A null value returns all columns Otherwise

only columns that are listed by name are returned All the content providers that come with the

platform define constants for their columns For example the androidproviderContactsPhones class

defines constants for the names of the columns in the phone table illustrated earlier ampmdash _ID

NUMBER NUMBER_KEY NAME and so on

A filter detailing which rows to return formatted as an SQL WHERE clause (excluding the WHERE

itself) A null value returns all rows (unless the URI limits the query to a single record)

Selection arguments

A sorting order for the rows that are returned formatted as an SQL ORDER BY clause (excluding the

ORDER BY itself) A null value returns the records in the default order for the table which may be

unordered

Lets look at an example query to retrieve a list of contact names and their primary phone numbers

import androidproviderContactsPeople import androiddatabaseCursor Form an array specifying which columns to return String[] projection = new String[] People_ID People_COUNT PeopleNAME PeopleNUMBER Get the base URI for the People table in the Contacts content provider Uri contacts = PeopleCONTENT_URI Make the query Cursor managedCursor = managedQuery(contacts projection Which columns to return null Which rows to return (all rows) null Selection arguments (none) Put the results in ascending order by name PeopleNAME + ASC)

This query retrieves data from the People table of the Contacts content provider It gets the name

primary phone number and unique record ID for each contact It also reports the number of records

that are returned as the _COUNT field of each record

The constants for the names of the columns are defined in various interfaces mdash _ID and _COUNT in

BaseColumns NAME in PeopleColumns and NUMBER in PhoneColumns The ContactsPeople

class implements each of these interfaces which is why the code example above could refer to them

using just the class name

What a query returns

A query returns a set of zero or more database records The names of the columns their default order

and their data types are specific to each content provider But every provider has an _ID column

which holds a unique numeric ID for each record Every provider can also report the number of records

returned as the _COUNT column its value is the same for all rows

Here is an example result set for the query in the previous section

_ID _COUNT NAME NUMBER

44 3 Alan Vain 212 555 1234

13 3 Bully Pulpit 425 555 6677

53 3 Rex Cars 201 555 4433

The retrieved data is exposed by a Cursor object that can be used to iterate backward or forward

through the result set You can use this object only to read the data To add modify or delete data

you must use a ContentResolver object

Reading retrieved data

The Cursor object returned by a query provides access to a recordset of results If you have queried

for a specific record by ID this set will contain only one value Otherwise it can contain multiple

values (If there are no matches it can also be empty) You can read data from specific fields in the

record but you must know the data type of the field because the Cursor object has a separate method

for reading each type of data mdash such as getString() getInt() and getFloat() (However for most types

if you call the method for reading strings the Cursor object will give you the String representation of

the data) The Cursor lets you request the column name from the index of the column or the index

number from the column name

The following snippet demonstrates reading names and phone numbers from the query illustrated

earlier

import androidproviderContactsPeople private void getColumnData(Cursor cur) if (curmoveToFirst()) String name String phoneNumber int nameColumn = curgetColumnIndex(PeopleNAME) int phoneColumn = curgetColumnIndex(PeopleNUMBER) String imagePath do Get the field values name = curgetString(nameColumn) phoneNumber = curgetString(phoneColumn) Do something with the values while (curmoveToNext())

If a query can return binary data such as an image or sound the data may be directly entered in the

table or the table entry for that data may be a string specifying a content URI that you can use to get

the data In general smaller amounts of data (say from 20 to 50K or less) are most often directly

entered in the table and can be read by calling CursorgetBlob() It returns a byte array

If the table entry is a content URI you should never try to open and read the file directly (for one thing

permissions problems can make this fail) Instead you should call ContentResolveropenInputStream()

to get an InputStream object that you can use to read the data

Modifying Data

Data kept by a content provider can be modified by

Adding new records

Adding new values to existing records

Batch updating existing records

Deleting records

All data modification is accomplished using ContentResolver methods Some content providers require

a more restrictive permission for writing data than they do for reading it If you dont have permission to

write to a content provider the ContentResolver methods will fail

Adding records

To add a new record to a content provider first set up a map of key-value pairs in a ContentValues

object where each key matches the name of a column in the content provider and the value is the

desired value for the new record in that column Then call ContentResolverinsert() and pass it the URI

of the provider and the ContentValues map This method returns the full URI of the new record mdash that

is the providers URI with the appended ID for the new record You can then use this URI to query and

get a Cursor over the new record and to further modify the record Heres an example

import androidproviderContactsPeople import androidcontentContentResolver import androidcontentContentValues ContentValues values = new ContentValues() Add Abraham Lincoln to contacts and make him a favorite valuesput(PeopleNAME Abraham Lincoln) 1 = the new contact is added to favorites 0 = the new contact is not added to favorites valuesput(PeopleSTARRED 1) Uri uri = getContentResolver()insert(PeopleCONTENT_URI values)

Adding new values

Once a record exists you can add new information to it or modify existing information For example

the next step in the example above would be to add contact information mdash like a phone number or an

IM or e-mail address mdash to the new entry

The best way to add to a record in the Contacts database is to append the name of the table where the

new data goes to the URI for the record then use the amended URI to add the new data values Each

Contacts table exposes a name for this purpose as a CONTENT_DIRECTORY constant The following

code continues the previous example by adding a phone number and e-mail address for the record

just created

Uri phoneUri = null Uri emailUri = null Add a phone number for Abraham Lincoln Begin with the URI for the new record just returned by insert() it ends with the _ID of the new record so we dont have to add the ID ourselves Then append the designation for the phone table to this URI and use the resulting URI to insert the phone number phoneUri = UriwithAppendedPath(uri PeoplePhonesCONTENT_DIRECTORY) valuesclear() valuesput(PeoplePhonesTYPE PeoplePhonesTYPE_MOBILE) valuesput(PeoplePhonesNUMBER 1233214567) getContentResolver()insert(phoneUri values) Now add an email address in the same way emailUri = UriwithAppendedPath(uri PeopleContactMethodsCONTENT_DIRECTORY) valuesclear() ContactMethodsKIND is used to distinguish different kinds of contact methods such as email IM etc valuesput(PeopleContactMethodsKIND ContactsKIND_EMAIL) valuesput(PeopleContactMethodsDATA testexamplecom) valuesput(PeopleContactMethodsTYPE PeopleContactMethodsTYPE_HOME) getContentResolver()insert(emailUri values)

You can place small amounts of binary data into a table by calling the version of ContentValuesput()

that takes a byte array That would work for a small icon-like image or a short audio clip for example

However if you have a large amount of binary data to add such as a photograph or a complete song

put a content URI for the data in the table and call ContentResolveropenOutputStream() with the files

URI (That causes the content provider to store the data in a file and record the file path in a hidden

field of the record)

In this regard the MediaStore content provider the main provider that dispenses image audio and

video data employs a special convention The same URI that is used with query() or managedQuery()

to get meta-information about the binary data (such as the caption of a photograph or the date it was

taken) is used with openInputStream() to get the data itself Similarly the same URI that is used with

insert() to put meta-information into a MediaStore record is used with openOutputStream() to place the

binary data there The following code snippet illustrates this convention

import androidproviderMediaStoreImagesMedia import androidcontentContentValues import javaioOutputStream Save the name and description of an image in a ContentValues map ContentValues values = new ContentValues(3) valuesput(MediaDISPLAY_NAME road_trip_1) valuesput(MediaDESCRIPTION Day 1 trip to Los Angeles) valuesput(MediaMIME_TYPE imagejpeg) Add a new record without the bitmap but with the values just set insert() returns the URI of the new record Uri uri = getContentResolver()insert(MediaEXTERNAL_CONTENT_URI values) Now get a handle to the file for that record and save the data into it Here sourceBitmap is a Bitmap object representing the file to save to the database try OutputStream outStream = getContentResolver()openOutputStream(uri) sourceBitmapcompress(BitmapCompressFormatJPEG 50 outStream) outStreamclose() catch (Exception e) Loge(TAG exception while writing image e)

Batch updating records

To batch update a group of records (for example to change NY to New York in all fields) call the

ContentResolverupdate() method with the columns and values to change

Deleting a record

To delete a single record call ContentResolverdelete() with the URI of a specific row

To delete multiple rows call ContentResolverdelete() with the URI of the type of record to delete (for

example androidproviderContactsPeopleCONTENT_URI) and an SQL WHERE clause defining

which rows to delete (Caution Be sure to include a valid WHERE clause if youre deleting a general

type or you risk deleting more records than you intended)

Creating a Content Provider

To create a content provider you must

Set up a system for storing the data Most content providers store their data using Androids file

storage methods or SQLite databases but you can store your data any way you want Android

provides the SQLiteOpenHelper class to help you create a database and SQLiteDatabase to manage

it

Extend the ContentProvider class to provide access to the data

Declare the content provider in the manifest file for your application (AndroidManifestxml)

The following sections have notes on the last two of these tasks

Extending the ContentProvider class

You define a ContentProvider subclass to expose your data to others using the conventions expected

by ContentResolver and Cursor objects Principally this means implementing six abstract methods

declared in the ContentProvider class

query()

insert()

update()

delete()

getType()

onCreate()

The query() method must return a Cursor object that can iterate over the requested data Cursor itself

is an interface but Android provides some ready-made Cursor objects that you can use For example

SQLiteCursor can iterate over data stored in an SQLite database You get the Cursor object by calling

any of the SQLiteDatabase classs query() methods There are other Cursor implementations mdash such

as MatrixCursor mdash for data not stored in a database

Because these ContentProvider methods can be called from various ContentResolver objects in

different processes and threads they must be implemented in a thread-safe manner

As a courtesy you might also want to call ContentResolvernotifyChange() to notify listeners when

there are modifications to the data

Beyond defining the subclass itself there are other steps you should take to simplify the work of clients

and make the class more accessible

Define a public static final Uri named CONTENT_URI This is the string that represents the full content

URI that your content provider handles You must define a unique string for this value The best

solution is to use the fully-qualified class name of the content provider (made lowercase) So for

example the URI for a TransportationProvider class could be defined as follows

public static final Uri CONTENT_URI = Uriparse(contentcomexamplecodelabtransportationprovider)

If the provider has subtables also define CONTENT_URI constants for each of the subtables These

URIs should all have the same authority (since that identifies the content provider) and be

distinguished only by their paths For example

contentcomexamplecodelabtransportationprovidertrain

contentcomexamplecodelabtransportationproviderairdomestic

contentcomexamplecodelabtransportationproviderairinternational

For an overview of content URIs see the Content URI Summary at the end of this document

Define the column names that the content provider will return to clients If you are using an underlying

database these column names are typically identical to the SQL database column names they

represent Also define public static String constants that clients can use to specify the columns in

queries and other instructions

Be sure to include an integer column named _id (with the constant _ID) for the IDs of the records

You should have this field whether or not you have another field (such as a URL) that is also unique

among all records If youre using the SQLite database the _ID field should be the following type

INTEGER PRIMARY KEY AUTOINCREMENT

The AUTOINCREMENT descriptor is optional But without it SQLite increments an ID counter field to

the next number above the largest existing number in the column If you delete the last row the next

row added will have the same ID as the deleted row AUTOINCREMENT avoids this by having SQLite

increment to the next largest value whether deleted or not

Carefully document the data type of each column Clients need this information to read the data

If you are handling a new data type you must define a new MIME type to return in your

implementation of ContentProvidergetType() The type depends in part on whether or not the content

URI submitted to getType() limits the request to a specific record Theres one form of the MIME type

for a single record and another for multiple records Use the Uri methods to help determine what is

being requested Here is the general format for each type

o For a single record vndandroidcursoritemvndyourcompanynamecontenttype

For example a request for train record 122 like this URI

contentcomexampletransportationprovidertrains122

might return this MIME type

vndandroidcursoritemvndexamplerail

o For multiple records vndandroidcursordirvndyourcompanynamecontenttype

For example a request for all train records like the following URI

contentcomexampletransportationprovidertrains

might return this MIME type

vndandroidcursordirvndexamplerail

If you are exposing byte data thats too big to put in the table itself mdash such as a large bitmap file mdash the

field that exposes the data to clients should actually contain a content URI string This is the field that

gives clients access to the data file The record should also have another field named _data that lists

the exact file path on the device for that file This field is not intended to be read by the client but by

the ContentResolver The client will call ContentResolveropenInputStream() on the user-facing field

holding the URI for the item The ContentResolver will request the _data field for that record and

because it has higher permissions than a client it should be able to access that file directly and return

a read wrapper for the file to the client

For an example of a private content provider implementation see the NodePadProvider class in the

Notepad sample application that ships with the SDK

Declaring the content provider

To let the Android system know about the content provider youve developed declare it with a

ltprovidergt element in the applications AndroidManifestxml file Content providers that are not

declared in the manifest are not visible to the Android system

The name attribute is the fully qualified name of the ContentProvider subclass The authorities attribute

is the authority part of the content URI that identifies the provider For example if the ContentProvider

subclass is AutoInfoProvider the ltprovidergt element might look like this

ltprovider androidname=comexampleautosAutoInfoProvider androidauthorities=comexampleautosautoinfoprovider gt ltprovidergt

Note that the authorities attribute omits the path part of a content URI For example if

AutoInfoProvider controlled subtables for different types of autos or different manufacturers

contentcomexampleautosautoinfoproviderhonda

contentcomexampleautosautoinfoprovidergmcompact

contentcomexampleautosautoinfoprovidergmsuv

those paths would not be declared in the manifest The authority is what identifies the provider not the

path your provider can interpret the path part of the URI in any way you choose

Other ltprovidergt attributes can set permissions to read and write data provide for an icon and text

that can be displayed to users enable and disable the provider and so on Set the multiprocess

attribute to true if data does not need to be synchronized between multiple running versions of the

content provider This permits an instance of the provider to be created in each client process

eliminating the need to perform IPC

Content URI Summary

Here is a recap of the important parts of a content URI

A Standard prefix indicating that the data is controlled by a content provider Its never modified

B The authority part of the URI it identifies the content provider For third-party applications this should

be a fully-qualified class name (reduced to lowercase) to ensure uniqueness The authority is declared

in the ltprovidergt elements authorities attribute

ltprovider androidname=TransportationProvider androidauthorities=comexampletransportationprovider gt

C The path that the content provider uses to determine what kind of data is being requested This can be

zero or more segments long If the content provider exposes only one type of data (only trains for

example) it can be absent If the provider exposes several types including subtypes it can be several

segments long mdash for example landbus landtrain seaship and seasubmarine to give four

possibilities

D The ID of the specific record being requested if any This is the _ID value of the requested record If

the request is not limited to a single record this segment and the trailing slash are omitted

contentcomexampletransportationprovidertrains

Intent and intent filters

Three of the core components of an application mdash activities services and broadcast receivers mdash 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 mdash 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 ContextstartActivity() or ActivitystartActivityForResult() to launch an

activity or get an existing activity to do something new (It can also be passed to ActivitysetResult() to

return information to the activity that called startActivityForResult())

An Intent object is passed to ContextstartService() to initiate a service or deliver new instructions to an

ongoing service Similarly an intent can be passed to ContextbindService() to establish a connection

between the calling component and a target service It can optionally initiate the service if its not

already running

Intent objects passed to any of the broadcast methods (such as ContextsendBroadcast()

ContextsendOrderedBroadcast() or ContextsendStickyBroadcast()) 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 mdash how it resolves which component should receive an intent message For

intents that dont explicitly name a target component this process involves testing the Intent object

against intent filters associated with potential targets

Intent Objects

An Intent object is a bundle of information It contains information of interest to the component that

receives the intent (such as the action to be taken and the data to act on) plus information of interest to

the Android system (such as the category of component that should handle the intent and instructions

on how to launch a target activity) Principally it can contain the following

Component name

The name of the component that should handle the intent This field is a ComponentName

object mdash a combination of the fully qualified class name of the target component (for example

comexampleprojectappFreneticActivity) and the package name set in the manifest file of the

application where the component resides (for example comexampleproject) The package

part of the component name and the package name set in the manifest do not necessarily have

to match

The component name is optional If it is set the Intent object is delivered to an instance of the

designated class If it is not set Android uses other information in the Intent object to locate a

suitable target mdash see Intent Resolution later in this document

The component name is set by setComponent() setClass() or setClassName() and read by

getComponent()

Action

A string naming the action to be performed mdash or in the case of broadcast intents the action

that took place and is being reported The Intent class defines a number of action constants

including these

Constant Target

component

Action

ACTION_CALL activity Initiate a phone call

ACTION_EDIT activity Display data for the user to edit

ACTION_MAIN activity Start up as the initial activity of a task

with no data input and no returned

output

ACTION_SYNC activity Synchronize data on a server with

data on the mobile device

ACTION_BATTERY_LOW broadcast

receiver

A warning that the battery is low

ACTION_HEADSET_PLUG broadcast

receiver

A headset has been plugged into the

device or unplugged from it

ACTION_SCREEN_ON broadcast

receiver

The screen has been turned on

ACTION_TIMEZONE_CHANGED broadcast

receiver

The setting for the time zone has

changed

See the Intent class description for a list of pre-defined constants for generic actions Other

actions are defined elsewhere in the Android API You can also define your own action strings

for activating the components in your application Those you invent should include the

application package as a prefix mdash for example comexampleprojectSHOW_COLOR

The action largely determines how the rest of the intent is structured mdash particularly the data and

extras fields mdash much as a method name determines a set of arguments and a return value For

this reason its a good idea to use action names that are as specific as possible and to couple

them tightly to the other fields of the intent In other words instead of defining an action in

isolation define an entire protocol for the Intent objects your components can handle

The action in an Intent object is set by the setAction() method and read by getAction()

Data

The URI of the data to be acted on and the MIME type of that data Different actions are paired

with different kinds of data specifications For example if the action field is ACTION_EDIT the

data field would contain the URI of the document to be displayed for editing If the action is

ACTION_CALL the data field would be a tel URI with the number to call Similarly if the action

is ACTION_VIEW and the data field is an http URI the receiving activity would be called upon

to download and display whatever data the URI refers to

When matching an intent to a component that is capable of handling the data its often

important to know the type of data (its MIME type) in addition to its URI For example a

component able to display image data should not be called upon to play an audio file

In many cases the data type can be inferred from the URI mdash particularly content URIs which

indicate that the data is located on the device and controlled by a content provider (see the

separate discussion on content providers) But the type can also be explicitly set in the Intent

object The setData() method specifies data only as a URI setType() specifies it only as a

MIME type and setDataAndType() specifies it as both a URI and a MIME type The URI is read

by getData() and the type by getType()

Category

A string containing additional information about the kind of component that should handle the

intent Any number of category descriptions can be placed in an Intent object As it does for

actions the Intent class defines several category constants including these

Constant Meaning

CATEGORY_BROWSABLE The target activity can be safely invoked by the browser to

display data referenced by a link mdash for example an image or

an e-mail message

CATEGORY_GADGET The activity can be embedded inside of another activity that

hosts gadgets

CATEGORY_HOME The activity displays the home screen the first screen the

user sees when the device is turned on or when the HOME

key is pressed

CATEGORY_LAUNCHER The activity can be the initial activity of a task and is listed in

the top-level application launcher

CATEGORY_PREFERENCE The target activity is a preference panel

See the Intent class description for the full list of categories

The addCategory() method places a category in an Intent object removeCategory() deletes a

category previously added and getCategories() gets the set of all categories currently in the

object

Extras

Key-value pairs for additional information that should be delivered to the component handling

the intent Just as some actions are paired with particular kinds of data URIs some are paired

with particular extras For example an ACTION_TIMEZONE_CHANGED intent has a time-

zone extra that identifies the new time zone and ACTION_HEADSET_PLUG has a state

extra indicating whether the headset is now plugged in or unplugged as well as a name extra

for the type of headset If you were to invent a SHOW_COLOR action the color value would be

set in an extra key-value pair

The Intent object has a series of put() methods for inserting various types of extra data and a

similar set of get() methods for reading the data These methods parallel those for Bundle

objects In fact the extras can be installed and read as a Bundle using the putExtras() and

getExtras() methods

Flags

Flags of various sorts Many instruct the Android system how to launch an activity (for example

which task the activity should belong to) and how to treat it after its launched (for example

whether it belongs in the list of recent activities) All these flags are defined in the Intent class

The Android system and the applications that come with the platform employ Intent objects both to

send out system-originated broadcasts and to activate system-defined components To see how to

structure an intent to activate a system component consult the list of intents in the reference

Intent Resolution

Intents can be divided into two groups

Explicit intents designate the target component by its name (the component name field mentioned

earlier has a value set) Since component names would generally not be known to developers of other

applications explicit intents are typically used for application-internal messages mdash such as an activity

starting a subordinate service or launching a sister activity

Implicit intents do not name a target (the field for the component name is blank) Implicit intents are

often used to activate components in other applications

Android delivers an explicit intent to an instance of the designated target class Nothing in the Intent

object other than the component name matters for determining which component should get the intent

A different strategy is needed for implicit intents In the absence of a designated target the Android

system must find the best component (or components) to handle the intent mdash a single activity or

service to perform the requested action or the set of broadcast receivers to respond to the broadcast

announcement It does so by comparing the contents of the Intent object to intent filters structures

associated with components that can potentially receive intents Filters advertise the capabilities of a

component and delimit the intents it can handle They open the component to the possibility of

receiving implicit intents of the advertised type If a component does not have any intent filters it can

receive only explicit intents A component with filters can receive both explicit and implicit intents

Only three aspects of an Intent object are consulted when the object is tested against an intent filter

action

data (both URI and data type)

category

The extras and flags play no part in resolving which component receives an intent

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 mdash but only unwanted implicit intents (those that dont 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

components 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 mdash 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 Pads filters are described in the Note Pad Example

section later)

Filters and security

An intent filter cannot be relied on for security While it opens a component to receiving only certain

kinds of implicit intents it does nothing to prevent explicit intents from targeting the component Even

though a filter restricts the intents a component will be asked to handle to certain actions and data

sources someone could always put together an explicit intent with a different action and data source

and name the component as the target

An intent filter is an instance of the IntentFilter class However since the Android system must know

about the capabilities of a component before it can launch that component intent filters are generally

not set up in Java code but in the applications manifest file (AndroidManifestxml) as ltintent-filtergt

elements (The one exception would be filters for broadcast receivers that are registered dynamically

by calling ContextregisterReceiver() they are directly created as IntentFilter objects)

A filter has fields that parallel the action data and category fields of an Intent object An implicit intent

is tested against the filter in all three areas To be delivered to the component that owns the filter it

must pass all three tests If it fails even one of them the Android system wont deliver it to the

component mdash at least not on the basis of that filter However since a component can have multiple

intent filters an intent that does not pass through one of a components filters might make it through on

another

Each of the three tests is described in detail below

Action test

An ltintent-filtergt element in the manifest file lists actions as ltactiongt subelements For

example

ltintent-filter gt ltaction androidname=comexampleprojectSHOW_CURRENT gt ltaction androidname=comexampleprojectSHOW_RECENT gt ltaction androidname=comexampleprojectSHOW_PENDING gt ltintent-filtergt

As the example shows while an Intent object names just a single action a filter may list more

than one The list cannot be empty a filter must contain at least one ltactiongt element or it will

block all intents

To pass this test the action specified in the Intent object must match one of the actions listed in

the filter If the object or the filter does not specify an action the results are as follows

If the filter fails to list any actions there is nothing for an intent to match so all intents fail the

test No intents can get through the filter

On the other hand an Intent object that doesnt specify an action automatically passes the test

mdash as long as the filter contains at least one action

Category test

An ltintent-filtergt element also lists categories as subelements For example

ltintent-filter gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryBROWSABLE gt ltintent-filtergt

Note that the constants described earlier for actions and categories are not used in the manifest

file The full string values are used instead For instance the

androidintentcategoryBROWSABLE string in the example above corresponds to the

CATEGORY_BROWSABLE constant mentioned earlier in this document Similarly the string

androidintentactionEDIT corresponds to the ACTION_EDIT constant

For an intent to pass the category test every category in the Intent object must match a

category in the filter The filter can list additional categories but it cannot omit any that are in the

intent

In principle therefore an Intent object with no categories should always pass this test

regardless of whats in the filter Thats mostly true However with one exception Android treats

all implicit intents passed to startActivity() as if they contained at least one category

androidintentcategoryDEFAULT (the CATEGORY_DEFAULT constant) Therefore activities

that are willing to receive implicit intents must include androidintentcategoryDEFAULT in

their intent filters (Filters with androidintentactionMAIN and

androidintentcategoryLAUNCHER settings are the exception They mark activities that begin

new tasks and that are represented on the launcher screen They can include

androidintentcategoryDEFAULT in the list of categories but dont need to) See Using intent

matching later for more on these filters)

Data test

Like the action and categories the data specification for an intent filter is contained in a

subelement And as in those cases the subelement can appear multiple times or not at all For

example

ltintent-filter gt ltdata androidmimeType=videompeg androidscheme=http gt ltdata androidmimeType=audiompeg androidscheme=http gt ltintent-filtergt

Each ltdatagt element can specify a URI and a data type (MIME media type) There are

separate attributes mdash scheme host port and path mdash for each part of the URI

schemehostportpath

For example in the following URI

contentcomexampleproject200foldersubfolderetc

the scheme is content the host is comexampleproject the port is 200 and the path is

foldersubfolderetc The host and port together constitute the URI authority if a host is not

specified the port is ignored

Each of these attributes is optional but they are not independent of each other For an authority

to be meaningful a scheme must also be specified For a path to be meaningful both a scheme

and an authority must be specified

When the URI in an Intent object is compared to a URI specification in a filter its compared

only to the parts of the URI actually mentioned in the filter For example if a filter specifies only

a scheme all URIs with that scheme match the filter If a filter specifies a scheme and an

authority but no path all URIs with the same scheme and authority match regardless of their

paths If a filter specifies a scheme an authority and a path only URIs with the same scheme

authority and path match However a path specification in the filter can contain wildcards to

require only a partial match of the path

The type attribute of a ltdatagt element specifies the MIME type of the data Its more common in

filters than a URI Both the Intent object and the filter can use a wildcard for the subtype field

mdash for example text or audio mdash indicating any subtype matches

The data test compares both the URI and the data type in the Intent object to a URI and data

type specified in the filter The rules are as follows

a An Intent object that contains neither a URI nor a data type passes the test only if the filter

likewise does not specify any URIs or data types

b An Intent object that contains a URI but no data type (and a type cannot be inferred from the

URI) passes the test only if its URI matches a URI in the filter and the filter likewise does not

specify a type This will be the case only for URIs like mailto and tel that do not refer to actual

data

c An Intent object that contains a data type but not a URI passes the test only if the filter lists the

same data type and similarly does not specify a URI

d An Intent object that contains both a URI and a data type (or a data type can be inferred from

the URI) passes the data type part of the test only if its type matches a type listed in the filter It

passes the URI part of the test either if its URI matches a URI in the filter or if it has a content

or file URI and the filter does not specify a URI In other words a component is presumed to

support content and file data if its filter lists only a data type

If an intent can pass through the filters of more than one activity or service the user may be asked

which component to activate An exception is raised if no target can be found

Common cases

The last rule shown above for the data test rule (d) reflects the expectation that components are able

to get local data from a file or content provider Therefore their filters can list just a data type and do

not need to explicitly name the content and file schemes This is a typical case A ltdatagt element like

the following for example tells Android that the component can get image data from a content

provider and display it

ltdata androidmimeType=image gt

Since most available data is dispensed by content providers filters that specify a data type but not a

URI are perhaps the most common

Another common configuration is filters with a scheme and a data type For example a ltdatagt

element like the following tells Android that the component can get video data from the network and

display it

ltdata androidscheme=http androidtype=video gt

Consider for example what the browser application does when the user follows a link on a web page

It first tries to display the data (as it could if the link was to an HTML page) If it cant display the data it

puts together an implicit intent with the scheme and data type and tries to start an activity that can do

the job If there are no takers it asks the download manager to download the data That puts it under

the control of a content provider so a potentially larger pool of activities (those with filters that just

name a data type) can respond

Most applications also have a way to start fresh without a reference to any particular data Activities

that can initiate applications have filters with androidintentactionMAIN specified as the action If

they are to be represented in the application launcher they also specify the

androidintentcategoryLAUNCHER category

ltintent-filter gt ltaction androidname=code androidintentactionMAIN gt ltcategory androidname=code androidintentcategoryLAUNCHER gt ltintent-filtergt

Using intent matching

Intents are matched against intent filters not only to discover a target component to activate but also

to discover something about the set of components on the device For example the Android system

populates the application launcher the top-level screen that shows the applications that are available

for the user to launch by finding all the activities with intent filters that specify the

androidintentactionMAIN action and androidintentcategoryLAUNCHER category (as illustrated

in the previous section) It then displays the icons and labels of those activities in the launcher

Similarly it discovers the home screen by looking for the activity with androidintentcategoryHOME

in its filter

Your application can use intent matching is a similar way The PackageManager has a set of query()

methods that return all components that can accept a particular intent and a similar series of

resolve() methods that determine the best component to respond to an intent For example

queryIntentActivities() returns a list of all activities that can perform the intent passed as an argument

and queryIntentServices() returns a similar list of services Neither method activates the components

they just list the ones that can respond Theres a similar method queryBroadcastReceivers() for

broadcast receivers

Note Pad Example

The Note Pad sample application enables users to browse through a list of notes view details about

individual items in the list edit the items and add a new item to the list This section looks at the intent

filters declared in its manifest file (If youre working offline in the SDK you can find all the source files

for this sample application including its manifest file at ltsdkgtsamplesNotePadindexhtml If youre

viewing the documentation online the source files are in the Tutorials and Sample Code section here)

In its manifest file the Note Pad application declares three activities each with at least one intent filter

It also declares a content provider that manages the note data Here is the manifest file in its entirety

ltmanifest xmlnsandroid=httpschemasandroidcomapkresandroid package=comexampleandroidnotepadgt ltapplication androidicon=drawableapp_notes androidlabel=stringapp_name gt ltprovider androidname=NotePadProvider androidauthorities=comgoogleproviderNotePad gt ltactivity androidname=NotesList androidlabel=stringtitle_notes_listgt ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltactivity androidname=NoteEditor androidtheme=androidstyleThemeLight androidlabel=stringtitle_note gt ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltactivitygt

ltactivity androidname=TitleEditor androidlabel=stringtitle_edit_title androidtheme=androidstyleThemeDialoggt ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltapplicationgt ltmanifestgt

The first activity NotesList is distinguished from the other activities by the fact that it operates on a

directory of notes (the note list) rather than on a single note It would generally serve as the initial user

interface into the application It can do three things as described by its three intent filters

1 ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt

This filter declares the main entry point into the Note Pad application The standard MAIN action is an

entry point that does not require any other information in the Intent (no data specification for example)

and the LAUNCHER category says that this entry point should be listed in the application launcher

2 ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

This filter declares the things that the activity can do on a directory of notes It can allow the user to

view or edit the directory (via the VIEW and EDIT actions) or to pick a particular note from the

directory (via the PICK action)

The mimeType attribute of the ltdatagt element specifies the kind of data that these actions operate on

It indicates that the activity can get a Cursor over zero or more items (vndandroidcursordir) from a

content provider that holds Note Pad data (vndgooglenote) The Intent object that launches the

activity would include a content URI specifying the exact data of this type that the activity should open

Note also the DEFAULT category supplied in this filter Its there because the ContextstartActivity()

and ActivitystartActivityForResult() methods treat all intents as if they contained the DEFAULT

category mdash with just two exceptions

o Intents that explicitly name the target activity

o Intents consisting of the MAIN action and LAUNCHER category

Therefore the DEFAULT category is required for all filters mdash except for those with the MAIN action

and LAUNCHER category (Intent filters are not consulted for explicit intents)

3 ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

This filter describes the activitys ability to return a note selected by the user without requiring any

specification of the directory the user should choose from The GET_CONTENT action is similar to the

PICK action In both cases the activity returns the URI for a note selected by the user (In each case

its returned to the activity that called startActivityForResult() to start the NoteList activity) Here

however the caller specifies the type of data desired instead of the directory of data the user will be

picking from

The data type vndandroidcursoritemvndgooglenote indicates the type of data the activity can

return mdash a URI for a single note From the returned URI the caller can get a Cursor for exactly one

item (vndandroidcursoritem) from the content provider that holds Note Pad data (vndgooglenote)

In other words for the PICK action in the previous filter the data type indicates the type of data the

activity could display to the user For the GET_CONTENT filter it indicates the type of data the activity

can return to the caller

Given these capabilities the following intents will resolve to the NotesList activity

action androidintentactionMAIN

Launches the activity with no data specified

action androidintentactionMAIN

category androidintentcategoryLAUNCHER

Launches the activity with no data selected specified This is the actual intent used by the

Launcher to populate its top-level list All activities with filters that match this action and

category are added to the list

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of all the notes under

contentcomgoogleproviderNotePadnotes The user can then browse through the list and

get information about the items in it

action androidintentactionPICK

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of the notes under

contentcomgoogleproviderNotePadnotes The user can then pick a note from the list and

the activity will return the URI for that item back to the activity that started the NoteList activity

action androidintentactionGET_CONTENT

data type vndandroidcursoritemvndgooglenote

Asks the activity to supply a single item of Note Pad data

The second activity NoteEditor shows users a single note entry and allows them to edit it It can do

two things as described by its two intent filters

1 ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The first primary purpose of this activity is to enable the user to interact with a single note ampmdash to

either VIEW the note or EDIT it (The EDIT_NOTE category is a synonym for EDIT) The intent would

contain the URI for data matching the MIME type vndandroidcursoritemvndgooglenote mdash that is

the URI for a single specific note It would typically be a URI that was returned by the PICK or

GET_CONTENT actions of the NoteList activity

As before this filter lists the DEFAULT category so that the activity can be launched by intents that

dont explicitly specify the NoteEditor class

2 ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

The secondary purpose of this activity is to enable the user to create a new note which it will INSERT

into an existing directory of notes The intent would contain the URI for data matching the MIME type

vndandroidcursordirvndgooglenote mdash that is the URI for the directory where the note should be

placed

Given these capabilities the following intents will resolve to the NoteEditor activity

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID (For details on how content

URIs specify individual members of a group see Content Providers)

action androidintentactionEDIT

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID and to let the user edit it If

the user saves the changes the activity updates the data for the note in the content provider

action androidintentactionINSERT

data contentcomgoogleproviderNotePadnotes

Asks the activity to create a new empty note in the notes list at

contentcomgoogleproviderNotePadnotes and allow the user to edit it If the user saves the

note its URI is returned to the caller

The last activity TitleEditor enables the user to edit the title of a note This could be implemented by

directly invoking the activity (by explicitly setting its component name in the Intent) without using an

intent filter But here we take the opportunity to show how to publish alternative operations on existing

data

ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The single intent filter for this activity uses a custom action called

comandroidnotepadactionEDIT_TITLE It must be invoked on a specific note (data type

vndandroidcursoritemvndgooglenote) like the previous VIEW and EDIT actions However here the

activity displays the title contained in the note data not the content of the note itself

In addition to supporting the usual DEFAULT category the title editor also supports two other standard

categories ALTERNATIVE and SELECTED_ALTERNATIVE These categories identify activities that

can be presented to users in a menu of options (much as the LAUNCHER category identifies activities

that should be presented to user in the application launcher) Note that the filter also supplies an

explicit label (via androidlabel=stringresolve_title) to better control what users see when

presented with this activity as an alternative action to the data they are currently viewing (For more

information on these categories and building options menus see the

PackageManagerqueryIntentActivityOptions() and MenuaddIntentOptions() methods)

Given these capabilities the following intent will resolve to the TitleEditor activity

action comandroidnotepadactionEDIT_TITLE

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the title associated with note ID and allow the user to edit the title

Processes and Threads

When an application component starts and the application does not have any other components

running the Android system starts a new Linux process for the application with a single thread of

execution By default all components of the same application run in the same process and thread

(called the main thread) If an application component starts and there already exists a process for

that application (because another component from the application exists) then the component is

started within that process and uses the same thread of execution However you can arrange for

different components in your application to run in separate processes and you can create additional

threads for any process

This document discusses how processes and threads work in an Android application

Processes

By default all components of the same application run in the same process and most applications

should not change this However if you find that you need to control which process a certain

component belongs to you can do so in the manifest file

The manifest entry for each type of component elementmdashltactivitygt ltservicegt ltreceivergt and

ltprovidergtmdashsupports an androidprocess attribute that can specify a process in which that component

should run You can set this attribute so that each component runs in its own process or so that some

components share a process while others do not You can also set androidprocess so that

components of different applications run in the same processmdashprovided that the applications share the

same Linux user ID and are signed with the same certificates

The ltapplicationgt element also supports an androidprocess attribute to set a default value that

applies to all components

Android might 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 thats killed are consequently destroyed A process is started again for those components

when theres again work for them to do

When deciding which processes to kill the Android system weighs their relative importance to the

user For example it more readily shuts down a process hosting activities that are no longer visible on

screen compared to a process hosting visible activities The decision whether to terminate a process

therefore depends on the state of the components running in that process The rules used to decide

which processes to terminate is discussed below

Process lifecycle

The Android system tries to maintain an application process for as long as possible but eventually

needs to remove old processes to reclaim memory for new or more important processes To determine

which processes to keep and which to kill the system places each process into an importance

hierarchy based on the components running in the process and the state of those components

Processes with the lowest importance are eliminated first then those with the next lowest importance

and so on as necessary to recover system resources

There are five levels in the importance hierarchy The following list presents the different types of

processes in order of importance (the first process is most important and is killed last)

1 Foreground process

A process that is required for what the user is currently doing A process is considered to be in the

foreground if any of the following conditions are true

o It hosts an Activity that the user is interacting with (the Activitys onResume() method has been called)

o It hosts a Service thats bound to the activity that the user is interacting with

o It hosts a Service thats running in the foregroundmdashthe service has called startForeground()

o It hosts a Service thats executing one of its lifecycle callbacks (onCreate() onStart() or onDestroy())

o It hosts a BroadcastReceiver thats executing its onReceive() method

Generally only a few foreground processes exist at any given time They are killed only as a last

resortmdashif memory is so low that they cannot all continue to run Generally at that point the device has

reached a memory paging state so killing some foreground processes is required to keep the user

interface responsive

2 Visible process

A process that doesnt have any foreground components but still can affect what the user sees on

screen A process is considered to be visible if either of the following conditions are true

o It hosts an Activity that is not in the foreground but is still visible to the user (its onPause() method has

been called) This might occur for example if the foreground activity started a dialog which allows the

previous activity to be seen behind it

o It hosts a Service thats bound to a visible (or foreground) activity

A visible process is considered extremely important and will not be killed unless doing so is required to

keep all foreground processes running

3 Service process

A process that is running a service that has been started with the startService() method and does not

fall into either of the two higher categories Although service processes are not directly tied to anything

the user sees they are generally doing things that the user cares about (such as playing music in the

background or downloading data on the network) so the system keeps them running unless theres

not enough memory to retain them along with all foreground and visible processes

4 Background process

A process holding an activity thats not currently visible to the user (the activitys onStop() method has

been called) These processes have no direct impact on the user experience and the system can kill

them at any time to reclaim memory for a foreground visible or service process Usually there are

many background processes running so they are kept in an LRU (least recently used) list to ensure

that the process with the activity that was most recently seen by the user is the last to be killed If an

activity implements its lifecycle methods correctly and saves its current state killing its process will not

have a visible effect on the user experience because when the user navigates back to the activity the

activity restores all of its visible state See the Activities document for information about saving and

restoring state

5 Empty process

A process that doesnt hold any active application components The only reason to keep this kind of

process alive is for caching purposes to improve startup time the next time a component needs to run

in it The system often kills these processes in order to balance overall system resources between

process caches and the underlying kernel caches

Android ranks a process at the highest level it can based upon the importance of the components

currently active in the process For example if a process hosts a service and a visible activity the

process is ranked as a visible process not a service process

In addition a processs ranking might be increased because other processes are dependent on itmdasha

process that is serving another process can never be ranked lower than the process it is serving For

example if a content provider in process A is serving a client in process B or if a service in process A

is bound to a component in process B process A is always considered at least as important as

process B

Because a process running a service is ranked higher than a process with background activities an

activity that initiates a long-running operation might do well to start a service for that operation rather

than simply create a worker threadmdashparticularly if the operation will likely outlast the activity For

example an activity thats uploading a picture to a web site should start a service to perform the

upload so that the upload can continue in the background even if the user leaves the activity Using a

service guarantees that the operation will have at least service process priority regardless of what

happens to the activity This is the same reason that broadcast receivers should employ services

rather than simply put time-consuming operations in a thread

Threads

When an application is launched the system creates a thread of execution for the application called

main This thread is very important because it is in charge of dispatching events to the appropriate

user interface widgets including drawing events It is also the thread in which your application interacts

with components from the Android UI toolkit (components from the androidwidget and androidview

packages) As such the main thread is also sometimes called the UI thread

The system does not create a separate thread for each instance of a component All components that

run in the same process are instantiated in the UI thread and system calls to each component are

dispatched from that thread Consequently methods that respond to system callbacks (such as

onKeyDown() to report user actions or a lifecycle callback method) always run in the UI thread of the

process

For instance when the user touches a button on the screen your apps UI thread dispatches the touch

event to the widget which in turn sets its pressed state and posts an invalidate request to the event

queue The UI thread dequeues the request and notifies the widget that it should redraw itself

When your app performs intensive work in response to user interaction this single thread model can

yield poor performance unless you implement your application properly Specifically if everything is

happening in the UI thread performing long operations such as network access or database queries

will block the whole UI When the thread is blocked no events can be dispatched including drawing

events From the users perspective the application appears to hang Even worse if the UI thread is

blocked for more than a few seconds (about 5 seconds currently) the user is presented with the

infamous application not responding (ANR) dialog The user might then decide to quit your

application and uninstall it if they are unhappy

Additionally the Andoid UI toolkit is not thread-safe So you must not manipulate your UI from a

worker threadmdashyou must do all manipulation to your user interface from the UI thread Thus there are

simply two rules to Androids single thread model

1 Do not block the UI thread

2 Do not access the Android UI toolkit from outside the UI thread

Worker threads

Because of the single thread model described above its vital to the responsiveness of your

applications UI that you do not block the UI thread If you have operations to perform that are not

instantaneous you should make sure to do them in separate threads (background or worker

threads)

For example below is some code for a click listener that downloads an image from a separate thread

and displays it in an ImageView

public void onClick(View v) new Thread(new Runnable() public void run() Bitmap b = loadImageFromNetwork(httpexamplecomimagepng) mImageViewsetImageBitmap(b) )start()

At first this seems to work fine because it creates a new thread to handle the network operation

However it violates the second rule of the single-threaded model do not access the Android UI toolkit

from outside the UI threadmdashthis sample modifies the ImageView from the worker thread instead of the

UI thread This can result in undefined and unexpected behavior which can be difficult and time-

consuming to track down

To fix this problem Android offers several ways to access the UI thread from other threads Here is a

list of methods that can help

ActivityrunOnUiThread(Runnable)

Viewpost(Runnable)

ViewpostDelayed(Runnable long)

For example you can fix the above code by using the Viewpost(Runnable) method

public void onClick(View v) new Thread(new Runnable() public void run() final Bitmap bitmap = loadImageFromNetwork(httpexamplecomimagepng) mImageViewpost(new Runnable() public void run() mImageViewsetImageBitmap(bitmap) ) )start()

Now this implementation is thread-safe the network operation is done from a separate thread while

the ImageView is manipulated from the UI thread

However as the complexity of the operation grows this kind of code can get complicated and difficult

to maintain To handle more complex interactions with a worker thread you might consider using a

Handler in your worker thread to process messages delivered from the UI thread Perhaps the best

solution though is to extend the AsyncTask class which simplifies the execution of worker thread

tasks that need to interact with the UI

Using AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface It performs the blocking

operations in a worker thread and then publishes the results on the UI thread without requiring you to

handle threads andor handlers yourself

To use it you must subclass AsyncTask and implement the doInBackground() callback method which

runs in a pool of background threads To update your UI you should implement onPostExecute()

which delivers the result from doInBackground() and runs in the UI thread so you can safely update

your UI You can then run the task by calling execute() from the UI thread

For example you can implement the previous example using AsyncTask this way

public void onClick(View v) new DownloadImageTask()execute(httpexamplecomimagepng) private class DownloadImageTask extends AsyncTaskltString Void Bitmapgt The system calls this to perform work in a worker thread and delivers it the parameters given to AsyncTaskexecute() protected Bitmap doInBackground(String urls) return loadImageFromNetwork(urls[0])

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 6: 03 services

constructor with a name for the worker thread public HelloIntentService() super(HelloIntentService) The IntentService calls this method from the default worker thread with the intent that started the service When this method returns IntentService stops the service as appropriate Override protected void onHandleIntent(Intent intent) Normally we would do some work here like download a file For our sample we just sleep for 5 seconds long endTime = SystemcurrentTimeMillis() + 51000 while (SystemcurrentTimeMillis() lt endTime) synchronized (this) try wait(endTime - SystemcurrentTimeMillis()) catch (Exception e)

Thats all you need a constructor and an implementation of onHandleIntent()

If you decide to also override other callback methods such as onCreate() onStartCommand() or

onDestroy() be sure to call the super implementation so that the IntentService can properly handle

the life of the worker thread

For example onStartCommand() must return the default implementation (which is how the intent gets

delivered to onHandleIntent())

Override public int onStartCommand(Intent intent int flags int startId) ToastmakeText(this service starting ToastLENGTH_SHORT)show() return superonStartCommand(intentflagsstartId)

Besides onHandleIntent() the only method from which you dont need to call the super class is

onBind() (but you only need to implement that if your service allows binding)

In the next section youll see how the same kind of service is implemented when extending the base

Service class which is a lot more code but which might be appropriate if you need to handle

simultaneous start requests

Extending the Service class

As you saw in the previous section using IntentService makes your implementation of a started

service very simple If however you require your service to perform multi-threading (instead of

processing start requests through a work queue) then you can extend the Service class to handle

each intent

For comparison the following example code is an implementation of the Service class that performs

the exact same work as the example above using IntentService That is for each start request it uses

a worker thread to perform the job and processes only one request at a time

public class HelloService extends Service private Looper mServiceLooper private ServiceHandler mServiceHandler Handler that receives messages from the thread private final class ServiceHandler extends Handler public ServiceHandler(Looper looper) super(looper) Override public void handleMessage(Message msg) Normally we would do some work here like download a file For our sample we just sleep for 5 seconds long endTime = SystemcurrentTimeMillis() + 51000 while (SystemcurrentTimeMillis() lt endTime) synchronized (this) try wait(endTime - SystemcurrentTimeMillis()) catch (Exception e) Stop the service using the startId so that we dont stop the service in the middle of handling another job stopSelf(msgarg1) Override public void onCreate() Start up the thread running the service Note that we create a separate thread because the service normally runs in the processs main thread which we dont want to block We also make it background priority so CPU-intensive work will not disrupt our UI HandlerThread thread = new HandlerThread(ServiceStartArguments ProcessTHREAD_PRIORITY_BACKGROUND) threadstart() Get the HandlerThreads Looper and use it for our Handler

mServiceLooper = threadgetLooper() mServiceHandler = new ServiceHandler(mServiceLooper) Override public int onStartCommand(Intent intent int flags int startId) ToastmakeText(this service starting ToastLENGTH_SHORT)show() For each start request send a message to start a job and deliver the start ID so we know which request were stopping when we finish the job Message msg = mServiceHandlerobtainMessage() msgarg1 = startId mServiceHandlersendMessage(msg) If we get killed after returning from here restart return START_STICKY Override public IBinder onBind(Intent intent) We dont provide binding so return null return null Override public void onDestroy() ToastmakeText(this service done ToastLENGTH_SHORT)show()

As you can see its a lot more work than using IntentService

However because you handle each call to onStartCommand() yourself you can perform multiple

requests simultaneously Thats not what this example does but if thats what you want then you can

create a new thread for each request and run them right away (instead of waiting for the previous

request to finish)

Notice that the onStartCommand() method must return an integer The integer is a value that

describes how the system should continue the service in the event that the system kills it (as

discussed above the default implementation for IntentService handles this for you though you are

able to modify it) The return value from onStartCommand() must be one of the following constants

START_NOT_STICKY

If the system kills the service after onStartCommand() returns do not recreate the service

unless there are pending intents to deliver This is the safest option to avoid running your

service when not necessary and when your application can simply restart any unfinished jobs

START_STICKY

If the system kills the service after onStartCommand() returns recreate the service and call

onStartCommand() but do not redeliver the last intent Instead the system calls

onStartCommand() with a null intent unless there were pending intents to start the service in

which case those intents are delivered This is suitable for media players (or similar services)

that are not executing commands but running indefinitely and waiting for a job

START_REDELIVER_INTENT

If the system kills the service after onStartCommand() returns recreate the service and call

onStartCommand() with the last intent that was delivered to the service Any pending intents are

delivered in turn This is suitable for services that are actively performing a job that should be

immediately resumed such as downloading a file

For more details about these return values see the linked reference documentation for each constant

Starting a Service

You can start a service from an activity or other application component by passing an Intent (specifying

the service to start) to startService() The Android system calls the services onStartCommand()

method and passes it the Intent (You should never call onStartCommand() directly)

For example an activity can start the example service in the previous section (HelloSevice) using an

explicit intent with startService()

Intent intent = new Intent(this HelloServiceclass) startService(intent)

The startService() method returns immediately and the Android system calls the services

onStartCommand() method If the service is not already running the system first calls onCreate() then

calls onStartCommand()

If the service does not also provide binding the intent delivered with startService() is the only mode of

communication between the application component and the service However if you want the service

to send a result back then the client that starts the service can create a PendingIntent for a broadcast

(with getBroadcast()) and deliver it to the service in the Intent that starts the service The service can

then use the broadcast to deliver a result

Multiple requests to start the service result in multiple corresponding calls to the services

onStartCommand() However only one request to stop the service (with stopSelf() or stopService()) is

required to stop it

Stopping a service

A started service must manage its own lifecycle That is the system does not stop or destroy the

service unless it must recover system memory and the service continues to run after

onStartCommand() returns So the service must stop itself by calling stopSelf() or another component

can stop it by calling stopService()

Once requested to stop with stopSelf() or stopService() the system destroys the service as soon as

possible

However if your service handles multiple requests to onStartCommand() concurrently then you

shouldnt stop the service when youre done processing a start request because you might have since

received a new start request (stopping at the end of the first request would terminate the second one)

To avoid this problem you can use stopSelf(int) to ensure that your request to stop the service is

always based on the most recent start request That is when you call stopSelf(int) you pass the ID of

the start request (the startId delivered to onStartCommand()) to which your stop request corresponds

Then if the service received a new start request before you were able to call stopSelf(int) then the ID

will not match and the service will not stop

Caution Its important that your application stops its services when its done working to avoid

wasting system resources and consuming battery power If necessary other components can stop

the service by calling stopService() Even if you enable binding for the service you must always

stop the service yourself if it ever received a call to onStartCommand()

For more information about the lifecycle of a service see the section below about Managing the

Lifecycle of a Service

Creating a Bound Service

A bound service is one that allows application components to bind to it by calling bindService() in order

to create a long-standing connection (and generally does not allow components to start it by calling

startService())

You should create a bound service when you want to interact with the service from activities and other

components in your application or to expose some of your applications functionality to other

applications through interprocess communication (IPC)

To create a bound service you must implement the onBind() callback method to return an IBinder that

defines the interface for communication with the service Other application components can then call

bindService() to retrieve the interface and begin calling methods on the service The service lives only

to serve the application component that is bound to it so when there are no components bound to the

service the system destroys it (you do not need to stop a bound service in the way you must when the

service is started through onStartCommand())

To create a bound service the first thing you must do is define the interface that specifies how a client

can communicate with the service This interface between the service and a client must be an

implementation of IBinder and is what your service must return from the onBind() callback method

Once the client receives the IBinder it can begin interacting with the service through that interface

Multiple clients can bind to the service at once When a client is done interacting with the service it

calls unbindService() to unbind Once there are no clients bound to the service the system destroys

the service

There are multiple ways to implement a bound service and the implementation is more complicated

than a started service so the bound service discussion appears in a separate document about Bound

Services

Sending Notifications to the User

Once running a service can notify the user of events using Toast Notifications or Status Bar

Notifications

A toast notification is a message that appears on the surface of the current window for a moment then

disappears while a status bar notification provides an icon in the status bar with a message which the

user can select in order to take an action (such as start an activity)

Usually a status bar notification is the best technique when some background work has completed

(such as a file completed downloading) and the user can now act on it When the user selects the

notification from the expanded view the notification can start an activity (such as to view the

downloaded file)

See the Toast Notifications or Status Bar Notifications developer guides for more information

Running a Service in the Foreground

A foreground service is a service thats considered to be something the user is actively aware of and

thus not a candidate for the system to kill when low on memory A foreground service must provide a

notification for the status bar which is placed under the Ongoing heading which means that the

notification cannot be dismissed unless the service is either stopped or removed from the foreground

For example a music player that plays music from a service should be set to run in the foreground

because the user is explicitly aware of its operation The notification in the status bar might indicate the

current song and allow the user to launch an activity to interact with the music player

To request that your service run in the foreground call startForeground() This method takes two

parameters an integer that uniquely identifies the notification and the Notification for the status bar

For example

Notification notification = new Notification(Rdrawableicon getText(Rstringticker_text) SystemcurrentTimeMillis()) Intent notificationIntent = new Intent(this ExampleActivityclass) PendingIntent pendingIntent = PendingIntentgetActivity(this 0 notificationIntent 0) notificationsetLatestEventInfo(this getText(Rstringnotification_title) getText(Rstringnotification_message) pendingIntent) startForeground(ONGOING_NOTIFICATION notification)

To remove the service from the foreground call stopForeground() This method takes a boolean

indicating whether to remove the status bar notification as well This method does not stop the service

However if you stop the service while its still running in the foreground then the notification is also

removed

Note The methods startForeground() and stopForeground() were introduced in Android 20 (API

Level 5) In order to run your service in the foreground on older versions of the platform you must

use the previous setForeground() methodmdashsee the startForeground() documentation for

information about how to provide backward compatibility

For more information about notifications see Creating Status Bar Notifications

Managing the Lifecycle of a Service

The lifecycle of a service is much simpler than that of an activity However its even more important

that you pay close attention to how your service is created and destroyed because a service can run

in the background without the user being aware

The service lifecyclemdashfrom when its created to when its destroyedmdashcan follow two different paths

A started service

The service is created when another component calls startService() The service then runs indefinitely

and must stop itself by calling stopSelf() Another component can also stop the service by calling

stopService() When the service is stopped the system destroys it

A bound service

The service is created when another component (a client) calls bindService() The client then

communicates with the service through an IBinder interface The client can close the connection by

calling unbindService() Multiple clients can bind to the same service and when all of them unbind the

system destroys the service (The service does not need to stop itself)

These two paths are not entirely separate That is you can bind to a service that was already started

with startService() For example a background music service could be started by calling startService()

with an Intent that identifies the music to play Later possibly when the user wants to exercise some

control over the player or get information about the current song an activity can bind to the service by

calling bindService() In cases like this stopService() or stopSelf() does not actually stop the service

until all clients unbind

Implementing the lifecycle callbacks

Like an activity a service has lifecycle callback methods that you can implement to monitor changes in

the services state and perform work at the appropriate times The following skeleton service

demonstrates each of the lifecycle methods

Figure 2 The service lifecycle The diagram on the left shows the lifecycle when the service is created

with startService() and the diagram on the right shows the lifecycle when the service is created with

bindService()

public class ExampleService extends Service int mStartMode indicates how to behave if the service is killed IBinder mBinder interface for clients that bind boolean mAllowRebind indicates whether onRebind should be used Override public void onCreate() The service is being created Override public int onStartCommand(Intent intent int flags int startId) The service is starting due to a call to startService() return mStartMode Override public IBinder onBind(Intent intent) A client is binding to the service with bindService() return mBinder Override public boolean onUnbind(Intent intent) All clients have unbound with unbindService()

return mAllowRebind Override public void onRebind(Intent intent) A client is binding to the service with bindService() after onUnbind() has already been called Override public void onDestroy() The service is no longer used and is being destroyed

Note Unlike the activity lifecycle callback methods you are not required to call the superclass

implementation of these callback methods

By implementing these methods you can monitor two nested loops of the services lifecycle

The entire lifetime of a service happens between the time onCreate() is called and the time

onDestroy() returns Like an activity a service does its initial setup in onCreate() and releases all

remaining resources in onDestroy() For example a music playback service could create the thread

where the music will be played in onCreate() then stop the thread in onDestroy()

The onCreate() and onDestroy() methods are called for all services whether theyre created by

startService() or bindService()

The active lifetime of a service begins with a call to either onStartCommand() or onBind() Each

method is handed the Intent that was passed to either startService() or bindService() respectively

If the service is started the active lifetime ends the same time that the entire lifetime ends (the service

is still active even after onStartCommand() returns) If the service is bound the active lifetime ends

when onUnbind() returns

Note Although a started service is stopped by a call to either stopSelf() or stopService() there is

not a respective callback for the service (theres no onStop() callback) So unless the service is

bound to a client the system destroys it when the service is stoppedmdashonDestroy() is the only

callback received

Figure 2 illustrates the typical callback methods for a service Although the figure separates services

that are created by startService() from those created by bindService() keep in mind that any service

no matter how its started can potentially allow clients to bind to it So a service that was initially

started with onStartCommand() (by a client calling startService()) can still receive a call to onBind()

(when a client calls bindService())

For more information about creating a service that provides binding see the Bound Services

document which includes more information about the onRebind() callback method in the section about

Managing the Lifecycle of a Bound Service

Bound Services

A bound service is the server in a client-server interface A bound service allows components (such as

activities) to bind to the service send requests receive responses and even perform interprocess

communication (IPC) A bound service typically lives only while it serves another application

component and does not run in the background indefinitely

This document shows you how to create a bound service including how to bind to the service from

other application components However you should also refer to the Services document for additional

information about services in general such as how to deliver notifications from a service set the

service to run in the foreground and more

The Basics

A bound service is an implementation of the Service class that allows other applications to bind to it

and interact with it To provide binding for a service you must implement the onBind() callback

method This method returns an IBinder object that defines the programming interface that clients can

use to interact with the service

Binding to a Started Service

As discussed in the Services document you can create a service that is both started and bound That

is the service can be started by calling startService() which allows the service to run indefinitely and

also allow a client to bind to the service by calling bindService()

If you do allow your service to be started and bound then when the service has been started the

system does not destroy the service when all clients unbind Instead you must explicitly stop the

service by calling stopSelf() or stopService()

Although you should usually implement either onBind() or onStartCommand() its sometimes

necessary to implement both For example a music player might find it useful to allow its service to run

indefinitely and also provide binding This way an activity can start the service to play some music and

the music continues to play even if the user leaves the application Then when the user returns to the

application the activity can bind to the service to regain control of playback

Be sure to read the section about Managing the Lifecycle of a Bound Service for more information

about the service lifecycle when adding binding to a started service

A client can bind to the service by calling bindService() When it does it must provide an

implementation of ServiceConnection which monitors the connection with the service The

bindService() method returns immediately without a value but when the Android system creates the

connection between the client and service it calls onServiceConnected() on the ServiceConnection to

deliver the IBinder that the client can use to communicate with the service

Multiple clients can connect to the service at once However the system calls your services onBind()

method to retrieve the IBinder only when the first client binds The system then delivers the same

IBinder to any additional clients that bind without calling onBind() again

When the last client unbinds from the service the system destroys the service (unless the service was

also started by startService())

When you implement your bound service the most important part is defining the interface that your

onBind() callback method returns There are a few different ways you can define your services IBinder

interface and the following section discusses each technique

Creating a Bound Service

When creating a service that provides binding you must provide an IBinder that provides the

programming interface that clients can use to interact with the service There are three ways you can

define the interface

Extending the Binder class

If your service is private to your own application and runs in the same process as the client

(which is common) you should create your interface by extending the Binder class and

returning an instance of it from onBind() The client receives the Binder and can use it to directly

access public methods available in either the Binder implementation or even the Service

This is the preferred technique when your service is merely a background worker for your own

application The only reason you would not create your interface this way is because your

service is used by other applications or across separate processes

Using a Messenger

If you need your interface to work across different processes you can create an interface for the

service with a Messenger In this manner the service defines a Handler that responds to

different types of Message objects This Handler is the basis for a Messenger that can then

share an IBinder with the client allowing the client to send commands to the service using

Message objects Additionally the client can define a Messenger of its own so the service can

send messages back

This is the simplest way to perform interprocess communication (IPC) because the Messenger

queues all requests into a single thread so that you dont have to design your service to be

thread-safe

Using AIDL

AIDL (Android Interface Definition Language) performs all the work to decompose objects into

primitives that the operating system can understand and marshall them across processes to

perform IPC The previous technique using a Messenger is actually based on AIDL as its

underlying structure As mentioned above the Messenger creates a queue of all the client

requests in a single thread so the service receives requests one at a time If however you

want your service to handle multiple requests simultaneously then you can use AIDL directly In

this case your service must be capable of multi-threading and be built thread-safe

To use AIDL directly you must create an aidl file that defines the programming interface The

Android SDK tools use this file to generate an abstract class that implements the interface and

handles IPC which you can then extend within your service

Note Most applications should not use AIDL to create a bound service because it may require

multithreading capabilities and can result in a more complicated implementation As such AIDL is

not suitable for most applications and this document does not discuss how to use it for your

service If youre certain that you need to use AIDL directly see the AIDL document

Extending the Binder class

If your service is used only by the local application and does not need to work across processes then

you can implement your own Binder class that provides your client direct access to public methods in

the service

Note This works only if the client and service are in the same application and process which is

most common For example this would work well for a music application that needs to bind an

activity to its own service thats playing music in the background

Heres how to set it up

1 In your service create an instance of Binder that either

o contains public methods that the client can call

o returns the current Service instance which has public methods the client can call

o or returns an instance of another class hosted by the service with public methods the client can call

2 Return this instance of Binder from the onBind() callback method

3 In the client receive the Binder from the onServiceConnected() callback method and make calls to the

bound service using the methods provided

Note The reason the service and client must be in the same application is so the client can cast

the returned object and properly call its APIs The service and client must also be in the same

process because this technique does not perform any marshalling across processes

For example heres a service that provides clients access to methods in the service through a Binder

implementation

public class LocalService extends Service

Binder given to clients

private final IBinder mBinder = new LocalBinder()

Random number generator

private final Random mGenerator = new Random()

Class used for the client Binder Because we know this service always

runs in the same process as its clients we dont need to deal with IPC

public class LocalBinder extends Binder

LocalService getService()

Return this instance of LocalService so clients can call public methods

return LocalServicethis

Override

public IBinder onBind(Intent intent)

return mBinder

method for clients

public int getRandomNumber()

return mGeneratornextInt(100)

The LocalBinder provides the getService() method for clients to retrieve the current instance of

LocalService This allows clients to call public methods in the service For example clients can call

getRandomNumber() from the service

Heres an activity that binds to LocalService and calls getRandomNumber() when a button is clicked

public class BindingActivity extends Activity

LocalService mService

boolean mBound = false

Override

protected void onCreate(Bundle savedInstanceState)

superonCreate(savedInstanceState)

setContentView(Rlayoutmain)

Override

protected void onStart()

superonStart()

Bind to LocalService

Intent intent = new Intent(this LocalServiceclass)

bindService(intent mConnection ContextBIND_AUTO_CREATE)

Override

protected void onStop()

superonStop()

Unbind from the service

if (mBound)

unbindService(mConnection)

mBound = false

Called when a button is clicked (the button in the layout file attaches to

this method with the androidonClick attribute)

public void onButtonClick(View v)

if (mBound)

Call a method from the LocalService

However if this call were something that might hang then this request should

occur in a separate thread to avoid slowing down the activity performance

int num = mServicegetRandomNumber()

ToastmakeText(this number + num ToastLENGTH_SHORT)show()

Defines callbacks for service binding passed to bindService()

private ServiceConnection mConnection = new ServiceConnection()

Override

public void onServiceConnected(ComponentName className

IBinder service)

Weve bound to LocalService cast the IBinder and get LocalService instance

LocalBinder binder = (LocalBinder) service

mService = bindergetService()

mBound = true

Override

public void onServiceDisconnected(ComponentName arg0)

mBound = false

The above sample shows how the client binds to the service using an implementation of

ServiceConnection and the onServiceConnected() callback The next section provides more

information about this process of binding to the service

Note The example above doesnt explicitly unbind from the service but all clients should unbind

at an appropriate time (such as when the activity pauses)

For more sample code see the LocalServicejava class and the LocalServiceActivitiesjava class in

ApiDemos

Using a Messenger

Compared to AIDL

When you need to perform IPC using a Messenger for your interface is simpler than implementing it

with AIDL because Messenger queues all calls to the service whereas a pure AIDL interface sends

simultaneous requests to the service which must then handle multi-threading

For most applications the service doesnt need to perform multi-threading so using a Messenger

allows the service to handle one call at a time If its important that your service be multi-threaded then

you should use AIDL to define your interface

If you need your service to communicate with remote processes then you can use a Messenger to

provide the interface for your service This technique allows you to perform interprocess

communication (IPC) without the need to use AIDL

Heres a summary of how to use a Messenger

The service implements a Handler that receives a callback for each call from a client

The Handler is used to create a Messenger object (which is a reference to the Handler)

The Messenger creates an IBinder that the service returns to clients from onBind()

Clients use the IBinder to instantiate the Messenger (that references the services Handler) which the

client uses to send Message objects to the service

The service receives each Message in its Handlermdashspecifically in the handleMessage() method

In this way there are no methods for the client to call on the service Instead the client delivers

messages (Message objects) that the service receives in its Handler

Heres a simple example service that uses a Messenger interface

public class MessengerService extends Service Command to the service to display a message static final int MSG_SAY_HELLO = 1 Handler of incoming messages from clients class IncomingHandler extends Handler Override public void handleMessage(Message msg) switch (msgwhat) case MSG_SAY_HELLO ToastmakeText(getApplicationContext() hello ToastLENGTH_SHORT)show() break default superhandleMessage(msg) Target we publish for clients to send messages to IncomingHandler final Messenger mMessenger = new Messenger(new IncomingHandler()) When binding to the service we return an interface to our messenger for sending messages to the service Override public IBinder onBind(Intent intent) ToastmakeText(getApplicationContext() binding ToastLENGTH_SHORT)show() return mMessengergetBinder()

Notice that the handleMessage() method in the Handler is where the service receives the incoming

Message and decides what to do based on the what member

All that a client needs to do is create a Messenger based on the IBinder returned by the service and

send a message using send() For example heres a simple activity that binds to the service and

delivers the MSG_SAY_HELLO message to the service

public class ActivityMessenger extends Activity Messenger for communicating with the service Messenger mService = null Flag indicating whether we have called bind on the service boolean mBound Class for interacting with the main interface of the service private ServiceConnection mConnection = new ServiceConnection() public void onServiceConnected(ComponentName className IBinder service) This is called when the connection with the service has been established giving us the object we can use to interact with the service We are communicating with the service using a Messenger so here we get a client-side representation of that from the raw IBinder object mService = new Messenger(service) mBound = true public void onServiceDisconnected(ComponentName className) This is called when the connection with the service has been unexpectedly disconnected -- that is its process crashed mService = null mBound = false public void sayHello(View v) if (mBound) return Create and send a message to the service using a supported what value Message msg = Messageobtain(null MessengerServiceMSG_SAY_HELLO 0 0) try mServicesend(msg) catch (RemoteException e) eprintStackTrace() Override protected void onCreate(Bundle savedInstanceState) superonCreate(savedInstanceState) setContentView(Rlayoutmain)

Override protected void onStart() superonStart() Bind to the service bindService(new Intent(this MessengerServiceclass) mConnection ContextBIND_AUTO_CREATE) Override protected void onStop() superonStop() Unbind from the service if (mBound) unbindService(mConnection) mBound = false

Notice that this example does not show how the service can respond to the client If you want the

service to respond then you need to also create a Messenger in the client Then when the client

receives the onServiceConnected() callback it sends a Message to the service that includes the

clients Messenger in the replyTo parameter of the send() method

You can see an example of how to provide two-way messaging in the MessengerServicejava (service)

and MessengerServiceActivitiesjava (client) samples

Binding to a Service

Application components (clients) can bind to a service by calling bindService() The Android system

then calls the services onBind() method which returns an IBinder for interacting with the service

The binding is asynchronous bindService() returns immediately and does not return the IBinder to the

client To receive the IBinder the client must create an instance of ServiceConnection and pass it to

bindService() The ServiceConnection includes a callback method that the system calls to deliver the

IBinder

Note Only activities services and content providers can bind to a servicemdashyou cannot bind to a

service from a broadcast receiver

So to bind to a service from your client you must

1 Implement ServiceConnection

Your implementation must override two callback methods

onServiceConnected()

The system calls this to deliver the IBinder returned by the services onBind() method

onServiceDisconnected()

The Android system calls this when the connection to the service is unexpectedly lost such as

when the service has crashed or has been killed This is not called when the client unbinds

2 Call bindService() passing the ServiceConnection implementation

3 When the system calls your onServiceConnected() callback method you can begin making calls to the

service using the methods defined by the interface

4 To disconnect from the service call unbindService()

When your client is destroyed it will unbind from the service but you should always unbind when

youre done interacting with the service or when your activity pauses so that the service can shutdown

while its not being used (Appropriate times to bind and unbind is discussed more below)

For example the following snippet connects the client to the service created above by extending the

Binder class so all it must do is cast the returned IBinder to the LocalService class and request the

LocalService instance

LocalService mService private ServiceConnection mConnection = new ServiceConnection() Called when the connection with the service is established public void onServiceConnected(ComponentName className IBinder service) Because we have bound to an explicit service that is running in our own process we can cast its IBinder to a concrete class and directly access it LocalBinder binder = (LocalBinder) service mService = bindergetService() mBound = true Called when the connection with the service disconnects unexpectedly public void onServiceDisconnected(ComponentName className) Loge(TAG onServiceDisconnected) mBound = false

With this ServiceConnection the client can bind to a service by passing this it to bindService() For

example

Intent intent = new Intent(this LocalServiceclass) bindService(intent mConnection ContextBIND_AUTO_CREATE)

The first parameter of bindService() is an Intent that explicitly names the service to bind (thought the

intent could be implicit)

The second parameter is the ServiceConnection object

The third parameter is a flag indicating options for the binding It should usually be

BIND_AUTO_CREATE in order to create the service if its not already alive Other possible values are

BIND_DEBUG_UNBIND and BIND_NOT_FOREGROUND or 0 for none

Additional notes

Here are some important notes about binding to a service

You should always trap DeadObjectException exceptions which are thrown when the connection has

broken This is the only exception thrown by remote methods

Objects are reference counted across processes

You should usually pair the binding and unbinding during matching bring-up and tear-down moments

of the clients lifecycle For example

o If you only need to interact with the service while your activity is visible you should bind during

onStart() and unbind during onStop()

o If you want your activity to receive responses even while it is stopped in the background then you can

bind during onCreate() and unbind during onDestroy() Beware that this implies that your activity needs

to use the service the entire time its running (even in the background) so if the service is in another

process then you increase the weight of the process and it becomes more likely that the system will

kill it

Note You should usually not bind and unbind during your activitys onResume() and onPause()

because these callbacks occur at every lifecycle transition and you should keep the processing that

occurs at these transitions to a minimum Also if multiple activities in your application bind to the same

service and there is a transition between two of those activities the service may be destroyed and

recreated as the current activity unbinds (during pause) before the next one binds (during resume)

(This activity transition for how activities coordinate their lifecycles is described in the Activities

document)

For more sample code showing how to bind to a service see the RemoteServicejava class in

ApiDemos

Managing the Lifecycle of a Bound Service

Figure 1 The lifecycle for a service

that is started and also allows binding

When a service is unbound from all

clients the Android system destroys it

(unless it was also started with

onStartCommand()) As such you

dont have to manage the lifecycle of

your service if its purely a bound

servicemdashthe Android system manages

it for you based on whether it is bound

to any clients

However if you choose to implement

the onStartCommand() callback

method then you must explicitly stop

the service because the service is

now considered to be started In this

case the service runs until the service

stops itself with stopSelf() or another

component calls stopService()

regardless of whether it is bound to

any clients

Additionally if your service is started and accepts binding then when the system calls your onUnbind()

method you can optionally return true if you would like to receive a call to onRebind() the next time a

client binds to the service (instead of receiving a call to onBind()) onRebind() returns void but the

client still receives the IBinder in its onServiceConnected() callback Below figure 1 illustrates the logic

for this kind of lifecycle

For more information about the lifecycle of an started service see the Services document

Content Providers

Content providers store and retrieve data and make it accessible to all applications Theyre the only

way to share data across applications theres no common storage area that all Android packages can

access

Android ships with a number of content providers for common data types (audio video images

personal contact information and so on) You can see some of them listed in the androidprovider

package You can query these providers for the data they contain (although for some you must

acquire the proper permission to read the data)

If you want to make your own data public you have two options You can create your own content

provider (a ContentProvider subclass) or you can add the data to an existing provider mdash if theres one

that controls the same type of data and you have permission to write to it

This document is an introduction to using content providers After a brief discussion of the

fundamentals it explores how to query a content provider how to modify data controlled by a provider

and how to create a content provider of your own

Content Provider Basics

How a content provider actually stores its data under the covers is up to its designer But all content

providers implement a common interface for querying the provider and returning results mdash as well as

for adding altering and deleting data Its an interface that clients use indirectly most generally

through ContentResolver objects You get a ContentResolver by calling getContentResolver() from

within the implementation of an Activity or other application component

ContentResolver cr = getContentResolver()

You can then use the ContentResolvers methods to interact with whatever content providers youre

interested in When a query is initiated the Android system identifies the content provider thats the

target of the query and makes sure that it is up and running The system instantiates all

ContentProvider objects you never need to do it on your own In fact you never deal directly with

ContentProvider objects at all Typically theres just a single instance of each type of ContentProvider

But it can communicate with multiple ContentResolver objects in different applications and processes

The interaction between processes is handled by the ContentResolver and ContentProvider classes

The data model

Content providers expose their data as a simple table on a database model where each row is a

record and each column is data of a particular type and meaning For example information about

people and their phone numbers might be exposed as follows

_ID NUMBER NUMBER_KEY LABEL NAME TYPE

13 (425) 555 6677 425 555 6677 Kirkland office Bully Pulpit TYPE_WORK

44 (212) 555-1234 212 555 1234 NY apartment Alan Vain TYPE_HOME

45 (212) 555-6657 212 555 6657 Downtown office Alan Vain TYPE_MOBILE

53 2015554433 201 555 4433 Love Nest Rex Cars TYPE_HOME

Every record includes a numeric _ID field that uniquely identifies the record within the table IDs can be

used to match records in related tables mdash for example to find a persons phone number in one table

and pictures of that person in another

A query returns a Cursor object that can move from record to record and column to column to read the

contents of each field It has specialized methods for reading each type of data So to read a field you

must know what type of data the field contains (Theres more on query results and Cursor objects

later)

URIs

Each content provider exposes a public URI (wrapped as a Uri object) that uniquely identifies its data

set A content provider that controls multiple data sets (multiple tables) exposes a separate URI for

each one All URIs for providers begin with the string content The content scheme identifies the

data as being controlled by a content provider

If youre defining a content provider its a good idea to also define a constant for its URI to simplify

client code and make future updates cleaner Android defines CONTENT_URI constants for all the

providers that come with the platform For example the URI for the table that matches phone numbers

to people and the URI for the table that holds pictures of people (both controlled by the Contacts

content provider) are

androidproviderContactsPhonesCONTENT_URI

androidproviderContactsPhotosCONTENT_URI

The URI constant is used in all interactions with the content provider Every ContentResolver method

takes the URI as its first argument Its what identifies which provider the ContentResolver should talk

to and which table of the provider is being targeted

Querying a Content Provider

You need three pieces of information to query a content provider

The URI that identifies the provider

The names of the data fields you want to receive

The data types for those fields

If youre querying a particular record you also need the ID for that record

Making the query

To query a content provider you can use either the ContentResolverquery() method or the

ActivitymanagedQuery() method Both methods take the same set of arguments and both return a

Cursor object However managedQuery() causes the activity to manage the life cycle of the Cursor A

managed Cursor handles all of the niceties such as unloading itself when the activity pauses and

requerying itself when the activity restarts You can ask an Activity to begin managing an unmanaged

Cursor object for you by calling ActivitystartManagingCursor()

The first argument to either query() or managedQuery() is the provider URI mdash the CONTENT_URI

constant that identifies a particular ContentProvider and data set (see URIs earlier)

To restrict a query to just one record you can append the _ID value for that record to the URI mdash that

is place a string matching the ID as the last segment of the path part of the URI For example if the ID

is 23 the URI would be

content 23

There are some helper methods particularly ContentUriswithAppendedId() and

UriwithAppendedPath() that make it easy to append an ID to a URI Both are static methods that

return a Uri object with the ID added So for example if you were looking for record 23 in the database

of people contacts you might construct a query as follows

import androidproviderContactsPeople import androidcontentContentUris import androidnetUri import androiddatabaseCursor Use the ContentUris method to produce the base URI for the contact with _ID == 23 Uri myPerson = ContentUriswithAppendedId(PeopleCONTENT_URI 23) Alternatively use the Uri method to produce the base URI It takes a string rather than an integer Uri myPerson = UriwithAppendedPath(PeopleCONTENT_URI 23) Then query for this specific record Cursor cur = managedQuery(myPerson null null null null)

The other arguments to the query() and managedQuery() methods delimit the query in more detail

They are

The names of the data columns that should be returned A null value returns all columns Otherwise

only columns that are listed by name are returned All the content providers that come with the

platform define constants for their columns For example the androidproviderContactsPhones class

defines constants for the names of the columns in the phone table illustrated earlier ampmdash _ID

NUMBER NUMBER_KEY NAME and so on

A filter detailing which rows to return formatted as an SQL WHERE clause (excluding the WHERE

itself) A null value returns all rows (unless the URI limits the query to a single record)

Selection arguments

A sorting order for the rows that are returned formatted as an SQL ORDER BY clause (excluding the

ORDER BY itself) A null value returns the records in the default order for the table which may be

unordered

Lets look at an example query to retrieve a list of contact names and their primary phone numbers

import androidproviderContactsPeople import androiddatabaseCursor Form an array specifying which columns to return String[] projection = new String[] People_ID People_COUNT PeopleNAME PeopleNUMBER Get the base URI for the People table in the Contacts content provider Uri contacts = PeopleCONTENT_URI Make the query Cursor managedCursor = managedQuery(contacts projection Which columns to return null Which rows to return (all rows) null Selection arguments (none) Put the results in ascending order by name PeopleNAME + ASC)

This query retrieves data from the People table of the Contacts content provider It gets the name

primary phone number and unique record ID for each contact It also reports the number of records

that are returned as the _COUNT field of each record

The constants for the names of the columns are defined in various interfaces mdash _ID and _COUNT in

BaseColumns NAME in PeopleColumns and NUMBER in PhoneColumns The ContactsPeople

class implements each of these interfaces which is why the code example above could refer to them

using just the class name

What a query returns

A query returns a set of zero or more database records The names of the columns their default order

and their data types are specific to each content provider But every provider has an _ID column

which holds a unique numeric ID for each record Every provider can also report the number of records

returned as the _COUNT column its value is the same for all rows

Here is an example result set for the query in the previous section

_ID _COUNT NAME NUMBER

44 3 Alan Vain 212 555 1234

13 3 Bully Pulpit 425 555 6677

53 3 Rex Cars 201 555 4433

The retrieved data is exposed by a Cursor object that can be used to iterate backward or forward

through the result set You can use this object only to read the data To add modify or delete data

you must use a ContentResolver object

Reading retrieved data

The Cursor object returned by a query provides access to a recordset of results If you have queried

for a specific record by ID this set will contain only one value Otherwise it can contain multiple

values (If there are no matches it can also be empty) You can read data from specific fields in the

record but you must know the data type of the field because the Cursor object has a separate method

for reading each type of data mdash such as getString() getInt() and getFloat() (However for most types

if you call the method for reading strings the Cursor object will give you the String representation of

the data) The Cursor lets you request the column name from the index of the column or the index

number from the column name

The following snippet demonstrates reading names and phone numbers from the query illustrated

earlier

import androidproviderContactsPeople private void getColumnData(Cursor cur) if (curmoveToFirst()) String name String phoneNumber int nameColumn = curgetColumnIndex(PeopleNAME) int phoneColumn = curgetColumnIndex(PeopleNUMBER) String imagePath do Get the field values name = curgetString(nameColumn) phoneNumber = curgetString(phoneColumn) Do something with the values while (curmoveToNext())

If a query can return binary data such as an image or sound the data may be directly entered in the

table or the table entry for that data may be a string specifying a content URI that you can use to get

the data In general smaller amounts of data (say from 20 to 50K or less) are most often directly

entered in the table and can be read by calling CursorgetBlob() It returns a byte array

If the table entry is a content URI you should never try to open and read the file directly (for one thing

permissions problems can make this fail) Instead you should call ContentResolveropenInputStream()

to get an InputStream object that you can use to read the data

Modifying Data

Data kept by a content provider can be modified by

Adding new records

Adding new values to existing records

Batch updating existing records

Deleting records

All data modification is accomplished using ContentResolver methods Some content providers require

a more restrictive permission for writing data than they do for reading it If you dont have permission to

write to a content provider the ContentResolver methods will fail

Adding records

To add a new record to a content provider first set up a map of key-value pairs in a ContentValues

object where each key matches the name of a column in the content provider and the value is the

desired value for the new record in that column Then call ContentResolverinsert() and pass it the URI

of the provider and the ContentValues map This method returns the full URI of the new record mdash that

is the providers URI with the appended ID for the new record You can then use this URI to query and

get a Cursor over the new record and to further modify the record Heres an example

import androidproviderContactsPeople import androidcontentContentResolver import androidcontentContentValues ContentValues values = new ContentValues() Add Abraham Lincoln to contacts and make him a favorite valuesput(PeopleNAME Abraham Lincoln) 1 = the new contact is added to favorites 0 = the new contact is not added to favorites valuesput(PeopleSTARRED 1) Uri uri = getContentResolver()insert(PeopleCONTENT_URI values)

Adding new values

Once a record exists you can add new information to it or modify existing information For example

the next step in the example above would be to add contact information mdash like a phone number or an

IM or e-mail address mdash to the new entry

The best way to add to a record in the Contacts database is to append the name of the table where the

new data goes to the URI for the record then use the amended URI to add the new data values Each

Contacts table exposes a name for this purpose as a CONTENT_DIRECTORY constant The following

code continues the previous example by adding a phone number and e-mail address for the record

just created

Uri phoneUri = null Uri emailUri = null Add a phone number for Abraham Lincoln Begin with the URI for the new record just returned by insert() it ends with the _ID of the new record so we dont have to add the ID ourselves Then append the designation for the phone table to this URI and use the resulting URI to insert the phone number phoneUri = UriwithAppendedPath(uri PeoplePhonesCONTENT_DIRECTORY) valuesclear() valuesput(PeoplePhonesTYPE PeoplePhonesTYPE_MOBILE) valuesput(PeoplePhonesNUMBER 1233214567) getContentResolver()insert(phoneUri values) Now add an email address in the same way emailUri = UriwithAppendedPath(uri PeopleContactMethodsCONTENT_DIRECTORY) valuesclear() ContactMethodsKIND is used to distinguish different kinds of contact methods such as email IM etc valuesput(PeopleContactMethodsKIND ContactsKIND_EMAIL) valuesput(PeopleContactMethodsDATA testexamplecom) valuesput(PeopleContactMethodsTYPE PeopleContactMethodsTYPE_HOME) getContentResolver()insert(emailUri values)

You can place small amounts of binary data into a table by calling the version of ContentValuesput()

that takes a byte array That would work for a small icon-like image or a short audio clip for example

However if you have a large amount of binary data to add such as a photograph or a complete song

put a content URI for the data in the table and call ContentResolveropenOutputStream() with the files

URI (That causes the content provider to store the data in a file and record the file path in a hidden

field of the record)

In this regard the MediaStore content provider the main provider that dispenses image audio and

video data employs a special convention The same URI that is used with query() or managedQuery()

to get meta-information about the binary data (such as the caption of a photograph or the date it was

taken) is used with openInputStream() to get the data itself Similarly the same URI that is used with

insert() to put meta-information into a MediaStore record is used with openOutputStream() to place the

binary data there The following code snippet illustrates this convention

import androidproviderMediaStoreImagesMedia import androidcontentContentValues import javaioOutputStream Save the name and description of an image in a ContentValues map ContentValues values = new ContentValues(3) valuesput(MediaDISPLAY_NAME road_trip_1) valuesput(MediaDESCRIPTION Day 1 trip to Los Angeles) valuesput(MediaMIME_TYPE imagejpeg) Add a new record without the bitmap but with the values just set insert() returns the URI of the new record Uri uri = getContentResolver()insert(MediaEXTERNAL_CONTENT_URI values) Now get a handle to the file for that record and save the data into it Here sourceBitmap is a Bitmap object representing the file to save to the database try OutputStream outStream = getContentResolver()openOutputStream(uri) sourceBitmapcompress(BitmapCompressFormatJPEG 50 outStream) outStreamclose() catch (Exception e) Loge(TAG exception while writing image e)

Batch updating records

To batch update a group of records (for example to change NY to New York in all fields) call the

ContentResolverupdate() method with the columns and values to change

Deleting a record

To delete a single record call ContentResolverdelete() with the URI of a specific row

To delete multiple rows call ContentResolverdelete() with the URI of the type of record to delete (for

example androidproviderContactsPeopleCONTENT_URI) and an SQL WHERE clause defining

which rows to delete (Caution Be sure to include a valid WHERE clause if youre deleting a general

type or you risk deleting more records than you intended)

Creating a Content Provider

To create a content provider you must

Set up a system for storing the data Most content providers store their data using Androids file

storage methods or SQLite databases but you can store your data any way you want Android

provides the SQLiteOpenHelper class to help you create a database and SQLiteDatabase to manage

it

Extend the ContentProvider class to provide access to the data

Declare the content provider in the manifest file for your application (AndroidManifestxml)

The following sections have notes on the last two of these tasks

Extending the ContentProvider class

You define a ContentProvider subclass to expose your data to others using the conventions expected

by ContentResolver and Cursor objects Principally this means implementing six abstract methods

declared in the ContentProvider class

query()

insert()

update()

delete()

getType()

onCreate()

The query() method must return a Cursor object that can iterate over the requested data Cursor itself

is an interface but Android provides some ready-made Cursor objects that you can use For example

SQLiteCursor can iterate over data stored in an SQLite database You get the Cursor object by calling

any of the SQLiteDatabase classs query() methods There are other Cursor implementations mdash such

as MatrixCursor mdash for data not stored in a database

Because these ContentProvider methods can be called from various ContentResolver objects in

different processes and threads they must be implemented in a thread-safe manner

As a courtesy you might also want to call ContentResolvernotifyChange() to notify listeners when

there are modifications to the data

Beyond defining the subclass itself there are other steps you should take to simplify the work of clients

and make the class more accessible

Define a public static final Uri named CONTENT_URI This is the string that represents the full content

URI that your content provider handles You must define a unique string for this value The best

solution is to use the fully-qualified class name of the content provider (made lowercase) So for

example the URI for a TransportationProvider class could be defined as follows

public static final Uri CONTENT_URI = Uriparse(contentcomexamplecodelabtransportationprovider)

If the provider has subtables also define CONTENT_URI constants for each of the subtables These

URIs should all have the same authority (since that identifies the content provider) and be

distinguished only by their paths For example

contentcomexamplecodelabtransportationprovidertrain

contentcomexamplecodelabtransportationproviderairdomestic

contentcomexamplecodelabtransportationproviderairinternational

For an overview of content URIs see the Content URI Summary at the end of this document

Define the column names that the content provider will return to clients If you are using an underlying

database these column names are typically identical to the SQL database column names they

represent Also define public static String constants that clients can use to specify the columns in

queries and other instructions

Be sure to include an integer column named _id (with the constant _ID) for the IDs of the records

You should have this field whether or not you have another field (such as a URL) that is also unique

among all records If youre using the SQLite database the _ID field should be the following type

INTEGER PRIMARY KEY AUTOINCREMENT

The AUTOINCREMENT descriptor is optional But without it SQLite increments an ID counter field to

the next number above the largest existing number in the column If you delete the last row the next

row added will have the same ID as the deleted row AUTOINCREMENT avoids this by having SQLite

increment to the next largest value whether deleted or not

Carefully document the data type of each column Clients need this information to read the data

If you are handling a new data type you must define a new MIME type to return in your

implementation of ContentProvidergetType() The type depends in part on whether or not the content

URI submitted to getType() limits the request to a specific record Theres one form of the MIME type

for a single record and another for multiple records Use the Uri methods to help determine what is

being requested Here is the general format for each type

o For a single record vndandroidcursoritemvndyourcompanynamecontenttype

For example a request for train record 122 like this URI

contentcomexampletransportationprovidertrains122

might return this MIME type

vndandroidcursoritemvndexamplerail

o For multiple records vndandroidcursordirvndyourcompanynamecontenttype

For example a request for all train records like the following URI

contentcomexampletransportationprovidertrains

might return this MIME type

vndandroidcursordirvndexamplerail

If you are exposing byte data thats too big to put in the table itself mdash such as a large bitmap file mdash the

field that exposes the data to clients should actually contain a content URI string This is the field that

gives clients access to the data file The record should also have another field named _data that lists

the exact file path on the device for that file This field is not intended to be read by the client but by

the ContentResolver The client will call ContentResolveropenInputStream() on the user-facing field

holding the URI for the item The ContentResolver will request the _data field for that record and

because it has higher permissions than a client it should be able to access that file directly and return

a read wrapper for the file to the client

For an example of a private content provider implementation see the NodePadProvider class in the

Notepad sample application that ships with the SDK

Declaring the content provider

To let the Android system know about the content provider youve developed declare it with a

ltprovidergt element in the applications AndroidManifestxml file Content providers that are not

declared in the manifest are not visible to the Android system

The name attribute is the fully qualified name of the ContentProvider subclass The authorities attribute

is the authority part of the content URI that identifies the provider For example if the ContentProvider

subclass is AutoInfoProvider the ltprovidergt element might look like this

ltprovider androidname=comexampleautosAutoInfoProvider androidauthorities=comexampleautosautoinfoprovider gt ltprovidergt

Note that the authorities attribute omits the path part of a content URI For example if

AutoInfoProvider controlled subtables for different types of autos or different manufacturers

contentcomexampleautosautoinfoproviderhonda

contentcomexampleautosautoinfoprovidergmcompact

contentcomexampleautosautoinfoprovidergmsuv

those paths would not be declared in the manifest The authority is what identifies the provider not the

path your provider can interpret the path part of the URI in any way you choose

Other ltprovidergt attributes can set permissions to read and write data provide for an icon and text

that can be displayed to users enable and disable the provider and so on Set the multiprocess

attribute to true if data does not need to be synchronized between multiple running versions of the

content provider This permits an instance of the provider to be created in each client process

eliminating the need to perform IPC

Content URI Summary

Here is a recap of the important parts of a content URI

A Standard prefix indicating that the data is controlled by a content provider Its never modified

B The authority part of the URI it identifies the content provider For third-party applications this should

be a fully-qualified class name (reduced to lowercase) to ensure uniqueness The authority is declared

in the ltprovidergt elements authorities attribute

ltprovider androidname=TransportationProvider androidauthorities=comexampletransportationprovider gt

C The path that the content provider uses to determine what kind of data is being requested This can be

zero or more segments long If the content provider exposes only one type of data (only trains for

example) it can be absent If the provider exposes several types including subtypes it can be several

segments long mdash for example landbus landtrain seaship and seasubmarine to give four

possibilities

D The ID of the specific record being requested if any This is the _ID value of the requested record If

the request is not limited to a single record this segment and the trailing slash are omitted

contentcomexampletransportationprovidertrains

Intent and intent filters

Three of the core components of an application mdash activities services and broadcast receivers mdash 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 mdash 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 ContextstartActivity() or ActivitystartActivityForResult() to launch an

activity or get an existing activity to do something new (It can also be passed to ActivitysetResult() to

return information to the activity that called startActivityForResult())

An Intent object is passed to ContextstartService() to initiate a service or deliver new instructions to an

ongoing service Similarly an intent can be passed to ContextbindService() to establish a connection

between the calling component and a target service It can optionally initiate the service if its not

already running

Intent objects passed to any of the broadcast methods (such as ContextsendBroadcast()

ContextsendOrderedBroadcast() or ContextsendStickyBroadcast()) 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 mdash how it resolves which component should receive an intent message For

intents that dont explicitly name a target component this process involves testing the Intent object

against intent filters associated with potential targets

Intent Objects

An Intent object is a bundle of information It contains information of interest to the component that

receives the intent (such as the action to be taken and the data to act on) plus information of interest to

the Android system (such as the category of component that should handle the intent and instructions

on how to launch a target activity) Principally it can contain the following

Component name

The name of the component that should handle the intent This field is a ComponentName

object mdash a combination of the fully qualified class name of the target component (for example

comexampleprojectappFreneticActivity) and the package name set in the manifest file of the

application where the component resides (for example comexampleproject) The package

part of the component name and the package name set in the manifest do not necessarily have

to match

The component name is optional If it is set the Intent object is delivered to an instance of the

designated class If it is not set Android uses other information in the Intent object to locate a

suitable target mdash see Intent Resolution later in this document

The component name is set by setComponent() setClass() or setClassName() and read by

getComponent()

Action

A string naming the action to be performed mdash or in the case of broadcast intents the action

that took place and is being reported The Intent class defines a number of action constants

including these

Constant Target

component

Action

ACTION_CALL activity Initiate a phone call

ACTION_EDIT activity Display data for the user to edit

ACTION_MAIN activity Start up as the initial activity of a task

with no data input and no returned

output

ACTION_SYNC activity Synchronize data on a server with

data on the mobile device

ACTION_BATTERY_LOW broadcast

receiver

A warning that the battery is low

ACTION_HEADSET_PLUG broadcast

receiver

A headset has been plugged into the

device or unplugged from it

ACTION_SCREEN_ON broadcast

receiver

The screen has been turned on

ACTION_TIMEZONE_CHANGED broadcast

receiver

The setting for the time zone has

changed

See the Intent class description for a list of pre-defined constants for generic actions Other

actions are defined elsewhere in the Android API You can also define your own action strings

for activating the components in your application Those you invent should include the

application package as a prefix mdash for example comexampleprojectSHOW_COLOR

The action largely determines how the rest of the intent is structured mdash particularly the data and

extras fields mdash much as a method name determines a set of arguments and a return value For

this reason its a good idea to use action names that are as specific as possible and to couple

them tightly to the other fields of the intent In other words instead of defining an action in

isolation define an entire protocol for the Intent objects your components can handle

The action in an Intent object is set by the setAction() method and read by getAction()

Data

The URI of the data to be acted on and the MIME type of that data Different actions are paired

with different kinds of data specifications For example if the action field is ACTION_EDIT the

data field would contain the URI of the document to be displayed for editing If the action is

ACTION_CALL the data field would be a tel URI with the number to call Similarly if the action

is ACTION_VIEW and the data field is an http URI the receiving activity would be called upon

to download and display whatever data the URI refers to

When matching an intent to a component that is capable of handling the data its often

important to know the type of data (its MIME type) in addition to its URI For example a

component able to display image data should not be called upon to play an audio file

In many cases the data type can be inferred from the URI mdash particularly content URIs which

indicate that the data is located on the device and controlled by a content provider (see the

separate discussion on content providers) But the type can also be explicitly set in the Intent

object The setData() method specifies data only as a URI setType() specifies it only as a

MIME type and setDataAndType() specifies it as both a URI and a MIME type The URI is read

by getData() and the type by getType()

Category

A string containing additional information about the kind of component that should handle the

intent Any number of category descriptions can be placed in an Intent object As it does for

actions the Intent class defines several category constants including these

Constant Meaning

CATEGORY_BROWSABLE The target activity can be safely invoked by the browser to

display data referenced by a link mdash for example an image or

an e-mail message

CATEGORY_GADGET The activity can be embedded inside of another activity that

hosts gadgets

CATEGORY_HOME The activity displays the home screen the first screen the

user sees when the device is turned on or when the HOME

key is pressed

CATEGORY_LAUNCHER The activity can be the initial activity of a task and is listed in

the top-level application launcher

CATEGORY_PREFERENCE The target activity is a preference panel

See the Intent class description for the full list of categories

The addCategory() method places a category in an Intent object removeCategory() deletes a

category previously added and getCategories() gets the set of all categories currently in the

object

Extras

Key-value pairs for additional information that should be delivered to the component handling

the intent Just as some actions are paired with particular kinds of data URIs some are paired

with particular extras For example an ACTION_TIMEZONE_CHANGED intent has a time-

zone extra that identifies the new time zone and ACTION_HEADSET_PLUG has a state

extra indicating whether the headset is now plugged in or unplugged as well as a name extra

for the type of headset If you were to invent a SHOW_COLOR action the color value would be

set in an extra key-value pair

The Intent object has a series of put() methods for inserting various types of extra data and a

similar set of get() methods for reading the data These methods parallel those for Bundle

objects In fact the extras can be installed and read as a Bundle using the putExtras() and

getExtras() methods

Flags

Flags of various sorts Many instruct the Android system how to launch an activity (for example

which task the activity should belong to) and how to treat it after its launched (for example

whether it belongs in the list of recent activities) All these flags are defined in the Intent class

The Android system and the applications that come with the platform employ Intent objects both to

send out system-originated broadcasts and to activate system-defined components To see how to

structure an intent to activate a system component consult the list of intents in the reference

Intent Resolution

Intents can be divided into two groups

Explicit intents designate the target component by its name (the component name field mentioned

earlier has a value set) Since component names would generally not be known to developers of other

applications explicit intents are typically used for application-internal messages mdash such as an activity

starting a subordinate service or launching a sister activity

Implicit intents do not name a target (the field for the component name is blank) Implicit intents are

often used to activate components in other applications

Android delivers an explicit intent to an instance of the designated target class Nothing in the Intent

object other than the component name matters for determining which component should get the intent

A different strategy is needed for implicit intents In the absence of a designated target the Android

system must find the best component (or components) to handle the intent mdash a single activity or

service to perform the requested action or the set of broadcast receivers to respond to the broadcast

announcement It does so by comparing the contents of the Intent object to intent filters structures

associated with components that can potentially receive intents Filters advertise the capabilities of a

component and delimit the intents it can handle They open the component to the possibility of

receiving implicit intents of the advertised type If a component does not have any intent filters it can

receive only explicit intents A component with filters can receive both explicit and implicit intents

Only three aspects of an Intent object are consulted when the object is tested against an intent filter

action

data (both URI and data type)

category

The extras and flags play no part in resolving which component receives an intent

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 mdash but only unwanted implicit intents (those that dont 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

components 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 mdash 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 Pads filters are described in the Note Pad Example

section later)

Filters and security

An intent filter cannot be relied on for security While it opens a component to receiving only certain

kinds of implicit intents it does nothing to prevent explicit intents from targeting the component Even

though a filter restricts the intents a component will be asked to handle to certain actions and data

sources someone could always put together an explicit intent with a different action and data source

and name the component as the target

An intent filter is an instance of the IntentFilter class However since the Android system must know

about the capabilities of a component before it can launch that component intent filters are generally

not set up in Java code but in the applications manifest file (AndroidManifestxml) as ltintent-filtergt

elements (The one exception would be filters for broadcast receivers that are registered dynamically

by calling ContextregisterReceiver() they are directly created as IntentFilter objects)

A filter has fields that parallel the action data and category fields of an Intent object An implicit intent

is tested against the filter in all three areas To be delivered to the component that owns the filter it

must pass all three tests If it fails even one of them the Android system wont deliver it to the

component mdash at least not on the basis of that filter However since a component can have multiple

intent filters an intent that does not pass through one of a components filters might make it through on

another

Each of the three tests is described in detail below

Action test

An ltintent-filtergt element in the manifest file lists actions as ltactiongt subelements For

example

ltintent-filter gt ltaction androidname=comexampleprojectSHOW_CURRENT gt ltaction androidname=comexampleprojectSHOW_RECENT gt ltaction androidname=comexampleprojectSHOW_PENDING gt ltintent-filtergt

As the example shows while an Intent object names just a single action a filter may list more

than one The list cannot be empty a filter must contain at least one ltactiongt element or it will

block all intents

To pass this test the action specified in the Intent object must match one of the actions listed in

the filter If the object or the filter does not specify an action the results are as follows

If the filter fails to list any actions there is nothing for an intent to match so all intents fail the

test No intents can get through the filter

On the other hand an Intent object that doesnt specify an action automatically passes the test

mdash as long as the filter contains at least one action

Category test

An ltintent-filtergt element also lists categories as subelements For example

ltintent-filter gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryBROWSABLE gt ltintent-filtergt

Note that the constants described earlier for actions and categories are not used in the manifest

file The full string values are used instead For instance the

androidintentcategoryBROWSABLE string in the example above corresponds to the

CATEGORY_BROWSABLE constant mentioned earlier in this document Similarly the string

androidintentactionEDIT corresponds to the ACTION_EDIT constant

For an intent to pass the category test every category in the Intent object must match a

category in the filter The filter can list additional categories but it cannot omit any that are in the

intent

In principle therefore an Intent object with no categories should always pass this test

regardless of whats in the filter Thats mostly true However with one exception Android treats

all implicit intents passed to startActivity() as if they contained at least one category

androidintentcategoryDEFAULT (the CATEGORY_DEFAULT constant) Therefore activities

that are willing to receive implicit intents must include androidintentcategoryDEFAULT in

their intent filters (Filters with androidintentactionMAIN and

androidintentcategoryLAUNCHER settings are the exception They mark activities that begin

new tasks and that are represented on the launcher screen They can include

androidintentcategoryDEFAULT in the list of categories but dont need to) See Using intent

matching later for more on these filters)

Data test

Like the action and categories the data specification for an intent filter is contained in a

subelement And as in those cases the subelement can appear multiple times or not at all For

example

ltintent-filter gt ltdata androidmimeType=videompeg androidscheme=http gt ltdata androidmimeType=audiompeg androidscheme=http gt ltintent-filtergt

Each ltdatagt element can specify a URI and a data type (MIME media type) There are

separate attributes mdash scheme host port and path mdash for each part of the URI

schemehostportpath

For example in the following URI

contentcomexampleproject200foldersubfolderetc

the scheme is content the host is comexampleproject the port is 200 and the path is

foldersubfolderetc The host and port together constitute the URI authority if a host is not

specified the port is ignored

Each of these attributes is optional but they are not independent of each other For an authority

to be meaningful a scheme must also be specified For a path to be meaningful both a scheme

and an authority must be specified

When the URI in an Intent object is compared to a URI specification in a filter its compared

only to the parts of the URI actually mentioned in the filter For example if a filter specifies only

a scheme all URIs with that scheme match the filter If a filter specifies a scheme and an

authority but no path all URIs with the same scheme and authority match regardless of their

paths If a filter specifies a scheme an authority and a path only URIs with the same scheme

authority and path match However a path specification in the filter can contain wildcards to

require only a partial match of the path

The type attribute of a ltdatagt element specifies the MIME type of the data Its more common in

filters than a URI Both the Intent object and the filter can use a wildcard for the subtype field

mdash for example text or audio mdash indicating any subtype matches

The data test compares both the URI and the data type in the Intent object to a URI and data

type specified in the filter The rules are as follows

a An Intent object that contains neither a URI nor a data type passes the test only if the filter

likewise does not specify any URIs or data types

b An Intent object that contains a URI but no data type (and a type cannot be inferred from the

URI) passes the test only if its URI matches a URI in the filter and the filter likewise does not

specify a type This will be the case only for URIs like mailto and tel that do not refer to actual

data

c An Intent object that contains a data type but not a URI passes the test only if the filter lists the

same data type and similarly does not specify a URI

d An Intent object that contains both a URI and a data type (or a data type can be inferred from

the URI) passes the data type part of the test only if its type matches a type listed in the filter It

passes the URI part of the test either if its URI matches a URI in the filter or if it has a content

or file URI and the filter does not specify a URI In other words a component is presumed to

support content and file data if its filter lists only a data type

If an intent can pass through the filters of more than one activity or service the user may be asked

which component to activate An exception is raised if no target can be found

Common cases

The last rule shown above for the data test rule (d) reflects the expectation that components are able

to get local data from a file or content provider Therefore their filters can list just a data type and do

not need to explicitly name the content and file schemes This is a typical case A ltdatagt element like

the following for example tells Android that the component can get image data from a content

provider and display it

ltdata androidmimeType=image gt

Since most available data is dispensed by content providers filters that specify a data type but not a

URI are perhaps the most common

Another common configuration is filters with a scheme and a data type For example a ltdatagt

element like the following tells Android that the component can get video data from the network and

display it

ltdata androidscheme=http androidtype=video gt

Consider for example what the browser application does when the user follows a link on a web page

It first tries to display the data (as it could if the link was to an HTML page) If it cant display the data it

puts together an implicit intent with the scheme and data type and tries to start an activity that can do

the job If there are no takers it asks the download manager to download the data That puts it under

the control of a content provider so a potentially larger pool of activities (those with filters that just

name a data type) can respond

Most applications also have a way to start fresh without a reference to any particular data Activities

that can initiate applications have filters with androidintentactionMAIN specified as the action If

they are to be represented in the application launcher they also specify the

androidintentcategoryLAUNCHER category

ltintent-filter gt ltaction androidname=code androidintentactionMAIN gt ltcategory androidname=code androidintentcategoryLAUNCHER gt ltintent-filtergt

Using intent matching

Intents are matched against intent filters not only to discover a target component to activate but also

to discover something about the set of components on the device For example the Android system

populates the application launcher the top-level screen that shows the applications that are available

for the user to launch by finding all the activities with intent filters that specify the

androidintentactionMAIN action and androidintentcategoryLAUNCHER category (as illustrated

in the previous section) It then displays the icons and labels of those activities in the launcher

Similarly it discovers the home screen by looking for the activity with androidintentcategoryHOME

in its filter

Your application can use intent matching is a similar way The PackageManager has a set of query()

methods that return all components that can accept a particular intent and a similar series of

resolve() methods that determine the best component to respond to an intent For example

queryIntentActivities() returns a list of all activities that can perform the intent passed as an argument

and queryIntentServices() returns a similar list of services Neither method activates the components

they just list the ones that can respond Theres a similar method queryBroadcastReceivers() for

broadcast receivers

Note Pad Example

The Note Pad sample application enables users to browse through a list of notes view details about

individual items in the list edit the items and add a new item to the list This section looks at the intent

filters declared in its manifest file (If youre working offline in the SDK you can find all the source files

for this sample application including its manifest file at ltsdkgtsamplesNotePadindexhtml If youre

viewing the documentation online the source files are in the Tutorials and Sample Code section here)

In its manifest file the Note Pad application declares three activities each with at least one intent filter

It also declares a content provider that manages the note data Here is the manifest file in its entirety

ltmanifest xmlnsandroid=httpschemasandroidcomapkresandroid package=comexampleandroidnotepadgt ltapplication androidicon=drawableapp_notes androidlabel=stringapp_name gt ltprovider androidname=NotePadProvider androidauthorities=comgoogleproviderNotePad gt ltactivity androidname=NotesList androidlabel=stringtitle_notes_listgt ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltactivity androidname=NoteEditor androidtheme=androidstyleThemeLight androidlabel=stringtitle_note gt ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltactivitygt

ltactivity androidname=TitleEditor androidlabel=stringtitle_edit_title androidtheme=androidstyleThemeDialoggt ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltapplicationgt ltmanifestgt

The first activity NotesList is distinguished from the other activities by the fact that it operates on a

directory of notes (the note list) rather than on a single note It would generally serve as the initial user

interface into the application It can do three things as described by its three intent filters

1 ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt

This filter declares the main entry point into the Note Pad application The standard MAIN action is an

entry point that does not require any other information in the Intent (no data specification for example)

and the LAUNCHER category says that this entry point should be listed in the application launcher

2 ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

This filter declares the things that the activity can do on a directory of notes It can allow the user to

view or edit the directory (via the VIEW and EDIT actions) or to pick a particular note from the

directory (via the PICK action)

The mimeType attribute of the ltdatagt element specifies the kind of data that these actions operate on

It indicates that the activity can get a Cursor over zero or more items (vndandroidcursordir) from a

content provider that holds Note Pad data (vndgooglenote) The Intent object that launches the

activity would include a content URI specifying the exact data of this type that the activity should open

Note also the DEFAULT category supplied in this filter Its there because the ContextstartActivity()

and ActivitystartActivityForResult() methods treat all intents as if they contained the DEFAULT

category mdash with just two exceptions

o Intents that explicitly name the target activity

o Intents consisting of the MAIN action and LAUNCHER category

Therefore the DEFAULT category is required for all filters mdash except for those with the MAIN action

and LAUNCHER category (Intent filters are not consulted for explicit intents)

3 ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

This filter describes the activitys ability to return a note selected by the user without requiring any

specification of the directory the user should choose from The GET_CONTENT action is similar to the

PICK action In both cases the activity returns the URI for a note selected by the user (In each case

its returned to the activity that called startActivityForResult() to start the NoteList activity) Here

however the caller specifies the type of data desired instead of the directory of data the user will be

picking from

The data type vndandroidcursoritemvndgooglenote indicates the type of data the activity can

return mdash a URI for a single note From the returned URI the caller can get a Cursor for exactly one

item (vndandroidcursoritem) from the content provider that holds Note Pad data (vndgooglenote)

In other words for the PICK action in the previous filter the data type indicates the type of data the

activity could display to the user For the GET_CONTENT filter it indicates the type of data the activity

can return to the caller

Given these capabilities the following intents will resolve to the NotesList activity

action androidintentactionMAIN

Launches the activity with no data specified

action androidintentactionMAIN

category androidintentcategoryLAUNCHER

Launches the activity with no data selected specified This is the actual intent used by the

Launcher to populate its top-level list All activities with filters that match this action and

category are added to the list

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of all the notes under

contentcomgoogleproviderNotePadnotes The user can then browse through the list and

get information about the items in it

action androidintentactionPICK

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of the notes under

contentcomgoogleproviderNotePadnotes The user can then pick a note from the list and

the activity will return the URI for that item back to the activity that started the NoteList activity

action androidintentactionGET_CONTENT

data type vndandroidcursoritemvndgooglenote

Asks the activity to supply a single item of Note Pad data

The second activity NoteEditor shows users a single note entry and allows them to edit it It can do

two things as described by its two intent filters

1 ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The first primary purpose of this activity is to enable the user to interact with a single note ampmdash to

either VIEW the note or EDIT it (The EDIT_NOTE category is a synonym for EDIT) The intent would

contain the URI for data matching the MIME type vndandroidcursoritemvndgooglenote mdash that is

the URI for a single specific note It would typically be a URI that was returned by the PICK or

GET_CONTENT actions of the NoteList activity

As before this filter lists the DEFAULT category so that the activity can be launched by intents that

dont explicitly specify the NoteEditor class

2 ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

The secondary purpose of this activity is to enable the user to create a new note which it will INSERT

into an existing directory of notes The intent would contain the URI for data matching the MIME type

vndandroidcursordirvndgooglenote mdash that is the URI for the directory where the note should be

placed

Given these capabilities the following intents will resolve to the NoteEditor activity

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID (For details on how content

URIs specify individual members of a group see Content Providers)

action androidintentactionEDIT

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID and to let the user edit it If

the user saves the changes the activity updates the data for the note in the content provider

action androidintentactionINSERT

data contentcomgoogleproviderNotePadnotes

Asks the activity to create a new empty note in the notes list at

contentcomgoogleproviderNotePadnotes and allow the user to edit it If the user saves the

note its URI is returned to the caller

The last activity TitleEditor enables the user to edit the title of a note This could be implemented by

directly invoking the activity (by explicitly setting its component name in the Intent) without using an

intent filter But here we take the opportunity to show how to publish alternative operations on existing

data

ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The single intent filter for this activity uses a custom action called

comandroidnotepadactionEDIT_TITLE It must be invoked on a specific note (data type

vndandroidcursoritemvndgooglenote) like the previous VIEW and EDIT actions However here the

activity displays the title contained in the note data not the content of the note itself

In addition to supporting the usual DEFAULT category the title editor also supports two other standard

categories ALTERNATIVE and SELECTED_ALTERNATIVE These categories identify activities that

can be presented to users in a menu of options (much as the LAUNCHER category identifies activities

that should be presented to user in the application launcher) Note that the filter also supplies an

explicit label (via androidlabel=stringresolve_title) to better control what users see when

presented with this activity as an alternative action to the data they are currently viewing (For more

information on these categories and building options menus see the

PackageManagerqueryIntentActivityOptions() and MenuaddIntentOptions() methods)

Given these capabilities the following intent will resolve to the TitleEditor activity

action comandroidnotepadactionEDIT_TITLE

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the title associated with note ID and allow the user to edit the title

Processes and Threads

When an application component starts and the application does not have any other components

running the Android system starts a new Linux process for the application with a single thread of

execution By default all components of the same application run in the same process and thread

(called the main thread) If an application component starts and there already exists a process for

that application (because another component from the application exists) then the component is

started within that process and uses the same thread of execution However you can arrange for

different components in your application to run in separate processes and you can create additional

threads for any process

This document discusses how processes and threads work in an Android application

Processes

By default all components of the same application run in the same process and most applications

should not change this However if you find that you need to control which process a certain

component belongs to you can do so in the manifest file

The manifest entry for each type of component elementmdashltactivitygt ltservicegt ltreceivergt and

ltprovidergtmdashsupports an androidprocess attribute that can specify a process in which that component

should run You can set this attribute so that each component runs in its own process or so that some

components share a process while others do not You can also set androidprocess so that

components of different applications run in the same processmdashprovided that the applications share the

same Linux user ID and are signed with the same certificates

The ltapplicationgt element also supports an androidprocess attribute to set a default value that

applies to all components

Android might 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 thats killed are consequently destroyed A process is started again for those components

when theres again work for them to do

When deciding which processes to kill the Android system weighs their relative importance to the

user For example it more readily shuts down a process hosting activities that are no longer visible on

screen compared to a process hosting visible activities The decision whether to terminate a process

therefore depends on the state of the components running in that process The rules used to decide

which processes to terminate is discussed below

Process lifecycle

The Android system tries to maintain an application process for as long as possible but eventually

needs to remove old processes to reclaim memory for new or more important processes To determine

which processes to keep and which to kill the system places each process into an importance

hierarchy based on the components running in the process and the state of those components

Processes with the lowest importance are eliminated first then those with the next lowest importance

and so on as necessary to recover system resources

There are five levels in the importance hierarchy The following list presents the different types of

processes in order of importance (the first process is most important and is killed last)

1 Foreground process

A process that is required for what the user is currently doing A process is considered to be in the

foreground if any of the following conditions are true

o It hosts an Activity that the user is interacting with (the Activitys onResume() method has been called)

o It hosts a Service thats bound to the activity that the user is interacting with

o It hosts a Service thats running in the foregroundmdashthe service has called startForeground()

o It hosts a Service thats executing one of its lifecycle callbacks (onCreate() onStart() or onDestroy())

o It hosts a BroadcastReceiver thats executing its onReceive() method

Generally only a few foreground processes exist at any given time They are killed only as a last

resortmdashif memory is so low that they cannot all continue to run Generally at that point the device has

reached a memory paging state so killing some foreground processes is required to keep the user

interface responsive

2 Visible process

A process that doesnt have any foreground components but still can affect what the user sees on

screen A process is considered to be visible if either of the following conditions are true

o It hosts an Activity that is not in the foreground but is still visible to the user (its onPause() method has

been called) This might occur for example if the foreground activity started a dialog which allows the

previous activity to be seen behind it

o It hosts a Service thats bound to a visible (or foreground) activity

A visible process is considered extremely important and will not be killed unless doing so is required to

keep all foreground processes running

3 Service process

A process that is running a service that has been started with the startService() method and does not

fall into either of the two higher categories Although service processes are not directly tied to anything

the user sees they are generally doing things that the user cares about (such as playing music in the

background or downloading data on the network) so the system keeps them running unless theres

not enough memory to retain them along with all foreground and visible processes

4 Background process

A process holding an activity thats not currently visible to the user (the activitys onStop() method has

been called) These processes have no direct impact on the user experience and the system can kill

them at any time to reclaim memory for a foreground visible or service process Usually there are

many background processes running so they are kept in an LRU (least recently used) list to ensure

that the process with the activity that was most recently seen by the user is the last to be killed If an

activity implements its lifecycle methods correctly and saves its current state killing its process will not

have a visible effect on the user experience because when the user navigates back to the activity the

activity restores all of its visible state See the Activities document for information about saving and

restoring state

5 Empty process

A process that doesnt hold any active application components The only reason to keep this kind of

process alive is for caching purposes to improve startup time the next time a component needs to run

in it The system often kills these processes in order to balance overall system resources between

process caches and the underlying kernel caches

Android ranks a process at the highest level it can based upon the importance of the components

currently active in the process For example if a process hosts a service and a visible activity the

process is ranked as a visible process not a service process

In addition a processs ranking might be increased because other processes are dependent on itmdasha

process that is serving another process can never be ranked lower than the process it is serving For

example if a content provider in process A is serving a client in process B or if a service in process A

is bound to a component in process B process A is always considered at least as important as

process B

Because a process running a service is ranked higher than a process with background activities an

activity that initiates a long-running operation might do well to start a service for that operation rather

than simply create a worker threadmdashparticularly if the operation will likely outlast the activity For

example an activity thats uploading a picture to a web site should start a service to perform the

upload so that the upload can continue in the background even if the user leaves the activity Using a

service guarantees that the operation will have at least service process priority regardless of what

happens to the activity This is the same reason that broadcast receivers should employ services

rather than simply put time-consuming operations in a thread

Threads

When an application is launched the system creates a thread of execution for the application called

main This thread is very important because it is in charge of dispatching events to the appropriate

user interface widgets including drawing events It is also the thread in which your application interacts

with components from the Android UI toolkit (components from the androidwidget and androidview

packages) As such the main thread is also sometimes called the UI thread

The system does not create a separate thread for each instance of a component All components that

run in the same process are instantiated in the UI thread and system calls to each component are

dispatched from that thread Consequently methods that respond to system callbacks (such as

onKeyDown() to report user actions or a lifecycle callback method) always run in the UI thread of the

process

For instance when the user touches a button on the screen your apps UI thread dispatches the touch

event to the widget which in turn sets its pressed state and posts an invalidate request to the event

queue The UI thread dequeues the request and notifies the widget that it should redraw itself

When your app performs intensive work in response to user interaction this single thread model can

yield poor performance unless you implement your application properly Specifically if everything is

happening in the UI thread performing long operations such as network access or database queries

will block the whole UI When the thread is blocked no events can be dispatched including drawing

events From the users perspective the application appears to hang Even worse if the UI thread is

blocked for more than a few seconds (about 5 seconds currently) the user is presented with the

infamous application not responding (ANR) dialog The user might then decide to quit your

application and uninstall it if they are unhappy

Additionally the Andoid UI toolkit is not thread-safe So you must not manipulate your UI from a

worker threadmdashyou must do all manipulation to your user interface from the UI thread Thus there are

simply two rules to Androids single thread model

1 Do not block the UI thread

2 Do not access the Android UI toolkit from outside the UI thread

Worker threads

Because of the single thread model described above its vital to the responsiveness of your

applications UI that you do not block the UI thread If you have operations to perform that are not

instantaneous you should make sure to do them in separate threads (background or worker

threads)

For example below is some code for a click listener that downloads an image from a separate thread

and displays it in an ImageView

public void onClick(View v) new Thread(new Runnable() public void run() Bitmap b = loadImageFromNetwork(httpexamplecomimagepng) mImageViewsetImageBitmap(b) )start()

At first this seems to work fine because it creates a new thread to handle the network operation

However it violates the second rule of the single-threaded model do not access the Android UI toolkit

from outside the UI threadmdashthis sample modifies the ImageView from the worker thread instead of the

UI thread This can result in undefined and unexpected behavior which can be difficult and time-

consuming to track down

To fix this problem Android offers several ways to access the UI thread from other threads Here is a

list of methods that can help

ActivityrunOnUiThread(Runnable)

Viewpost(Runnable)

ViewpostDelayed(Runnable long)

For example you can fix the above code by using the Viewpost(Runnable) method

public void onClick(View v) new Thread(new Runnable() public void run() final Bitmap bitmap = loadImageFromNetwork(httpexamplecomimagepng) mImageViewpost(new Runnable() public void run() mImageViewsetImageBitmap(bitmap) ) )start()

Now this implementation is thread-safe the network operation is done from a separate thread while

the ImageView is manipulated from the UI thread

However as the complexity of the operation grows this kind of code can get complicated and difficult

to maintain To handle more complex interactions with a worker thread you might consider using a

Handler in your worker thread to process messages delivered from the UI thread Perhaps the best

solution though is to extend the AsyncTask class which simplifies the execution of worker thread

tasks that need to interact with the UI

Using AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface It performs the blocking

operations in a worker thread and then publishes the results on the UI thread without requiring you to

handle threads andor handlers yourself

To use it you must subclass AsyncTask and implement the doInBackground() callback method which

runs in a pool of background threads To update your UI you should implement onPostExecute()

which delivers the result from doInBackground() and runs in the UI thread so you can safely update

your UI You can then run the task by calling execute() from the UI thread

For example you can implement the previous example using AsyncTask this way

public void onClick(View v) new DownloadImageTask()execute(httpexamplecomimagepng) private class DownloadImageTask extends AsyncTaskltString Void Bitmapgt The system calls this to perform work in a worker thread and delivers it the parameters given to AsyncTaskexecute() protected Bitmap doInBackground(String urls) return loadImageFromNetwork(urls[0])

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 7: 03 services

Extending the Service class

As you saw in the previous section using IntentService makes your implementation of a started

service very simple If however you require your service to perform multi-threading (instead of

processing start requests through a work queue) then you can extend the Service class to handle

each intent

For comparison the following example code is an implementation of the Service class that performs

the exact same work as the example above using IntentService That is for each start request it uses

a worker thread to perform the job and processes only one request at a time

public class HelloService extends Service private Looper mServiceLooper private ServiceHandler mServiceHandler Handler that receives messages from the thread private final class ServiceHandler extends Handler public ServiceHandler(Looper looper) super(looper) Override public void handleMessage(Message msg) Normally we would do some work here like download a file For our sample we just sleep for 5 seconds long endTime = SystemcurrentTimeMillis() + 51000 while (SystemcurrentTimeMillis() lt endTime) synchronized (this) try wait(endTime - SystemcurrentTimeMillis()) catch (Exception e) Stop the service using the startId so that we dont stop the service in the middle of handling another job stopSelf(msgarg1) Override public void onCreate() Start up the thread running the service Note that we create a separate thread because the service normally runs in the processs main thread which we dont want to block We also make it background priority so CPU-intensive work will not disrupt our UI HandlerThread thread = new HandlerThread(ServiceStartArguments ProcessTHREAD_PRIORITY_BACKGROUND) threadstart() Get the HandlerThreads Looper and use it for our Handler

mServiceLooper = threadgetLooper() mServiceHandler = new ServiceHandler(mServiceLooper) Override public int onStartCommand(Intent intent int flags int startId) ToastmakeText(this service starting ToastLENGTH_SHORT)show() For each start request send a message to start a job and deliver the start ID so we know which request were stopping when we finish the job Message msg = mServiceHandlerobtainMessage() msgarg1 = startId mServiceHandlersendMessage(msg) If we get killed after returning from here restart return START_STICKY Override public IBinder onBind(Intent intent) We dont provide binding so return null return null Override public void onDestroy() ToastmakeText(this service done ToastLENGTH_SHORT)show()

As you can see its a lot more work than using IntentService

However because you handle each call to onStartCommand() yourself you can perform multiple

requests simultaneously Thats not what this example does but if thats what you want then you can

create a new thread for each request and run them right away (instead of waiting for the previous

request to finish)

Notice that the onStartCommand() method must return an integer The integer is a value that

describes how the system should continue the service in the event that the system kills it (as

discussed above the default implementation for IntentService handles this for you though you are

able to modify it) The return value from onStartCommand() must be one of the following constants

START_NOT_STICKY

If the system kills the service after onStartCommand() returns do not recreate the service

unless there are pending intents to deliver This is the safest option to avoid running your

service when not necessary and when your application can simply restart any unfinished jobs

START_STICKY

If the system kills the service after onStartCommand() returns recreate the service and call

onStartCommand() but do not redeliver the last intent Instead the system calls

onStartCommand() with a null intent unless there were pending intents to start the service in

which case those intents are delivered This is suitable for media players (or similar services)

that are not executing commands but running indefinitely and waiting for a job

START_REDELIVER_INTENT

If the system kills the service after onStartCommand() returns recreate the service and call

onStartCommand() with the last intent that was delivered to the service Any pending intents are

delivered in turn This is suitable for services that are actively performing a job that should be

immediately resumed such as downloading a file

For more details about these return values see the linked reference documentation for each constant

Starting a Service

You can start a service from an activity or other application component by passing an Intent (specifying

the service to start) to startService() The Android system calls the services onStartCommand()

method and passes it the Intent (You should never call onStartCommand() directly)

For example an activity can start the example service in the previous section (HelloSevice) using an

explicit intent with startService()

Intent intent = new Intent(this HelloServiceclass) startService(intent)

The startService() method returns immediately and the Android system calls the services

onStartCommand() method If the service is not already running the system first calls onCreate() then

calls onStartCommand()

If the service does not also provide binding the intent delivered with startService() is the only mode of

communication between the application component and the service However if you want the service

to send a result back then the client that starts the service can create a PendingIntent for a broadcast

(with getBroadcast()) and deliver it to the service in the Intent that starts the service The service can

then use the broadcast to deliver a result

Multiple requests to start the service result in multiple corresponding calls to the services

onStartCommand() However only one request to stop the service (with stopSelf() or stopService()) is

required to stop it

Stopping a service

A started service must manage its own lifecycle That is the system does not stop or destroy the

service unless it must recover system memory and the service continues to run after

onStartCommand() returns So the service must stop itself by calling stopSelf() or another component

can stop it by calling stopService()

Once requested to stop with stopSelf() or stopService() the system destroys the service as soon as

possible

However if your service handles multiple requests to onStartCommand() concurrently then you

shouldnt stop the service when youre done processing a start request because you might have since

received a new start request (stopping at the end of the first request would terminate the second one)

To avoid this problem you can use stopSelf(int) to ensure that your request to stop the service is

always based on the most recent start request That is when you call stopSelf(int) you pass the ID of

the start request (the startId delivered to onStartCommand()) to which your stop request corresponds

Then if the service received a new start request before you were able to call stopSelf(int) then the ID

will not match and the service will not stop

Caution Its important that your application stops its services when its done working to avoid

wasting system resources and consuming battery power If necessary other components can stop

the service by calling stopService() Even if you enable binding for the service you must always

stop the service yourself if it ever received a call to onStartCommand()

For more information about the lifecycle of a service see the section below about Managing the

Lifecycle of a Service

Creating a Bound Service

A bound service is one that allows application components to bind to it by calling bindService() in order

to create a long-standing connection (and generally does not allow components to start it by calling

startService())

You should create a bound service when you want to interact with the service from activities and other

components in your application or to expose some of your applications functionality to other

applications through interprocess communication (IPC)

To create a bound service you must implement the onBind() callback method to return an IBinder that

defines the interface for communication with the service Other application components can then call

bindService() to retrieve the interface and begin calling methods on the service The service lives only

to serve the application component that is bound to it so when there are no components bound to the

service the system destroys it (you do not need to stop a bound service in the way you must when the

service is started through onStartCommand())

To create a bound service the first thing you must do is define the interface that specifies how a client

can communicate with the service This interface between the service and a client must be an

implementation of IBinder and is what your service must return from the onBind() callback method

Once the client receives the IBinder it can begin interacting with the service through that interface

Multiple clients can bind to the service at once When a client is done interacting with the service it

calls unbindService() to unbind Once there are no clients bound to the service the system destroys

the service

There are multiple ways to implement a bound service and the implementation is more complicated

than a started service so the bound service discussion appears in a separate document about Bound

Services

Sending Notifications to the User

Once running a service can notify the user of events using Toast Notifications or Status Bar

Notifications

A toast notification is a message that appears on the surface of the current window for a moment then

disappears while a status bar notification provides an icon in the status bar with a message which the

user can select in order to take an action (such as start an activity)

Usually a status bar notification is the best technique when some background work has completed

(such as a file completed downloading) and the user can now act on it When the user selects the

notification from the expanded view the notification can start an activity (such as to view the

downloaded file)

See the Toast Notifications or Status Bar Notifications developer guides for more information

Running a Service in the Foreground

A foreground service is a service thats considered to be something the user is actively aware of and

thus not a candidate for the system to kill when low on memory A foreground service must provide a

notification for the status bar which is placed under the Ongoing heading which means that the

notification cannot be dismissed unless the service is either stopped or removed from the foreground

For example a music player that plays music from a service should be set to run in the foreground

because the user is explicitly aware of its operation The notification in the status bar might indicate the

current song and allow the user to launch an activity to interact with the music player

To request that your service run in the foreground call startForeground() This method takes two

parameters an integer that uniquely identifies the notification and the Notification for the status bar

For example

Notification notification = new Notification(Rdrawableicon getText(Rstringticker_text) SystemcurrentTimeMillis()) Intent notificationIntent = new Intent(this ExampleActivityclass) PendingIntent pendingIntent = PendingIntentgetActivity(this 0 notificationIntent 0) notificationsetLatestEventInfo(this getText(Rstringnotification_title) getText(Rstringnotification_message) pendingIntent) startForeground(ONGOING_NOTIFICATION notification)

To remove the service from the foreground call stopForeground() This method takes a boolean

indicating whether to remove the status bar notification as well This method does not stop the service

However if you stop the service while its still running in the foreground then the notification is also

removed

Note The methods startForeground() and stopForeground() were introduced in Android 20 (API

Level 5) In order to run your service in the foreground on older versions of the platform you must

use the previous setForeground() methodmdashsee the startForeground() documentation for

information about how to provide backward compatibility

For more information about notifications see Creating Status Bar Notifications

Managing the Lifecycle of a Service

The lifecycle of a service is much simpler than that of an activity However its even more important

that you pay close attention to how your service is created and destroyed because a service can run

in the background without the user being aware

The service lifecyclemdashfrom when its created to when its destroyedmdashcan follow two different paths

A started service

The service is created when another component calls startService() The service then runs indefinitely

and must stop itself by calling stopSelf() Another component can also stop the service by calling

stopService() When the service is stopped the system destroys it

A bound service

The service is created when another component (a client) calls bindService() The client then

communicates with the service through an IBinder interface The client can close the connection by

calling unbindService() Multiple clients can bind to the same service and when all of them unbind the

system destroys the service (The service does not need to stop itself)

These two paths are not entirely separate That is you can bind to a service that was already started

with startService() For example a background music service could be started by calling startService()

with an Intent that identifies the music to play Later possibly when the user wants to exercise some

control over the player or get information about the current song an activity can bind to the service by

calling bindService() In cases like this stopService() or stopSelf() does not actually stop the service

until all clients unbind

Implementing the lifecycle callbacks

Like an activity a service has lifecycle callback methods that you can implement to monitor changes in

the services state and perform work at the appropriate times The following skeleton service

demonstrates each of the lifecycle methods

Figure 2 The service lifecycle The diagram on the left shows the lifecycle when the service is created

with startService() and the diagram on the right shows the lifecycle when the service is created with

bindService()

public class ExampleService extends Service int mStartMode indicates how to behave if the service is killed IBinder mBinder interface for clients that bind boolean mAllowRebind indicates whether onRebind should be used Override public void onCreate() The service is being created Override public int onStartCommand(Intent intent int flags int startId) The service is starting due to a call to startService() return mStartMode Override public IBinder onBind(Intent intent) A client is binding to the service with bindService() return mBinder Override public boolean onUnbind(Intent intent) All clients have unbound with unbindService()

return mAllowRebind Override public void onRebind(Intent intent) A client is binding to the service with bindService() after onUnbind() has already been called Override public void onDestroy() The service is no longer used and is being destroyed

Note Unlike the activity lifecycle callback methods you are not required to call the superclass

implementation of these callback methods

By implementing these methods you can monitor two nested loops of the services lifecycle

The entire lifetime of a service happens between the time onCreate() is called and the time

onDestroy() returns Like an activity a service does its initial setup in onCreate() and releases all

remaining resources in onDestroy() For example a music playback service could create the thread

where the music will be played in onCreate() then stop the thread in onDestroy()

The onCreate() and onDestroy() methods are called for all services whether theyre created by

startService() or bindService()

The active lifetime of a service begins with a call to either onStartCommand() or onBind() Each

method is handed the Intent that was passed to either startService() or bindService() respectively

If the service is started the active lifetime ends the same time that the entire lifetime ends (the service

is still active even after onStartCommand() returns) If the service is bound the active lifetime ends

when onUnbind() returns

Note Although a started service is stopped by a call to either stopSelf() or stopService() there is

not a respective callback for the service (theres no onStop() callback) So unless the service is

bound to a client the system destroys it when the service is stoppedmdashonDestroy() is the only

callback received

Figure 2 illustrates the typical callback methods for a service Although the figure separates services

that are created by startService() from those created by bindService() keep in mind that any service

no matter how its started can potentially allow clients to bind to it So a service that was initially

started with onStartCommand() (by a client calling startService()) can still receive a call to onBind()

(when a client calls bindService())

For more information about creating a service that provides binding see the Bound Services

document which includes more information about the onRebind() callback method in the section about

Managing the Lifecycle of a Bound Service

Bound Services

A bound service is the server in a client-server interface A bound service allows components (such as

activities) to bind to the service send requests receive responses and even perform interprocess

communication (IPC) A bound service typically lives only while it serves another application

component and does not run in the background indefinitely

This document shows you how to create a bound service including how to bind to the service from

other application components However you should also refer to the Services document for additional

information about services in general such as how to deliver notifications from a service set the

service to run in the foreground and more

The Basics

A bound service is an implementation of the Service class that allows other applications to bind to it

and interact with it To provide binding for a service you must implement the onBind() callback

method This method returns an IBinder object that defines the programming interface that clients can

use to interact with the service

Binding to a Started Service

As discussed in the Services document you can create a service that is both started and bound That

is the service can be started by calling startService() which allows the service to run indefinitely and

also allow a client to bind to the service by calling bindService()

If you do allow your service to be started and bound then when the service has been started the

system does not destroy the service when all clients unbind Instead you must explicitly stop the

service by calling stopSelf() or stopService()

Although you should usually implement either onBind() or onStartCommand() its sometimes

necessary to implement both For example a music player might find it useful to allow its service to run

indefinitely and also provide binding This way an activity can start the service to play some music and

the music continues to play even if the user leaves the application Then when the user returns to the

application the activity can bind to the service to regain control of playback

Be sure to read the section about Managing the Lifecycle of a Bound Service for more information

about the service lifecycle when adding binding to a started service

A client can bind to the service by calling bindService() When it does it must provide an

implementation of ServiceConnection which monitors the connection with the service The

bindService() method returns immediately without a value but when the Android system creates the

connection between the client and service it calls onServiceConnected() on the ServiceConnection to

deliver the IBinder that the client can use to communicate with the service

Multiple clients can connect to the service at once However the system calls your services onBind()

method to retrieve the IBinder only when the first client binds The system then delivers the same

IBinder to any additional clients that bind without calling onBind() again

When the last client unbinds from the service the system destroys the service (unless the service was

also started by startService())

When you implement your bound service the most important part is defining the interface that your

onBind() callback method returns There are a few different ways you can define your services IBinder

interface and the following section discusses each technique

Creating a Bound Service

When creating a service that provides binding you must provide an IBinder that provides the

programming interface that clients can use to interact with the service There are three ways you can

define the interface

Extending the Binder class

If your service is private to your own application and runs in the same process as the client

(which is common) you should create your interface by extending the Binder class and

returning an instance of it from onBind() The client receives the Binder and can use it to directly

access public methods available in either the Binder implementation or even the Service

This is the preferred technique when your service is merely a background worker for your own

application The only reason you would not create your interface this way is because your

service is used by other applications or across separate processes

Using a Messenger

If you need your interface to work across different processes you can create an interface for the

service with a Messenger In this manner the service defines a Handler that responds to

different types of Message objects This Handler is the basis for a Messenger that can then

share an IBinder with the client allowing the client to send commands to the service using

Message objects Additionally the client can define a Messenger of its own so the service can

send messages back

This is the simplest way to perform interprocess communication (IPC) because the Messenger

queues all requests into a single thread so that you dont have to design your service to be

thread-safe

Using AIDL

AIDL (Android Interface Definition Language) performs all the work to decompose objects into

primitives that the operating system can understand and marshall them across processes to

perform IPC The previous technique using a Messenger is actually based on AIDL as its

underlying structure As mentioned above the Messenger creates a queue of all the client

requests in a single thread so the service receives requests one at a time If however you

want your service to handle multiple requests simultaneously then you can use AIDL directly In

this case your service must be capable of multi-threading and be built thread-safe

To use AIDL directly you must create an aidl file that defines the programming interface The

Android SDK tools use this file to generate an abstract class that implements the interface and

handles IPC which you can then extend within your service

Note Most applications should not use AIDL to create a bound service because it may require

multithreading capabilities and can result in a more complicated implementation As such AIDL is

not suitable for most applications and this document does not discuss how to use it for your

service If youre certain that you need to use AIDL directly see the AIDL document

Extending the Binder class

If your service is used only by the local application and does not need to work across processes then

you can implement your own Binder class that provides your client direct access to public methods in

the service

Note This works only if the client and service are in the same application and process which is

most common For example this would work well for a music application that needs to bind an

activity to its own service thats playing music in the background

Heres how to set it up

1 In your service create an instance of Binder that either

o contains public methods that the client can call

o returns the current Service instance which has public methods the client can call

o or returns an instance of another class hosted by the service with public methods the client can call

2 Return this instance of Binder from the onBind() callback method

3 In the client receive the Binder from the onServiceConnected() callback method and make calls to the

bound service using the methods provided

Note The reason the service and client must be in the same application is so the client can cast

the returned object and properly call its APIs The service and client must also be in the same

process because this technique does not perform any marshalling across processes

For example heres a service that provides clients access to methods in the service through a Binder

implementation

public class LocalService extends Service

Binder given to clients

private final IBinder mBinder = new LocalBinder()

Random number generator

private final Random mGenerator = new Random()

Class used for the client Binder Because we know this service always

runs in the same process as its clients we dont need to deal with IPC

public class LocalBinder extends Binder

LocalService getService()

Return this instance of LocalService so clients can call public methods

return LocalServicethis

Override

public IBinder onBind(Intent intent)

return mBinder

method for clients

public int getRandomNumber()

return mGeneratornextInt(100)

The LocalBinder provides the getService() method for clients to retrieve the current instance of

LocalService This allows clients to call public methods in the service For example clients can call

getRandomNumber() from the service

Heres an activity that binds to LocalService and calls getRandomNumber() when a button is clicked

public class BindingActivity extends Activity

LocalService mService

boolean mBound = false

Override

protected void onCreate(Bundle savedInstanceState)

superonCreate(savedInstanceState)

setContentView(Rlayoutmain)

Override

protected void onStart()

superonStart()

Bind to LocalService

Intent intent = new Intent(this LocalServiceclass)

bindService(intent mConnection ContextBIND_AUTO_CREATE)

Override

protected void onStop()

superonStop()

Unbind from the service

if (mBound)

unbindService(mConnection)

mBound = false

Called when a button is clicked (the button in the layout file attaches to

this method with the androidonClick attribute)

public void onButtonClick(View v)

if (mBound)

Call a method from the LocalService

However if this call were something that might hang then this request should

occur in a separate thread to avoid slowing down the activity performance

int num = mServicegetRandomNumber()

ToastmakeText(this number + num ToastLENGTH_SHORT)show()

Defines callbacks for service binding passed to bindService()

private ServiceConnection mConnection = new ServiceConnection()

Override

public void onServiceConnected(ComponentName className

IBinder service)

Weve bound to LocalService cast the IBinder and get LocalService instance

LocalBinder binder = (LocalBinder) service

mService = bindergetService()

mBound = true

Override

public void onServiceDisconnected(ComponentName arg0)

mBound = false

The above sample shows how the client binds to the service using an implementation of

ServiceConnection and the onServiceConnected() callback The next section provides more

information about this process of binding to the service

Note The example above doesnt explicitly unbind from the service but all clients should unbind

at an appropriate time (such as when the activity pauses)

For more sample code see the LocalServicejava class and the LocalServiceActivitiesjava class in

ApiDemos

Using a Messenger

Compared to AIDL

When you need to perform IPC using a Messenger for your interface is simpler than implementing it

with AIDL because Messenger queues all calls to the service whereas a pure AIDL interface sends

simultaneous requests to the service which must then handle multi-threading

For most applications the service doesnt need to perform multi-threading so using a Messenger

allows the service to handle one call at a time If its important that your service be multi-threaded then

you should use AIDL to define your interface

If you need your service to communicate with remote processes then you can use a Messenger to

provide the interface for your service This technique allows you to perform interprocess

communication (IPC) without the need to use AIDL

Heres a summary of how to use a Messenger

The service implements a Handler that receives a callback for each call from a client

The Handler is used to create a Messenger object (which is a reference to the Handler)

The Messenger creates an IBinder that the service returns to clients from onBind()

Clients use the IBinder to instantiate the Messenger (that references the services Handler) which the

client uses to send Message objects to the service

The service receives each Message in its Handlermdashspecifically in the handleMessage() method

In this way there are no methods for the client to call on the service Instead the client delivers

messages (Message objects) that the service receives in its Handler

Heres a simple example service that uses a Messenger interface

public class MessengerService extends Service Command to the service to display a message static final int MSG_SAY_HELLO = 1 Handler of incoming messages from clients class IncomingHandler extends Handler Override public void handleMessage(Message msg) switch (msgwhat) case MSG_SAY_HELLO ToastmakeText(getApplicationContext() hello ToastLENGTH_SHORT)show() break default superhandleMessage(msg) Target we publish for clients to send messages to IncomingHandler final Messenger mMessenger = new Messenger(new IncomingHandler()) When binding to the service we return an interface to our messenger for sending messages to the service Override public IBinder onBind(Intent intent) ToastmakeText(getApplicationContext() binding ToastLENGTH_SHORT)show() return mMessengergetBinder()

Notice that the handleMessage() method in the Handler is where the service receives the incoming

Message and decides what to do based on the what member

All that a client needs to do is create a Messenger based on the IBinder returned by the service and

send a message using send() For example heres a simple activity that binds to the service and

delivers the MSG_SAY_HELLO message to the service

public class ActivityMessenger extends Activity Messenger for communicating with the service Messenger mService = null Flag indicating whether we have called bind on the service boolean mBound Class for interacting with the main interface of the service private ServiceConnection mConnection = new ServiceConnection() public void onServiceConnected(ComponentName className IBinder service) This is called when the connection with the service has been established giving us the object we can use to interact with the service We are communicating with the service using a Messenger so here we get a client-side representation of that from the raw IBinder object mService = new Messenger(service) mBound = true public void onServiceDisconnected(ComponentName className) This is called when the connection with the service has been unexpectedly disconnected -- that is its process crashed mService = null mBound = false public void sayHello(View v) if (mBound) return Create and send a message to the service using a supported what value Message msg = Messageobtain(null MessengerServiceMSG_SAY_HELLO 0 0) try mServicesend(msg) catch (RemoteException e) eprintStackTrace() Override protected void onCreate(Bundle savedInstanceState) superonCreate(savedInstanceState) setContentView(Rlayoutmain)

Override protected void onStart() superonStart() Bind to the service bindService(new Intent(this MessengerServiceclass) mConnection ContextBIND_AUTO_CREATE) Override protected void onStop() superonStop() Unbind from the service if (mBound) unbindService(mConnection) mBound = false

Notice that this example does not show how the service can respond to the client If you want the

service to respond then you need to also create a Messenger in the client Then when the client

receives the onServiceConnected() callback it sends a Message to the service that includes the

clients Messenger in the replyTo parameter of the send() method

You can see an example of how to provide two-way messaging in the MessengerServicejava (service)

and MessengerServiceActivitiesjava (client) samples

Binding to a Service

Application components (clients) can bind to a service by calling bindService() The Android system

then calls the services onBind() method which returns an IBinder for interacting with the service

The binding is asynchronous bindService() returns immediately and does not return the IBinder to the

client To receive the IBinder the client must create an instance of ServiceConnection and pass it to

bindService() The ServiceConnection includes a callback method that the system calls to deliver the

IBinder

Note Only activities services and content providers can bind to a servicemdashyou cannot bind to a

service from a broadcast receiver

So to bind to a service from your client you must

1 Implement ServiceConnection

Your implementation must override two callback methods

onServiceConnected()

The system calls this to deliver the IBinder returned by the services onBind() method

onServiceDisconnected()

The Android system calls this when the connection to the service is unexpectedly lost such as

when the service has crashed or has been killed This is not called when the client unbinds

2 Call bindService() passing the ServiceConnection implementation

3 When the system calls your onServiceConnected() callback method you can begin making calls to the

service using the methods defined by the interface

4 To disconnect from the service call unbindService()

When your client is destroyed it will unbind from the service but you should always unbind when

youre done interacting with the service or when your activity pauses so that the service can shutdown

while its not being used (Appropriate times to bind and unbind is discussed more below)

For example the following snippet connects the client to the service created above by extending the

Binder class so all it must do is cast the returned IBinder to the LocalService class and request the

LocalService instance

LocalService mService private ServiceConnection mConnection = new ServiceConnection() Called when the connection with the service is established public void onServiceConnected(ComponentName className IBinder service) Because we have bound to an explicit service that is running in our own process we can cast its IBinder to a concrete class and directly access it LocalBinder binder = (LocalBinder) service mService = bindergetService() mBound = true Called when the connection with the service disconnects unexpectedly public void onServiceDisconnected(ComponentName className) Loge(TAG onServiceDisconnected) mBound = false

With this ServiceConnection the client can bind to a service by passing this it to bindService() For

example

Intent intent = new Intent(this LocalServiceclass) bindService(intent mConnection ContextBIND_AUTO_CREATE)

The first parameter of bindService() is an Intent that explicitly names the service to bind (thought the

intent could be implicit)

The second parameter is the ServiceConnection object

The third parameter is a flag indicating options for the binding It should usually be

BIND_AUTO_CREATE in order to create the service if its not already alive Other possible values are

BIND_DEBUG_UNBIND and BIND_NOT_FOREGROUND or 0 for none

Additional notes

Here are some important notes about binding to a service

You should always trap DeadObjectException exceptions which are thrown when the connection has

broken This is the only exception thrown by remote methods

Objects are reference counted across processes

You should usually pair the binding and unbinding during matching bring-up and tear-down moments

of the clients lifecycle For example

o If you only need to interact with the service while your activity is visible you should bind during

onStart() and unbind during onStop()

o If you want your activity to receive responses even while it is stopped in the background then you can

bind during onCreate() and unbind during onDestroy() Beware that this implies that your activity needs

to use the service the entire time its running (even in the background) so if the service is in another

process then you increase the weight of the process and it becomes more likely that the system will

kill it

Note You should usually not bind and unbind during your activitys onResume() and onPause()

because these callbacks occur at every lifecycle transition and you should keep the processing that

occurs at these transitions to a minimum Also if multiple activities in your application bind to the same

service and there is a transition between two of those activities the service may be destroyed and

recreated as the current activity unbinds (during pause) before the next one binds (during resume)

(This activity transition for how activities coordinate their lifecycles is described in the Activities

document)

For more sample code showing how to bind to a service see the RemoteServicejava class in

ApiDemos

Managing the Lifecycle of a Bound Service

Figure 1 The lifecycle for a service

that is started and also allows binding

When a service is unbound from all

clients the Android system destroys it

(unless it was also started with

onStartCommand()) As such you

dont have to manage the lifecycle of

your service if its purely a bound

servicemdashthe Android system manages

it for you based on whether it is bound

to any clients

However if you choose to implement

the onStartCommand() callback

method then you must explicitly stop

the service because the service is

now considered to be started In this

case the service runs until the service

stops itself with stopSelf() or another

component calls stopService()

regardless of whether it is bound to

any clients

Additionally if your service is started and accepts binding then when the system calls your onUnbind()

method you can optionally return true if you would like to receive a call to onRebind() the next time a

client binds to the service (instead of receiving a call to onBind()) onRebind() returns void but the

client still receives the IBinder in its onServiceConnected() callback Below figure 1 illustrates the logic

for this kind of lifecycle

For more information about the lifecycle of an started service see the Services document

Content Providers

Content providers store and retrieve data and make it accessible to all applications Theyre the only

way to share data across applications theres no common storage area that all Android packages can

access

Android ships with a number of content providers for common data types (audio video images

personal contact information and so on) You can see some of them listed in the androidprovider

package You can query these providers for the data they contain (although for some you must

acquire the proper permission to read the data)

If you want to make your own data public you have two options You can create your own content

provider (a ContentProvider subclass) or you can add the data to an existing provider mdash if theres one

that controls the same type of data and you have permission to write to it

This document is an introduction to using content providers After a brief discussion of the

fundamentals it explores how to query a content provider how to modify data controlled by a provider

and how to create a content provider of your own

Content Provider Basics

How a content provider actually stores its data under the covers is up to its designer But all content

providers implement a common interface for querying the provider and returning results mdash as well as

for adding altering and deleting data Its an interface that clients use indirectly most generally

through ContentResolver objects You get a ContentResolver by calling getContentResolver() from

within the implementation of an Activity or other application component

ContentResolver cr = getContentResolver()

You can then use the ContentResolvers methods to interact with whatever content providers youre

interested in When a query is initiated the Android system identifies the content provider thats the

target of the query and makes sure that it is up and running The system instantiates all

ContentProvider objects you never need to do it on your own In fact you never deal directly with

ContentProvider objects at all Typically theres just a single instance of each type of ContentProvider

But it can communicate with multiple ContentResolver objects in different applications and processes

The interaction between processes is handled by the ContentResolver and ContentProvider classes

The data model

Content providers expose their data as a simple table on a database model where each row is a

record and each column is data of a particular type and meaning For example information about

people and their phone numbers might be exposed as follows

_ID NUMBER NUMBER_KEY LABEL NAME TYPE

13 (425) 555 6677 425 555 6677 Kirkland office Bully Pulpit TYPE_WORK

44 (212) 555-1234 212 555 1234 NY apartment Alan Vain TYPE_HOME

45 (212) 555-6657 212 555 6657 Downtown office Alan Vain TYPE_MOBILE

53 2015554433 201 555 4433 Love Nest Rex Cars TYPE_HOME

Every record includes a numeric _ID field that uniquely identifies the record within the table IDs can be

used to match records in related tables mdash for example to find a persons phone number in one table

and pictures of that person in another

A query returns a Cursor object that can move from record to record and column to column to read the

contents of each field It has specialized methods for reading each type of data So to read a field you

must know what type of data the field contains (Theres more on query results and Cursor objects

later)

URIs

Each content provider exposes a public URI (wrapped as a Uri object) that uniquely identifies its data

set A content provider that controls multiple data sets (multiple tables) exposes a separate URI for

each one All URIs for providers begin with the string content The content scheme identifies the

data as being controlled by a content provider

If youre defining a content provider its a good idea to also define a constant for its URI to simplify

client code and make future updates cleaner Android defines CONTENT_URI constants for all the

providers that come with the platform For example the URI for the table that matches phone numbers

to people and the URI for the table that holds pictures of people (both controlled by the Contacts

content provider) are

androidproviderContactsPhonesCONTENT_URI

androidproviderContactsPhotosCONTENT_URI

The URI constant is used in all interactions with the content provider Every ContentResolver method

takes the URI as its first argument Its what identifies which provider the ContentResolver should talk

to and which table of the provider is being targeted

Querying a Content Provider

You need three pieces of information to query a content provider

The URI that identifies the provider

The names of the data fields you want to receive

The data types for those fields

If youre querying a particular record you also need the ID for that record

Making the query

To query a content provider you can use either the ContentResolverquery() method or the

ActivitymanagedQuery() method Both methods take the same set of arguments and both return a

Cursor object However managedQuery() causes the activity to manage the life cycle of the Cursor A

managed Cursor handles all of the niceties such as unloading itself when the activity pauses and

requerying itself when the activity restarts You can ask an Activity to begin managing an unmanaged

Cursor object for you by calling ActivitystartManagingCursor()

The first argument to either query() or managedQuery() is the provider URI mdash the CONTENT_URI

constant that identifies a particular ContentProvider and data set (see URIs earlier)

To restrict a query to just one record you can append the _ID value for that record to the URI mdash that

is place a string matching the ID as the last segment of the path part of the URI For example if the ID

is 23 the URI would be

content 23

There are some helper methods particularly ContentUriswithAppendedId() and

UriwithAppendedPath() that make it easy to append an ID to a URI Both are static methods that

return a Uri object with the ID added So for example if you were looking for record 23 in the database

of people contacts you might construct a query as follows

import androidproviderContactsPeople import androidcontentContentUris import androidnetUri import androiddatabaseCursor Use the ContentUris method to produce the base URI for the contact with _ID == 23 Uri myPerson = ContentUriswithAppendedId(PeopleCONTENT_URI 23) Alternatively use the Uri method to produce the base URI It takes a string rather than an integer Uri myPerson = UriwithAppendedPath(PeopleCONTENT_URI 23) Then query for this specific record Cursor cur = managedQuery(myPerson null null null null)

The other arguments to the query() and managedQuery() methods delimit the query in more detail

They are

The names of the data columns that should be returned A null value returns all columns Otherwise

only columns that are listed by name are returned All the content providers that come with the

platform define constants for their columns For example the androidproviderContactsPhones class

defines constants for the names of the columns in the phone table illustrated earlier ampmdash _ID

NUMBER NUMBER_KEY NAME and so on

A filter detailing which rows to return formatted as an SQL WHERE clause (excluding the WHERE

itself) A null value returns all rows (unless the URI limits the query to a single record)

Selection arguments

A sorting order for the rows that are returned formatted as an SQL ORDER BY clause (excluding the

ORDER BY itself) A null value returns the records in the default order for the table which may be

unordered

Lets look at an example query to retrieve a list of contact names and their primary phone numbers

import androidproviderContactsPeople import androiddatabaseCursor Form an array specifying which columns to return String[] projection = new String[] People_ID People_COUNT PeopleNAME PeopleNUMBER Get the base URI for the People table in the Contacts content provider Uri contacts = PeopleCONTENT_URI Make the query Cursor managedCursor = managedQuery(contacts projection Which columns to return null Which rows to return (all rows) null Selection arguments (none) Put the results in ascending order by name PeopleNAME + ASC)

This query retrieves data from the People table of the Contacts content provider It gets the name

primary phone number and unique record ID for each contact It also reports the number of records

that are returned as the _COUNT field of each record

The constants for the names of the columns are defined in various interfaces mdash _ID and _COUNT in

BaseColumns NAME in PeopleColumns and NUMBER in PhoneColumns The ContactsPeople

class implements each of these interfaces which is why the code example above could refer to them

using just the class name

What a query returns

A query returns a set of zero or more database records The names of the columns their default order

and their data types are specific to each content provider But every provider has an _ID column

which holds a unique numeric ID for each record Every provider can also report the number of records

returned as the _COUNT column its value is the same for all rows

Here is an example result set for the query in the previous section

_ID _COUNT NAME NUMBER

44 3 Alan Vain 212 555 1234

13 3 Bully Pulpit 425 555 6677

53 3 Rex Cars 201 555 4433

The retrieved data is exposed by a Cursor object that can be used to iterate backward or forward

through the result set You can use this object only to read the data To add modify or delete data

you must use a ContentResolver object

Reading retrieved data

The Cursor object returned by a query provides access to a recordset of results If you have queried

for a specific record by ID this set will contain only one value Otherwise it can contain multiple

values (If there are no matches it can also be empty) You can read data from specific fields in the

record but you must know the data type of the field because the Cursor object has a separate method

for reading each type of data mdash such as getString() getInt() and getFloat() (However for most types

if you call the method for reading strings the Cursor object will give you the String representation of

the data) The Cursor lets you request the column name from the index of the column or the index

number from the column name

The following snippet demonstrates reading names and phone numbers from the query illustrated

earlier

import androidproviderContactsPeople private void getColumnData(Cursor cur) if (curmoveToFirst()) String name String phoneNumber int nameColumn = curgetColumnIndex(PeopleNAME) int phoneColumn = curgetColumnIndex(PeopleNUMBER) String imagePath do Get the field values name = curgetString(nameColumn) phoneNumber = curgetString(phoneColumn) Do something with the values while (curmoveToNext())

If a query can return binary data such as an image or sound the data may be directly entered in the

table or the table entry for that data may be a string specifying a content URI that you can use to get

the data In general smaller amounts of data (say from 20 to 50K or less) are most often directly

entered in the table and can be read by calling CursorgetBlob() It returns a byte array

If the table entry is a content URI you should never try to open and read the file directly (for one thing

permissions problems can make this fail) Instead you should call ContentResolveropenInputStream()

to get an InputStream object that you can use to read the data

Modifying Data

Data kept by a content provider can be modified by

Adding new records

Adding new values to existing records

Batch updating existing records

Deleting records

All data modification is accomplished using ContentResolver methods Some content providers require

a more restrictive permission for writing data than they do for reading it If you dont have permission to

write to a content provider the ContentResolver methods will fail

Adding records

To add a new record to a content provider first set up a map of key-value pairs in a ContentValues

object where each key matches the name of a column in the content provider and the value is the

desired value for the new record in that column Then call ContentResolverinsert() and pass it the URI

of the provider and the ContentValues map This method returns the full URI of the new record mdash that

is the providers URI with the appended ID for the new record You can then use this URI to query and

get a Cursor over the new record and to further modify the record Heres an example

import androidproviderContactsPeople import androidcontentContentResolver import androidcontentContentValues ContentValues values = new ContentValues() Add Abraham Lincoln to contacts and make him a favorite valuesput(PeopleNAME Abraham Lincoln) 1 = the new contact is added to favorites 0 = the new contact is not added to favorites valuesput(PeopleSTARRED 1) Uri uri = getContentResolver()insert(PeopleCONTENT_URI values)

Adding new values

Once a record exists you can add new information to it or modify existing information For example

the next step in the example above would be to add contact information mdash like a phone number or an

IM or e-mail address mdash to the new entry

The best way to add to a record in the Contacts database is to append the name of the table where the

new data goes to the URI for the record then use the amended URI to add the new data values Each

Contacts table exposes a name for this purpose as a CONTENT_DIRECTORY constant The following

code continues the previous example by adding a phone number and e-mail address for the record

just created

Uri phoneUri = null Uri emailUri = null Add a phone number for Abraham Lincoln Begin with the URI for the new record just returned by insert() it ends with the _ID of the new record so we dont have to add the ID ourselves Then append the designation for the phone table to this URI and use the resulting URI to insert the phone number phoneUri = UriwithAppendedPath(uri PeoplePhonesCONTENT_DIRECTORY) valuesclear() valuesput(PeoplePhonesTYPE PeoplePhonesTYPE_MOBILE) valuesput(PeoplePhonesNUMBER 1233214567) getContentResolver()insert(phoneUri values) Now add an email address in the same way emailUri = UriwithAppendedPath(uri PeopleContactMethodsCONTENT_DIRECTORY) valuesclear() ContactMethodsKIND is used to distinguish different kinds of contact methods such as email IM etc valuesput(PeopleContactMethodsKIND ContactsKIND_EMAIL) valuesput(PeopleContactMethodsDATA testexamplecom) valuesput(PeopleContactMethodsTYPE PeopleContactMethodsTYPE_HOME) getContentResolver()insert(emailUri values)

You can place small amounts of binary data into a table by calling the version of ContentValuesput()

that takes a byte array That would work for a small icon-like image or a short audio clip for example

However if you have a large amount of binary data to add such as a photograph or a complete song

put a content URI for the data in the table and call ContentResolveropenOutputStream() with the files

URI (That causes the content provider to store the data in a file and record the file path in a hidden

field of the record)

In this regard the MediaStore content provider the main provider that dispenses image audio and

video data employs a special convention The same URI that is used with query() or managedQuery()

to get meta-information about the binary data (such as the caption of a photograph or the date it was

taken) is used with openInputStream() to get the data itself Similarly the same URI that is used with

insert() to put meta-information into a MediaStore record is used with openOutputStream() to place the

binary data there The following code snippet illustrates this convention

import androidproviderMediaStoreImagesMedia import androidcontentContentValues import javaioOutputStream Save the name and description of an image in a ContentValues map ContentValues values = new ContentValues(3) valuesput(MediaDISPLAY_NAME road_trip_1) valuesput(MediaDESCRIPTION Day 1 trip to Los Angeles) valuesput(MediaMIME_TYPE imagejpeg) Add a new record without the bitmap but with the values just set insert() returns the URI of the new record Uri uri = getContentResolver()insert(MediaEXTERNAL_CONTENT_URI values) Now get a handle to the file for that record and save the data into it Here sourceBitmap is a Bitmap object representing the file to save to the database try OutputStream outStream = getContentResolver()openOutputStream(uri) sourceBitmapcompress(BitmapCompressFormatJPEG 50 outStream) outStreamclose() catch (Exception e) Loge(TAG exception while writing image e)

Batch updating records

To batch update a group of records (for example to change NY to New York in all fields) call the

ContentResolverupdate() method with the columns and values to change

Deleting a record

To delete a single record call ContentResolverdelete() with the URI of a specific row

To delete multiple rows call ContentResolverdelete() with the URI of the type of record to delete (for

example androidproviderContactsPeopleCONTENT_URI) and an SQL WHERE clause defining

which rows to delete (Caution Be sure to include a valid WHERE clause if youre deleting a general

type or you risk deleting more records than you intended)

Creating a Content Provider

To create a content provider you must

Set up a system for storing the data Most content providers store their data using Androids file

storage methods or SQLite databases but you can store your data any way you want Android

provides the SQLiteOpenHelper class to help you create a database and SQLiteDatabase to manage

it

Extend the ContentProvider class to provide access to the data

Declare the content provider in the manifest file for your application (AndroidManifestxml)

The following sections have notes on the last two of these tasks

Extending the ContentProvider class

You define a ContentProvider subclass to expose your data to others using the conventions expected

by ContentResolver and Cursor objects Principally this means implementing six abstract methods

declared in the ContentProvider class

query()

insert()

update()

delete()

getType()

onCreate()

The query() method must return a Cursor object that can iterate over the requested data Cursor itself

is an interface but Android provides some ready-made Cursor objects that you can use For example

SQLiteCursor can iterate over data stored in an SQLite database You get the Cursor object by calling

any of the SQLiteDatabase classs query() methods There are other Cursor implementations mdash such

as MatrixCursor mdash for data not stored in a database

Because these ContentProvider methods can be called from various ContentResolver objects in

different processes and threads they must be implemented in a thread-safe manner

As a courtesy you might also want to call ContentResolvernotifyChange() to notify listeners when

there are modifications to the data

Beyond defining the subclass itself there are other steps you should take to simplify the work of clients

and make the class more accessible

Define a public static final Uri named CONTENT_URI This is the string that represents the full content

URI that your content provider handles You must define a unique string for this value The best

solution is to use the fully-qualified class name of the content provider (made lowercase) So for

example the URI for a TransportationProvider class could be defined as follows

public static final Uri CONTENT_URI = Uriparse(contentcomexamplecodelabtransportationprovider)

If the provider has subtables also define CONTENT_URI constants for each of the subtables These

URIs should all have the same authority (since that identifies the content provider) and be

distinguished only by their paths For example

contentcomexamplecodelabtransportationprovidertrain

contentcomexamplecodelabtransportationproviderairdomestic

contentcomexamplecodelabtransportationproviderairinternational

For an overview of content URIs see the Content URI Summary at the end of this document

Define the column names that the content provider will return to clients If you are using an underlying

database these column names are typically identical to the SQL database column names they

represent Also define public static String constants that clients can use to specify the columns in

queries and other instructions

Be sure to include an integer column named _id (with the constant _ID) for the IDs of the records

You should have this field whether or not you have another field (such as a URL) that is also unique

among all records If youre using the SQLite database the _ID field should be the following type

INTEGER PRIMARY KEY AUTOINCREMENT

The AUTOINCREMENT descriptor is optional But without it SQLite increments an ID counter field to

the next number above the largest existing number in the column If you delete the last row the next

row added will have the same ID as the deleted row AUTOINCREMENT avoids this by having SQLite

increment to the next largest value whether deleted or not

Carefully document the data type of each column Clients need this information to read the data

If you are handling a new data type you must define a new MIME type to return in your

implementation of ContentProvidergetType() The type depends in part on whether or not the content

URI submitted to getType() limits the request to a specific record Theres one form of the MIME type

for a single record and another for multiple records Use the Uri methods to help determine what is

being requested Here is the general format for each type

o For a single record vndandroidcursoritemvndyourcompanynamecontenttype

For example a request for train record 122 like this URI

contentcomexampletransportationprovidertrains122

might return this MIME type

vndandroidcursoritemvndexamplerail

o For multiple records vndandroidcursordirvndyourcompanynamecontenttype

For example a request for all train records like the following URI

contentcomexampletransportationprovidertrains

might return this MIME type

vndandroidcursordirvndexamplerail

If you are exposing byte data thats too big to put in the table itself mdash such as a large bitmap file mdash the

field that exposes the data to clients should actually contain a content URI string This is the field that

gives clients access to the data file The record should also have another field named _data that lists

the exact file path on the device for that file This field is not intended to be read by the client but by

the ContentResolver The client will call ContentResolveropenInputStream() on the user-facing field

holding the URI for the item The ContentResolver will request the _data field for that record and

because it has higher permissions than a client it should be able to access that file directly and return

a read wrapper for the file to the client

For an example of a private content provider implementation see the NodePadProvider class in the

Notepad sample application that ships with the SDK

Declaring the content provider

To let the Android system know about the content provider youve developed declare it with a

ltprovidergt element in the applications AndroidManifestxml file Content providers that are not

declared in the manifest are not visible to the Android system

The name attribute is the fully qualified name of the ContentProvider subclass The authorities attribute

is the authority part of the content URI that identifies the provider For example if the ContentProvider

subclass is AutoInfoProvider the ltprovidergt element might look like this

ltprovider androidname=comexampleautosAutoInfoProvider androidauthorities=comexampleautosautoinfoprovider gt ltprovidergt

Note that the authorities attribute omits the path part of a content URI For example if

AutoInfoProvider controlled subtables for different types of autos or different manufacturers

contentcomexampleautosautoinfoproviderhonda

contentcomexampleautosautoinfoprovidergmcompact

contentcomexampleautosautoinfoprovidergmsuv

those paths would not be declared in the manifest The authority is what identifies the provider not the

path your provider can interpret the path part of the URI in any way you choose

Other ltprovidergt attributes can set permissions to read and write data provide for an icon and text

that can be displayed to users enable and disable the provider and so on Set the multiprocess

attribute to true if data does not need to be synchronized between multiple running versions of the

content provider This permits an instance of the provider to be created in each client process

eliminating the need to perform IPC

Content URI Summary

Here is a recap of the important parts of a content URI

A Standard prefix indicating that the data is controlled by a content provider Its never modified

B The authority part of the URI it identifies the content provider For third-party applications this should

be a fully-qualified class name (reduced to lowercase) to ensure uniqueness The authority is declared

in the ltprovidergt elements authorities attribute

ltprovider androidname=TransportationProvider androidauthorities=comexampletransportationprovider gt

C The path that the content provider uses to determine what kind of data is being requested This can be

zero or more segments long If the content provider exposes only one type of data (only trains for

example) it can be absent If the provider exposes several types including subtypes it can be several

segments long mdash for example landbus landtrain seaship and seasubmarine to give four

possibilities

D The ID of the specific record being requested if any This is the _ID value of the requested record If

the request is not limited to a single record this segment and the trailing slash are omitted

contentcomexampletransportationprovidertrains

Intent and intent filters

Three of the core components of an application mdash activities services and broadcast receivers mdash 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 mdash 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 ContextstartActivity() or ActivitystartActivityForResult() to launch an

activity or get an existing activity to do something new (It can also be passed to ActivitysetResult() to

return information to the activity that called startActivityForResult())

An Intent object is passed to ContextstartService() to initiate a service or deliver new instructions to an

ongoing service Similarly an intent can be passed to ContextbindService() to establish a connection

between the calling component and a target service It can optionally initiate the service if its not

already running

Intent objects passed to any of the broadcast methods (such as ContextsendBroadcast()

ContextsendOrderedBroadcast() or ContextsendStickyBroadcast()) 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 mdash how it resolves which component should receive an intent message For

intents that dont explicitly name a target component this process involves testing the Intent object

against intent filters associated with potential targets

Intent Objects

An Intent object is a bundle of information It contains information of interest to the component that

receives the intent (such as the action to be taken and the data to act on) plus information of interest to

the Android system (such as the category of component that should handle the intent and instructions

on how to launch a target activity) Principally it can contain the following

Component name

The name of the component that should handle the intent This field is a ComponentName

object mdash a combination of the fully qualified class name of the target component (for example

comexampleprojectappFreneticActivity) and the package name set in the manifest file of the

application where the component resides (for example comexampleproject) The package

part of the component name and the package name set in the manifest do not necessarily have

to match

The component name is optional If it is set the Intent object is delivered to an instance of the

designated class If it is not set Android uses other information in the Intent object to locate a

suitable target mdash see Intent Resolution later in this document

The component name is set by setComponent() setClass() or setClassName() and read by

getComponent()

Action

A string naming the action to be performed mdash or in the case of broadcast intents the action

that took place and is being reported The Intent class defines a number of action constants

including these

Constant Target

component

Action

ACTION_CALL activity Initiate a phone call

ACTION_EDIT activity Display data for the user to edit

ACTION_MAIN activity Start up as the initial activity of a task

with no data input and no returned

output

ACTION_SYNC activity Synchronize data on a server with

data on the mobile device

ACTION_BATTERY_LOW broadcast

receiver

A warning that the battery is low

ACTION_HEADSET_PLUG broadcast

receiver

A headset has been plugged into the

device or unplugged from it

ACTION_SCREEN_ON broadcast

receiver

The screen has been turned on

ACTION_TIMEZONE_CHANGED broadcast

receiver

The setting for the time zone has

changed

See the Intent class description for a list of pre-defined constants for generic actions Other

actions are defined elsewhere in the Android API You can also define your own action strings

for activating the components in your application Those you invent should include the

application package as a prefix mdash for example comexampleprojectSHOW_COLOR

The action largely determines how the rest of the intent is structured mdash particularly the data and

extras fields mdash much as a method name determines a set of arguments and a return value For

this reason its a good idea to use action names that are as specific as possible and to couple

them tightly to the other fields of the intent In other words instead of defining an action in

isolation define an entire protocol for the Intent objects your components can handle

The action in an Intent object is set by the setAction() method and read by getAction()

Data

The URI of the data to be acted on and the MIME type of that data Different actions are paired

with different kinds of data specifications For example if the action field is ACTION_EDIT the

data field would contain the URI of the document to be displayed for editing If the action is

ACTION_CALL the data field would be a tel URI with the number to call Similarly if the action

is ACTION_VIEW and the data field is an http URI the receiving activity would be called upon

to download and display whatever data the URI refers to

When matching an intent to a component that is capable of handling the data its often

important to know the type of data (its MIME type) in addition to its URI For example a

component able to display image data should not be called upon to play an audio file

In many cases the data type can be inferred from the URI mdash particularly content URIs which

indicate that the data is located on the device and controlled by a content provider (see the

separate discussion on content providers) But the type can also be explicitly set in the Intent

object The setData() method specifies data only as a URI setType() specifies it only as a

MIME type and setDataAndType() specifies it as both a URI and a MIME type The URI is read

by getData() and the type by getType()

Category

A string containing additional information about the kind of component that should handle the

intent Any number of category descriptions can be placed in an Intent object As it does for

actions the Intent class defines several category constants including these

Constant Meaning

CATEGORY_BROWSABLE The target activity can be safely invoked by the browser to

display data referenced by a link mdash for example an image or

an e-mail message

CATEGORY_GADGET The activity can be embedded inside of another activity that

hosts gadgets

CATEGORY_HOME The activity displays the home screen the first screen the

user sees when the device is turned on or when the HOME

key is pressed

CATEGORY_LAUNCHER The activity can be the initial activity of a task and is listed in

the top-level application launcher

CATEGORY_PREFERENCE The target activity is a preference panel

See the Intent class description for the full list of categories

The addCategory() method places a category in an Intent object removeCategory() deletes a

category previously added and getCategories() gets the set of all categories currently in the

object

Extras

Key-value pairs for additional information that should be delivered to the component handling

the intent Just as some actions are paired with particular kinds of data URIs some are paired

with particular extras For example an ACTION_TIMEZONE_CHANGED intent has a time-

zone extra that identifies the new time zone and ACTION_HEADSET_PLUG has a state

extra indicating whether the headset is now plugged in or unplugged as well as a name extra

for the type of headset If you were to invent a SHOW_COLOR action the color value would be

set in an extra key-value pair

The Intent object has a series of put() methods for inserting various types of extra data and a

similar set of get() methods for reading the data These methods parallel those for Bundle

objects In fact the extras can be installed and read as a Bundle using the putExtras() and

getExtras() methods

Flags

Flags of various sorts Many instruct the Android system how to launch an activity (for example

which task the activity should belong to) and how to treat it after its launched (for example

whether it belongs in the list of recent activities) All these flags are defined in the Intent class

The Android system and the applications that come with the platform employ Intent objects both to

send out system-originated broadcasts and to activate system-defined components To see how to

structure an intent to activate a system component consult the list of intents in the reference

Intent Resolution

Intents can be divided into two groups

Explicit intents designate the target component by its name (the component name field mentioned

earlier has a value set) Since component names would generally not be known to developers of other

applications explicit intents are typically used for application-internal messages mdash such as an activity

starting a subordinate service or launching a sister activity

Implicit intents do not name a target (the field for the component name is blank) Implicit intents are

often used to activate components in other applications

Android delivers an explicit intent to an instance of the designated target class Nothing in the Intent

object other than the component name matters for determining which component should get the intent

A different strategy is needed for implicit intents In the absence of a designated target the Android

system must find the best component (or components) to handle the intent mdash a single activity or

service to perform the requested action or the set of broadcast receivers to respond to the broadcast

announcement It does so by comparing the contents of the Intent object to intent filters structures

associated with components that can potentially receive intents Filters advertise the capabilities of a

component and delimit the intents it can handle They open the component to the possibility of

receiving implicit intents of the advertised type If a component does not have any intent filters it can

receive only explicit intents A component with filters can receive both explicit and implicit intents

Only three aspects of an Intent object are consulted when the object is tested against an intent filter

action

data (both URI and data type)

category

The extras and flags play no part in resolving which component receives an intent

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 mdash but only unwanted implicit intents (those that dont 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

components 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 mdash 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 Pads filters are described in the Note Pad Example

section later)

Filters and security

An intent filter cannot be relied on for security While it opens a component to receiving only certain

kinds of implicit intents it does nothing to prevent explicit intents from targeting the component Even

though a filter restricts the intents a component will be asked to handle to certain actions and data

sources someone could always put together an explicit intent with a different action and data source

and name the component as the target

An intent filter is an instance of the IntentFilter class However since the Android system must know

about the capabilities of a component before it can launch that component intent filters are generally

not set up in Java code but in the applications manifest file (AndroidManifestxml) as ltintent-filtergt

elements (The one exception would be filters for broadcast receivers that are registered dynamically

by calling ContextregisterReceiver() they are directly created as IntentFilter objects)

A filter has fields that parallel the action data and category fields of an Intent object An implicit intent

is tested against the filter in all three areas To be delivered to the component that owns the filter it

must pass all three tests If it fails even one of them the Android system wont deliver it to the

component mdash at least not on the basis of that filter However since a component can have multiple

intent filters an intent that does not pass through one of a components filters might make it through on

another

Each of the three tests is described in detail below

Action test

An ltintent-filtergt element in the manifest file lists actions as ltactiongt subelements For

example

ltintent-filter gt ltaction androidname=comexampleprojectSHOW_CURRENT gt ltaction androidname=comexampleprojectSHOW_RECENT gt ltaction androidname=comexampleprojectSHOW_PENDING gt ltintent-filtergt

As the example shows while an Intent object names just a single action a filter may list more

than one The list cannot be empty a filter must contain at least one ltactiongt element or it will

block all intents

To pass this test the action specified in the Intent object must match one of the actions listed in

the filter If the object or the filter does not specify an action the results are as follows

If the filter fails to list any actions there is nothing for an intent to match so all intents fail the

test No intents can get through the filter

On the other hand an Intent object that doesnt specify an action automatically passes the test

mdash as long as the filter contains at least one action

Category test

An ltintent-filtergt element also lists categories as subelements For example

ltintent-filter gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryBROWSABLE gt ltintent-filtergt

Note that the constants described earlier for actions and categories are not used in the manifest

file The full string values are used instead For instance the

androidintentcategoryBROWSABLE string in the example above corresponds to the

CATEGORY_BROWSABLE constant mentioned earlier in this document Similarly the string

androidintentactionEDIT corresponds to the ACTION_EDIT constant

For an intent to pass the category test every category in the Intent object must match a

category in the filter The filter can list additional categories but it cannot omit any that are in the

intent

In principle therefore an Intent object with no categories should always pass this test

regardless of whats in the filter Thats mostly true However with one exception Android treats

all implicit intents passed to startActivity() as if they contained at least one category

androidintentcategoryDEFAULT (the CATEGORY_DEFAULT constant) Therefore activities

that are willing to receive implicit intents must include androidintentcategoryDEFAULT in

their intent filters (Filters with androidintentactionMAIN and

androidintentcategoryLAUNCHER settings are the exception They mark activities that begin

new tasks and that are represented on the launcher screen They can include

androidintentcategoryDEFAULT in the list of categories but dont need to) See Using intent

matching later for more on these filters)

Data test

Like the action and categories the data specification for an intent filter is contained in a

subelement And as in those cases the subelement can appear multiple times or not at all For

example

ltintent-filter gt ltdata androidmimeType=videompeg androidscheme=http gt ltdata androidmimeType=audiompeg androidscheme=http gt ltintent-filtergt

Each ltdatagt element can specify a URI and a data type (MIME media type) There are

separate attributes mdash scheme host port and path mdash for each part of the URI

schemehostportpath

For example in the following URI

contentcomexampleproject200foldersubfolderetc

the scheme is content the host is comexampleproject the port is 200 and the path is

foldersubfolderetc The host and port together constitute the URI authority if a host is not

specified the port is ignored

Each of these attributes is optional but they are not independent of each other For an authority

to be meaningful a scheme must also be specified For a path to be meaningful both a scheme

and an authority must be specified

When the URI in an Intent object is compared to a URI specification in a filter its compared

only to the parts of the URI actually mentioned in the filter For example if a filter specifies only

a scheme all URIs with that scheme match the filter If a filter specifies a scheme and an

authority but no path all URIs with the same scheme and authority match regardless of their

paths If a filter specifies a scheme an authority and a path only URIs with the same scheme

authority and path match However a path specification in the filter can contain wildcards to

require only a partial match of the path

The type attribute of a ltdatagt element specifies the MIME type of the data Its more common in

filters than a URI Both the Intent object and the filter can use a wildcard for the subtype field

mdash for example text or audio mdash indicating any subtype matches

The data test compares both the URI and the data type in the Intent object to a URI and data

type specified in the filter The rules are as follows

a An Intent object that contains neither a URI nor a data type passes the test only if the filter

likewise does not specify any URIs or data types

b An Intent object that contains a URI but no data type (and a type cannot be inferred from the

URI) passes the test only if its URI matches a URI in the filter and the filter likewise does not

specify a type This will be the case only for URIs like mailto and tel that do not refer to actual

data

c An Intent object that contains a data type but not a URI passes the test only if the filter lists the

same data type and similarly does not specify a URI

d An Intent object that contains both a URI and a data type (or a data type can be inferred from

the URI) passes the data type part of the test only if its type matches a type listed in the filter It

passes the URI part of the test either if its URI matches a URI in the filter or if it has a content

or file URI and the filter does not specify a URI In other words a component is presumed to

support content and file data if its filter lists only a data type

If an intent can pass through the filters of more than one activity or service the user may be asked

which component to activate An exception is raised if no target can be found

Common cases

The last rule shown above for the data test rule (d) reflects the expectation that components are able

to get local data from a file or content provider Therefore their filters can list just a data type and do

not need to explicitly name the content and file schemes This is a typical case A ltdatagt element like

the following for example tells Android that the component can get image data from a content

provider and display it

ltdata androidmimeType=image gt

Since most available data is dispensed by content providers filters that specify a data type but not a

URI are perhaps the most common

Another common configuration is filters with a scheme and a data type For example a ltdatagt

element like the following tells Android that the component can get video data from the network and

display it

ltdata androidscheme=http androidtype=video gt

Consider for example what the browser application does when the user follows a link on a web page

It first tries to display the data (as it could if the link was to an HTML page) If it cant display the data it

puts together an implicit intent with the scheme and data type and tries to start an activity that can do

the job If there are no takers it asks the download manager to download the data That puts it under

the control of a content provider so a potentially larger pool of activities (those with filters that just

name a data type) can respond

Most applications also have a way to start fresh without a reference to any particular data Activities

that can initiate applications have filters with androidintentactionMAIN specified as the action If

they are to be represented in the application launcher they also specify the

androidintentcategoryLAUNCHER category

ltintent-filter gt ltaction androidname=code androidintentactionMAIN gt ltcategory androidname=code androidintentcategoryLAUNCHER gt ltintent-filtergt

Using intent matching

Intents are matched against intent filters not only to discover a target component to activate but also

to discover something about the set of components on the device For example the Android system

populates the application launcher the top-level screen that shows the applications that are available

for the user to launch by finding all the activities with intent filters that specify the

androidintentactionMAIN action and androidintentcategoryLAUNCHER category (as illustrated

in the previous section) It then displays the icons and labels of those activities in the launcher

Similarly it discovers the home screen by looking for the activity with androidintentcategoryHOME

in its filter

Your application can use intent matching is a similar way The PackageManager has a set of query()

methods that return all components that can accept a particular intent and a similar series of

resolve() methods that determine the best component to respond to an intent For example

queryIntentActivities() returns a list of all activities that can perform the intent passed as an argument

and queryIntentServices() returns a similar list of services Neither method activates the components

they just list the ones that can respond Theres a similar method queryBroadcastReceivers() for

broadcast receivers

Note Pad Example

The Note Pad sample application enables users to browse through a list of notes view details about

individual items in the list edit the items and add a new item to the list This section looks at the intent

filters declared in its manifest file (If youre working offline in the SDK you can find all the source files

for this sample application including its manifest file at ltsdkgtsamplesNotePadindexhtml If youre

viewing the documentation online the source files are in the Tutorials and Sample Code section here)

In its manifest file the Note Pad application declares three activities each with at least one intent filter

It also declares a content provider that manages the note data Here is the manifest file in its entirety

ltmanifest xmlnsandroid=httpschemasandroidcomapkresandroid package=comexampleandroidnotepadgt ltapplication androidicon=drawableapp_notes androidlabel=stringapp_name gt ltprovider androidname=NotePadProvider androidauthorities=comgoogleproviderNotePad gt ltactivity androidname=NotesList androidlabel=stringtitle_notes_listgt ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltactivity androidname=NoteEditor androidtheme=androidstyleThemeLight androidlabel=stringtitle_note gt ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltactivitygt

ltactivity androidname=TitleEditor androidlabel=stringtitle_edit_title androidtheme=androidstyleThemeDialoggt ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltapplicationgt ltmanifestgt

The first activity NotesList is distinguished from the other activities by the fact that it operates on a

directory of notes (the note list) rather than on a single note It would generally serve as the initial user

interface into the application It can do three things as described by its three intent filters

1 ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt

This filter declares the main entry point into the Note Pad application The standard MAIN action is an

entry point that does not require any other information in the Intent (no data specification for example)

and the LAUNCHER category says that this entry point should be listed in the application launcher

2 ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

This filter declares the things that the activity can do on a directory of notes It can allow the user to

view or edit the directory (via the VIEW and EDIT actions) or to pick a particular note from the

directory (via the PICK action)

The mimeType attribute of the ltdatagt element specifies the kind of data that these actions operate on

It indicates that the activity can get a Cursor over zero or more items (vndandroidcursordir) from a

content provider that holds Note Pad data (vndgooglenote) The Intent object that launches the

activity would include a content URI specifying the exact data of this type that the activity should open

Note also the DEFAULT category supplied in this filter Its there because the ContextstartActivity()

and ActivitystartActivityForResult() methods treat all intents as if they contained the DEFAULT

category mdash with just two exceptions

o Intents that explicitly name the target activity

o Intents consisting of the MAIN action and LAUNCHER category

Therefore the DEFAULT category is required for all filters mdash except for those with the MAIN action

and LAUNCHER category (Intent filters are not consulted for explicit intents)

3 ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

This filter describes the activitys ability to return a note selected by the user without requiring any

specification of the directory the user should choose from The GET_CONTENT action is similar to the

PICK action In both cases the activity returns the URI for a note selected by the user (In each case

its returned to the activity that called startActivityForResult() to start the NoteList activity) Here

however the caller specifies the type of data desired instead of the directory of data the user will be

picking from

The data type vndandroidcursoritemvndgooglenote indicates the type of data the activity can

return mdash a URI for a single note From the returned URI the caller can get a Cursor for exactly one

item (vndandroidcursoritem) from the content provider that holds Note Pad data (vndgooglenote)

In other words for the PICK action in the previous filter the data type indicates the type of data the

activity could display to the user For the GET_CONTENT filter it indicates the type of data the activity

can return to the caller

Given these capabilities the following intents will resolve to the NotesList activity

action androidintentactionMAIN

Launches the activity with no data specified

action androidintentactionMAIN

category androidintentcategoryLAUNCHER

Launches the activity with no data selected specified This is the actual intent used by the

Launcher to populate its top-level list All activities with filters that match this action and

category are added to the list

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of all the notes under

contentcomgoogleproviderNotePadnotes The user can then browse through the list and

get information about the items in it

action androidintentactionPICK

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of the notes under

contentcomgoogleproviderNotePadnotes The user can then pick a note from the list and

the activity will return the URI for that item back to the activity that started the NoteList activity

action androidintentactionGET_CONTENT

data type vndandroidcursoritemvndgooglenote

Asks the activity to supply a single item of Note Pad data

The second activity NoteEditor shows users a single note entry and allows them to edit it It can do

two things as described by its two intent filters

1 ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The first primary purpose of this activity is to enable the user to interact with a single note ampmdash to

either VIEW the note or EDIT it (The EDIT_NOTE category is a synonym for EDIT) The intent would

contain the URI for data matching the MIME type vndandroidcursoritemvndgooglenote mdash that is

the URI for a single specific note It would typically be a URI that was returned by the PICK or

GET_CONTENT actions of the NoteList activity

As before this filter lists the DEFAULT category so that the activity can be launched by intents that

dont explicitly specify the NoteEditor class

2 ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

The secondary purpose of this activity is to enable the user to create a new note which it will INSERT

into an existing directory of notes The intent would contain the URI for data matching the MIME type

vndandroidcursordirvndgooglenote mdash that is the URI for the directory where the note should be

placed

Given these capabilities the following intents will resolve to the NoteEditor activity

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID (For details on how content

URIs specify individual members of a group see Content Providers)

action androidintentactionEDIT

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID and to let the user edit it If

the user saves the changes the activity updates the data for the note in the content provider

action androidintentactionINSERT

data contentcomgoogleproviderNotePadnotes

Asks the activity to create a new empty note in the notes list at

contentcomgoogleproviderNotePadnotes and allow the user to edit it If the user saves the

note its URI is returned to the caller

The last activity TitleEditor enables the user to edit the title of a note This could be implemented by

directly invoking the activity (by explicitly setting its component name in the Intent) without using an

intent filter But here we take the opportunity to show how to publish alternative operations on existing

data

ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The single intent filter for this activity uses a custom action called

comandroidnotepadactionEDIT_TITLE It must be invoked on a specific note (data type

vndandroidcursoritemvndgooglenote) like the previous VIEW and EDIT actions However here the

activity displays the title contained in the note data not the content of the note itself

In addition to supporting the usual DEFAULT category the title editor also supports two other standard

categories ALTERNATIVE and SELECTED_ALTERNATIVE These categories identify activities that

can be presented to users in a menu of options (much as the LAUNCHER category identifies activities

that should be presented to user in the application launcher) Note that the filter also supplies an

explicit label (via androidlabel=stringresolve_title) to better control what users see when

presented with this activity as an alternative action to the data they are currently viewing (For more

information on these categories and building options menus see the

PackageManagerqueryIntentActivityOptions() and MenuaddIntentOptions() methods)

Given these capabilities the following intent will resolve to the TitleEditor activity

action comandroidnotepadactionEDIT_TITLE

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the title associated with note ID and allow the user to edit the title

Processes and Threads

When an application component starts and the application does not have any other components

running the Android system starts a new Linux process for the application with a single thread of

execution By default all components of the same application run in the same process and thread

(called the main thread) If an application component starts and there already exists a process for

that application (because another component from the application exists) then the component is

started within that process and uses the same thread of execution However you can arrange for

different components in your application to run in separate processes and you can create additional

threads for any process

This document discusses how processes and threads work in an Android application

Processes

By default all components of the same application run in the same process and most applications

should not change this However if you find that you need to control which process a certain

component belongs to you can do so in the manifest file

The manifest entry for each type of component elementmdashltactivitygt ltservicegt ltreceivergt and

ltprovidergtmdashsupports an androidprocess attribute that can specify a process in which that component

should run You can set this attribute so that each component runs in its own process or so that some

components share a process while others do not You can also set androidprocess so that

components of different applications run in the same processmdashprovided that the applications share the

same Linux user ID and are signed with the same certificates

The ltapplicationgt element also supports an androidprocess attribute to set a default value that

applies to all components

Android might 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 thats killed are consequently destroyed A process is started again for those components

when theres again work for them to do

When deciding which processes to kill the Android system weighs their relative importance to the

user For example it more readily shuts down a process hosting activities that are no longer visible on

screen compared to a process hosting visible activities The decision whether to terminate a process

therefore depends on the state of the components running in that process The rules used to decide

which processes to terminate is discussed below

Process lifecycle

The Android system tries to maintain an application process for as long as possible but eventually

needs to remove old processes to reclaim memory for new or more important processes To determine

which processes to keep and which to kill the system places each process into an importance

hierarchy based on the components running in the process and the state of those components

Processes with the lowest importance are eliminated first then those with the next lowest importance

and so on as necessary to recover system resources

There are five levels in the importance hierarchy The following list presents the different types of

processes in order of importance (the first process is most important and is killed last)

1 Foreground process

A process that is required for what the user is currently doing A process is considered to be in the

foreground if any of the following conditions are true

o It hosts an Activity that the user is interacting with (the Activitys onResume() method has been called)

o It hosts a Service thats bound to the activity that the user is interacting with

o It hosts a Service thats running in the foregroundmdashthe service has called startForeground()

o It hosts a Service thats executing one of its lifecycle callbacks (onCreate() onStart() or onDestroy())

o It hosts a BroadcastReceiver thats executing its onReceive() method

Generally only a few foreground processes exist at any given time They are killed only as a last

resortmdashif memory is so low that they cannot all continue to run Generally at that point the device has

reached a memory paging state so killing some foreground processes is required to keep the user

interface responsive

2 Visible process

A process that doesnt have any foreground components but still can affect what the user sees on

screen A process is considered to be visible if either of the following conditions are true

o It hosts an Activity that is not in the foreground but is still visible to the user (its onPause() method has

been called) This might occur for example if the foreground activity started a dialog which allows the

previous activity to be seen behind it

o It hosts a Service thats bound to a visible (or foreground) activity

A visible process is considered extremely important and will not be killed unless doing so is required to

keep all foreground processes running

3 Service process

A process that is running a service that has been started with the startService() method and does not

fall into either of the two higher categories Although service processes are not directly tied to anything

the user sees they are generally doing things that the user cares about (such as playing music in the

background or downloading data on the network) so the system keeps them running unless theres

not enough memory to retain them along with all foreground and visible processes

4 Background process

A process holding an activity thats not currently visible to the user (the activitys onStop() method has

been called) These processes have no direct impact on the user experience and the system can kill

them at any time to reclaim memory for a foreground visible or service process Usually there are

many background processes running so they are kept in an LRU (least recently used) list to ensure

that the process with the activity that was most recently seen by the user is the last to be killed If an

activity implements its lifecycle methods correctly and saves its current state killing its process will not

have a visible effect on the user experience because when the user navigates back to the activity the

activity restores all of its visible state See the Activities document for information about saving and

restoring state

5 Empty process

A process that doesnt hold any active application components The only reason to keep this kind of

process alive is for caching purposes to improve startup time the next time a component needs to run

in it The system often kills these processes in order to balance overall system resources between

process caches and the underlying kernel caches

Android ranks a process at the highest level it can based upon the importance of the components

currently active in the process For example if a process hosts a service and a visible activity the

process is ranked as a visible process not a service process

In addition a processs ranking might be increased because other processes are dependent on itmdasha

process that is serving another process can never be ranked lower than the process it is serving For

example if a content provider in process A is serving a client in process B or if a service in process A

is bound to a component in process B process A is always considered at least as important as

process B

Because a process running a service is ranked higher than a process with background activities an

activity that initiates a long-running operation might do well to start a service for that operation rather

than simply create a worker threadmdashparticularly if the operation will likely outlast the activity For

example an activity thats uploading a picture to a web site should start a service to perform the

upload so that the upload can continue in the background even if the user leaves the activity Using a

service guarantees that the operation will have at least service process priority regardless of what

happens to the activity This is the same reason that broadcast receivers should employ services

rather than simply put time-consuming operations in a thread

Threads

When an application is launched the system creates a thread of execution for the application called

main This thread is very important because it is in charge of dispatching events to the appropriate

user interface widgets including drawing events It is also the thread in which your application interacts

with components from the Android UI toolkit (components from the androidwidget and androidview

packages) As such the main thread is also sometimes called the UI thread

The system does not create a separate thread for each instance of a component All components that

run in the same process are instantiated in the UI thread and system calls to each component are

dispatched from that thread Consequently methods that respond to system callbacks (such as

onKeyDown() to report user actions or a lifecycle callback method) always run in the UI thread of the

process

For instance when the user touches a button on the screen your apps UI thread dispatches the touch

event to the widget which in turn sets its pressed state and posts an invalidate request to the event

queue The UI thread dequeues the request and notifies the widget that it should redraw itself

When your app performs intensive work in response to user interaction this single thread model can

yield poor performance unless you implement your application properly Specifically if everything is

happening in the UI thread performing long operations such as network access or database queries

will block the whole UI When the thread is blocked no events can be dispatched including drawing

events From the users perspective the application appears to hang Even worse if the UI thread is

blocked for more than a few seconds (about 5 seconds currently) the user is presented with the

infamous application not responding (ANR) dialog The user might then decide to quit your

application and uninstall it if they are unhappy

Additionally the Andoid UI toolkit is not thread-safe So you must not manipulate your UI from a

worker threadmdashyou must do all manipulation to your user interface from the UI thread Thus there are

simply two rules to Androids single thread model

1 Do not block the UI thread

2 Do not access the Android UI toolkit from outside the UI thread

Worker threads

Because of the single thread model described above its vital to the responsiveness of your

applications UI that you do not block the UI thread If you have operations to perform that are not

instantaneous you should make sure to do them in separate threads (background or worker

threads)

For example below is some code for a click listener that downloads an image from a separate thread

and displays it in an ImageView

public void onClick(View v) new Thread(new Runnable() public void run() Bitmap b = loadImageFromNetwork(httpexamplecomimagepng) mImageViewsetImageBitmap(b) )start()

At first this seems to work fine because it creates a new thread to handle the network operation

However it violates the second rule of the single-threaded model do not access the Android UI toolkit

from outside the UI threadmdashthis sample modifies the ImageView from the worker thread instead of the

UI thread This can result in undefined and unexpected behavior which can be difficult and time-

consuming to track down

To fix this problem Android offers several ways to access the UI thread from other threads Here is a

list of methods that can help

ActivityrunOnUiThread(Runnable)

Viewpost(Runnable)

ViewpostDelayed(Runnable long)

For example you can fix the above code by using the Viewpost(Runnable) method

public void onClick(View v) new Thread(new Runnable() public void run() final Bitmap bitmap = loadImageFromNetwork(httpexamplecomimagepng) mImageViewpost(new Runnable() public void run() mImageViewsetImageBitmap(bitmap) ) )start()

Now this implementation is thread-safe the network operation is done from a separate thread while

the ImageView is manipulated from the UI thread

However as the complexity of the operation grows this kind of code can get complicated and difficult

to maintain To handle more complex interactions with a worker thread you might consider using a

Handler in your worker thread to process messages delivered from the UI thread Perhaps the best

solution though is to extend the AsyncTask class which simplifies the execution of worker thread

tasks that need to interact with the UI

Using AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface It performs the blocking

operations in a worker thread and then publishes the results on the UI thread without requiring you to

handle threads andor handlers yourself

To use it you must subclass AsyncTask and implement the doInBackground() callback method which

runs in a pool of background threads To update your UI you should implement onPostExecute()

which delivers the result from doInBackground() and runs in the UI thread so you can safely update

your UI You can then run the task by calling execute() from the UI thread

For example you can implement the previous example using AsyncTask this way

public void onClick(View v) new DownloadImageTask()execute(httpexamplecomimagepng) private class DownloadImageTask extends AsyncTaskltString Void Bitmapgt The system calls this to perform work in a worker thread and delivers it the parameters given to AsyncTaskexecute() protected Bitmap doInBackground(String urls) return loadImageFromNetwork(urls[0])

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 8: 03 services

mServiceLooper = threadgetLooper() mServiceHandler = new ServiceHandler(mServiceLooper) Override public int onStartCommand(Intent intent int flags int startId) ToastmakeText(this service starting ToastLENGTH_SHORT)show() For each start request send a message to start a job and deliver the start ID so we know which request were stopping when we finish the job Message msg = mServiceHandlerobtainMessage() msgarg1 = startId mServiceHandlersendMessage(msg) If we get killed after returning from here restart return START_STICKY Override public IBinder onBind(Intent intent) We dont provide binding so return null return null Override public void onDestroy() ToastmakeText(this service done ToastLENGTH_SHORT)show()

As you can see its a lot more work than using IntentService

However because you handle each call to onStartCommand() yourself you can perform multiple

requests simultaneously Thats not what this example does but if thats what you want then you can

create a new thread for each request and run them right away (instead of waiting for the previous

request to finish)

Notice that the onStartCommand() method must return an integer The integer is a value that

describes how the system should continue the service in the event that the system kills it (as

discussed above the default implementation for IntentService handles this for you though you are

able to modify it) The return value from onStartCommand() must be one of the following constants

START_NOT_STICKY

If the system kills the service after onStartCommand() returns do not recreate the service

unless there are pending intents to deliver This is the safest option to avoid running your

service when not necessary and when your application can simply restart any unfinished jobs

START_STICKY

If the system kills the service after onStartCommand() returns recreate the service and call

onStartCommand() but do not redeliver the last intent Instead the system calls

onStartCommand() with a null intent unless there were pending intents to start the service in

which case those intents are delivered This is suitable for media players (or similar services)

that are not executing commands but running indefinitely and waiting for a job

START_REDELIVER_INTENT

If the system kills the service after onStartCommand() returns recreate the service and call

onStartCommand() with the last intent that was delivered to the service Any pending intents are

delivered in turn This is suitable for services that are actively performing a job that should be

immediately resumed such as downloading a file

For more details about these return values see the linked reference documentation for each constant

Starting a Service

You can start a service from an activity or other application component by passing an Intent (specifying

the service to start) to startService() The Android system calls the services onStartCommand()

method and passes it the Intent (You should never call onStartCommand() directly)

For example an activity can start the example service in the previous section (HelloSevice) using an

explicit intent with startService()

Intent intent = new Intent(this HelloServiceclass) startService(intent)

The startService() method returns immediately and the Android system calls the services

onStartCommand() method If the service is not already running the system first calls onCreate() then

calls onStartCommand()

If the service does not also provide binding the intent delivered with startService() is the only mode of

communication between the application component and the service However if you want the service

to send a result back then the client that starts the service can create a PendingIntent for a broadcast

(with getBroadcast()) and deliver it to the service in the Intent that starts the service The service can

then use the broadcast to deliver a result

Multiple requests to start the service result in multiple corresponding calls to the services

onStartCommand() However only one request to stop the service (with stopSelf() or stopService()) is

required to stop it

Stopping a service

A started service must manage its own lifecycle That is the system does not stop or destroy the

service unless it must recover system memory and the service continues to run after

onStartCommand() returns So the service must stop itself by calling stopSelf() or another component

can stop it by calling stopService()

Once requested to stop with stopSelf() or stopService() the system destroys the service as soon as

possible

However if your service handles multiple requests to onStartCommand() concurrently then you

shouldnt stop the service when youre done processing a start request because you might have since

received a new start request (stopping at the end of the first request would terminate the second one)

To avoid this problem you can use stopSelf(int) to ensure that your request to stop the service is

always based on the most recent start request That is when you call stopSelf(int) you pass the ID of

the start request (the startId delivered to onStartCommand()) to which your stop request corresponds

Then if the service received a new start request before you were able to call stopSelf(int) then the ID

will not match and the service will not stop

Caution Its important that your application stops its services when its done working to avoid

wasting system resources and consuming battery power If necessary other components can stop

the service by calling stopService() Even if you enable binding for the service you must always

stop the service yourself if it ever received a call to onStartCommand()

For more information about the lifecycle of a service see the section below about Managing the

Lifecycle of a Service

Creating a Bound Service

A bound service is one that allows application components to bind to it by calling bindService() in order

to create a long-standing connection (and generally does not allow components to start it by calling

startService())

You should create a bound service when you want to interact with the service from activities and other

components in your application or to expose some of your applications functionality to other

applications through interprocess communication (IPC)

To create a bound service you must implement the onBind() callback method to return an IBinder that

defines the interface for communication with the service Other application components can then call

bindService() to retrieve the interface and begin calling methods on the service The service lives only

to serve the application component that is bound to it so when there are no components bound to the

service the system destroys it (you do not need to stop a bound service in the way you must when the

service is started through onStartCommand())

To create a bound service the first thing you must do is define the interface that specifies how a client

can communicate with the service This interface between the service and a client must be an

implementation of IBinder and is what your service must return from the onBind() callback method

Once the client receives the IBinder it can begin interacting with the service through that interface

Multiple clients can bind to the service at once When a client is done interacting with the service it

calls unbindService() to unbind Once there are no clients bound to the service the system destroys

the service

There are multiple ways to implement a bound service and the implementation is more complicated

than a started service so the bound service discussion appears in a separate document about Bound

Services

Sending Notifications to the User

Once running a service can notify the user of events using Toast Notifications or Status Bar

Notifications

A toast notification is a message that appears on the surface of the current window for a moment then

disappears while a status bar notification provides an icon in the status bar with a message which the

user can select in order to take an action (such as start an activity)

Usually a status bar notification is the best technique when some background work has completed

(such as a file completed downloading) and the user can now act on it When the user selects the

notification from the expanded view the notification can start an activity (such as to view the

downloaded file)

See the Toast Notifications or Status Bar Notifications developer guides for more information

Running a Service in the Foreground

A foreground service is a service thats considered to be something the user is actively aware of and

thus not a candidate for the system to kill when low on memory A foreground service must provide a

notification for the status bar which is placed under the Ongoing heading which means that the

notification cannot be dismissed unless the service is either stopped or removed from the foreground

For example a music player that plays music from a service should be set to run in the foreground

because the user is explicitly aware of its operation The notification in the status bar might indicate the

current song and allow the user to launch an activity to interact with the music player

To request that your service run in the foreground call startForeground() This method takes two

parameters an integer that uniquely identifies the notification and the Notification for the status bar

For example

Notification notification = new Notification(Rdrawableicon getText(Rstringticker_text) SystemcurrentTimeMillis()) Intent notificationIntent = new Intent(this ExampleActivityclass) PendingIntent pendingIntent = PendingIntentgetActivity(this 0 notificationIntent 0) notificationsetLatestEventInfo(this getText(Rstringnotification_title) getText(Rstringnotification_message) pendingIntent) startForeground(ONGOING_NOTIFICATION notification)

To remove the service from the foreground call stopForeground() This method takes a boolean

indicating whether to remove the status bar notification as well This method does not stop the service

However if you stop the service while its still running in the foreground then the notification is also

removed

Note The methods startForeground() and stopForeground() were introduced in Android 20 (API

Level 5) In order to run your service in the foreground on older versions of the platform you must

use the previous setForeground() methodmdashsee the startForeground() documentation for

information about how to provide backward compatibility

For more information about notifications see Creating Status Bar Notifications

Managing the Lifecycle of a Service

The lifecycle of a service is much simpler than that of an activity However its even more important

that you pay close attention to how your service is created and destroyed because a service can run

in the background without the user being aware

The service lifecyclemdashfrom when its created to when its destroyedmdashcan follow two different paths

A started service

The service is created when another component calls startService() The service then runs indefinitely

and must stop itself by calling stopSelf() Another component can also stop the service by calling

stopService() When the service is stopped the system destroys it

A bound service

The service is created when another component (a client) calls bindService() The client then

communicates with the service through an IBinder interface The client can close the connection by

calling unbindService() Multiple clients can bind to the same service and when all of them unbind the

system destroys the service (The service does not need to stop itself)

These two paths are not entirely separate That is you can bind to a service that was already started

with startService() For example a background music service could be started by calling startService()

with an Intent that identifies the music to play Later possibly when the user wants to exercise some

control over the player or get information about the current song an activity can bind to the service by

calling bindService() In cases like this stopService() or stopSelf() does not actually stop the service

until all clients unbind

Implementing the lifecycle callbacks

Like an activity a service has lifecycle callback methods that you can implement to monitor changes in

the services state and perform work at the appropriate times The following skeleton service

demonstrates each of the lifecycle methods

Figure 2 The service lifecycle The diagram on the left shows the lifecycle when the service is created

with startService() and the diagram on the right shows the lifecycle when the service is created with

bindService()

public class ExampleService extends Service int mStartMode indicates how to behave if the service is killed IBinder mBinder interface for clients that bind boolean mAllowRebind indicates whether onRebind should be used Override public void onCreate() The service is being created Override public int onStartCommand(Intent intent int flags int startId) The service is starting due to a call to startService() return mStartMode Override public IBinder onBind(Intent intent) A client is binding to the service with bindService() return mBinder Override public boolean onUnbind(Intent intent) All clients have unbound with unbindService()

return mAllowRebind Override public void onRebind(Intent intent) A client is binding to the service with bindService() after onUnbind() has already been called Override public void onDestroy() The service is no longer used and is being destroyed

Note Unlike the activity lifecycle callback methods you are not required to call the superclass

implementation of these callback methods

By implementing these methods you can monitor two nested loops of the services lifecycle

The entire lifetime of a service happens between the time onCreate() is called and the time

onDestroy() returns Like an activity a service does its initial setup in onCreate() and releases all

remaining resources in onDestroy() For example a music playback service could create the thread

where the music will be played in onCreate() then stop the thread in onDestroy()

The onCreate() and onDestroy() methods are called for all services whether theyre created by

startService() or bindService()

The active lifetime of a service begins with a call to either onStartCommand() or onBind() Each

method is handed the Intent that was passed to either startService() or bindService() respectively

If the service is started the active lifetime ends the same time that the entire lifetime ends (the service

is still active even after onStartCommand() returns) If the service is bound the active lifetime ends

when onUnbind() returns

Note Although a started service is stopped by a call to either stopSelf() or stopService() there is

not a respective callback for the service (theres no onStop() callback) So unless the service is

bound to a client the system destroys it when the service is stoppedmdashonDestroy() is the only

callback received

Figure 2 illustrates the typical callback methods for a service Although the figure separates services

that are created by startService() from those created by bindService() keep in mind that any service

no matter how its started can potentially allow clients to bind to it So a service that was initially

started with onStartCommand() (by a client calling startService()) can still receive a call to onBind()

(when a client calls bindService())

For more information about creating a service that provides binding see the Bound Services

document which includes more information about the onRebind() callback method in the section about

Managing the Lifecycle of a Bound Service

Bound Services

A bound service is the server in a client-server interface A bound service allows components (such as

activities) to bind to the service send requests receive responses and even perform interprocess

communication (IPC) A bound service typically lives only while it serves another application

component and does not run in the background indefinitely

This document shows you how to create a bound service including how to bind to the service from

other application components However you should also refer to the Services document for additional

information about services in general such as how to deliver notifications from a service set the

service to run in the foreground and more

The Basics

A bound service is an implementation of the Service class that allows other applications to bind to it

and interact with it To provide binding for a service you must implement the onBind() callback

method This method returns an IBinder object that defines the programming interface that clients can

use to interact with the service

Binding to a Started Service

As discussed in the Services document you can create a service that is both started and bound That

is the service can be started by calling startService() which allows the service to run indefinitely and

also allow a client to bind to the service by calling bindService()

If you do allow your service to be started and bound then when the service has been started the

system does not destroy the service when all clients unbind Instead you must explicitly stop the

service by calling stopSelf() or stopService()

Although you should usually implement either onBind() or onStartCommand() its sometimes

necessary to implement both For example a music player might find it useful to allow its service to run

indefinitely and also provide binding This way an activity can start the service to play some music and

the music continues to play even if the user leaves the application Then when the user returns to the

application the activity can bind to the service to regain control of playback

Be sure to read the section about Managing the Lifecycle of a Bound Service for more information

about the service lifecycle when adding binding to a started service

A client can bind to the service by calling bindService() When it does it must provide an

implementation of ServiceConnection which monitors the connection with the service The

bindService() method returns immediately without a value but when the Android system creates the

connection between the client and service it calls onServiceConnected() on the ServiceConnection to

deliver the IBinder that the client can use to communicate with the service

Multiple clients can connect to the service at once However the system calls your services onBind()

method to retrieve the IBinder only when the first client binds The system then delivers the same

IBinder to any additional clients that bind without calling onBind() again

When the last client unbinds from the service the system destroys the service (unless the service was

also started by startService())

When you implement your bound service the most important part is defining the interface that your

onBind() callback method returns There are a few different ways you can define your services IBinder

interface and the following section discusses each technique

Creating a Bound Service

When creating a service that provides binding you must provide an IBinder that provides the

programming interface that clients can use to interact with the service There are three ways you can

define the interface

Extending the Binder class

If your service is private to your own application and runs in the same process as the client

(which is common) you should create your interface by extending the Binder class and

returning an instance of it from onBind() The client receives the Binder and can use it to directly

access public methods available in either the Binder implementation or even the Service

This is the preferred technique when your service is merely a background worker for your own

application The only reason you would not create your interface this way is because your

service is used by other applications or across separate processes

Using a Messenger

If you need your interface to work across different processes you can create an interface for the

service with a Messenger In this manner the service defines a Handler that responds to

different types of Message objects This Handler is the basis for a Messenger that can then

share an IBinder with the client allowing the client to send commands to the service using

Message objects Additionally the client can define a Messenger of its own so the service can

send messages back

This is the simplest way to perform interprocess communication (IPC) because the Messenger

queues all requests into a single thread so that you dont have to design your service to be

thread-safe

Using AIDL

AIDL (Android Interface Definition Language) performs all the work to decompose objects into

primitives that the operating system can understand and marshall them across processes to

perform IPC The previous technique using a Messenger is actually based on AIDL as its

underlying structure As mentioned above the Messenger creates a queue of all the client

requests in a single thread so the service receives requests one at a time If however you

want your service to handle multiple requests simultaneously then you can use AIDL directly In

this case your service must be capable of multi-threading and be built thread-safe

To use AIDL directly you must create an aidl file that defines the programming interface The

Android SDK tools use this file to generate an abstract class that implements the interface and

handles IPC which you can then extend within your service

Note Most applications should not use AIDL to create a bound service because it may require

multithreading capabilities and can result in a more complicated implementation As such AIDL is

not suitable for most applications and this document does not discuss how to use it for your

service If youre certain that you need to use AIDL directly see the AIDL document

Extending the Binder class

If your service is used only by the local application and does not need to work across processes then

you can implement your own Binder class that provides your client direct access to public methods in

the service

Note This works only if the client and service are in the same application and process which is

most common For example this would work well for a music application that needs to bind an

activity to its own service thats playing music in the background

Heres how to set it up

1 In your service create an instance of Binder that either

o contains public methods that the client can call

o returns the current Service instance which has public methods the client can call

o or returns an instance of another class hosted by the service with public methods the client can call

2 Return this instance of Binder from the onBind() callback method

3 In the client receive the Binder from the onServiceConnected() callback method and make calls to the

bound service using the methods provided

Note The reason the service and client must be in the same application is so the client can cast

the returned object and properly call its APIs The service and client must also be in the same

process because this technique does not perform any marshalling across processes

For example heres a service that provides clients access to methods in the service through a Binder

implementation

public class LocalService extends Service

Binder given to clients

private final IBinder mBinder = new LocalBinder()

Random number generator

private final Random mGenerator = new Random()

Class used for the client Binder Because we know this service always

runs in the same process as its clients we dont need to deal with IPC

public class LocalBinder extends Binder

LocalService getService()

Return this instance of LocalService so clients can call public methods

return LocalServicethis

Override

public IBinder onBind(Intent intent)

return mBinder

method for clients

public int getRandomNumber()

return mGeneratornextInt(100)

The LocalBinder provides the getService() method for clients to retrieve the current instance of

LocalService This allows clients to call public methods in the service For example clients can call

getRandomNumber() from the service

Heres an activity that binds to LocalService and calls getRandomNumber() when a button is clicked

public class BindingActivity extends Activity

LocalService mService

boolean mBound = false

Override

protected void onCreate(Bundle savedInstanceState)

superonCreate(savedInstanceState)

setContentView(Rlayoutmain)

Override

protected void onStart()

superonStart()

Bind to LocalService

Intent intent = new Intent(this LocalServiceclass)

bindService(intent mConnection ContextBIND_AUTO_CREATE)

Override

protected void onStop()

superonStop()

Unbind from the service

if (mBound)

unbindService(mConnection)

mBound = false

Called when a button is clicked (the button in the layout file attaches to

this method with the androidonClick attribute)

public void onButtonClick(View v)

if (mBound)

Call a method from the LocalService

However if this call were something that might hang then this request should

occur in a separate thread to avoid slowing down the activity performance

int num = mServicegetRandomNumber()

ToastmakeText(this number + num ToastLENGTH_SHORT)show()

Defines callbacks for service binding passed to bindService()

private ServiceConnection mConnection = new ServiceConnection()

Override

public void onServiceConnected(ComponentName className

IBinder service)

Weve bound to LocalService cast the IBinder and get LocalService instance

LocalBinder binder = (LocalBinder) service

mService = bindergetService()

mBound = true

Override

public void onServiceDisconnected(ComponentName arg0)

mBound = false

The above sample shows how the client binds to the service using an implementation of

ServiceConnection and the onServiceConnected() callback The next section provides more

information about this process of binding to the service

Note The example above doesnt explicitly unbind from the service but all clients should unbind

at an appropriate time (such as when the activity pauses)

For more sample code see the LocalServicejava class and the LocalServiceActivitiesjava class in

ApiDemos

Using a Messenger

Compared to AIDL

When you need to perform IPC using a Messenger for your interface is simpler than implementing it

with AIDL because Messenger queues all calls to the service whereas a pure AIDL interface sends

simultaneous requests to the service which must then handle multi-threading

For most applications the service doesnt need to perform multi-threading so using a Messenger

allows the service to handle one call at a time If its important that your service be multi-threaded then

you should use AIDL to define your interface

If you need your service to communicate with remote processes then you can use a Messenger to

provide the interface for your service This technique allows you to perform interprocess

communication (IPC) without the need to use AIDL

Heres a summary of how to use a Messenger

The service implements a Handler that receives a callback for each call from a client

The Handler is used to create a Messenger object (which is a reference to the Handler)

The Messenger creates an IBinder that the service returns to clients from onBind()

Clients use the IBinder to instantiate the Messenger (that references the services Handler) which the

client uses to send Message objects to the service

The service receives each Message in its Handlermdashspecifically in the handleMessage() method

In this way there are no methods for the client to call on the service Instead the client delivers

messages (Message objects) that the service receives in its Handler

Heres a simple example service that uses a Messenger interface

public class MessengerService extends Service Command to the service to display a message static final int MSG_SAY_HELLO = 1 Handler of incoming messages from clients class IncomingHandler extends Handler Override public void handleMessage(Message msg) switch (msgwhat) case MSG_SAY_HELLO ToastmakeText(getApplicationContext() hello ToastLENGTH_SHORT)show() break default superhandleMessage(msg) Target we publish for clients to send messages to IncomingHandler final Messenger mMessenger = new Messenger(new IncomingHandler()) When binding to the service we return an interface to our messenger for sending messages to the service Override public IBinder onBind(Intent intent) ToastmakeText(getApplicationContext() binding ToastLENGTH_SHORT)show() return mMessengergetBinder()

Notice that the handleMessage() method in the Handler is where the service receives the incoming

Message and decides what to do based on the what member

All that a client needs to do is create a Messenger based on the IBinder returned by the service and

send a message using send() For example heres a simple activity that binds to the service and

delivers the MSG_SAY_HELLO message to the service

public class ActivityMessenger extends Activity Messenger for communicating with the service Messenger mService = null Flag indicating whether we have called bind on the service boolean mBound Class for interacting with the main interface of the service private ServiceConnection mConnection = new ServiceConnection() public void onServiceConnected(ComponentName className IBinder service) This is called when the connection with the service has been established giving us the object we can use to interact with the service We are communicating with the service using a Messenger so here we get a client-side representation of that from the raw IBinder object mService = new Messenger(service) mBound = true public void onServiceDisconnected(ComponentName className) This is called when the connection with the service has been unexpectedly disconnected -- that is its process crashed mService = null mBound = false public void sayHello(View v) if (mBound) return Create and send a message to the service using a supported what value Message msg = Messageobtain(null MessengerServiceMSG_SAY_HELLO 0 0) try mServicesend(msg) catch (RemoteException e) eprintStackTrace() Override protected void onCreate(Bundle savedInstanceState) superonCreate(savedInstanceState) setContentView(Rlayoutmain)

Override protected void onStart() superonStart() Bind to the service bindService(new Intent(this MessengerServiceclass) mConnection ContextBIND_AUTO_CREATE) Override protected void onStop() superonStop() Unbind from the service if (mBound) unbindService(mConnection) mBound = false

Notice that this example does not show how the service can respond to the client If you want the

service to respond then you need to also create a Messenger in the client Then when the client

receives the onServiceConnected() callback it sends a Message to the service that includes the

clients Messenger in the replyTo parameter of the send() method

You can see an example of how to provide two-way messaging in the MessengerServicejava (service)

and MessengerServiceActivitiesjava (client) samples

Binding to a Service

Application components (clients) can bind to a service by calling bindService() The Android system

then calls the services onBind() method which returns an IBinder for interacting with the service

The binding is asynchronous bindService() returns immediately and does not return the IBinder to the

client To receive the IBinder the client must create an instance of ServiceConnection and pass it to

bindService() The ServiceConnection includes a callback method that the system calls to deliver the

IBinder

Note Only activities services and content providers can bind to a servicemdashyou cannot bind to a

service from a broadcast receiver

So to bind to a service from your client you must

1 Implement ServiceConnection

Your implementation must override two callback methods

onServiceConnected()

The system calls this to deliver the IBinder returned by the services onBind() method

onServiceDisconnected()

The Android system calls this when the connection to the service is unexpectedly lost such as

when the service has crashed or has been killed This is not called when the client unbinds

2 Call bindService() passing the ServiceConnection implementation

3 When the system calls your onServiceConnected() callback method you can begin making calls to the

service using the methods defined by the interface

4 To disconnect from the service call unbindService()

When your client is destroyed it will unbind from the service but you should always unbind when

youre done interacting with the service or when your activity pauses so that the service can shutdown

while its not being used (Appropriate times to bind and unbind is discussed more below)

For example the following snippet connects the client to the service created above by extending the

Binder class so all it must do is cast the returned IBinder to the LocalService class and request the

LocalService instance

LocalService mService private ServiceConnection mConnection = new ServiceConnection() Called when the connection with the service is established public void onServiceConnected(ComponentName className IBinder service) Because we have bound to an explicit service that is running in our own process we can cast its IBinder to a concrete class and directly access it LocalBinder binder = (LocalBinder) service mService = bindergetService() mBound = true Called when the connection with the service disconnects unexpectedly public void onServiceDisconnected(ComponentName className) Loge(TAG onServiceDisconnected) mBound = false

With this ServiceConnection the client can bind to a service by passing this it to bindService() For

example

Intent intent = new Intent(this LocalServiceclass) bindService(intent mConnection ContextBIND_AUTO_CREATE)

The first parameter of bindService() is an Intent that explicitly names the service to bind (thought the

intent could be implicit)

The second parameter is the ServiceConnection object

The third parameter is a flag indicating options for the binding It should usually be

BIND_AUTO_CREATE in order to create the service if its not already alive Other possible values are

BIND_DEBUG_UNBIND and BIND_NOT_FOREGROUND or 0 for none

Additional notes

Here are some important notes about binding to a service

You should always trap DeadObjectException exceptions which are thrown when the connection has

broken This is the only exception thrown by remote methods

Objects are reference counted across processes

You should usually pair the binding and unbinding during matching bring-up and tear-down moments

of the clients lifecycle For example

o If you only need to interact with the service while your activity is visible you should bind during

onStart() and unbind during onStop()

o If you want your activity to receive responses even while it is stopped in the background then you can

bind during onCreate() and unbind during onDestroy() Beware that this implies that your activity needs

to use the service the entire time its running (even in the background) so if the service is in another

process then you increase the weight of the process and it becomes more likely that the system will

kill it

Note You should usually not bind and unbind during your activitys onResume() and onPause()

because these callbacks occur at every lifecycle transition and you should keep the processing that

occurs at these transitions to a minimum Also if multiple activities in your application bind to the same

service and there is a transition between two of those activities the service may be destroyed and

recreated as the current activity unbinds (during pause) before the next one binds (during resume)

(This activity transition for how activities coordinate their lifecycles is described in the Activities

document)

For more sample code showing how to bind to a service see the RemoteServicejava class in

ApiDemos

Managing the Lifecycle of a Bound Service

Figure 1 The lifecycle for a service

that is started and also allows binding

When a service is unbound from all

clients the Android system destroys it

(unless it was also started with

onStartCommand()) As such you

dont have to manage the lifecycle of

your service if its purely a bound

servicemdashthe Android system manages

it for you based on whether it is bound

to any clients

However if you choose to implement

the onStartCommand() callback

method then you must explicitly stop

the service because the service is

now considered to be started In this

case the service runs until the service

stops itself with stopSelf() or another

component calls stopService()

regardless of whether it is bound to

any clients

Additionally if your service is started and accepts binding then when the system calls your onUnbind()

method you can optionally return true if you would like to receive a call to onRebind() the next time a

client binds to the service (instead of receiving a call to onBind()) onRebind() returns void but the

client still receives the IBinder in its onServiceConnected() callback Below figure 1 illustrates the logic

for this kind of lifecycle

For more information about the lifecycle of an started service see the Services document

Content Providers

Content providers store and retrieve data and make it accessible to all applications Theyre the only

way to share data across applications theres no common storage area that all Android packages can

access

Android ships with a number of content providers for common data types (audio video images

personal contact information and so on) You can see some of them listed in the androidprovider

package You can query these providers for the data they contain (although for some you must

acquire the proper permission to read the data)

If you want to make your own data public you have two options You can create your own content

provider (a ContentProvider subclass) or you can add the data to an existing provider mdash if theres one

that controls the same type of data and you have permission to write to it

This document is an introduction to using content providers After a brief discussion of the

fundamentals it explores how to query a content provider how to modify data controlled by a provider

and how to create a content provider of your own

Content Provider Basics

How a content provider actually stores its data under the covers is up to its designer But all content

providers implement a common interface for querying the provider and returning results mdash as well as

for adding altering and deleting data Its an interface that clients use indirectly most generally

through ContentResolver objects You get a ContentResolver by calling getContentResolver() from

within the implementation of an Activity or other application component

ContentResolver cr = getContentResolver()

You can then use the ContentResolvers methods to interact with whatever content providers youre

interested in When a query is initiated the Android system identifies the content provider thats the

target of the query and makes sure that it is up and running The system instantiates all

ContentProvider objects you never need to do it on your own In fact you never deal directly with

ContentProvider objects at all Typically theres just a single instance of each type of ContentProvider

But it can communicate with multiple ContentResolver objects in different applications and processes

The interaction between processes is handled by the ContentResolver and ContentProvider classes

The data model

Content providers expose their data as a simple table on a database model where each row is a

record and each column is data of a particular type and meaning For example information about

people and their phone numbers might be exposed as follows

_ID NUMBER NUMBER_KEY LABEL NAME TYPE

13 (425) 555 6677 425 555 6677 Kirkland office Bully Pulpit TYPE_WORK

44 (212) 555-1234 212 555 1234 NY apartment Alan Vain TYPE_HOME

45 (212) 555-6657 212 555 6657 Downtown office Alan Vain TYPE_MOBILE

53 2015554433 201 555 4433 Love Nest Rex Cars TYPE_HOME

Every record includes a numeric _ID field that uniquely identifies the record within the table IDs can be

used to match records in related tables mdash for example to find a persons phone number in one table

and pictures of that person in another

A query returns a Cursor object that can move from record to record and column to column to read the

contents of each field It has specialized methods for reading each type of data So to read a field you

must know what type of data the field contains (Theres more on query results and Cursor objects

later)

URIs

Each content provider exposes a public URI (wrapped as a Uri object) that uniquely identifies its data

set A content provider that controls multiple data sets (multiple tables) exposes a separate URI for

each one All URIs for providers begin with the string content The content scheme identifies the

data as being controlled by a content provider

If youre defining a content provider its a good idea to also define a constant for its URI to simplify

client code and make future updates cleaner Android defines CONTENT_URI constants for all the

providers that come with the platform For example the URI for the table that matches phone numbers

to people and the URI for the table that holds pictures of people (both controlled by the Contacts

content provider) are

androidproviderContactsPhonesCONTENT_URI

androidproviderContactsPhotosCONTENT_URI

The URI constant is used in all interactions with the content provider Every ContentResolver method

takes the URI as its first argument Its what identifies which provider the ContentResolver should talk

to and which table of the provider is being targeted

Querying a Content Provider

You need three pieces of information to query a content provider

The URI that identifies the provider

The names of the data fields you want to receive

The data types for those fields

If youre querying a particular record you also need the ID for that record

Making the query

To query a content provider you can use either the ContentResolverquery() method or the

ActivitymanagedQuery() method Both methods take the same set of arguments and both return a

Cursor object However managedQuery() causes the activity to manage the life cycle of the Cursor A

managed Cursor handles all of the niceties such as unloading itself when the activity pauses and

requerying itself when the activity restarts You can ask an Activity to begin managing an unmanaged

Cursor object for you by calling ActivitystartManagingCursor()

The first argument to either query() or managedQuery() is the provider URI mdash the CONTENT_URI

constant that identifies a particular ContentProvider and data set (see URIs earlier)

To restrict a query to just one record you can append the _ID value for that record to the URI mdash that

is place a string matching the ID as the last segment of the path part of the URI For example if the ID

is 23 the URI would be

content 23

There are some helper methods particularly ContentUriswithAppendedId() and

UriwithAppendedPath() that make it easy to append an ID to a URI Both are static methods that

return a Uri object with the ID added So for example if you were looking for record 23 in the database

of people contacts you might construct a query as follows

import androidproviderContactsPeople import androidcontentContentUris import androidnetUri import androiddatabaseCursor Use the ContentUris method to produce the base URI for the contact with _ID == 23 Uri myPerson = ContentUriswithAppendedId(PeopleCONTENT_URI 23) Alternatively use the Uri method to produce the base URI It takes a string rather than an integer Uri myPerson = UriwithAppendedPath(PeopleCONTENT_URI 23) Then query for this specific record Cursor cur = managedQuery(myPerson null null null null)

The other arguments to the query() and managedQuery() methods delimit the query in more detail

They are

The names of the data columns that should be returned A null value returns all columns Otherwise

only columns that are listed by name are returned All the content providers that come with the

platform define constants for their columns For example the androidproviderContactsPhones class

defines constants for the names of the columns in the phone table illustrated earlier ampmdash _ID

NUMBER NUMBER_KEY NAME and so on

A filter detailing which rows to return formatted as an SQL WHERE clause (excluding the WHERE

itself) A null value returns all rows (unless the URI limits the query to a single record)

Selection arguments

A sorting order for the rows that are returned formatted as an SQL ORDER BY clause (excluding the

ORDER BY itself) A null value returns the records in the default order for the table which may be

unordered

Lets look at an example query to retrieve a list of contact names and their primary phone numbers

import androidproviderContactsPeople import androiddatabaseCursor Form an array specifying which columns to return String[] projection = new String[] People_ID People_COUNT PeopleNAME PeopleNUMBER Get the base URI for the People table in the Contacts content provider Uri contacts = PeopleCONTENT_URI Make the query Cursor managedCursor = managedQuery(contacts projection Which columns to return null Which rows to return (all rows) null Selection arguments (none) Put the results in ascending order by name PeopleNAME + ASC)

This query retrieves data from the People table of the Contacts content provider It gets the name

primary phone number and unique record ID for each contact It also reports the number of records

that are returned as the _COUNT field of each record

The constants for the names of the columns are defined in various interfaces mdash _ID and _COUNT in

BaseColumns NAME in PeopleColumns and NUMBER in PhoneColumns The ContactsPeople

class implements each of these interfaces which is why the code example above could refer to them

using just the class name

What a query returns

A query returns a set of zero or more database records The names of the columns their default order

and their data types are specific to each content provider But every provider has an _ID column

which holds a unique numeric ID for each record Every provider can also report the number of records

returned as the _COUNT column its value is the same for all rows

Here is an example result set for the query in the previous section

_ID _COUNT NAME NUMBER

44 3 Alan Vain 212 555 1234

13 3 Bully Pulpit 425 555 6677

53 3 Rex Cars 201 555 4433

The retrieved data is exposed by a Cursor object that can be used to iterate backward or forward

through the result set You can use this object only to read the data To add modify or delete data

you must use a ContentResolver object

Reading retrieved data

The Cursor object returned by a query provides access to a recordset of results If you have queried

for a specific record by ID this set will contain only one value Otherwise it can contain multiple

values (If there are no matches it can also be empty) You can read data from specific fields in the

record but you must know the data type of the field because the Cursor object has a separate method

for reading each type of data mdash such as getString() getInt() and getFloat() (However for most types

if you call the method for reading strings the Cursor object will give you the String representation of

the data) The Cursor lets you request the column name from the index of the column or the index

number from the column name

The following snippet demonstrates reading names and phone numbers from the query illustrated

earlier

import androidproviderContactsPeople private void getColumnData(Cursor cur) if (curmoveToFirst()) String name String phoneNumber int nameColumn = curgetColumnIndex(PeopleNAME) int phoneColumn = curgetColumnIndex(PeopleNUMBER) String imagePath do Get the field values name = curgetString(nameColumn) phoneNumber = curgetString(phoneColumn) Do something with the values while (curmoveToNext())

If a query can return binary data such as an image or sound the data may be directly entered in the

table or the table entry for that data may be a string specifying a content URI that you can use to get

the data In general smaller amounts of data (say from 20 to 50K or less) are most often directly

entered in the table and can be read by calling CursorgetBlob() It returns a byte array

If the table entry is a content URI you should never try to open and read the file directly (for one thing

permissions problems can make this fail) Instead you should call ContentResolveropenInputStream()

to get an InputStream object that you can use to read the data

Modifying Data

Data kept by a content provider can be modified by

Adding new records

Adding new values to existing records

Batch updating existing records

Deleting records

All data modification is accomplished using ContentResolver methods Some content providers require

a more restrictive permission for writing data than they do for reading it If you dont have permission to

write to a content provider the ContentResolver methods will fail

Adding records

To add a new record to a content provider first set up a map of key-value pairs in a ContentValues

object where each key matches the name of a column in the content provider and the value is the

desired value for the new record in that column Then call ContentResolverinsert() and pass it the URI

of the provider and the ContentValues map This method returns the full URI of the new record mdash that

is the providers URI with the appended ID for the new record You can then use this URI to query and

get a Cursor over the new record and to further modify the record Heres an example

import androidproviderContactsPeople import androidcontentContentResolver import androidcontentContentValues ContentValues values = new ContentValues() Add Abraham Lincoln to contacts and make him a favorite valuesput(PeopleNAME Abraham Lincoln) 1 = the new contact is added to favorites 0 = the new contact is not added to favorites valuesput(PeopleSTARRED 1) Uri uri = getContentResolver()insert(PeopleCONTENT_URI values)

Adding new values

Once a record exists you can add new information to it or modify existing information For example

the next step in the example above would be to add contact information mdash like a phone number or an

IM or e-mail address mdash to the new entry

The best way to add to a record in the Contacts database is to append the name of the table where the

new data goes to the URI for the record then use the amended URI to add the new data values Each

Contacts table exposes a name for this purpose as a CONTENT_DIRECTORY constant The following

code continues the previous example by adding a phone number and e-mail address for the record

just created

Uri phoneUri = null Uri emailUri = null Add a phone number for Abraham Lincoln Begin with the URI for the new record just returned by insert() it ends with the _ID of the new record so we dont have to add the ID ourselves Then append the designation for the phone table to this URI and use the resulting URI to insert the phone number phoneUri = UriwithAppendedPath(uri PeoplePhonesCONTENT_DIRECTORY) valuesclear() valuesput(PeoplePhonesTYPE PeoplePhonesTYPE_MOBILE) valuesput(PeoplePhonesNUMBER 1233214567) getContentResolver()insert(phoneUri values) Now add an email address in the same way emailUri = UriwithAppendedPath(uri PeopleContactMethodsCONTENT_DIRECTORY) valuesclear() ContactMethodsKIND is used to distinguish different kinds of contact methods such as email IM etc valuesput(PeopleContactMethodsKIND ContactsKIND_EMAIL) valuesput(PeopleContactMethodsDATA testexamplecom) valuesput(PeopleContactMethodsTYPE PeopleContactMethodsTYPE_HOME) getContentResolver()insert(emailUri values)

You can place small amounts of binary data into a table by calling the version of ContentValuesput()

that takes a byte array That would work for a small icon-like image or a short audio clip for example

However if you have a large amount of binary data to add such as a photograph or a complete song

put a content URI for the data in the table and call ContentResolveropenOutputStream() with the files

URI (That causes the content provider to store the data in a file and record the file path in a hidden

field of the record)

In this regard the MediaStore content provider the main provider that dispenses image audio and

video data employs a special convention The same URI that is used with query() or managedQuery()

to get meta-information about the binary data (such as the caption of a photograph or the date it was

taken) is used with openInputStream() to get the data itself Similarly the same URI that is used with

insert() to put meta-information into a MediaStore record is used with openOutputStream() to place the

binary data there The following code snippet illustrates this convention

import androidproviderMediaStoreImagesMedia import androidcontentContentValues import javaioOutputStream Save the name and description of an image in a ContentValues map ContentValues values = new ContentValues(3) valuesput(MediaDISPLAY_NAME road_trip_1) valuesput(MediaDESCRIPTION Day 1 trip to Los Angeles) valuesput(MediaMIME_TYPE imagejpeg) Add a new record without the bitmap but with the values just set insert() returns the URI of the new record Uri uri = getContentResolver()insert(MediaEXTERNAL_CONTENT_URI values) Now get a handle to the file for that record and save the data into it Here sourceBitmap is a Bitmap object representing the file to save to the database try OutputStream outStream = getContentResolver()openOutputStream(uri) sourceBitmapcompress(BitmapCompressFormatJPEG 50 outStream) outStreamclose() catch (Exception e) Loge(TAG exception while writing image e)

Batch updating records

To batch update a group of records (for example to change NY to New York in all fields) call the

ContentResolverupdate() method with the columns and values to change

Deleting a record

To delete a single record call ContentResolverdelete() with the URI of a specific row

To delete multiple rows call ContentResolverdelete() with the URI of the type of record to delete (for

example androidproviderContactsPeopleCONTENT_URI) and an SQL WHERE clause defining

which rows to delete (Caution Be sure to include a valid WHERE clause if youre deleting a general

type or you risk deleting more records than you intended)

Creating a Content Provider

To create a content provider you must

Set up a system for storing the data Most content providers store their data using Androids file

storage methods or SQLite databases but you can store your data any way you want Android

provides the SQLiteOpenHelper class to help you create a database and SQLiteDatabase to manage

it

Extend the ContentProvider class to provide access to the data

Declare the content provider in the manifest file for your application (AndroidManifestxml)

The following sections have notes on the last two of these tasks

Extending the ContentProvider class

You define a ContentProvider subclass to expose your data to others using the conventions expected

by ContentResolver and Cursor objects Principally this means implementing six abstract methods

declared in the ContentProvider class

query()

insert()

update()

delete()

getType()

onCreate()

The query() method must return a Cursor object that can iterate over the requested data Cursor itself

is an interface but Android provides some ready-made Cursor objects that you can use For example

SQLiteCursor can iterate over data stored in an SQLite database You get the Cursor object by calling

any of the SQLiteDatabase classs query() methods There are other Cursor implementations mdash such

as MatrixCursor mdash for data not stored in a database

Because these ContentProvider methods can be called from various ContentResolver objects in

different processes and threads they must be implemented in a thread-safe manner

As a courtesy you might also want to call ContentResolvernotifyChange() to notify listeners when

there are modifications to the data

Beyond defining the subclass itself there are other steps you should take to simplify the work of clients

and make the class more accessible

Define a public static final Uri named CONTENT_URI This is the string that represents the full content

URI that your content provider handles You must define a unique string for this value The best

solution is to use the fully-qualified class name of the content provider (made lowercase) So for

example the URI for a TransportationProvider class could be defined as follows

public static final Uri CONTENT_URI = Uriparse(contentcomexamplecodelabtransportationprovider)

If the provider has subtables also define CONTENT_URI constants for each of the subtables These

URIs should all have the same authority (since that identifies the content provider) and be

distinguished only by their paths For example

contentcomexamplecodelabtransportationprovidertrain

contentcomexamplecodelabtransportationproviderairdomestic

contentcomexamplecodelabtransportationproviderairinternational

For an overview of content URIs see the Content URI Summary at the end of this document

Define the column names that the content provider will return to clients If you are using an underlying

database these column names are typically identical to the SQL database column names they

represent Also define public static String constants that clients can use to specify the columns in

queries and other instructions

Be sure to include an integer column named _id (with the constant _ID) for the IDs of the records

You should have this field whether or not you have another field (such as a URL) that is also unique

among all records If youre using the SQLite database the _ID field should be the following type

INTEGER PRIMARY KEY AUTOINCREMENT

The AUTOINCREMENT descriptor is optional But without it SQLite increments an ID counter field to

the next number above the largest existing number in the column If you delete the last row the next

row added will have the same ID as the deleted row AUTOINCREMENT avoids this by having SQLite

increment to the next largest value whether deleted or not

Carefully document the data type of each column Clients need this information to read the data

If you are handling a new data type you must define a new MIME type to return in your

implementation of ContentProvidergetType() The type depends in part on whether or not the content

URI submitted to getType() limits the request to a specific record Theres one form of the MIME type

for a single record and another for multiple records Use the Uri methods to help determine what is

being requested Here is the general format for each type

o For a single record vndandroidcursoritemvndyourcompanynamecontenttype

For example a request for train record 122 like this URI

contentcomexampletransportationprovidertrains122

might return this MIME type

vndandroidcursoritemvndexamplerail

o For multiple records vndandroidcursordirvndyourcompanynamecontenttype

For example a request for all train records like the following URI

contentcomexampletransportationprovidertrains

might return this MIME type

vndandroidcursordirvndexamplerail

If you are exposing byte data thats too big to put in the table itself mdash such as a large bitmap file mdash the

field that exposes the data to clients should actually contain a content URI string This is the field that

gives clients access to the data file The record should also have another field named _data that lists

the exact file path on the device for that file This field is not intended to be read by the client but by

the ContentResolver The client will call ContentResolveropenInputStream() on the user-facing field

holding the URI for the item The ContentResolver will request the _data field for that record and

because it has higher permissions than a client it should be able to access that file directly and return

a read wrapper for the file to the client

For an example of a private content provider implementation see the NodePadProvider class in the

Notepad sample application that ships with the SDK

Declaring the content provider

To let the Android system know about the content provider youve developed declare it with a

ltprovidergt element in the applications AndroidManifestxml file Content providers that are not

declared in the manifest are not visible to the Android system

The name attribute is the fully qualified name of the ContentProvider subclass The authorities attribute

is the authority part of the content URI that identifies the provider For example if the ContentProvider

subclass is AutoInfoProvider the ltprovidergt element might look like this

ltprovider androidname=comexampleautosAutoInfoProvider androidauthorities=comexampleautosautoinfoprovider gt ltprovidergt

Note that the authorities attribute omits the path part of a content URI For example if

AutoInfoProvider controlled subtables for different types of autos or different manufacturers

contentcomexampleautosautoinfoproviderhonda

contentcomexampleautosautoinfoprovidergmcompact

contentcomexampleautosautoinfoprovidergmsuv

those paths would not be declared in the manifest The authority is what identifies the provider not the

path your provider can interpret the path part of the URI in any way you choose

Other ltprovidergt attributes can set permissions to read and write data provide for an icon and text

that can be displayed to users enable and disable the provider and so on Set the multiprocess

attribute to true if data does not need to be synchronized between multiple running versions of the

content provider This permits an instance of the provider to be created in each client process

eliminating the need to perform IPC

Content URI Summary

Here is a recap of the important parts of a content URI

A Standard prefix indicating that the data is controlled by a content provider Its never modified

B The authority part of the URI it identifies the content provider For third-party applications this should

be a fully-qualified class name (reduced to lowercase) to ensure uniqueness The authority is declared

in the ltprovidergt elements authorities attribute

ltprovider androidname=TransportationProvider androidauthorities=comexampletransportationprovider gt

C The path that the content provider uses to determine what kind of data is being requested This can be

zero or more segments long If the content provider exposes only one type of data (only trains for

example) it can be absent If the provider exposes several types including subtypes it can be several

segments long mdash for example landbus landtrain seaship and seasubmarine to give four

possibilities

D The ID of the specific record being requested if any This is the _ID value of the requested record If

the request is not limited to a single record this segment and the trailing slash are omitted

contentcomexampletransportationprovidertrains

Intent and intent filters

Three of the core components of an application mdash activities services and broadcast receivers mdash 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 mdash 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 ContextstartActivity() or ActivitystartActivityForResult() to launch an

activity or get an existing activity to do something new (It can also be passed to ActivitysetResult() to

return information to the activity that called startActivityForResult())

An Intent object is passed to ContextstartService() to initiate a service or deliver new instructions to an

ongoing service Similarly an intent can be passed to ContextbindService() to establish a connection

between the calling component and a target service It can optionally initiate the service if its not

already running

Intent objects passed to any of the broadcast methods (such as ContextsendBroadcast()

ContextsendOrderedBroadcast() or ContextsendStickyBroadcast()) 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 mdash how it resolves which component should receive an intent message For

intents that dont explicitly name a target component this process involves testing the Intent object

against intent filters associated with potential targets

Intent Objects

An Intent object is a bundle of information It contains information of interest to the component that

receives the intent (such as the action to be taken and the data to act on) plus information of interest to

the Android system (such as the category of component that should handle the intent and instructions

on how to launch a target activity) Principally it can contain the following

Component name

The name of the component that should handle the intent This field is a ComponentName

object mdash a combination of the fully qualified class name of the target component (for example

comexampleprojectappFreneticActivity) and the package name set in the manifest file of the

application where the component resides (for example comexampleproject) The package

part of the component name and the package name set in the manifest do not necessarily have

to match

The component name is optional If it is set the Intent object is delivered to an instance of the

designated class If it is not set Android uses other information in the Intent object to locate a

suitable target mdash see Intent Resolution later in this document

The component name is set by setComponent() setClass() or setClassName() and read by

getComponent()

Action

A string naming the action to be performed mdash or in the case of broadcast intents the action

that took place and is being reported The Intent class defines a number of action constants

including these

Constant Target

component

Action

ACTION_CALL activity Initiate a phone call

ACTION_EDIT activity Display data for the user to edit

ACTION_MAIN activity Start up as the initial activity of a task

with no data input and no returned

output

ACTION_SYNC activity Synchronize data on a server with

data on the mobile device

ACTION_BATTERY_LOW broadcast

receiver

A warning that the battery is low

ACTION_HEADSET_PLUG broadcast

receiver

A headset has been plugged into the

device or unplugged from it

ACTION_SCREEN_ON broadcast

receiver

The screen has been turned on

ACTION_TIMEZONE_CHANGED broadcast

receiver

The setting for the time zone has

changed

See the Intent class description for a list of pre-defined constants for generic actions Other

actions are defined elsewhere in the Android API You can also define your own action strings

for activating the components in your application Those you invent should include the

application package as a prefix mdash for example comexampleprojectSHOW_COLOR

The action largely determines how the rest of the intent is structured mdash particularly the data and

extras fields mdash much as a method name determines a set of arguments and a return value For

this reason its a good idea to use action names that are as specific as possible and to couple

them tightly to the other fields of the intent In other words instead of defining an action in

isolation define an entire protocol for the Intent objects your components can handle

The action in an Intent object is set by the setAction() method and read by getAction()

Data

The URI of the data to be acted on and the MIME type of that data Different actions are paired

with different kinds of data specifications For example if the action field is ACTION_EDIT the

data field would contain the URI of the document to be displayed for editing If the action is

ACTION_CALL the data field would be a tel URI with the number to call Similarly if the action

is ACTION_VIEW and the data field is an http URI the receiving activity would be called upon

to download and display whatever data the URI refers to

When matching an intent to a component that is capable of handling the data its often

important to know the type of data (its MIME type) in addition to its URI For example a

component able to display image data should not be called upon to play an audio file

In many cases the data type can be inferred from the URI mdash particularly content URIs which

indicate that the data is located on the device and controlled by a content provider (see the

separate discussion on content providers) But the type can also be explicitly set in the Intent

object The setData() method specifies data only as a URI setType() specifies it only as a

MIME type and setDataAndType() specifies it as both a URI and a MIME type The URI is read

by getData() and the type by getType()

Category

A string containing additional information about the kind of component that should handle the

intent Any number of category descriptions can be placed in an Intent object As it does for

actions the Intent class defines several category constants including these

Constant Meaning

CATEGORY_BROWSABLE The target activity can be safely invoked by the browser to

display data referenced by a link mdash for example an image or

an e-mail message

CATEGORY_GADGET The activity can be embedded inside of another activity that

hosts gadgets

CATEGORY_HOME The activity displays the home screen the first screen the

user sees when the device is turned on or when the HOME

key is pressed

CATEGORY_LAUNCHER The activity can be the initial activity of a task and is listed in

the top-level application launcher

CATEGORY_PREFERENCE The target activity is a preference panel

See the Intent class description for the full list of categories

The addCategory() method places a category in an Intent object removeCategory() deletes a

category previously added and getCategories() gets the set of all categories currently in the

object

Extras

Key-value pairs for additional information that should be delivered to the component handling

the intent Just as some actions are paired with particular kinds of data URIs some are paired

with particular extras For example an ACTION_TIMEZONE_CHANGED intent has a time-

zone extra that identifies the new time zone and ACTION_HEADSET_PLUG has a state

extra indicating whether the headset is now plugged in or unplugged as well as a name extra

for the type of headset If you were to invent a SHOW_COLOR action the color value would be

set in an extra key-value pair

The Intent object has a series of put() methods for inserting various types of extra data and a

similar set of get() methods for reading the data These methods parallel those for Bundle

objects In fact the extras can be installed and read as a Bundle using the putExtras() and

getExtras() methods

Flags

Flags of various sorts Many instruct the Android system how to launch an activity (for example

which task the activity should belong to) and how to treat it after its launched (for example

whether it belongs in the list of recent activities) All these flags are defined in the Intent class

The Android system and the applications that come with the platform employ Intent objects both to

send out system-originated broadcasts and to activate system-defined components To see how to

structure an intent to activate a system component consult the list of intents in the reference

Intent Resolution

Intents can be divided into two groups

Explicit intents designate the target component by its name (the component name field mentioned

earlier has a value set) Since component names would generally not be known to developers of other

applications explicit intents are typically used for application-internal messages mdash such as an activity

starting a subordinate service or launching a sister activity

Implicit intents do not name a target (the field for the component name is blank) Implicit intents are

often used to activate components in other applications

Android delivers an explicit intent to an instance of the designated target class Nothing in the Intent

object other than the component name matters for determining which component should get the intent

A different strategy is needed for implicit intents In the absence of a designated target the Android

system must find the best component (or components) to handle the intent mdash a single activity or

service to perform the requested action or the set of broadcast receivers to respond to the broadcast

announcement It does so by comparing the contents of the Intent object to intent filters structures

associated with components that can potentially receive intents Filters advertise the capabilities of a

component and delimit the intents it can handle They open the component to the possibility of

receiving implicit intents of the advertised type If a component does not have any intent filters it can

receive only explicit intents A component with filters can receive both explicit and implicit intents

Only three aspects of an Intent object are consulted when the object is tested against an intent filter

action

data (both URI and data type)

category

The extras and flags play no part in resolving which component receives an intent

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 mdash but only unwanted implicit intents (those that dont 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

components 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 mdash 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 Pads filters are described in the Note Pad Example

section later)

Filters and security

An intent filter cannot be relied on for security While it opens a component to receiving only certain

kinds of implicit intents it does nothing to prevent explicit intents from targeting the component Even

though a filter restricts the intents a component will be asked to handle to certain actions and data

sources someone could always put together an explicit intent with a different action and data source

and name the component as the target

An intent filter is an instance of the IntentFilter class However since the Android system must know

about the capabilities of a component before it can launch that component intent filters are generally

not set up in Java code but in the applications manifest file (AndroidManifestxml) as ltintent-filtergt

elements (The one exception would be filters for broadcast receivers that are registered dynamically

by calling ContextregisterReceiver() they are directly created as IntentFilter objects)

A filter has fields that parallel the action data and category fields of an Intent object An implicit intent

is tested against the filter in all three areas To be delivered to the component that owns the filter it

must pass all three tests If it fails even one of them the Android system wont deliver it to the

component mdash at least not on the basis of that filter However since a component can have multiple

intent filters an intent that does not pass through one of a components filters might make it through on

another

Each of the three tests is described in detail below

Action test

An ltintent-filtergt element in the manifest file lists actions as ltactiongt subelements For

example

ltintent-filter gt ltaction androidname=comexampleprojectSHOW_CURRENT gt ltaction androidname=comexampleprojectSHOW_RECENT gt ltaction androidname=comexampleprojectSHOW_PENDING gt ltintent-filtergt

As the example shows while an Intent object names just a single action a filter may list more

than one The list cannot be empty a filter must contain at least one ltactiongt element or it will

block all intents

To pass this test the action specified in the Intent object must match one of the actions listed in

the filter If the object or the filter does not specify an action the results are as follows

If the filter fails to list any actions there is nothing for an intent to match so all intents fail the

test No intents can get through the filter

On the other hand an Intent object that doesnt specify an action automatically passes the test

mdash as long as the filter contains at least one action

Category test

An ltintent-filtergt element also lists categories as subelements For example

ltintent-filter gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryBROWSABLE gt ltintent-filtergt

Note that the constants described earlier for actions and categories are not used in the manifest

file The full string values are used instead For instance the

androidintentcategoryBROWSABLE string in the example above corresponds to the

CATEGORY_BROWSABLE constant mentioned earlier in this document Similarly the string

androidintentactionEDIT corresponds to the ACTION_EDIT constant

For an intent to pass the category test every category in the Intent object must match a

category in the filter The filter can list additional categories but it cannot omit any that are in the

intent

In principle therefore an Intent object with no categories should always pass this test

regardless of whats in the filter Thats mostly true However with one exception Android treats

all implicit intents passed to startActivity() as if they contained at least one category

androidintentcategoryDEFAULT (the CATEGORY_DEFAULT constant) Therefore activities

that are willing to receive implicit intents must include androidintentcategoryDEFAULT in

their intent filters (Filters with androidintentactionMAIN and

androidintentcategoryLAUNCHER settings are the exception They mark activities that begin

new tasks and that are represented on the launcher screen They can include

androidintentcategoryDEFAULT in the list of categories but dont need to) See Using intent

matching later for more on these filters)

Data test

Like the action and categories the data specification for an intent filter is contained in a

subelement And as in those cases the subelement can appear multiple times or not at all For

example

ltintent-filter gt ltdata androidmimeType=videompeg androidscheme=http gt ltdata androidmimeType=audiompeg androidscheme=http gt ltintent-filtergt

Each ltdatagt element can specify a URI and a data type (MIME media type) There are

separate attributes mdash scheme host port and path mdash for each part of the URI

schemehostportpath

For example in the following URI

contentcomexampleproject200foldersubfolderetc

the scheme is content the host is comexampleproject the port is 200 and the path is

foldersubfolderetc The host and port together constitute the URI authority if a host is not

specified the port is ignored

Each of these attributes is optional but they are not independent of each other For an authority

to be meaningful a scheme must also be specified For a path to be meaningful both a scheme

and an authority must be specified

When the URI in an Intent object is compared to a URI specification in a filter its compared

only to the parts of the URI actually mentioned in the filter For example if a filter specifies only

a scheme all URIs with that scheme match the filter If a filter specifies a scheme and an

authority but no path all URIs with the same scheme and authority match regardless of their

paths If a filter specifies a scheme an authority and a path only URIs with the same scheme

authority and path match However a path specification in the filter can contain wildcards to

require only a partial match of the path

The type attribute of a ltdatagt element specifies the MIME type of the data Its more common in

filters than a URI Both the Intent object and the filter can use a wildcard for the subtype field

mdash for example text or audio mdash indicating any subtype matches

The data test compares both the URI and the data type in the Intent object to a URI and data

type specified in the filter The rules are as follows

a An Intent object that contains neither a URI nor a data type passes the test only if the filter

likewise does not specify any URIs or data types

b An Intent object that contains a URI but no data type (and a type cannot be inferred from the

URI) passes the test only if its URI matches a URI in the filter and the filter likewise does not

specify a type This will be the case only for URIs like mailto and tel that do not refer to actual

data

c An Intent object that contains a data type but not a URI passes the test only if the filter lists the

same data type and similarly does not specify a URI

d An Intent object that contains both a URI and a data type (or a data type can be inferred from

the URI) passes the data type part of the test only if its type matches a type listed in the filter It

passes the URI part of the test either if its URI matches a URI in the filter or if it has a content

or file URI and the filter does not specify a URI In other words a component is presumed to

support content and file data if its filter lists only a data type

If an intent can pass through the filters of more than one activity or service the user may be asked

which component to activate An exception is raised if no target can be found

Common cases

The last rule shown above for the data test rule (d) reflects the expectation that components are able

to get local data from a file or content provider Therefore their filters can list just a data type and do

not need to explicitly name the content and file schemes This is a typical case A ltdatagt element like

the following for example tells Android that the component can get image data from a content

provider and display it

ltdata androidmimeType=image gt

Since most available data is dispensed by content providers filters that specify a data type but not a

URI are perhaps the most common

Another common configuration is filters with a scheme and a data type For example a ltdatagt

element like the following tells Android that the component can get video data from the network and

display it

ltdata androidscheme=http androidtype=video gt

Consider for example what the browser application does when the user follows a link on a web page

It first tries to display the data (as it could if the link was to an HTML page) If it cant display the data it

puts together an implicit intent with the scheme and data type and tries to start an activity that can do

the job If there are no takers it asks the download manager to download the data That puts it under

the control of a content provider so a potentially larger pool of activities (those with filters that just

name a data type) can respond

Most applications also have a way to start fresh without a reference to any particular data Activities

that can initiate applications have filters with androidintentactionMAIN specified as the action If

they are to be represented in the application launcher they also specify the

androidintentcategoryLAUNCHER category

ltintent-filter gt ltaction androidname=code androidintentactionMAIN gt ltcategory androidname=code androidintentcategoryLAUNCHER gt ltintent-filtergt

Using intent matching

Intents are matched against intent filters not only to discover a target component to activate but also

to discover something about the set of components on the device For example the Android system

populates the application launcher the top-level screen that shows the applications that are available

for the user to launch by finding all the activities with intent filters that specify the

androidintentactionMAIN action and androidintentcategoryLAUNCHER category (as illustrated

in the previous section) It then displays the icons and labels of those activities in the launcher

Similarly it discovers the home screen by looking for the activity with androidintentcategoryHOME

in its filter

Your application can use intent matching is a similar way The PackageManager has a set of query()

methods that return all components that can accept a particular intent and a similar series of

resolve() methods that determine the best component to respond to an intent For example

queryIntentActivities() returns a list of all activities that can perform the intent passed as an argument

and queryIntentServices() returns a similar list of services Neither method activates the components

they just list the ones that can respond Theres a similar method queryBroadcastReceivers() for

broadcast receivers

Note Pad Example

The Note Pad sample application enables users to browse through a list of notes view details about

individual items in the list edit the items and add a new item to the list This section looks at the intent

filters declared in its manifest file (If youre working offline in the SDK you can find all the source files

for this sample application including its manifest file at ltsdkgtsamplesNotePadindexhtml If youre

viewing the documentation online the source files are in the Tutorials and Sample Code section here)

In its manifest file the Note Pad application declares three activities each with at least one intent filter

It also declares a content provider that manages the note data Here is the manifest file in its entirety

ltmanifest xmlnsandroid=httpschemasandroidcomapkresandroid package=comexampleandroidnotepadgt ltapplication androidicon=drawableapp_notes androidlabel=stringapp_name gt ltprovider androidname=NotePadProvider androidauthorities=comgoogleproviderNotePad gt ltactivity androidname=NotesList androidlabel=stringtitle_notes_listgt ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltactivity androidname=NoteEditor androidtheme=androidstyleThemeLight androidlabel=stringtitle_note gt ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltactivitygt

ltactivity androidname=TitleEditor androidlabel=stringtitle_edit_title androidtheme=androidstyleThemeDialoggt ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltapplicationgt ltmanifestgt

The first activity NotesList is distinguished from the other activities by the fact that it operates on a

directory of notes (the note list) rather than on a single note It would generally serve as the initial user

interface into the application It can do three things as described by its three intent filters

1 ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt

This filter declares the main entry point into the Note Pad application The standard MAIN action is an

entry point that does not require any other information in the Intent (no data specification for example)

and the LAUNCHER category says that this entry point should be listed in the application launcher

2 ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

This filter declares the things that the activity can do on a directory of notes It can allow the user to

view or edit the directory (via the VIEW and EDIT actions) or to pick a particular note from the

directory (via the PICK action)

The mimeType attribute of the ltdatagt element specifies the kind of data that these actions operate on

It indicates that the activity can get a Cursor over zero or more items (vndandroidcursordir) from a

content provider that holds Note Pad data (vndgooglenote) The Intent object that launches the

activity would include a content URI specifying the exact data of this type that the activity should open

Note also the DEFAULT category supplied in this filter Its there because the ContextstartActivity()

and ActivitystartActivityForResult() methods treat all intents as if they contained the DEFAULT

category mdash with just two exceptions

o Intents that explicitly name the target activity

o Intents consisting of the MAIN action and LAUNCHER category

Therefore the DEFAULT category is required for all filters mdash except for those with the MAIN action

and LAUNCHER category (Intent filters are not consulted for explicit intents)

3 ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

This filter describes the activitys ability to return a note selected by the user without requiring any

specification of the directory the user should choose from The GET_CONTENT action is similar to the

PICK action In both cases the activity returns the URI for a note selected by the user (In each case

its returned to the activity that called startActivityForResult() to start the NoteList activity) Here

however the caller specifies the type of data desired instead of the directory of data the user will be

picking from

The data type vndandroidcursoritemvndgooglenote indicates the type of data the activity can

return mdash a URI for a single note From the returned URI the caller can get a Cursor for exactly one

item (vndandroidcursoritem) from the content provider that holds Note Pad data (vndgooglenote)

In other words for the PICK action in the previous filter the data type indicates the type of data the

activity could display to the user For the GET_CONTENT filter it indicates the type of data the activity

can return to the caller

Given these capabilities the following intents will resolve to the NotesList activity

action androidintentactionMAIN

Launches the activity with no data specified

action androidintentactionMAIN

category androidintentcategoryLAUNCHER

Launches the activity with no data selected specified This is the actual intent used by the

Launcher to populate its top-level list All activities with filters that match this action and

category are added to the list

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of all the notes under

contentcomgoogleproviderNotePadnotes The user can then browse through the list and

get information about the items in it

action androidintentactionPICK

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of the notes under

contentcomgoogleproviderNotePadnotes The user can then pick a note from the list and

the activity will return the URI for that item back to the activity that started the NoteList activity

action androidintentactionGET_CONTENT

data type vndandroidcursoritemvndgooglenote

Asks the activity to supply a single item of Note Pad data

The second activity NoteEditor shows users a single note entry and allows them to edit it It can do

two things as described by its two intent filters

1 ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The first primary purpose of this activity is to enable the user to interact with a single note ampmdash to

either VIEW the note or EDIT it (The EDIT_NOTE category is a synonym for EDIT) The intent would

contain the URI for data matching the MIME type vndandroidcursoritemvndgooglenote mdash that is

the URI for a single specific note It would typically be a URI that was returned by the PICK or

GET_CONTENT actions of the NoteList activity

As before this filter lists the DEFAULT category so that the activity can be launched by intents that

dont explicitly specify the NoteEditor class

2 ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

The secondary purpose of this activity is to enable the user to create a new note which it will INSERT

into an existing directory of notes The intent would contain the URI for data matching the MIME type

vndandroidcursordirvndgooglenote mdash that is the URI for the directory where the note should be

placed

Given these capabilities the following intents will resolve to the NoteEditor activity

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID (For details on how content

URIs specify individual members of a group see Content Providers)

action androidintentactionEDIT

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID and to let the user edit it If

the user saves the changes the activity updates the data for the note in the content provider

action androidintentactionINSERT

data contentcomgoogleproviderNotePadnotes

Asks the activity to create a new empty note in the notes list at

contentcomgoogleproviderNotePadnotes and allow the user to edit it If the user saves the

note its URI is returned to the caller

The last activity TitleEditor enables the user to edit the title of a note This could be implemented by

directly invoking the activity (by explicitly setting its component name in the Intent) without using an

intent filter But here we take the opportunity to show how to publish alternative operations on existing

data

ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The single intent filter for this activity uses a custom action called

comandroidnotepadactionEDIT_TITLE It must be invoked on a specific note (data type

vndandroidcursoritemvndgooglenote) like the previous VIEW and EDIT actions However here the

activity displays the title contained in the note data not the content of the note itself

In addition to supporting the usual DEFAULT category the title editor also supports two other standard

categories ALTERNATIVE and SELECTED_ALTERNATIVE These categories identify activities that

can be presented to users in a menu of options (much as the LAUNCHER category identifies activities

that should be presented to user in the application launcher) Note that the filter also supplies an

explicit label (via androidlabel=stringresolve_title) to better control what users see when

presented with this activity as an alternative action to the data they are currently viewing (For more

information on these categories and building options menus see the

PackageManagerqueryIntentActivityOptions() and MenuaddIntentOptions() methods)

Given these capabilities the following intent will resolve to the TitleEditor activity

action comandroidnotepadactionEDIT_TITLE

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the title associated with note ID and allow the user to edit the title

Processes and Threads

When an application component starts and the application does not have any other components

running the Android system starts a new Linux process for the application with a single thread of

execution By default all components of the same application run in the same process and thread

(called the main thread) If an application component starts and there already exists a process for

that application (because another component from the application exists) then the component is

started within that process and uses the same thread of execution However you can arrange for

different components in your application to run in separate processes and you can create additional

threads for any process

This document discusses how processes and threads work in an Android application

Processes

By default all components of the same application run in the same process and most applications

should not change this However if you find that you need to control which process a certain

component belongs to you can do so in the manifest file

The manifest entry for each type of component elementmdashltactivitygt ltservicegt ltreceivergt and

ltprovidergtmdashsupports an androidprocess attribute that can specify a process in which that component

should run You can set this attribute so that each component runs in its own process or so that some

components share a process while others do not You can also set androidprocess so that

components of different applications run in the same processmdashprovided that the applications share the

same Linux user ID and are signed with the same certificates

The ltapplicationgt element also supports an androidprocess attribute to set a default value that

applies to all components

Android might 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 thats killed are consequently destroyed A process is started again for those components

when theres again work for them to do

When deciding which processes to kill the Android system weighs their relative importance to the

user For example it more readily shuts down a process hosting activities that are no longer visible on

screen compared to a process hosting visible activities The decision whether to terminate a process

therefore depends on the state of the components running in that process The rules used to decide

which processes to terminate is discussed below

Process lifecycle

The Android system tries to maintain an application process for as long as possible but eventually

needs to remove old processes to reclaim memory for new or more important processes To determine

which processes to keep and which to kill the system places each process into an importance

hierarchy based on the components running in the process and the state of those components

Processes with the lowest importance are eliminated first then those with the next lowest importance

and so on as necessary to recover system resources

There are five levels in the importance hierarchy The following list presents the different types of

processes in order of importance (the first process is most important and is killed last)

1 Foreground process

A process that is required for what the user is currently doing A process is considered to be in the

foreground if any of the following conditions are true

o It hosts an Activity that the user is interacting with (the Activitys onResume() method has been called)

o It hosts a Service thats bound to the activity that the user is interacting with

o It hosts a Service thats running in the foregroundmdashthe service has called startForeground()

o It hosts a Service thats executing one of its lifecycle callbacks (onCreate() onStart() or onDestroy())

o It hosts a BroadcastReceiver thats executing its onReceive() method

Generally only a few foreground processes exist at any given time They are killed only as a last

resortmdashif memory is so low that they cannot all continue to run Generally at that point the device has

reached a memory paging state so killing some foreground processes is required to keep the user

interface responsive

2 Visible process

A process that doesnt have any foreground components but still can affect what the user sees on

screen A process is considered to be visible if either of the following conditions are true

o It hosts an Activity that is not in the foreground but is still visible to the user (its onPause() method has

been called) This might occur for example if the foreground activity started a dialog which allows the

previous activity to be seen behind it

o It hosts a Service thats bound to a visible (or foreground) activity

A visible process is considered extremely important and will not be killed unless doing so is required to

keep all foreground processes running

3 Service process

A process that is running a service that has been started with the startService() method and does not

fall into either of the two higher categories Although service processes are not directly tied to anything

the user sees they are generally doing things that the user cares about (such as playing music in the

background or downloading data on the network) so the system keeps them running unless theres

not enough memory to retain them along with all foreground and visible processes

4 Background process

A process holding an activity thats not currently visible to the user (the activitys onStop() method has

been called) These processes have no direct impact on the user experience and the system can kill

them at any time to reclaim memory for a foreground visible or service process Usually there are

many background processes running so they are kept in an LRU (least recently used) list to ensure

that the process with the activity that was most recently seen by the user is the last to be killed If an

activity implements its lifecycle methods correctly and saves its current state killing its process will not

have a visible effect on the user experience because when the user navigates back to the activity the

activity restores all of its visible state See the Activities document for information about saving and

restoring state

5 Empty process

A process that doesnt hold any active application components The only reason to keep this kind of

process alive is for caching purposes to improve startup time the next time a component needs to run

in it The system often kills these processes in order to balance overall system resources between

process caches and the underlying kernel caches

Android ranks a process at the highest level it can based upon the importance of the components

currently active in the process For example if a process hosts a service and a visible activity the

process is ranked as a visible process not a service process

In addition a processs ranking might be increased because other processes are dependent on itmdasha

process that is serving another process can never be ranked lower than the process it is serving For

example if a content provider in process A is serving a client in process B or if a service in process A

is bound to a component in process B process A is always considered at least as important as

process B

Because a process running a service is ranked higher than a process with background activities an

activity that initiates a long-running operation might do well to start a service for that operation rather

than simply create a worker threadmdashparticularly if the operation will likely outlast the activity For

example an activity thats uploading a picture to a web site should start a service to perform the

upload so that the upload can continue in the background even if the user leaves the activity Using a

service guarantees that the operation will have at least service process priority regardless of what

happens to the activity This is the same reason that broadcast receivers should employ services

rather than simply put time-consuming operations in a thread

Threads

When an application is launched the system creates a thread of execution for the application called

main This thread is very important because it is in charge of dispatching events to the appropriate

user interface widgets including drawing events It is also the thread in which your application interacts

with components from the Android UI toolkit (components from the androidwidget and androidview

packages) As such the main thread is also sometimes called the UI thread

The system does not create a separate thread for each instance of a component All components that

run in the same process are instantiated in the UI thread and system calls to each component are

dispatched from that thread Consequently methods that respond to system callbacks (such as

onKeyDown() to report user actions or a lifecycle callback method) always run in the UI thread of the

process

For instance when the user touches a button on the screen your apps UI thread dispatches the touch

event to the widget which in turn sets its pressed state and posts an invalidate request to the event

queue The UI thread dequeues the request and notifies the widget that it should redraw itself

When your app performs intensive work in response to user interaction this single thread model can

yield poor performance unless you implement your application properly Specifically if everything is

happening in the UI thread performing long operations such as network access or database queries

will block the whole UI When the thread is blocked no events can be dispatched including drawing

events From the users perspective the application appears to hang Even worse if the UI thread is

blocked for more than a few seconds (about 5 seconds currently) the user is presented with the

infamous application not responding (ANR) dialog The user might then decide to quit your

application and uninstall it if they are unhappy

Additionally the Andoid UI toolkit is not thread-safe So you must not manipulate your UI from a

worker threadmdashyou must do all manipulation to your user interface from the UI thread Thus there are

simply two rules to Androids single thread model

1 Do not block the UI thread

2 Do not access the Android UI toolkit from outside the UI thread

Worker threads

Because of the single thread model described above its vital to the responsiveness of your

applications UI that you do not block the UI thread If you have operations to perform that are not

instantaneous you should make sure to do them in separate threads (background or worker

threads)

For example below is some code for a click listener that downloads an image from a separate thread

and displays it in an ImageView

public void onClick(View v) new Thread(new Runnable() public void run() Bitmap b = loadImageFromNetwork(httpexamplecomimagepng) mImageViewsetImageBitmap(b) )start()

At first this seems to work fine because it creates a new thread to handle the network operation

However it violates the second rule of the single-threaded model do not access the Android UI toolkit

from outside the UI threadmdashthis sample modifies the ImageView from the worker thread instead of the

UI thread This can result in undefined and unexpected behavior which can be difficult and time-

consuming to track down

To fix this problem Android offers several ways to access the UI thread from other threads Here is a

list of methods that can help

ActivityrunOnUiThread(Runnable)

Viewpost(Runnable)

ViewpostDelayed(Runnable long)

For example you can fix the above code by using the Viewpost(Runnable) method

public void onClick(View v) new Thread(new Runnable() public void run() final Bitmap bitmap = loadImageFromNetwork(httpexamplecomimagepng) mImageViewpost(new Runnable() public void run() mImageViewsetImageBitmap(bitmap) ) )start()

Now this implementation is thread-safe the network operation is done from a separate thread while

the ImageView is manipulated from the UI thread

However as the complexity of the operation grows this kind of code can get complicated and difficult

to maintain To handle more complex interactions with a worker thread you might consider using a

Handler in your worker thread to process messages delivered from the UI thread Perhaps the best

solution though is to extend the AsyncTask class which simplifies the execution of worker thread

tasks that need to interact with the UI

Using AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface It performs the blocking

operations in a worker thread and then publishes the results on the UI thread without requiring you to

handle threads andor handlers yourself

To use it you must subclass AsyncTask and implement the doInBackground() callback method which

runs in a pool of background threads To update your UI you should implement onPostExecute()

which delivers the result from doInBackground() and runs in the UI thread so you can safely update

your UI You can then run the task by calling execute() from the UI thread

For example you can implement the previous example using AsyncTask this way

public void onClick(View v) new DownloadImageTask()execute(httpexamplecomimagepng) private class DownloadImageTask extends AsyncTaskltString Void Bitmapgt The system calls this to perform work in a worker thread and delivers it the parameters given to AsyncTaskexecute() protected Bitmap doInBackground(String urls) return loadImageFromNetwork(urls[0])

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 9: 03 services

If the system kills the service after onStartCommand() returns recreate the service and call

onStartCommand() but do not redeliver the last intent Instead the system calls

onStartCommand() with a null intent unless there were pending intents to start the service in

which case those intents are delivered This is suitable for media players (or similar services)

that are not executing commands but running indefinitely and waiting for a job

START_REDELIVER_INTENT

If the system kills the service after onStartCommand() returns recreate the service and call

onStartCommand() with the last intent that was delivered to the service Any pending intents are

delivered in turn This is suitable for services that are actively performing a job that should be

immediately resumed such as downloading a file

For more details about these return values see the linked reference documentation for each constant

Starting a Service

You can start a service from an activity or other application component by passing an Intent (specifying

the service to start) to startService() The Android system calls the services onStartCommand()

method and passes it the Intent (You should never call onStartCommand() directly)

For example an activity can start the example service in the previous section (HelloSevice) using an

explicit intent with startService()

Intent intent = new Intent(this HelloServiceclass) startService(intent)

The startService() method returns immediately and the Android system calls the services

onStartCommand() method If the service is not already running the system first calls onCreate() then

calls onStartCommand()

If the service does not also provide binding the intent delivered with startService() is the only mode of

communication between the application component and the service However if you want the service

to send a result back then the client that starts the service can create a PendingIntent for a broadcast

(with getBroadcast()) and deliver it to the service in the Intent that starts the service The service can

then use the broadcast to deliver a result

Multiple requests to start the service result in multiple corresponding calls to the services

onStartCommand() However only one request to stop the service (with stopSelf() or stopService()) is

required to stop it

Stopping a service

A started service must manage its own lifecycle That is the system does not stop or destroy the

service unless it must recover system memory and the service continues to run after

onStartCommand() returns So the service must stop itself by calling stopSelf() or another component

can stop it by calling stopService()

Once requested to stop with stopSelf() or stopService() the system destroys the service as soon as

possible

However if your service handles multiple requests to onStartCommand() concurrently then you

shouldnt stop the service when youre done processing a start request because you might have since

received a new start request (stopping at the end of the first request would terminate the second one)

To avoid this problem you can use stopSelf(int) to ensure that your request to stop the service is

always based on the most recent start request That is when you call stopSelf(int) you pass the ID of

the start request (the startId delivered to onStartCommand()) to which your stop request corresponds

Then if the service received a new start request before you were able to call stopSelf(int) then the ID

will not match and the service will not stop

Caution Its important that your application stops its services when its done working to avoid

wasting system resources and consuming battery power If necessary other components can stop

the service by calling stopService() Even if you enable binding for the service you must always

stop the service yourself if it ever received a call to onStartCommand()

For more information about the lifecycle of a service see the section below about Managing the

Lifecycle of a Service

Creating a Bound Service

A bound service is one that allows application components to bind to it by calling bindService() in order

to create a long-standing connection (and generally does not allow components to start it by calling

startService())

You should create a bound service when you want to interact with the service from activities and other

components in your application or to expose some of your applications functionality to other

applications through interprocess communication (IPC)

To create a bound service you must implement the onBind() callback method to return an IBinder that

defines the interface for communication with the service Other application components can then call

bindService() to retrieve the interface and begin calling methods on the service The service lives only

to serve the application component that is bound to it so when there are no components bound to the

service the system destroys it (you do not need to stop a bound service in the way you must when the

service is started through onStartCommand())

To create a bound service the first thing you must do is define the interface that specifies how a client

can communicate with the service This interface between the service and a client must be an

implementation of IBinder and is what your service must return from the onBind() callback method

Once the client receives the IBinder it can begin interacting with the service through that interface

Multiple clients can bind to the service at once When a client is done interacting with the service it

calls unbindService() to unbind Once there are no clients bound to the service the system destroys

the service

There are multiple ways to implement a bound service and the implementation is more complicated

than a started service so the bound service discussion appears in a separate document about Bound

Services

Sending Notifications to the User

Once running a service can notify the user of events using Toast Notifications or Status Bar

Notifications

A toast notification is a message that appears on the surface of the current window for a moment then

disappears while a status bar notification provides an icon in the status bar with a message which the

user can select in order to take an action (such as start an activity)

Usually a status bar notification is the best technique when some background work has completed

(such as a file completed downloading) and the user can now act on it When the user selects the

notification from the expanded view the notification can start an activity (such as to view the

downloaded file)

See the Toast Notifications or Status Bar Notifications developer guides for more information

Running a Service in the Foreground

A foreground service is a service thats considered to be something the user is actively aware of and

thus not a candidate for the system to kill when low on memory A foreground service must provide a

notification for the status bar which is placed under the Ongoing heading which means that the

notification cannot be dismissed unless the service is either stopped or removed from the foreground

For example a music player that plays music from a service should be set to run in the foreground

because the user is explicitly aware of its operation The notification in the status bar might indicate the

current song and allow the user to launch an activity to interact with the music player

To request that your service run in the foreground call startForeground() This method takes two

parameters an integer that uniquely identifies the notification and the Notification for the status bar

For example

Notification notification = new Notification(Rdrawableicon getText(Rstringticker_text) SystemcurrentTimeMillis()) Intent notificationIntent = new Intent(this ExampleActivityclass) PendingIntent pendingIntent = PendingIntentgetActivity(this 0 notificationIntent 0) notificationsetLatestEventInfo(this getText(Rstringnotification_title) getText(Rstringnotification_message) pendingIntent) startForeground(ONGOING_NOTIFICATION notification)

To remove the service from the foreground call stopForeground() This method takes a boolean

indicating whether to remove the status bar notification as well This method does not stop the service

However if you stop the service while its still running in the foreground then the notification is also

removed

Note The methods startForeground() and stopForeground() were introduced in Android 20 (API

Level 5) In order to run your service in the foreground on older versions of the platform you must

use the previous setForeground() methodmdashsee the startForeground() documentation for

information about how to provide backward compatibility

For more information about notifications see Creating Status Bar Notifications

Managing the Lifecycle of a Service

The lifecycle of a service is much simpler than that of an activity However its even more important

that you pay close attention to how your service is created and destroyed because a service can run

in the background without the user being aware

The service lifecyclemdashfrom when its created to when its destroyedmdashcan follow two different paths

A started service

The service is created when another component calls startService() The service then runs indefinitely

and must stop itself by calling stopSelf() Another component can also stop the service by calling

stopService() When the service is stopped the system destroys it

A bound service

The service is created when another component (a client) calls bindService() The client then

communicates with the service through an IBinder interface The client can close the connection by

calling unbindService() Multiple clients can bind to the same service and when all of them unbind the

system destroys the service (The service does not need to stop itself)

These two paths are not entirely separate That is you can bind to a service that was already started

with startService() For example a background music service could be started by calling startService()

with an Intent that identifies the music to play Later possibly when the user wants to exercise some

control over the player or get information about the current song an activity can bind to the service by

calling bindService() In cases like this stopService() or stopSelf() does not actually stop the service

until all clients unbind

Implementing the lifecycle callbacks

Like an activity a service has lifecycle callback methods that you can implement to monitor changes in

the services state and perform work at the appropriate times The following skeleton service

demonstrates each of the lifecycle methods

Figure 2 The service lifecycle The diagram on the left shows the lifecycle when the service is created

with startService() and the diagram on the right shows the lifecycle when the service is created with

bindService()

public class ExampleService extends Service int mStartMode indicates how to behave if the service is killed IBinder mBinder interface for clients that bind boolean mAllowRebind indicates whether onRebind should be used Override public void onCreate() The service is being created Override public int onStartCommand(Intent intent int flags int startId) The service is starting due to a call to startService() return mStartMode Override public IBinder onBind(Intent intent) A client is binding to the service with bindService() return mBinder Override public boolean onUnbind(Intent intent) All clients have unbound with unbindService()

return mAllowRebind Override public void onRebind(Intent intent) A client is binding to the service with bindService() after onUnbind() has already been called Override public void onDestroy() The service is no longer used and is being destroyed

Note Unlike the activity lifecycle callback methods you are not required to call the superclass

implementation of these callback methods

By implementing these methods you can monitor two nested loops of the services lifecycle

The entire lifetime of a service happens between the time onCreate() is called and the time

onDestroy() returns Like an activity a service does its initial setup in onCreate() and releases all

remaining resources in onDestroy() For example a music playback service could create the thread

where the music will be played in onCreate() then stop the thread in onDestroy()

The onCreate() and onDestroy() methods are called for all services whether theyre created by

startService() or bindService()

The active lifetime of a service begins with a call to either onStartCommand() or onBind() Each

method is handed the Intent that was passed to either startService() or bindService() respectively

If the service is started the active lifetime ends the same time that the entire lifetime ends (the service

is still active even after onStartCommand() returns) If the service is bound the active lifetime ends

when onUnbind() returns

Note Although a started service is stopped by a call to either stopSelf() or stopService() there is

not a respective callback for the service (theres no onStop() callback) So unless the service is

bound to a client the system destroys it when the service is stoppedmdashonDestroy() is the only

callback received

Figure 2 illustrates the typical callback methods for a service Although the figure separates services

that are created by startService() from those created by bindService() keep in mind that any service

no matter how its started can potentially allow clients to bind to it So a service that was initially

started with onStartCommand() (by a client calling startService()) can still receive a call to onBind()

(when a client calls bindService())

For more information about creating a service that provides binding see the Bound Services

document which includes more information about the onRebind() callback method in the section about

Managing the Lifecycle of a Bound Service

Bound Services

A bound service is the server in a client-server interface A bound service allows components (such as

activities) to bind to the service send requests receive responses and even perform interprocess

communication (IPC) A bound service typically lives only while it serves another application

component and does not run in the background indefinitely

This document shows you how to create a bound service including how to bind to the service from

other application components However you should also refer to the Services document for additional

information about services in general such as how to deliver notifications from a service set the

service to run in the foreground and more

The Basics

A bound service is an implementation of the Service class that allows other applications to bind to it

and interact with it To provide binding for a service you must implement the onBind() callback

method This method returns an IBinder object that defines the programming interface that clients can

use to interact with the service

Binding to a Started Service

As discussed in the Services document you can create a service that is both started and bound That

is the service can be started by calling startService() which allows the service to run indefinitely and

also allow a client to bind to the service by calling bindService()

If you do allow your service to be started and bound then when the service has been started the

system does not destroy the service when all clients unbind Instead you must explicitly stop the

service by calling stopSelf() or stopService()

Although you should usually implement either onBind() or onStartCommand() its sometimes

necessary to implement both For example a music player might find it useful to allow its service to run

indefinitely and also provide binding This way an activity can start the service to play some music and

the music continues to play even if the user leaves the application Then when the user returns to the

application the activity can bind to the service to regain control of playback

Be sure to read the section about Managing the Lifecycle of a Bound Service for more information

about the service lifecycle when adding binding to a started service

A client can bind to the service by calling bindService() When it does it must provide an

implementation of ServiceConnection which monitors the connection with the service The

bindService() method returns immediately without a value but when the Android system creates the

connection between the client and service it calls onServiceConnected() on the ServiceConnection to

deliver the IBinder that the client can use to communicate with the service

Multiple clients can connect to the service at once However the system calls your services onBind()

method to retrieve the IBinder only when the first client binds The system then delivers the same

IBinder to any additional clients that bind without calling onBind() again

When the last client unbinds from the service the system destroys the service (unless the service was

also started by startService())

When you implement your bound service the most important part is defining the interface that your

onBind() callback method returns There are a few different ways you can define your services IBinder

interface and the following section discusses each technique

Creating a Bound Service

When creating a service that provides binding you must provide an IBinder that provides the

programming interface that clients can use to interact with the service There are three ways you can

define the interface

Extending the Binder class

If your service is private to your own application and runs in the same process as the client

(which is common) you should create your interface by extending the Binder class and

returning an instance of it from onBind() The client receives the Binder and can use it to directly

access public methods available in either the Binder implementation or even the Service

This is the preferred technique when your service is merely a background worker for your own

application The only reason you would not create your interface this way is because your

service is used by other applications or across separate processes

Using a Messenger

If you need your interface to work across different processes you can create an interface for the

service with a Messenger In this manner the service defines a Handler that responds to

different types of Message objects This Handler is the basis for a Messenger that can then

share an IBinder with the client allowing the client to send commands to the service using

Message objects Additionally the client can define a Messenger of its own so the service can

send messages back

This is the simplest way to perform interprocess communication (IPC) because the Messenger

queues all requests into a single thread so that you dont have to design your service to be

thread-safe

Using AIDL

AIDL (Android Interface Definition Language) performs all the work to decompose objects into

primitives that the operating system can understand and marshall them across processes to

perform IPC The previous technique using a Messenger is actually based on AIDL as its

underlying structure As mentioned above the Messenger creates a queue of all the client

requests in a single thread so the service receives requests one at a time If however you

want your service to handle multiple requests simultaneously then you can use AIDL directly In

this case your service must be capable of multi-threading and be built thread-safe

To use AIDL directly you must create an aidl file that defines the programming interface The

Android SDK tools use this file to generate an abstract class that implements the interface and

handles IPC which you can then extend within your service

Note Most applications should not use AIDL to create a bound service because it may require

multithreading capabilities and can result in a more complicated implementation As such AIDL is

not suitable for most applications and this document does not discuss how to use it for your

service If youre certain that you need to use AIDL directly see the AIDL document

Extending the Binder class

If your service is used only by the local application and does not need to work across processes then

you can implement your own Binder class that provides your client direct access to public methods in

the service

Note This works only if the client and service are in the same application and process which is

most common For example this would work well for a music application that needs to bind an

activity to its own service thats playing music in the background

Heres how to set it up

1 In your service create an instance of Binder that either

o contains public methods that the client can call

o returns the current Service instance which has public methods the client can call

o or returns an instance of another class hosted by the service with public methods the client can call

2 Return this instance of Binder from the onBind() callback method

3 In the client receive the Binder from the onServiceConnected() callback method and make calls to the

bound service using the methods provided

Note The reason the service and client must be in the same application is so the client can cast

the returned object and properly call its APIs The service and client must also be in the same

process because this technique does not perform any marshalling across processes

For example heres a service that provides clients access to methods in the service through a Binder

implementation

public class LocalService extends Service

Binder given to clients

private final IBinder mBinder = new LocalBinder()

Random number generator

private final Random mGenerator = new Random()

Class used for the client Binder Because we know this service always

runs in the same process as its clients we dont need to deal with IPC

public class LocalBinder extends Binder

LocalService getService()

Return this instance of LocalService so clients can call public methods

return LocalServicethis

Override

public IBinder onBind(Intent intent)

return mBinder

method for clients

public int getRandomNumber()

return mGeneratornextInt(100)

The LocalBinder provides the getService() method for clients to retrieve the current instance of

LocalService This allows clients to call public methods in the service For example clients can call

getRandomNumber() from the service

Heres an activity that binds to LocalService and calls getRandomNumber() when a button is clicked

public class BindingActivity extends Activity

LocalService mService

boolean mBound = false

Override

protected void onCreate(Bundle savedInstanceState)

superonCreate(savedInstanceState)

setContentView(Rlayoutmain)

Override

protected void onStart()

superonStart()

Bind to LocalService

Intent intent = new Intent(this LocalServiceclass)

bindService(intent mConnection ContextBIND_AUTO_CREATE)

Override

protected void onStop()

superonStop()

Unbind from the service

if (mBound)

unbindService(mConnection)

mBound = false

Called when a button is clicked (the button in the layout file attaches to

this method with the androidonClick attribute)

public void onButtonClick(View v)

if (mBound)

Call a method from the LocalService

However if this call were something that might hang then this request should

occur in a separate thread to avoid slowing down the activity performance

int num = mServicegetRandomNumber()

ToastmakeText(this number + num ToastLENGTH_SHORT)show()

Defines callbacks for service binding passed to bindService()

private ServiceConnection mConnection = new ServiceConnection()

Override

public void onServiceConnected(ComponentName className

IBinder service)

Weve bound to LocalService cast the IBinder and get LocalService instance

LocalBinder binder = (LocalBinder) service

mService = bindergetService()

mBound = true

Override

public void onServiceDisconnected(ComponentName arg0)

mBound = false

The above sample shows how the client binds to the service using an implementation of

ServiceConnection and the onServiceConnected() callback The next section provides more

information about this process of binding to the service

Note The example above doesnt explicitly unbind from the service but all clients should unbind

at an appropriate time (such as when the activity pauses)

For more sample code see the LocalServicejava class and the LocalServiceActivitiesjava class in

ApiDemos

Using a Messenger

Compared to AIDL

When you need to perform IPC using a Messenger for your interface is simpler than implementing it

with AIDL because Messenger queues all calls to the service whereas a pure AIDL interface sends

simultaneous requests to the service which must then handle multi-threading

For most applications the service doesnt need to perform multi-threading so using a Messenger

allows the service to handle one call at a time If its important that your service be multi-threaded then

you should use AIDL to define your interface

If you need your service to communicate with remote processes then you can use a Messenger to

provide the interface for your service This technique allows you to perform interprocess

communication (IPC) without the need to use AIDL

Heres a summary of how to use a Messenger

The service implements a Handler that receives a callback for each call from a client

The Handler is used to create a Messenger object (which is a reference to the Handler)

The Messenger creates an IBinder that the service returns to clients from onBind()

Clients use the IBinder to instantiate the Messenger (that references the services Handler) which the

client uses to send Message objects to the service

The service receives each Message in its Handlermdashspecifically in the handleMessage() method

In this way there are no methods for the client to call on the service Instead the client delivers

messages (Message objects) that the service receives in its Handler

Heres a simple example service that uses a Messenger interface

public class MessengerService extends Service Command to the service to display a message static final int MSG_SAY_HELLO = 1 Handler of incoming messages from clients class IncomingHandler extends Handler Override public void handleMessage(Message msg) switch (msgwhat) case MSG_SAY_HELLO ToastmakeText(getApplicationContext() hello ToastLENGTH_SHORT)show() break default superhandleMessage(msg) Target we publish for clients to send messages to IncomingHandler final Messenger mMessenger = new Messenger(new IncomingHandler()) When binding to the service we return an interface to our messenger for sending messages to the service Override public IBinder onBind(Intent intent) ToastmakeText(getApplicationContext() binding ToastLENGTH_SHORT)show() return mMessengergetBinder()

Notice that the handleMessage() method in the Handler is where the service receives the incoming

Message and decides what to do based on the what member

All that a client needs to do is create a Messenger based on the IBinder returned by the service and

send a message using send() For example heres a simple activity that binds to the service and

delivers the MSG_SAY_HELLO message to the service

public class ActivityMessenger extends Activity Messenger for communicating with the service Messenger mService = null Flag indicating whether we have called bind on the service boolean mBound Class for interacting with the main interface of the service private ServiceConnection mConnection = new ServiceConnection() public void onServiceConnected(ComponentName className IBinder service) This is called when the connection with the service has been established giving us the object we can use to interact with the service We are communicating with the service using a Messenger so here we get a client-side representation of that from the raw IBinder object mService = new Messenger(service) mBound = true public void onServiceDisconnected(ComponentName className) This is called when the connection with the service has been unexpectedly disconnected -- that is its process crashed mService = null mBound = false public void sayHello(View v) if (mBound) return Create and send a message to the service using a supported what value Message msg = Messageobtain(null MessengerServiceMSG_SAY_HELLO 0 0) try mServicesend(msg) catch (RemoteException e) eprintStackTrace() Override protected void onCreate(Bundle savedInstanceState) superonCreate(savedInstanceState) setContentView(Rlayoutmain)

Override protected void onStart() superonStart() Bind to the service bindService(new Intent(this MessengerServiceclass) mConnection ContextBIND_AUTO_CREATE) Override protected void onStop() superonStop() Unbind from the service if (mBound) unbindService(mConnection) mBound = false

Notice that this example does not show how the service can respond to the client If you want the

service to respond then you need to also create a Messenger in the client Then when the client

receives the onServiceConnected() callback it sends a Message to the service that includes the

clients Messenger in the replyTo parameter of the send() method

You can see an example of how to provide two-way messaging in the MessengerServicejava (service)

and MessengerServiceActivitiesjava (client) samples

Binding to a Service

Application components (clients) can bind to a service by calling bindService() The Android system

then calls the services onBind() method which returns an IBinder for interacting with the service

The binding is asynchronous bindService() returns immediately and does not return the IBinder to the

client To receive the IBinder the client must create an instance of ServiceConnection and pass it to

bindService() The ServiceConnection includes a callback method that the system calls to deliver the

IBinder

Note Only activities services and content providers can bind to a servicemdashyou cannot bind to a

service from a broadcast receiver

So to bind to a service from your client you must

1 Implement ServiceConnection

Your implementation must override two callback methods

onServiceConnected()

The system calls this to deliver the IBinder returned by the services onBind() method

onServiceDisconnected()

The Android system calls this when the connection to the service is unexpectedly lost such as

when the service has crashed or has been killed This is not called when the client unbinds

2 Call bindService() passing the ServiceConnection implementation

3 When the system calls your onServiceConnected() callback method you can begin making calls to the

service using the methods defined by the interface

4 To disconnect from the service call unbindService()

When your client is destroyed it will unbind from the service but you should always unbind when

youre done interacting with the service or when your activity pauses so that the service can shutdown

while its not being used (Appropriate times to bind and unbind is discussed more below)

For example the following snippet connects the client to the service created above by extending the

Binder class so all it must do is cast the returned IBinder to the LocalService class and request the

LocalService instance

LocalService mService private ServiceConnection mConnection = new ServiceConnection() Called when the connection with the service is established public void onServiceConnected(ComponentName className IBinder service) Because we have bound to an explicit service that is running in our own process we can cast its IBinder to a concrete class and directly access it LocalBinder binder = (LocalBinder) service mService = bindergetService() mBound = true Called when the connection with the service disconnects unexpectedly public void onServiceDisconnected(ComponentName className) Loge(TAG onServiceDisconnected) mBound = false

With this ServiceConnection the client can bind to a service by passing this it to bindService() For

example

Intent intent = new Intent(this LocalServiceclass) bindService(intent mConnection ContextBIND_AUTO_CREATE)

The first parameter of bindService() is an Intent that explicitly names the service to bind (thought the

intent could be implicit)

The second parameter is the ServiceConnection object

The third parameter is a flag indicating options for the binding It should usually be

BIND_AUTO_CREATE in order to create the service if its not already alive Other possible values are

BIND_DEBUG_UNBIND and BIND_NOT_FOREGROUND or 0 for none

Additional notes

Here are some important notes about binding to a service

You should always trap DeadObjectException exceptions which are thrown when the connection has

broken This is the only exception thrown by remote methods

Objects are reference counted across processes

You should usually pair the binding and unbinding during matching bring-up and tear-down moments

of the clients lifecycle For example

o If you only need to interact with the service while your activity is visible you should bind during

onStart() and unbind during onStop()

o If you want your activity to receive responses even while it is stopped in the background then you can

bind during onCreate() and unbind during onDestroy() Beware that this implies that your activity needs

to use the service the entire time its running (even in the background) so if the service is in another

process then you increase the weight of the process and it becomes more likely that the system will

kill it

Note You should usually not bind and unbind during your activitys onResume() and onPause()

because these callbacks occur at every lifecycle transition and you should keep the processing that

occurs at these transitions to a minimum Also if multiple activities in your application bind to the same

service and there is a transition between two of those activities the service may be destroyed and

recreated as the current activity unbinds (during pause) before the next one binds (during resume)

(This activity transition for how activities coordinate their lifecycles is described in the Activities

document)

For more sample code showing how to bind to a service see the RemoteServicejava class in

ApiDemos

Managing the Lifecycle of a Bound Service

Figure 1 The lifecycle for a service

that is started and also allows binding

When a service is unbound from all

clients the Android system destroys it

(unless it was also started with

onStartCommand()) As such you

dont have to manage the lifecycle of

your service if its purely a bound

servicemdashthe Android system manages

it for you based on whether it is bound

to any clients

However if you choose to implement

the onStartCommand() callback

method then you must explicitly stop

the service because the service is

now considered to be started In this

case the service runs until the service

stops itself with stopSelf() or another

component calls stopService()

regardless of whether it is bound to

any clients

Additionally if your service is started and accepts binding then when the system calls your onUnbind()

method you can optionally return true if you would like to receive a call to onRebind() the next time a

client binds to the service (instead of receiving a call to onBind()) onRebind() returns void but the

client still receives the IBinder in its onServiceConnected() callback Below figure 1 illustrates the logic

for this kind of lifecycle

For more information about the lifecycle of an started service see the Services document

Content Providers

Content providers store and retrieve data and make it accessible to all applications Theyre the only

way to share data across applications theres no common storage area that all Android packages can

access

Android ships with a number of content providers for common data types (audio video images

personal contact information and so on) You can see some of them listed in the androidprovider

package You can query these providers for the data they contain (although for some you must

acquire the proper permission to read the data)

If you want to make your own data public you have two options You can create your own content

provider (a ContentProvider subclass) or you can add the data to an existing provider mdash if theres one

that controls the same type of data and you have permission to write to it

This document is an introduction to using content providers After a brief discussion of the

fundamentals it explores how to query a content provider how to modify data controlled by a provider

and how to create a content provider of your own

Content Provider Basics

How a content provider actually stores its data under the covers is up to its designer But all content

providers implement a common interface for querying the provider and returning results mdash as well as

for adding altering and deleting data Its an interface that clients use indirectly most generally

through ContentResolver objects You get a ContentResolver by calling getContentResolver() from

within the implementation of an Activity or other application component

ContentResolver cr = getContentResolver()

You can then use the ContentResolvers methods to interact with whatever content providers youre

interested in When a query is initiated the Android system identifies the content provider thats the

target of the query and makes sure that it is up and running The system instantiates all

ContentProvider objects you never need to do it on your own In fact you never deal directly with

ContentProvider objects at all Typically theres just a single instance of each type of ContentProvider

But it can communicate with multiple ContentResolver objects in different applications and processes

The interaction between processes is handled by the ContentResolver and ContentProvider classes

The data model

Content providers expose their data as a simple table on a database model where each row is a

record and each column is data of a particular type and meaning For example information about

people and their phone numbers might be exposed as follows

_ID NUMBER NUMBER_KEY LABEL NAME TYPE

13 (425) 555 6677 425 555 6677 Kirkland office Bully Pulpit TYPE_WORK

44 (212) 555-1234 212 555 1234 NY apartment Alan Vain TYPE_HOME

45 (212) 555-6657 212 555 6657 Downtown office Alan Vain TYPE_MOBILE

53 2015554433 201 555 4433 Love Nest Rex Cars TYPE_HOME

Every record includes a numeric _ID field that uniquely identifies the record within the table IDs can be

used to match records in related tables mdash for example to find a persons phone number in one table

and pictures of that person in another

A query returns a Cursor object that can move from record to record and column to column to read the

contents of each field It has specialized methods for reading each type of data So to read a field you

must know what type of data the field contains (Theres more on query results and Cursor objects

later)

URIs

Each content provider exposes a public URI (wrapped as a Uri object) that uniquely identifies its data

set A content provider that controls multiple data sets (multiple tables) exposes a separate URI for

each one All URIs for providers begin with the string content The content scheme identifies the

data as being controlled by a content provider

If youre defining a content provider its a good idea to also define a constant for its URI to simplify

client code and make future updates cleaner Android defines CONTENT_URI constants for all the

providers that come with the platform For example the URI for the table that matches phone numbers

to people and the URI for the table that holds pictures of people (both controlled by the Contacts

content provider) are

androidproviderContactsPhonesCONTENT_URI

androidproviderContactsPhotosCONTENT_URI

The URI constant is used in all interactions with the content provider Every ContentResolver method

takes the URI as its first argument Its what identifies which provider the ContentResolver should talk

to and which table of the provider is being targeted

Querying a Content Provider

You need three pieces of information to query a content provider

The URI that identifies the provider

The names of the data fields you want to receive

The data types for those fields

If youre querying a particular record you also need the ID for that record

Making the query

To query a content provider you can use either the ContentResolverquery() method or the

ActivitymanagedQuery() method Both methods take the same set of arguments and both return a

Cursor object However managedQuery() causes the activity to manage the life cycle of the Cursor A

managed Cursor handles all of the niceties such as unloading itself when the activity pauses and

requerying itself when the activity restarts You can ask an Activity to begin managing an unmanaged

Cursor object for you by calling ActivitystartManagingCursor()

The first argument to either query() or managedQuery() is the provider URI mdash the CONTENT_URI

constant that identifies a particular ContentProvider and data set (see URIs earlier)

To restrict a query to just one record you can append the _ID value for that record to the URI mdash that

is place a string matching the ID as the last segment of the path part of the URI For example if the ID

is 23 the URI would be

content 23

There are some helper methods particularly ContentUriswithAppendedId() and

UriwithAppendedPath() that make it easy to append an ID to a URI Both are static methods that

return a Uri object with the ID added So for example if you were looking for record 23 in the database

of people contacts you might construct a query as follows

import androidproviderContactsPeople import androidcontentContentUris import androidnetUri import androiddatabaseCursor Use the ContentUris method to produce the base URI for the contact with _ID == 23 Uri myPerson = ContentUriswithAppendedId(PeopleCONTENT_URI 23) Alternatively use the Uri method to produce the base URI It takes a string rather than an integer Uri myPerson = UriwithAppendedPath(PeopleCONTENT_URI 23) Then query for this specific record Cursor cur = managedQuery(myPerson null null null null)

The other arguments to the query() and managedQuery() methods delimit the query in more detail

They are

The names of the data columns that should be returned A null value returns all columns Otherwise

only columns that are listed by name are returned All the content providers that come with the

platform define constants for their columns For example the androidproviderContactsPhones class

defines constants for the names of the columns in the phone table illustrated earlier ampmdash _ID

NUMBER NUMBER_KEY NAME and so on

A filter detailing which rows to return formatted as an SQL WHERE clause (excluding the WHERE

itself) A null value returns all rows (unless the URI limits the query to a single record)

Selection arguments

A sorting order for the rows that are returned formatted as an SQL ORDER BY clause (excluding the

ORDER BY itself) A null value returns the records in the default order for the table which may be

unordered

Lets look at an example query to retrieve a list of contact names and their primary phone numbers

import androidproviderContactsPeople import androiddatabaseCursor Form an array specifying which columns to return String[] projection = new String[] People_ID People_COUNT PeopleNAME PeopleNUMBER Get the base URI for the People table in the Contacts content provider Uri contacts = PeopleCONTENT_URI Make the query Cursor managedCursor = managedQuery(contacts projection Which columns to return null Which rows to return (all rows) null Selection arguments (none) Put the results in ascending order by name PeopleNAME + ASC)

This query retrieves data from the People table of the Contacts content provider It gets the name

primary phone number and unique record ID for each contact It also reports the number of records

that are returned as the _COUNT field of each record

The constants for the names of the columns are defined in various interfaces mdash _ID and _COUNT in

BaseColumns NAME in PeopleColumns and NUMBER in PhoneColumns The ContactsPeople

class implements each of these interfaces which is why the code example above could refer to them

using just the class name

What a query returns

A query returns a set of zero or more database records The names of the columns their default order

and their data types are specific to each content provider But every provider has an _ID column

which holds a unique numeric ID for each record Every provider can also report the number of records

returned as the _COUNT column its value is the same for all rows

Here is an example result set for the query in the previous section

_ID _COUNT NAME NUMBER

44 3 Alan Vain 212 555 1234

13 3 Bully Pulpit 425 555 6677

53 3 Rex Cars 201 555 4433

The retrieved data is exposed by a Cursor object that can be used to iterate backward or forward

through the result set You can use this object only to read the data To add modify or delete data

you must use a ContentResolver object

Reading retrieved data

The Cursor object returned by a query provides access to a recordset of results If you have queried

for a specific record by ID this set will contain only one value Otherwise it can contain multiple

values (If there are no matches it can also be empty) You can read data from specific fields in the

record but you must know the data type of the field because the Cursor object has a separate method

for reading each type of data mdash such as getString() getInt() and getFloat() (However for most types

if you call the method for reading strings the Cursor object will give you the String representation of

the data) The Cursor lets you request the column name from the index of the column or the index

number from the column name

The following snippet demonstrates reading names and phone numbers from the query illustrated

earlier

import androidproviderContactsPeople private void getColumnData(Cursor cur) if (curmoveToFirst()) String name String phoneNumber int nameColumn = curgetColumnIndex(PeopleNAME) int phoneColumn = curgetColumnIndex(PeopleNUMBER) String imagePath do Get the field values name = curgetString(nameColumn) phoneNumber = curgetString(phoneColumn) Do something with the values while (curmoveToNext())

If a query can return binary data such as an image or sound the data may be directly entered in the

table or the table entry for that data may be a string specifying a content URI that you can use to get

the data In general smaller amounts of data (say from 20 to 50K or less) are most often directly

entered in the table and can be read by calling CursorgetBlob() It returns a byte array

If the table entry is a content URI you should never try to open and read the file directly (for one thing

permissions problems can make this fail) Instead you should call ContentResolveropenInputStream()

to get an InputStream object that you can use to read the data

Modifying Data

Data kept by a content provider can be modified by

Adding new records

Adding new values to existing records

Batch updating existing records

Deleting records

All data modification is accomplished using ContentResolver methods Some content providers require

a more restrictive permission for writing data than they do for reading it If you dont have permission to

write to a content provider the ContentResolver methods will fail

Adding records

To add a new record to a content provider first set up a map of key-value pairs in a ContentValues

object where each key matches the name of a column in the content provider and the value is the

desired value for the new record in that column Then call ContentResolverinsert() and pass it the URI

of the provider and the ContentValues map This method returns the full URI of the new record mdash that

is the providers URI with the appended ID for the new record You can then use this URI to query and

get a Cursor over the new record and to further modify the record Heres an example

import androidproviderContactsPeople import androidcontentContentResolver import androidcontentContentValues ContentValues values = new ContentValues() Add Abraham Lincoln to contacts and make him a favorite valuesput(PeopleNAME Abraham Lincoln) 1 = the new contact is added to favorites 0 = the new contact is not added to favorites valuesput(PeopleSTARRED 1) Uri uri = getContentResolver()insert(PeopleCONTENT_URI values)

Adding new values

Once a record exists you can add new information to it or modify existing information For example

the next step in the example above would be to add contact information mdash like a phone number or an

IM or e-mail address mdash to the new entry

The best way to add to a record in the Contacts database is to append the name of the table where the

new data goes to the URI for the record then use the amended URI to add the new data values Each

Contacts table exposes a name for this purpose as a CONTENT_DIRECTORY constant The following

code continues the previous example by adding a phone number and e-mail address for the record

just created

Uri phoneUri = null Uri emailUri = null Add a phone number for Abraham Lincoln Begin with the URI for the new record just returned by insert() it ends with the _ID of the new record so we dont have to add the ID ourselves Then append the designation for the phone table to this URI and use the resulting URI to insert the phone number phoneUri = UriwithAppendedPath(uri PeoplePhonesCONTENT_DIRECTORY) valuesclear() valuesput(PeoplePhonesTYPE PeoplePhonesTYPE_MOBILE) valuesput(PeoplePhonesNUMBER 1233214567) getContentResolver()insert(phoneUri values) Now add an email address in the same way emailUri = UriwithAppendedPath(uri PeopleContactMethodsCONTENT_DIRECTORY) valuesclear() ContactMethodsKIND is used to distinguish different kinds of contact methods such as email IM etc valuesput(PeopleContactMethodsKIND ContactsKIND_EMAIL) valuesput(PeopleContactMethodsDATA testexamplecom) valuesput(PeopleContactMethodsTYPE PeopleContactMethodsTYPE_HOME) getContentResolver()insert(emailUri values)

You can place small amounts of binary data into a table by calling the version of ContentValuesput()

that takes a byte array That would work for a small icon-like image or a short audio clip for example

However if you have a large amount of binary data to add such as a photograph or a complete song

put a content URI for the data in the table and call ContentResolveropenOutputStream() with the files

URI (That causes the content provider to store the data in a file and record the file path in a hidden

field of the record)

In this regard the MediaStore content provider the main provider that dispenses image audio and

video data employs a special convention The same URI that is used with query() or managedQuery()

to get meta-information about the binary data (such as the caption of a photograph or the date it was

taken) is used with openInputStream() to get the data itself Similarly the same URI that is used with

insert() to put meta-information into a MediaStore record is used with openOutputStream() to place the

binary data there The following code snippet illustrates this convention

import androidproviderMediaStoreImagesMedia import androidcontentContentValues import javaioOutputStream Save the name and description of an image in a ContentValues map ContentValues values = new ContentValues(3) valuesput(MediaDISPLAY_NAME road_trip_1) valuesput(MediaDESCRIPTION Day 1 trip to Los Angeles) valuesput(MediaMIME_TYPE imagejpeg) Add a new record without the bitmap but with the values just set insert() returns the URI of the new record Uri uri = getContentResolver()insert(MediaEXTERNAL_CONTENT_URI values) Now get a handle to the file for that record and save the data into it Here sourceBitmap is a Bitmap object representing the file to save to the database try OutputStream outStream = getContentResolver()openOutputStream(uri) sourceBitmapcompress(BitmapCompressFormatJPEG 50 outStream) outStreamclose() catch (Exception e) Loge(TAG exception while writing image e)

Batch updating records

To batch update a group of records (for example to change NY to New York in all fields) call the

ContentResolverupdate() method with the columns and values to change

Deleting a record

To delete a single record call ContentResolverdelete() with the URI of a specific row

To delete multiple rows call ContentResolverdelete() with the URI of the type of record to delete (for

example androidproviderContactsPeopleCONTENT_URI) and an SQL WHERE clause defining

which rows to delete (Caution Be sure to include a valid WHERE clause if youre deleting a general

type or you risk deleting more records than you intended)

Creating a Content Provider

To create a content provider you must

Set up a system for storing the data Most content providers store their data using Androids file

storage methods or SQLite databases but you can store your data any way you want Android

provides the SQLiteOpenHelper class to help you create a database and SQLiteDatabase to manage

it

Extend the ContentProvider class to provide access to the data

Declare the content provider in the manifest file for your application (AndroidManifestxml)

The following sections have notes on the last two of these tasks

Extending the ContentProvider class

You define a ContentProvider subclass to expose your data to others using the conventions expected

by ContentResolver and Cursor objects Principally this means implementing six abstract methods

declared in the ContentProvider class

query()

insert()

update()

delete()

getType()

onCreate()

The query() method must return a Cursor object that can iterate over the requested data Cursor itself

is an interface but Android provides some ready-made Cursor objects that you can use For example

SQLiteCursor can iterate over data stored in an SQLite database You get the Cursor object by calling

any of the SQLiteDatabase classs query() methods There are other Cursor implementations mdash such

as MatrixCursor mdash for data not stored in a database

Because these ContentProvider methods can be called from various ContentResolver objects in

different processes and threads they must be implemented in a thread-safe manner

As a courtesy you might also want to call ContentResolvernotifyChange() to notify listeners when

there are modifications to the data

Beyond defining the subclass itself there are other steps you should take to simplify the work of clients

and make the class more accessible

Define a public static final Uri named CONTENT_URI This is the string that represents the full content

URI that your content provider handles You must define a unique string for this value The best

solution is to use the fully-qualified class name of the content provider (made lowercase) So for

example the URI for a TransportationProvider class could be defined as follows

public static final Uri CONTENT_URI = Uriparse(contentcomexamplecodelabtransportationprovider)

If the provider has subtables also define CONTENT_URI constants for each of the subtables These

URIs should all have the same authority (since that identifies the content provider) and be

distinguished only by their paths For example

contentcomexamplecodelabtransportationprovidertrain

contentcomexamplecodelabtransportationproviderairdomestic

contentcomexamplecodelabtransportationproviderairinternational

For an overview of content URIs see the Content URI Summary at the end of this document

Define the column names that the content provider will return to clients If you are using an underlying

database these column names are typically identical to the SQL database column names they

represent Also define public static String constants that clients can use to specify the columns in

queries and other instructions

Be sure to include an integer column named _id (with the constant _ID) for the IDs of the records

You should have this field whether or not you have another field (such as a URL) that is also unique

among all records If youre using the SQLite database the _ID field should be the following type

INTEGER PRIMARY KEY AUTOINCREMENT

The AUTOINCREMENT descriptor is optional But without it SQLite increments an ID counter field to

the next number above the largest existing number in the column If you delete the last row the next

row added will have the same ID as the deleted row AUTOINCREMENT avoids this by having SQLite

increment to the next largest value whether deleted or not

Carefully document the data type of each column Clients need this information to read the data

If you are handling a new data type you must define a new MIME type to return in your

implementation of ContentProvidergetType() The type depends in part on whether or not the content

URI submitted to getType() limits the request to a specific record Theres one form of the MIME type

for a single record and another for multiple records Use the Uri methods to help determine what is

being requested Here is the general format for each type

o For a single record vndandroidcursoritemvndyourcompanynamecontenttype

For example a request for train record 122 like this URI

contentcomexampletransportationprovidertrains122

might return this MIME type

vndandroidcursoritemvndexamplerail

o For multiple records vndandroidcursordirvndyourcompanynamecontenttype

For example a request for all train records like the following URI

contentcomexampletransportationprovidertrains

might return this MIME type

vndandroidcursordirvndexamplerail

If you are exposing byte data thats too big to put in the table itself mdash such as a large bitmap file mdash the

field that exposes the data to clients should actually contain a content URI string This is the field that

gives clients access to the data file The record should also have another field named _data that lists

the exact file path on the device for that file This field is not intended to be read by the client but by

the ContentResolver The client will call ContentResolveropenInputStream() on the user-facing field

holding the URI for the item The ContentResolver will request the _data field for that record and

because it has higher permissions than a client it should be able to access that file directly and return

a read wrapper for the file to the client

For an example of a private content provider implementation see the NodePadProvider class in the

Notepad sample application that ships with the SDK

Declaring the content provider

To let the Android system know about the content provider youve developed declare it with a

ltprovidergt element in the applications AndroidManifestxml file Content providers that are not

declared in the manifest are not visible to the Android system

The name attribute is the fully qualified name of the ContentProvider subclass The authorities attribute

is the authority part of the content URI that identifies the provider For example if the ContentProvider

subclass is AutoInfoProvider the ltprovidergt element might look like this

ltprovider androidname=comexampleautosAutoInfoProvider androidauthorities=comexampleautosautoinfoprovider gt ltprovidergt

Note that the authorities attribute omits the path part of a content URI For example if

AutoInfoProvider controlled subtables for different types of autos or different manufacturers

contentcomexampleautosautoinfoproviderhonda

contentcomexampleautosautoinfoprovidergmcompact

contentcomexampleautosautoinfoprovidergmsuv

those paths would not be declared in the manifest The authority is what identifies the provider not the

path your provider can interpret the path part of the URI in any way you choose

Other ltprovidergt attributes can set permissions to read and write data provide for an icon and text

that can be displayed to users enable and disable the provider and so on Set the multiprocess

attribute to true if data does not need to be synchronized between multiple running versions of the

content provider This permits an instance of the provider to be created in each client process

eliminating the need to perform IPC

Content URI Summary

Here is a recap of the important parts of a content URI

A Standard prefix indicating that the data is controlled by a content provider Its never modified

B The authority part of the URI it identifies the content provider For third-party applications this should

be a fully-qualified class name (reduced to lowercase) to ensure uniqueness The authority is declared

in the ltprovidergt elements authorities attribute

ltprovider androidname=TransportationProvider androidauthorities=comexampletransportationprovider gt

C The path that the content provider uses to determine what kind of data is being requested This can be

zero or more segments long If the content provider exposes only one type of data (only trains for

example) it can be absent If the provider exposes several types including subtypes it can be several

segments long mdash for example landbus landtrain seaship and seasubmarine to give four

possibilities

D The ID of the specific record being requested if any This is the _ID value of the requested record If

the request is not limited to a single record this segment and the trailing slash are omitted

contentcomexampletransportationprovidertrains

Intent and intent filters

Three of the core components of an application mdash activities services and broadcast receivers mdash 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 mdash 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 ContextstartActivity() or ActivitystartActivityForResult() to launch an

activity or get an existing activity to do something new (It can also be passed to ActivitysetResult() to

return information to the activity that called startActivityForResult())

An Intent object is passed to ContextstartService() to initiate a service or deliver new instructions to an

ongoing service Similarly an intent can be passed to ContextbindService() to establish a connection

between the calling component and a target service It can optionally initiate the service if its not

already running

Intent objects passed to any of the broadcast methods (such as ContextsendBroadcast()

ContextsendOrderedBroadcast() or ContextsendStickyBroadcast()) 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 mdash how it resolves which component should receive an intent message For

intents that dont explicitly name a target component this process involves testing the Intent object

against intent filters associated with potential targets

Intent Objects

An Intent object is a bundle of information It contains information of interest to the component that

receives the intent (such as the action to be taken and the data to act on) plus information of interest to

the Android system (such as the category of component that should handle the intent and instructions

on how to launch a target activity) Principally it can contain the following

Component name

The name of the component that should handle the intent This field is a ComponentName

object mdash a combination of the fully qualified class name of the target component (for example

comexampleprojectappFreneticActivity) and the package name set in the manifest file of the

application where the component resides (for example comexampleproject) The package

part of the component name and the package name set in the manifest do not necessarily have

to match

The component name is optional If it is set the Intent object is delivered to an instance of the

designated class If it is not set Android uses other information in the Intent object to locate a

suitable target mdash see Intent Resolution later in this document

The component name is set by setComponent() setClass() or setClassName() and read by

getComponent()

Action

A string naming the action to be performed mdash or in the case of broadcast intents the action

that took place and is being reported The Intent class defines a number of action constants

including these

Constant Target

component

Action

ACTION_CALL activity Initiate a phone call

ACTION_EDIT activity Display data for the user to edit

ACTION_MAIN activity Start up as the initial activity of a task

with no data input and no returned

output

ACTION_SYNC activity Synchronize data on a server with

data on the mobile device

ACTION_BATTERY_LOW broadcast

receiver

A warning that the battery is low

ACTION_HEADSET_PLUG broadcast

receiver

A headset has been plugged into the

device or unplugged from it

ACTION_SCREEN_ON broadcast

receiver

The screen has been turned on

ACTION_TIMEZONE_CHANGED broadcast

receiver

The setting for the time zone has

changed

See the Intent class description for a list of pre-defined constants for generic actions Other

actions are defined elsewhere in the Android API You can also define your own action strings

for activating the components in your application Those you invent should include the

application package as a prefix mdash for example comexampleprojectSHOW_COLOR

The action largely determines how the rest of the intent is structured mdash particularly the data and

extras fields mdash much as a method name determines a set of arguments and a return value For

this reason its a good idea to use action names that are as specific as possible and to couple

them tightly to the other fields of the intent In other words instead of defining an action in

isolation define an entire protocol for the Intent objects your components can handle

The action in an Intent object is set by the setAction() method and read by getAction()

Data

The URI of the data to be acted on and the MIME type of that data Different actions are paired

with different kinds of data specifications For example if the action field is ACTION_EDIT the

data field would contain the URI of the document to be displayed for editing If the action is

ACTION_CALL the data field would be a tel URI with the number to call Similarly if the action

is ACTION_VIEW and the data field is an http URI the receiving activity would be called upon

to download and display whatever data the URI refers to

When matching an intent to a component that is capable of handling the data its often

important to know the type of data (its MIME type) in addition to its URI For example a

component able to display image data should not be called upon to play an audio file

In many cases the data type can be inferred from the URI mdash particularly content URIs which

indicate that the data is located on the device and controlled by a content provider (see the

separate discussion on content providers) But the type can also be explicitly set in the Intent

object The setData() method specifies data only as a URI setType() specifies it only as a

MIME type and setDataAndType() specifies it as both a URI and a MIME type The URI is read

by getData() and the type by getType()

Category

A string containing additional information about the kind of component that should handle the

intent Any number of category descriptions can be placed in an Intent object As it does for

actions the Intent class defines several category constants including these

Constant Meaning

CATEGORY_BROWSABLE The target activity can be safely invoked by the browser to

display data referenced by a link mdash for example an image or

an e-mail message

CATEGORY_GADGET The activity can be embedded inside of another activity that

hosts gadgets

CATEGORY_HOME The activity displays the home screen the first screen the

user sees when the device is turned on or when the HOME

key is pressed

CATEGORY_LAUNCHER The activity can be the initial activity of a task and is listed in

the top-level application launcher

CATEGORY_PREFERENCE The target activity is a preference panel

See the Intent class description for the full list of categories

The addCategory() method places a category in an Intent object removeCategory() deletes a

category previously added and getCategories() gets the set of all categories currently in the

object

Extras

Key-value pairs for additional information that should be delivered to the component handling

the intent Just as some actions are paired with particular kinds of data URIs some are paired

with particular extras For example an ACTION_TIMEZONE_CHANGED intent has a time-

zone extra that identifies the new time zone and ACTION_HEADSET_PLUG has a state

extra indicating whether the headset is now plugged in or unplugged as well as a name extra

for the type of headset If you were to invent a SHOW_COLOR action the color value would be

set in an extra key-value pair

The Intent object has a series of put() methods for inserting various types of extra data and a

similar set of get() methods for reading the data These methods parallel those for Bundle

objects In fact the extras can be installed and read as a Bundle using the putExtras() and

getExtras() methods

Flags

Flags of various sorts Many instruct the Android system how to launch an activity (for example

which task the activity should belong to) and how to treat it after its launched (for example

whether it belongs in the list of recent activities) All these flags are defined in the Intent class

The Android system and the applications that come with the platform employ Intent objects both to

send out system-originated broadcasts and to activate system-defined components To see how to

structure an intent to activate a system component consult the list of intents in the reference

Intent Resolution

Intents can be divided into two groups

Explicit intents designate the target component by its name (the component name field mentioned

earlier has a value set) Since component names would generally not be known to developers of other

applications explicit intents are typically used for application-internal messages mdash such as an activity

starting a subordinate service or launching a sister activity

Implicit intents do not name a target (the field for the component name is blank) Implicit intents are

often used to activate components in other applications

Android delivers an explicit intent to an instance of the designated target class Nothing in the Intent

object other than the component name matters for determining which component should get the intent

A different strategy is needed for implicit intents In the absence of a designated target the Android

system must find the best component (or components) to handle the intent mdash a single activity or

service to perform the requested action or the set of broadcast receivers to respond to the broadcast

announcement It does so by comparing the contents of the Intent object to intent filters structures

associated with components that can potentially receive intents Filters advertise the capabilities of a

component and delimit the intents it can handle They open the component to the possibility of

receiving implicit intents of the advertised type If a component does not have any intent filters it can

receive only explicit intents A component with filters can receive both explicit and implicit intents

Only three aspects of an Intent object are consulted when the object is tested against an intent filter

action

data (both URI and data type)

category

The extras and flags play no part in resolving which component receives an intent

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 mdash but only unwanted implicit intents (those that dont 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

components 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 mdash 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 Pads filters are described in the Note Pad Example

section later)

Filters and security

An intent filter cannot be relied on for security While it opens a component to receiving only certain

kinds of implicit intents it does nothing to prevent explicit intents from targeting the component Even

though a filter restricts the intents a component will be asked to handle to certain actions and data

sources someone could always put together an explicit intent with a different action and data source

and name the component as the target

An intent filter is an instance of the IntentFilter class However since the Android system must know

about the capabilities of a component before it can launch that component intent filters are generally

not set up in Java code but in the applications manifest file (AndroidManifestxml) as ltintent-filtergt

elements (The one exception would be filters for broadcast receivers that are registered dynamically

by calling ContextregisterReceiver() they are directly created as IntentFilter objects)

A filter has fields that parallel the action data and category fields of an Intent object An implicit intent

is tested against the filter in all three areas To be delivered to the component that owns the filter it

must pass all three tests If it fails even one of them the Android system wont deliver it to the

component mdash at least not on the basis of that filter However since a component can have multiple

intent filters an intent that does not pass through one of a components filters might make it through on

another

Each of the three tests is described in detail below

Action test

An ltintent-filtergt element in the manifest file lists actions as ltactiongt subelements For

example

ltintent-filter gt ltaction androidname=comexampleprojectSHOW_CURRENT gt ltaction androidname=comexampleprojectSHOW_RECENT gt ltaction androidname=comexampleprojectSHOW_PENDING gt ltintent-filtergt

As the example shows while an Intent object names just a single action a filter may list more

than one The list cannot be empty a filter must contain at least one ltactiongt element or it will

block all intents

To pass this test the action specified in the Intent object must match one of the actions listed in

the filter If the object or the filter does not specify an action the results are as follows

If the filter fails to list any actions there is nothing for an intent to match so all intents fail the

test No intents can get through the filter

On the other hand an Intent object that doesnt specify an action automatically passes the test

mdash as long as the filter contains at least one action

Category test

An ltintent-filtergt element also lists categories as subelements For example

ltintent-filter gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryBROWSABLE gt ltintent-filtergt

Note that the constants described earlier for actions and categories are not used in the manifest

file The full string values are used instead For instance the

androidintentcategoryBROWSABLE string in the example above corresponds to the

CATEGORY_BROWSABLE constant mentioned earlier in this document Similarly the string

androidintentactionEDIT corresponds to the ACTION_EDIT constant

For an intent to pass the category test every category in the Intent object must match a

category in the filter The filter can list additional categories but it cannot omit any that are in the

intent

In principle therefore an Intent object with no categories should always pass this test

regardless of whats in the filter Thats mostly true However with one exception Android treats

all implicit intents passed to startActivity() as if they contained at least one category

androidintentcategoryDEFAULT (the CATEGORY_DEFAULT constant) Therefore activities

that are willing to receive implicit intents must include androidintentcategoryDEFAULT in

their intent filters (Filters with androidintentactionMAIN and

androidintentcategoryLAUNCHER settings are the exception They mark activities that begin

new tasks and that are represented on the launcher screen They can include

androidintentcategoryDEFAULT in the list of categories but dont need to) See Using intent

matching later for more on these filters)

Data test

Like the action and categories the data specification for an intent filter is contained in a

subelement And as in those cases the subelement can appear multiple times or not at all For

example

ltintent-filter gt ltdata androidmimeType=videompeg androidscheme=http gt ltdata androidmimeType=audiompeg androidscheme=http gt ltintent-filtergt

Each ltdatagt element can specify a URI and a data type (MIME media type) There are

separate attributes mdash scheme host port and path mdash for each part of the URI

schemehostportpath

For example in the following URI

contentcomexampleproject200foldersubfolderetc

the scheme is content the host is comexampleproject the port is 200 and the path is

foldersubfolderetc The host and port together constitute the URI authority if a host is not

specified the port is ignored

Each of these attributes is optional but they are not independent of each other For an authority

to be meaningful a scheme must also be specified For a path to be meaningful both a scheme

and an authority must be specified

When the URI in an Intent object is compared to a URI specification in a filter its compared

only to the parts of the URI actually mentioned in the filter For example if a filter specifies only

a scheme all URIs with that scheme match the filter If a filter specifies a scheme and an

authority but no path all URIs with the same scheme and authority match regardless of their

paths If a filter specifies a scheme an authority and a path only URIs with the same scheme

authority and path match However a path specification in the filter can contain wildcards to

require only a partial match of the path

The type attribute of a ltdatagt element specifies the MIME type of the data Its more common in

filters than a URI Both the Intent object and the filter can use a wildcard for the subtype field

mdash for example text or audio mdash indicating any subtype matches

The data test compares both the URI and the data type in the Intent object to a URI and data

type specified in the filter The rules are as follows

a An Intent object that contains neither a URI nor a data type passes the test only if the filter

likewise does not specify any URIs or data types

b An Intent object that contains a URI but no data type (and a type cannot be inferred from the

URI) passes the test only if its URI matches a URI in the filter and the filter likewise does not

specify a type This will be the case only for URIs like mailto and tel that do not refer to actual

data

c An Intent object that contains a data type but not a URI passes the test only if the filter lists the

same data type and similarly does not specify a URI

d An Intent object that contains both a URI and a data type (or a data type can be inferred from

the URI) passes the data type part of the test only if its type matches a type listed in the filter It

passes the URI part of the test either if its URI matches a URI in the filter or if it has a content

or file URI and the filter does not specify a URI In other words a component is presumed to

support content and file data if its filter lists only a data type

If an intent can pass through the filters of more than one activity or service the user may be asked

which component to activate An exception is raised if no target can be found

Common cases

The last rule shown above for the data test rule (d) reflects the expectation that components are able

to get local data from a file or content provider Therefore their filters can list just a data type and do

not need to explicitly name the content and file schemes This is a typical case A ltdatagt element like

the following for example tells Android that the component can get image data from a content

provider and display it

ltdata androidmimeType=image gt

Since most available data is dispensed by content providers filters that specify a data type but not a

URI are perhaps the most common

Another common configuration is filters with a scheme and a data type For example a ltdatagt

element like the following tells Android that the component can get video data from the network and

display it

ltdata androidscheme=http androidtype=video gt

Consider for example what the browser application does when the user follows a link on a web page

It first tries to display the data (as it could if the link was to an HTML page) If it cant display the data it

puts together an implicit intent with the scheme and data type and tries to start an activity that can do

the job If there are no takers it asks the download manager to download the data That puts it under

the control of a content provider so a potentially larger pool of activities (those with filters that just

name a data type) can respond

Most applications also have a way to start fresh without a reference to any particular data Activities

that can initiate applications have filters with androidintentactionMAIN specified as the action If

they are to be represented in the application launcher they also specify the

androidintentcategoryLAUNCHER category

ltintent-filter gt ltaction androidname=code androidintentactionMAIN gt ltcategory androidname=code androidintentcategoryLAUNCHER gt ltintent-filtergt

Using intent matching

Intents are matched against intent filters not only to discover a target component to activate but also

to discover something about the set of components on the device For example the Android system

populates the application launcher the top-level screen that shows the applications that are available

for the user to launch by finding all the activities with intent filters that specify the

androidintentactionMAIN action and androidintentcategoryLAUNCHER category (as illustrated

in the previous section) It then displays the icons and labels of those activities in the launcher

Similarly it discovers the home screen by looking for the activity with androidintentcategoryHOME

in its filter

Your application can use intent matching is a similar way The PackageManager has a set of query()

methods that return all components that can accept a particular intent and a similar series of

resolve() methods that determine the best component to respond to an intent For example

queryIntentActivities() returns a list of all activities that can perform the intent passed as an argument

and queryIntentServices() returns a similar list of services Neither method activates the components

they just list the ones that can respond Theres a similar method queryBroadcastReceivers() for

broadcast receivers

Note Pad Example

The Note Pad sample application enables users to browse through a list of notes view details about

individual items in the list edit the items and add a new item to the list This section looks at the intent

filters declared in its manifest file (If youre working offline in the SDK you can find all the source files

for this sample application including its manifest file at ltsdkgtsamplesNotePadindexhtml If youre

viewing the documentation online the source files are in the Tutorials and Sample Code section here)

In its manifest file the Note Pad application declares three activities each with at least one intent filter

It also declares a content provider that manages the note data Here is the manifest file in its entirety

ltmanifest xmlnsandroid=httpschemasandroidcomapkresandroid package=comexampleandroidnotepadgt ltapplication androidicon=drawableapp_notes androidlabel=stringapp_name gt ltprovider androidname=NotePadProvider androidauthorities=comgoogleproviderNotePad gt ltactivity androidname=NotesList androidlabel=stringtitle_notes_listgt ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltactivity androidname=NoteEditor androidtheme=androidstyleThemeLight androidlabel=stringtitle_note gt ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltactivitygt

ltactivity androidname=TitleEditor androidlabel=stringtitle_edit_title androidtheme=androidstyleThemeDialoggt ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltapplicationgt ltmanifestgt

The first activity NotesList is distinguished from the other activities by the fact that it operates on a

directory of notes (the note list) rather than on a single note It would generally serve as the initial user

interface into the application It can do three things as described by its three intent filters

1 ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt

This filter declares the main entry point into the Note Pad application The standard MAIN action is an

entry point that does not require any other information in the Intent (no data specification for example)

and the LAUNCHER category says that this entry point should be listed in the application launcher

2 ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

This filter declares the things that the activity can do on a directory of notes It can allow the user to

view or edit the directory (via the VIEW and EDIT actions) or to pick a particular note from the

directory (via the PICK action)

The mimeType attribute of the ltdatagt element specifies the kind of data that these actions operate on

It indicates that the activity can get a Cursor over zero or more items (vndandroidcursordir) from a

content provider that holds Note Pad data (vndgooglenote) The Intent object that launches the

activity would include a content URI specifying the exact data of this type that the activity should open

Note also the DEFAULT category supplied in this filter Its there because the ContextstartActivity()

and ActivitystartActivityForResult() methods treat all intents as if they contained the DEFAULT

category mdash with just two exceptions

o Intents that explicitly name the target activity

o Intents consisting of the MAIN action and LAUNCHER category

Therefore the DEFAULT category is required for all filters mdash except for those with the MAIN action

and LAUNCHER category (Intent filters are not consulted for explicit intents)

3 ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

This filter describes the activitys ability to return a note selected by the user without requiring any

specification of the directory the user should choose from The GET_CONTENT action is similar to the

PICK action In both cases the activity returns the URI for a note selected by the user (In each case

its returned to the activity that called startActivityForResult() to start the NoteList activity) Here

however the caller specifies the type of data desired instead of the directory of data the user will be

picking from

The data type vndandroidcursoritemvndgooglenote indicates the type of data the activity can

return mdash a URI for a single note From the returned URI the caller can get a Cursor for exactly one

item (vndandroidcursoritem) from the content provider that holds Note Pad data (vndgooglenote)

In other words for the PICK action in the previous filter the data type indicates the type of data the

activity could display to the user For the GET_CONTENT filter it indicates the type of data the activity

can return to the caller

Given these capabilities the following intents will resolve to the NotesList activity

action androidintentactionMAIN

Launches the activity with no data specified

action androidintentactionMAIN

category androidintentcategoryLAUNCHER

Launches the activity with no data selected specified This is the actual intent used by the

Launcher to populate its top-level list All activities with filters that match this action and

category are added to the list

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of all the notes under

contentcomgoogleproviderNotePadnotes The user can then browse through the list and

get information about the items in it

action androidintentactionPICK

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of the notes under

contentcomgoogleproviderNotePadnotes The user can then pick a note from the list and

the activity will return the URI for that item back to the activity that started the NoteList activity

action androidintentactionGET_CONTENT

data type vndandroidcursoritemvndgooglenote

Asks the activity to supply a single item of Note Pad data

The second activity NoteEditor shows users a single note entry and allows them to edit it It can do

two things as described by its two intent filters

1 ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The first primary purpose of this activity is to enable the user to interact with a single note ampmdash to

either VIEW the note or EDIT it (The EDIT_NOTE category is a synonym for EDIT) The intent would

contain the URI for data matching the MIME type vndandroidcursoritemvndgooglenote mdash that is

the URI for a single specific note It would typically be a URI that was returned by the PICK or

GET_CONTENT actions of the NoteList activity

As before this filter lists the DEFAULT category so that the activity can be launched by intents that

dont explicitly specify the NoteEditor class

2 ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

The secondary purpose of this activity is to enable the user to create a new note which it will INSERT

into an existing directory of notes The intent would contain the URI for data matching the MIME type

vndandroidcursordirvndgooglenote mdash that is the URI for the directory where the note should be

placed

Given these capabilities the following intents will resolve to the NoteEditor activity

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID (For details on how content

URIs specify individual members of a group see Content Providers)

action androidintentactionEDIT

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID and to let the user edit it If

the user saves the changes the activity updates the data for the note in the content provider

action androidintentactionINSERT

data contentcomgoogleproviderNotePadnotes

Asks the activity to create a new empty note in the notes list at

contentcomgoogleproviderNotePadnotes and allow the user to edit it If the user saves the

note its URI is returned to the caller

The last activity TitleEditor enables the user to edit the title of a note This could be implemented by

directly invoking the activity (by explicitly setting its component name in the Intent) without using an

intent filter But here we take the opportunity to show how to publish alternative operations on existing

data

ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The single intent filter for this activity uses a custom action called

comandroidnotepadactionEDIT_TITLE It must be invoked on a specific note (data type

vndandroidcursoritemvndgooglenote) like the previous VIEW and EDIT actions However here the

activity displays the title contained in the note data not the content of the note itself

In addition to supporting the usual DEFAULT category the title editor also supports two other standard

categories ALTERNATIVE and SELECTED_ALTERNATIVE These categories identify activities that

can be presented to users in a menu of options (much as the LAUNCHER category identifies activities

that should be presented to user in the application launcher) Note that the filter also supplies an

explicit label (via androidlabel=stringresolve_title) to better control what users see when

presented with this activity as an alternative action to the data they are currently viewing (For more

information on these categories and building options menus see the

PackageManagerqueryIntentActivityOptions() and MenuaddIntentOptions() methods)

Given these capabilities the following intent will resolve to the TitleEditor activity

action comandroidnotepadactionEDIT_TITLE

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the title associated with note ID and allow the user to edit the title

Processes and Threads

When an application component starts and the application does not have any other components

running the Android system starts a new Linux process for the application with a single thread of

execution By default all components of the same application run in the same process and thread

(called the main thread) If an application component starts and there already exists a process for

that application (because another component from the application exists) then the component is

started within that process and uses the same thread of execution However you can arrange for

different components in your application to run in separate processes and you can create additional

threads for any process

This document discusses how processes and threads work in an Android application

Processes

By default all components of the same application run in the same process and most applications

should not change this However if you find that you need to control which process a certain

component belongs to you can do so in the manifest file

The manifest entry for each type of component elementmdashltactivitygt ltservicegt ltreceivergt and

ltprovidergtmdashsupports an androidprocess attribute that can specify a process in which that component

should run You can set this attribute so that each component runs in its own process or so that some

components share a process while others do not You can also set androidprocess so that

components of different applications run in the same processmdashprovided that the applications share the

same Linux user ID and are signed with the same certificates

The ltapplicationgt element also supports an androidprocess attribute to set a default value that

applies to all components

Android might 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 thats killed are consequently destroyed A process is started again for those components

when theres again work for them to do

When deciding which processes to kill the Android system weighs their relative importance to the

user For example it more readily shuts down a process hosting activities that are no longer visible on

screen compared to a process hosting visible activities The decision whether to terminate a process

therefore depends on the state of the components running in that process The rules used to decide

which processes to terminate is discussed below

Process lifecycle

The Android system tries to maintain an application process for as long as possible but eventually

needs to remove old processes to reclaim memory for new or more important processes To determine

which processes to keep and which to kill the system places each process into an importance

hierarchy based on the components running in the process and the state of those components

Processes with the lowest importance are eliminated first then those with the next lowest importance

and so on as necessary to recover system resources

There are five levels in the importance hierarchy The following list presents the different types of

processes in order of importance (the first process is most important and is killed last)

1 Foreground process

A process that is required for what the user is currently doing A process is considered to be in the

foreground if any of the following conditions are true

o It hosts an Activity that the user is interacting with (the Activitys onResume() method has been called)

o It hosts a Service thats bound to the activity that the user is interacting with

o It hosts a Service thats running in the foregroundmdashthe service has called startForeground()

o It hosts a Service thats executing one of its lifecycle callbacks (onCreate() onStart() or onDestroy())

o It hosts a BroadcastReceiver thats executing its onReceive() method

Generally only a few foreground processes exist at any given time They are killed only as a last

resortmdashif memory is so low that they cannot all continue to run Generally at that point the device has

reached a memory paging state so killing some foreground processes is required to keep the user

interface responsive

2 Visible process

A process that doesnt have any foreground components but still can affect what the user sees on

screen A process is considered to be visible if either of the following conditions are true

o It hosts an Activity that is not in the foreground but is still visible to the user (its onPause() method has

been called) This might occur for example if the foreground activity started a dialog which allows the

previous activity to be seen behind it

o It hosts a Service thats bound to a visible (or foreground) activity

A visible process is considered extremely important and will not be killed unless doing so is required to

keep all foreground processes running

3 Service process

A process that is running a service that has been started with the startService() method and does not

fall into either of the two higher categories Although service processes are not directly tied to anything

the user sees they are generally doing things that the user cares about (such as playing music in the

background or downloading data on the network) so the system keeps them running unless theres

not enough memory to retain them along with all foreground and visible processes

4 Background process

A process holding an activity thats not currently visible to the user (the activitys onStop() method has

been called) These processes have no direct impact on the user experience and the system can kill

them at any time to reclaim memory for a foreground visible or service process Usually there are

many background processes running so they are kept in an LRU (least recently used) list to ensure

that the process with the activity that was most recently seen by the user is the last to be killed If an

activity implements its lifecycle methods correctly and saves its current state killing its process will not

have a visible effect on the user experience because when the user navigates back to the activity the

activity restores all of its visible state See the Activities document for information about saving and

restoring state

5 Empty process

A process that doesnt hold any active application components The only reason to keep this kind of

process alive is for caching purposes to improve startup time the next time a component needs to run

in it The system often kills these processes in order to balance overall system resources between

process caches and the underlying kernel caches

Android ranks a process at the highest level it can based upon the importance of the components

currently active in the process For example if a process hosts a service and a visible activity the

process is ranked as a visible process not a service process

In addition a processs ranking might be increased because other processes are dependent on itmdasha

process that is serving another process can never be ranked lower than the process it is serving For

example if a content provider in process A is serving a client in process B or if a service in process A

is bound to a component in process B process A is always considered at least as important as

process B

Because a process running a service is ranked higher than a process with background activities an

activity that initiates a long-running operation might do well to start a service for that operation rather

than simply create a worker threadmdashparticularly if the operation will likely outlast the activity For

example an activity thats uploading a picture to a web site should start a service to perform the

upload so that the upload can continue in the background even if the user leaves the activity Using a

service guarantees that the operation will have at least service process priority regardless of what

happens to the activity This is the same reason that broadcast receivers should employ services

rather than simply put time-consuming operations in a thread

Threads

When an application is launched the system creates a thread of execution for the application called

main This thread is very important because it is in charge of dispatching events to the appropriate

user interface widgets including drawing events It is also the thread in which your application interacts

with components from the Android UI toolkit (components from the androidwidget and androidview

packages) As such the main thread is also sometimes called the UI thread

The system does not create a separate thread for each instance of a component All components that

run in the same process are instantiated in the UI thread and system calls to each component are

dispatched from that thread Consequently methods that respond to system callbacks (such as

onKeyDown() to report user actions or a lifecycle callback method) always run in the UI thread of the

process

For instance when the user touches a button on the screen your apps UI thread dispatches the touch

event to the widget which in turn sets its pressed state and posts an invalidate request to the event

queue The UI thread dequeues the request and notifies the widget that it should redraw itself

When your app performs intensive work in response to user interaction this single thread model can

yield poor performance unless you implement your application properly Specifically if everything is

happening in the UI thread performing long operations such as network access or database queries

will block the whole UI When the thread is blocked no events can be dispatched including drawing

events From the users perspective the application appears to hang Even worse if the UI thread is

blocked for more than a few seconds (about 5 seconds currently) the user is presented with the

infamous application not responding (ANR) dialog The user might then decide to quit your

application and uninstall it if they are unhappy

Additionally the Andoid UI toolkit is not thread-safe So you must not manipulate your UI from a

worker threadmdashyou must do all manipulation to your user interface from the UI thread Thus there are

simply two rules to Androids single thread model

1 Do not block the UI thread

2 Do not access the Android UI toolkit from outside the UI thread

Worker threads

Because of the single thread model described above its vital to the responsiveness of your

applications UI that you do not block the UI thread If you have operations to perform that are not

instantaneous you should make sure to do them in separate threads (background or worker

threads)

For example below is some code for a click listener that downloads an image from a separate thread

and displays it in an ImageView

public void onClick(View v) new Thread(new Runnable() public void run() Bitmap b = loadImageFromNetwork(httpexamplecomimagepng) mImageViewsetImageBitmap(b) )start()

At first this seems to work fine because it creates a new thread to handle the network operation

However it violates the second rule of the single-threaded model do not access the Android UI toolkit

from outside the UI threadmdashthis sample modifies the ImageView from the worker thread instead of the

UI thread This can result in undefined and unexpected behavior which can be difficult and time-

consuming to track down

To fix this problem Android offers several ways to access the UI thread from other threads Here is a

list of methods that can help

ActivityrunOnUiThread(Runnable)

Viewpost(Runnable)

ViewpostDelayed(Runnable long)

For example you can fix the above code by using the Viewpost(Runnable) method

public void onClick(View v) new Thread(new Runnable() public void run() final Bitmap bitmap = loadImageFromNetwork(httpexamplecomimagepng) mImageViewpost(new Runnable() public void run() mImageViewsetImageBitmap(bitmap) ) )start()

Now this implementation is thread-safe the network operation is done from a separate thread while

the ImageView is manipulated from the UI thread

However as the complexity of the operation grows this kind of code can get complicated and difficult

to maintain To handle more complex interactions with a worker thread you might consider using a

Handler in your worker thread to process messages delivered from the UI thread Perhaps the best

solution though is to extend the AsyncTask class which simplifies the execution of worker thread

tasks that need to interact with the UI

Using AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface It performs the blocking

operations in a worker thread and then publishes the results on the UI thread without requiring you to

handle threads andor handlers yourself

To use it you must subclass AsyncTask and implement the doInBackground() callback method which

runs in a pool of background threads To update your UI you should implement onPostExecute()

which delivers the result from doInBackground() and runs in the UI thread so you can safely update

your UI You can then run the task by calling execute() from the UI thread

For example you can implement the previous example using AsyncTask this way

public void onClick(View v) new DownloadImageTask()execute(httpexamplecomimagepng) private class DownloadImageTask extends AsyncTaskltString Void Bitmapgt The system calls this to perform work in a worker thread and delivers it the parameters given to AsyncTaskexecute() protected Bitmap doInBackground(String urls) return loadImageFromNetwork(urls[0])

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 10: 03 services

Once requested to stop with stopSelf() or stopService() the system destroys the service as soon as

possible

However if your service handles multiple requests to onStartCommand() concurrently then you

shouldnt stop the service when youre done processing a start request because you might have since

received a new start request (stopping at the end of the first request would terminate the second one)

To avoid this problem you can use stopSelf(int) to ensure that your request to stop the service is

always based on the most recent start request That is when you call stopSelf(int) you pass the ID of

the start request (the startId delivered to onStartCommand()) to which your stop request corresponds

Then if the service received a new start request before you were able to call stopSelf(int) then the ID

will not match and the service will not stop

Caution Its important that your application stops its services when its done working to avoid

wasting system resources and consuming battery power If necessary other components can stop

the service by calling stopService() Even if you enable binding for the service you must always

stop the service yourself if it ever received a call to onStartCommand()

For more information about the lifecycle of a service see the section below about Managing the

Lifecycle of a Service

Creating a Bound Service

A bound service is one that allows application components to bind to it by calling bindService() in order

to create a long-standing connection (and generally does not allow components to start it by calling

startService())

You should create a bound service when you want to interact with the service from activities and other

components in your application or to expose some of your applications functionality to other

applications through interprocess communication (IPC)

To create a bound service you must implement the onBind() callback method to return an IBinder that

defines the interface for communication with the service Other application components can then call

bindService() to retrieve the interface and begin calling methods on the service The service lives only

to serve the application component that is bound to it so when there are no components bound to the

service the system destroys it (you do not need to stop a bound service in the way you must when the

service is started through onStartCommand())

To create a bound service the first thing you must do is define the interface that specifies how a client

can communicate with the service This interface between the service and a client must be an

implementation of IBinder and is what your service must return from the onBind() callback method

Once the client receives the IBinder it can begin interacting with the service through that interface

Multiple clients can bind to the service at once When a client is done interacting with the service it

calls unbindService() to unbind Once there are no clients bound to the service the system destroys

the service

There are multiple ways to implement a bound service and the implementation is more complicated

than a started service so the bound service discussion appears in a separate document about Bound

Services

Sending Notifications to the User

Once running a service can notify the user of events using Toast Notifications or Status Bar

Notifications

A toast notification is a message that appears on the surface of the current window for a moment then

disappears while a status bar notification provides an icon in the status bar with a message which the

user can select in order to take an action (such as start an activity)

Usually a status bar notification is the best technique when some background work has completed

(such as a file completed downloading) and the user can now act on it When the user selects the

notification from the expanded view the notification can start an activity (such as to view the

downloaded file)

See the Toast Notifications or Status Bar Notifications developer guides for more information

Running a Service in the Foreground

A foreground service is a service thats considered to be something the user is actively aware of and

thus not a candidate for the system to kill when low on memory A foreground service must provide a

notification for the status bar which is placed under the Ongoing heading which means that the

notification cannot be dismissed unless the service is either stopped or removed from the foreground

For example a music player that plays music from a service should be set to run in the foreground

because the user is explicitly aware of its operation The notification in the status bar might indicate the

current song and allow the user to launch an activity to interact with the music player

To request that your service run in the foreground call startForeground() This method takes two

parameters an integer that uniquely identifies the notification and the Notification for the status bar

For example

Notification notification = new Notification(Rdrawableicon getText(Rstringticker_text) SystemcurrentTimeMillis()) Intent notificationIntent = new Intent(this ExampleActivityclass) PendingIntent pendingIntent = PendingIntentgetActivity(this 0 notificationIntent 0) notificationsetLatestEventInfo(this getText(Rstringnotification_title) getText(Rstringnotification_message) pendingIntent) startForeground(ONGOING_NOTIFICATION notification)

To remove the service from the foreground call stopForeground() This method takes a boolean

indicating whether to remove the status bar notification as well This method does not stop the service

However if you stop the service while its still running in the foreground then the notification is also

removed

Note The methods startForeground() and stopForeground() were introduced in Android 20 (API

Level 5) In order to run your service in the foreground on older versions of the platform you must

use the previous setForeground() methodmdashsee the startForeground() documentation for

information about how to provide backward compatibility

For more information about notifications see Creating Status Bar Notifications

Managing the Lifecycle of a Service

The lifecycle of a service is much simpler than that of an activity However its even more important

that you pay close attention to how your service is created and destroyed because a service can run

in the background without the user being aware

The service lifecyclemdashfrom when its created to when its destroyedmdashcan follow two different paths

A started service

The service is created when another component calls startService() The service then runs indefinitely

and must stop itself by calling stopSelf() Another component can also stop the service by calling

stopService() When the service is stopped the system destroys it

A bound service

The service is created when another component (a client) calls bindService() The client then

communicates with the service through an IBinder interface The client can close the connection by

calling unbindService() Multiple clients can bind to the same service and when all of them unbind the

system destroys the service (The service does not need to stop itself)

These two paths are not entirely separate That is you can bind to a service that was already started

with startService() For example a background music service could be started by calling startService()

with an Intent that identifies the music to play Later possibly when the user wants to exercise some

control over the player or get information about the current song an activity can bind to the service by

calling bindService() In cases like this stopService() or stopSelf() does not actually stop the service

until all clients unbind

Implementing the lifecycle callbacks

Like an activity a service has lifecycle callback methods that you can implement to monitor changes in

the services state and perform work at the appropriate times The following skeleton service

demonstrates each of the lifecycle methods

Figure 2 The service lifecycle The diagram on the left shows the lifecycle when the service is created

with startService() and the diagram on the right shows the lifecycle when the service is created with

bindService()

public class ExampleService extends Service int mStartMode indicates how to behave if the service is killed IBinder mBinder interface for clients that bind boolean mAllowRebind indicates whether onRebind should be used Override public void onCreate() The service is being created Override public int onStartCommand(Intent intent int flags int startId) The service is starting due to a call to startService() return mStartMode Override public IBinder onBind(Intent intent) A client is binding to the service with bindService() return mBinder Override public boolean onUnbind(Intent intent) All clients have unbound with unbindService()

return mAllowRebind Override public void onRebind(Intent intent) A client is binding to the service with bindService() after onUnbind() has already been called Override public void onDestroy() The service is no longer used and is being destroyed

Note Unlike the activity lifecycle callback methods you are not required to call the superclass

implementation of these callback methods

By implementing these methods you can monitor two nested loops of the services lifecycle

The entire lifetime of a service happens between the time onCreate() is called and the time

onDestroy() returns Like an activity a service does its initial setup in onCreate() and releases all

remaining resources in onDestroy() For example a music playback service could create the thread

where the music will be played in onCreate() then stop the thread in onDestroy()

The onCreate() and onDestroy() methods are called for all services whether theyre created by

startService() or bindService()

The active lifetime of a service begins with a call to either onStartCommand() or onBind() Each

method is handed the Intent that was passed to either startService() or bindService() respectively

If the service is started the active lifetime ends the same time that the entire lifetime ends (the service

is still active even after onStartCommand() returns) If the service is bound the active lifetime ends

when onUnbind() returns

Note Although a started service is stopped by a call to either stopSelf() or stopService() there is

not a respective callback for the service (theres no onStop() callback) So unless the service is

bound to a client the system destroys it when the service is stoppedmdashonDestroy() is the only

callback received

Figure 2 illustrates the typical callback methods for a service Although the figure separates services

that are created by startService() from those created by bindService() keep in mind that any service

no matter how its started can potentially allow clients to bind to it So a service that was initially

started with onStartCommand() (by a client calling startService()) can still receive a call to onBind()

(when a client calls bindService())

For more information about creating a service that provides binding see the Bound Services

document which includes more information about the onRebind() callback method in the section about

Managing the Lifecycle of a Bound Service

Bound Services

A bound service is the server in a client-server interface A bound service allows components (such as

activities) to bind to the service send requests receive responses and even perform interprocess

communication (IPC) A bound service typically lives only while it serves another application

component and does not run in the background indefinitely

This document shows you how to create a bound service including how to bind to the service from

other application components However you should also refer to the Services document for additional

information about services in general such as how to deliver notifications from a service set the

service to run in the foreground and more

The Basics

A bound service is an implementation of the Service class that allows other applications to bind to it

and interact with it To provide binding for a service you must implement the onBind() callback

method This method returns an IBinder object that defines the programming interface that clients can

use to interact with the service

Binding to a Started Service

As discussed in the Services document you can create a service that is both started and bound That

is the service can be started by calling startService() which allows the service to run indefinitely and

also allow a client to bind to the service by calling bindService()

If you do allow your service to be started and bound then when the service has been started the

system does not destroy the service when all clients unbind Instead you must explicitly stop the

service by calling stopSelf() or stopService()

Although you should usually implement either onBind() or onStartCommand() its sometimes

necessary to implement both For example a music player might find it useful to allow its service to run

indefinitely and also provide binding This way an activity can start the service to play some music and

the music continues to play even if the user leaves the application Then when the user returns to the

application the activity can bind to the service to regain control of playback

Be sure to read the section about Managing the Lifecycle of a Bound Service for more information

about the service lifecycle when adding binding to a started service

A client can bind to the service by calling bindService() When it does it must provide an

implementation of ServiceConnection which monitors the connection with the service The

bindService() method returns immediately without a value but when the Android system creates the

connection between the client and service it calls onServiceConnected() on the ServiceConnection to

deliver the IBinder that the client can use to communicate with the service

Multiple clients can connect to the service at once However the system calls your services onBind()

method to retrieve the IBinder only when the first client binds The system then delivers the same

IBinder to any additional clients that bind without calling onBind() again

When the last client unbinds from the service the system destroys the service (unless the service was

also started by startService())

When you implement your bound service the most important part is defining the interface that your

onBind() callback method returns There are a few different ways you can define your services IBinder

interface and the following section discusses each technique

Creating a Bound Service

When creating a service that provides binding you must provide an IBinder that provides the

programming interface that clients can use to interact with the service There are three ways you can

define the interface

Extending the Binder class

If your service is private to your own application and runs in the same process as the client

(which is common) you should create your interface by extending the Binder class and

returning an instance of it from onBind() The client receives the Binder and can use it to directly

access public methods available in either the Binder implementation or even the Service

This is the preferred technique when your service is merely a background worker for your own

application The only reason you would not create your interface this way is because your

service is used by other applications or across separate processes

Using a Messenger

If you need your interface to work across different processes you can create an interface for the

service with a Messenger In this manner the service defines a Handler that responds to

different types of Message objects This Handler is the basis for a Messenger that can then

share an IBinder with the client allowing the client to send commands to the service using

Message objects Additionally the client can define a Messenger of its own so the service can

send messages back

This is the simplest way to perform interprocess communication (IPC) because the Messenger

queues all requests into a single thread so that you dont have to design your service to be

thread-safe

Using AIDL

AIDL (Android Interface Definition Language) performs all the work to decompose objects into

primitives that the operating system can understand and marshall them across processes to

perform IPC The previous technique using a Messenger is actually based on AIDL as its

underlying structure As mentioned above the Messenger creates a queue of all the client

requests in a single thread so the service receives requests one at a time If however you

want your service to handle multiple requests simultaneously then you can use AIDL directly In

this case your service must be capable of multi-threading and be built thread-safe

To use AIDL directly you must create an aidl file that defines the programming interface The

Android SDK tools use this file to generate an abstract class that implements the interface and

handles IPC which you can then extend within your service

Note Most applications should not use AIDL to create a bound service because it may require

multithreading capabilities and can result in a more complicated implementation As such AIDL is

not suitable for most applications and this document does not discuss how to use it for your

service If youre certain that you need to use AIDL directly see the AIDL document

Extending the Binder class

If your service is used only by the local application and does not need to work across processes then

you can implement your own Binder class that provides your client direct access to public methods in

the service

Note This works only if the client and service are in the same application and process which is

most common For example this would work well for a music application that needs to bind an

activity to its own service thats playing music in the background

Heres how to set it up

1 In your service create an instance of Binder that either

o contains public methods that the client can call

o returns the current Service instance which has public methods the client can call

o or returns an instance of another class hosted by the service with public methods the client can call

2 Return this instance of Binder from the onBind() callback method

3 In the client receive the Binder from the onServiceConnected() callback method and make calls to the

bound service using the methods provided

Note The reason the service and client must be in the same application is so the client can cast

the returned object and properly call its APIs The service and client must also be in the same

process because this technique does not perform any marshalling across processes

For example heres a service that provides clients access to methods in the service through a Binder

implementation

public class LocalService extends Service

Binder given to clients

private final IBinder mBinder = new LocalBinder()

Random number generator

private final Random mGenerator = new Random()

Class used for the client Binder Because we know this service always

runs in the same process as its clients we dont need to deal with IPC

public class LocalBinder extends Binder

LocalService getService()

Return this instance of LocalService so clients can call public methods

return LocalServicethis

Override

public IBinder onBind(Intent intent)

return mBinder

method for clients

public int getRandomNumber()

return mGeneratornextInt(100)

The LocalBinder provides the getService() method for clients to retrieve the current instance of

LocalService This allows clients to call public methods in the service For example clients can call

getRandomNumber() from the service

Heres an activity that binds to LocalService and calls getRandomNumber() when a button is clicked

public class BindingActivity extends Activity

LocalService mService

boolean mBound = false

Override

protected void onCreate(Bundle savedInstanceState)

superonCreate(savedInstanceState)

setContentView(Rlayoutmain)

Override

protected void onStart()

superonStart()

Bind to LocalService

Intent intent = new Intent(this LocalServiceclass)

bindService(intent mConnection ContextBIND_AUTO_CREATE)

Override

protected void onStop()

superonStop()

Unbind from the service

if (mBound)

unbindService(mConnection)

mBound = false

Called when a button is clicked (the button in the layout file attaches to

this method with the androidonClick attribute)

public void onButtonClick(View v)

if (mBound)

Call a method from the LocalService

However if this call were something that might hang then this request should

occur in a separate thread to avoid slowing down the activity performance

int num = mServicegetRandomNumber()

ToastmakeText(this number + num ToastLENGTH_SHORT)show()

Defines callbacks for service binding passed to bindService()

private ServiceConnection mConnection = new ServiceConnection()

Override

public void onServiceConnected(ComponentName className

IBinder service)

Weve bound to LocalService cast the IBinder and get LocalService instance

LocalBinder binder = (LocalBinder) service

mService = bindergetService()

mBound = true

Override

public void onServiceDisconnected(ComponentName arg0)

mBound = false

The above sample shows how the client binds to the service using an implementation of

ServiceConnection and the onServiceConnected() callback The next section provides more

information about this process of binding to the service

Note The example above doesnt explicitly unbind from the service but all clients should unbind

at an appropriate time (such as when the activity pauses)

For more sample code see the LocalServicejava class and the LocalServiceActivitiesjava class in

ApiDemos

Using a Messenger

Compared to AIDL

When you need to perform IPC using a Messenger for your interface is simpler than implementing it

with AIDL because Messenger queues all calls to the service whereas a pure AIDL interface sends

simultaneous requests to the service which must then handle multi-threading

For most applications the service doesnt need to perform multi-threading so using a Messenger

allows the service to handle one call at a time If its important that your service be multi-threaded then

you should use AIDL to define your interface

If you need your service to communicate with remote processes then you can use a Messenger to

provide the interface for your service This technique allows you to perform interprocess

communication (IPC) without the need to use AIDL

Heres a summary of how to use a Messenger

The service implements a Handler that receives a callback for each call from a client

The Handler is used to create a Messenger object (which is a reference to the Handler)

The Messenger creates an IBinder that the service returns to clients from onBind()

Clients use the IBinder to instantiate the Messenger (that references the services Handler) which the

client uses to send Message objects to the service

The service receives each Message in its Handlermdashspecifically in the handleMessage() method

In this way there are no methods for the client to call on the service Instead the client delivers

messages (Message objects) that the service receives in its Handler

Heres a simple example service that uses a Messenger interface

public class MessengerService extends Service Command to the service to display a message static final int MSG_SAY_HELLO = 1 Handler of incoming messages from clients class IncomingHandler extends Handler Override public void handleMessage(Message msg) switch (msgwhat) case MSG_SAY_HELLO ToastmakeText(getApplicationContext() hello ToastLENGTH_SHORT)show() break default superhandleMessage(msg) Target we publish for clients to send messages to IncomingHandler final Messenger mMessenger = new Messenger(new IncomingHandler()) When binding to the service we return an interface to our messenger for sending messages to the service Override public IBinder onBind(Intent intent) ToastmakeText(getApplicationContext() binding ToastLENGTH_SHORT)show() return mMessengergetBinder()

Notice that the handleMessage() method in the Handler is where the service receives the incoming

Message and decides what to do based on the what member

All that a client needs to do is create a Messenger based on the IBinder returned by the service and

send a message using send() For example heres a simple activity that binds to the service and

delivers the MSG_SAY_HELLO message to the service

public class ActivityMessenger extends Activity Messenger for communicating with the service Messenger mService = null Flag indicating whether we have called bind on the service boolean mBound Class for interacting with the main interface of the service private ServiceConnection mConnection = new ServiceConnection() public void onServiceConnected(ComponentName className IBinder service) This is called when the connection with the service has been established giving us the object we can use to interact with the service We are communicating with the service using a Messenger so here we get a client-side representation of that from the raw IBinder object mService = new Messenger(service) mBound = true public void onServiceDisconnected(ComponentName className) This is called when the connection with the service has been unexpectedly disconnected -- that is its process crashed mService = null mBound = false public void sayHello(View v) if (mBound) return Create and send a message to the service using a supported what value Message msg = Messageobtain(null MessengerServiceMSG_SAY_HELLO 0 0) try mServicesend(msg) catch (RemoteException e) eprintStackTrace() Override protected void onCreate(Bundle savedInstanceState) superonCreate(savedInstanceState) setContentView(Rlayoutmain)

Override protected void onStart() superonStart() Bind to the service bindService(new Intent(this MessengerServiceclass) mConnection ContextBIND_AUTO_CREATE) Override protected void onStop() superonStop() Unbind from the service if (mBound) unbindService(mConnection) mBound = false

Notice that this example does not show how the service can respond to the client If you want the

service to respond then you need to also create a Messenger in the client Then when the client

receives the onServiceConnected() callback it sends a Message to the service that includes the

clients Messenger in the replyTo parameter of the send() method

You can see an example of how to provide two-way messaging in the MessengerServicejava (service)

and MessengerServiceActivitiesjava (client) samples

Binding to a Service

Application components (clients) can bind to a service by calling bindService() The Android system

then calls the services onBind() method which returns an IBinder for interacting with the service

The binding is asynchronous bindService() returns immediately and does not return the IBinder to the

client To receive the IBinder the client must create an instance of ServiceConnection and pass it to

bindService() The ServiceConnection includes a callback method that the system calls to deliver the

IBinder

Note Only activities services and content providers can bind to a servicemdashyou cannot bind to a

service from a broadcast receiver

So to bind to a service from your client you must

1 Implement ServiceConnection

Your implementation must override two callback methods

onServiceConnected()

The system calls this to deliver the IBinder returned by the services onBind() method

onServiceDisconnected()

The Android system calls this when the connection to the service is unexpectedly lost such as

when the service has crashed or has been killed This is not called when the client unbinds

2 Call bindService() passing the ServiceConnection implementation

3 When the system calls your onServiceConnected() callback method you can begin making calls to the

service using the methods defined by the interface

4 To disconnect from the service call unbindService()

When your client is destroyed it will unbind from the service but you should always unbind when

youre done interacting with the service or when your activity pauses so that the service can shutdown

while its not being used (Appropriate times to bind and unbind is discussed more below)

For example the following snippet connects the client to the service created above by extending the

Binder class so all it must do is cast the returned IBinder to the LocalService class and request the

LocalService instance

LocalService mService private ServiceConnection mConnection = new ServiceConnection() Called when the connection with the service is established public void onServiceConnected(ComponentName className IBinder service) Because we have bound to an explicit service that is running in our own process we can cast its IBinder to a concrete class and directly access it LocalBinder binder = (LocalBinder) service mService = bindergetService() mBound = true Called when the connection with the service disconnects unexpectedly public void onServiceDisconnected(ComponentName className) Loge(TAG onServiceDisconnected) mBound = false

With this ServiceConnection the client can bind to a service by passing this it to bindService() For

example

Intent intent = new Intent(this LocalServiceclass) bindService(intent mConnection ContextBIND_AUTO_CREATE)

The first parameter of bindService() is an Intent that explicitly names the service to bind (thought the

intent could be implicit)

The second parameter is the ServiceConnection object

The third parameter is a flag indicating options for the binding It should usually be

BIND_AUTO_CREATE in order to create the service if its not already alive Other possible values are

BIND_DEBUG_UNBIND and BIND_NOT_FOREGROUND or 0 for none

Additional notes

Here are some important notes about binding to a service

You should always trap DeadObjectException exceptions which are thrown when the connection has

broken This is the only exception thrown by remote methods

Objects are reference counted across processes

You should usually pair the binding and unbinding during matching bring-up and tear-down moments

of the clients lifecycle For example

o If you only need to interact with the service while your activity is visible you should bind during

onStart() and unbind during onStop()

o If you want your activity to receive responses even while it is stopped in the background then you can

bind during onCreate() and unbind during onDestroy() Beware that this implies that your activity needs

to use the service the entire time its running (even in the background) so if the service is in another

process then you increase the weight of the process and it becomes more likely that the system will

kill it

Note You should usually not bind and unbind during your activitys onResume() and onPause()

because these callbacks occur at every lifecycle transition and you should keep the processing that

occurs at these transitions to a minimum Also if multiple activities in your application bind to the same

service and there is a transition between two of those activities the service may be destroyed and

recreated as the current activity unbinds (during pause) before the next one binds (during resume)

(This activity transition for how activities coordinate their lifecycles is described in the Activities

document)

For more sample code showing how to bind to a service see the RemoteServicejava class in

ApiDemos

Managing the Lifecycle of a Bound Service

Figure 1 The lifecycle for a service

that is started and also allows binding

When a service is unbound from all

clients the Android system destroys it

(unless it was also started with

onStartCommand()) As such you

dont have to manage the lifecycle of

your service if its purely a bound

servicemdashthe Android system manages

it for you based on whether it is bound

to any clients

However if you choose to implement

the onStartCommand() callback

method then you must explicitly stop

the service because the service is

now considered to be started In this

case the service runs until the service

stops itself with stopSelf() or another

component calls stopService()

regardless of whether it is bound to

any clients

Additionally if your service is started and accepts binding then when the system calls your onUnbind()

method you can optionally return true if you would like to receive a call to onRebind() the next time a

client binds to the service (instead of receiving a call to onBind()) onRebind() returns void but the

client still receives the IBinder in its onServiceConnected() callback Below figure 1 illustrates the logic

for this kind of lifecycle

For more information about the lifecycle of an started service see the Services document

Content Providers

Content providers store and retrieve data and make it accessible to all applications Theyre the only

way to share data across applications theres no common storage area that all Android packages can

access

Android ships with a number of content providers for common data types (audio video images

personal contact information and so on) You can see some of them listed in the androidprovider

package You can query these providers for the data they contain (although for some you must

acquire the proper permission to read the data)

If you want to make your own data public you have two options You can create your own content

provider (a ContentProvider subclass) or you can add the data to an existing provider mdash if theres one

that controls the same type of data and you have permission to write to it

This document is an introduction to using content providers After a brief discussion of the

fundamentals it explores how to query a content provider how to modify data controlled by a provider

and how to create a content provider of your own

Content Provider Basics

How a content provider actually stores its data under the covers is up to its designer But all content

providers implement a common interface for querying the provider and returning results mdash as well as

for adding altering and deleting data Its an interface that clients use indirectly most generally

through ContentResolver objects You get a ContentResolver by calling getContentResolver() from

within the implementation of an Activity or other application component

ContentResolver cr = getContentResolver()

You can then use the ContentResolvers methods to interact with whatever content providers youre

interested in When a query is initiated the Android system identifies the content provider thats the

target of the query and makes sure that it is up and running The system instantiates all

ContentProvider objects you never need to do it on your own In fact you never deal directly with

ContentProvider objects at all Typically theres just a single instance of each type of ContentProvider

But it can communicate with multiple ContentResolver objects in different applications and processes

The interaction between processes is handled by the ContentResolver and ContentProvider classes

The data model

Content providers expose their data as a simple table on a database model where each row is a

record and each column is data of a particular type and meaning For example information about

people and their phone numbers might be exposed as follows

_ID NUMBER NUMBER_KEY LABEL NAME TYPE

13 (425) 555 6677 425 555 6677 Kirkland office Bully Pulpit TYPE_WORK

44 (212) 555-1234 212 555 1234 NY apartment Alan Vain TYPE_HOME

45 (212) 555-6657 212 555 6657 Downtown office Alan Vain TYPE_MOBILE

53 2015554433 201 555 4433 Love Nest Rex Cars TYPE_HOME

Every record includes a numeric _ID field that uniquely identifies the record within the table IDs can be

used to match records in related tables mdash for example to find a persons phone number in one table

and pictures of that person in another

A query returns a Cursor object that can move from record to record and column to column to read the

contents of each field It has specialized methods for reading each type of data So to read a field you

must know what type of data the field contains (Theres more on query results and Cursor objects

later)

URIs

Each content provider exposes a public URI (wrapped as a Uri object) that uniquely identifies its data

set A content provider that controls multiple data sets (multiple tables) exposes a separate URI for

each one All URIs for providers begin with the string content The content scheme identifies the

data as being controlled by a content provider

If youre defining a content provider its a good idea to also define a constant for its URI to simplify

client code and make future updates cleaner Android defines CONTENT_URI constants for all the

providers that come with the platform For example the URI for the table that matches phone numbers

to people and the URI for the table that holds pictures of people (both controlled by the Contacts

content provider) are

androidproviderContactsPhonesCONTENT_URI

androidproviderContactsPhotosCONTENT_URI

The URI constant is used in all interactions with the content provider Every ContentResolver method

takes the URI as its first argument Its what identifies which provider the ContentResolver should talk

to and which table of the provider is being targeted

Querying a Content Provider

You need three pieces of information to query a content provider

The URI that identifies the provider

The names of the data fields you want to receive

The data types for those fields

If youre querying a particular record you also need the ID for that record

Making the query

To query a content provider you can use either the ContentResolverquery() method or the

ActivitymanagedQuery() method Both methods take the same set of arguments and both return a

Cursor object However managedQuery() causes the activity to manage the life cycle of the Cursor A

managed Cursor handles all of the niceties such as unloading itself when the activity pauses and

requerying itself when the activity restarts You can ask an Activity to begin managing an unmanaged

Cursor object for you by calling ActivitystartManagingCursor()

The first argument to either query() or managedQuery() is the provider URI mdash the CONTENT_URI

constant that identifies a particular ContentProvider and data set (see URIs earlier)

To restrict a query to just one record you can append the _ID value for that record to the URI mdash that

is place a string matching the ID as the last segment of the path part of the URI For example if the ID

is 23 the URI would be

content 23

There are some helper methods particularly ContentUriswithAppendedId() and

UriwithAppendedPath() that make it easy to append an ID to a URI Both are static methods that

return a Uri object with the ID added So for example if you were looking for record 23 in the database

of people contacts you might construct a query as follows

import androidproviderContactsPeople import androidcontentContentUris import androidnetUri import androiddatabaseCursor Use the ContentUris method to produce the base URI for the contact with _ID == 23 Uri myPerson = ContentUriswithAppendedId(PeopleCONTENT_URI 23) Alternatively use the Uri method to produce the base URI It takes a string rather than an integer Uri myPerson = UriwithAppendedPath(PeopleCONTENT_URI 23) Then query for this specific record Cursor cur = managedQuery(myPerson null null null null)

The other arguments to the query() and managedQuery() methods delimit the query in more detail

They are

The names of the data columns that should be returned A null value returns all columns Otherwise

only columns that are listed by name are returned All the content providers that come with the

platform define constants for their columns For example the androidproviderContactsPhones class

defines constants for the names of the columns in the phone table illustrated earlier ampmdash _ID

NUMBER NUMBER_KEY NAME and so on

A filter detailing which rows to return formatted as an SQL WHERE clause (excluding the WHERE

itself) A null value returns all rows (unless the URI limits the query to a single record)

Selection arguments

A sorting order for the rows that are returned formatted as an SQL ORDER BY clause (excluding the

ORDER BY itself) A null value returns the records in the default order for the table which may be

unordered

Lets look at an example query to retrieve a list of contact names and their primary phone numbers

import androidproviderContactsPeople import androiddatabaseCursor Form an array specifying which columns to return String[] projection = new String[] People_ID People_COUNT PeopleNAME PeopleNUMBER Get the base URI for the People table in the Contacts content provider Uri contacts = PeopleCONTENT_URI Make the query Cursor managedCursor = managedQuery(contacts projection Which columns to return null Which rows to return (all rows) null Selection arguments (none) Put the results in ascending order by name PeopleNAME + ASC)

This query retrieves data from the People table of the Contacts content provider It gets the name

primary phone number and unique record ID for each contact It also reports the number of records

that are returned as the _COUNT field of each record

The constants for the names of the columns are defined in various interfaces mdash _ID and _COUNT in

BaseColumns NAME in PeopleColumns and NUMBER in PhoneColumns The ContactsPeople

class implements each of these interfaces which is why the code example above could refer to them

using just the class name

What a query returns

A query returns a set of zero or more database records The names of the columns their default order

and their data types are specific to each content provider But every provider has an _ID column

which holds a unique numeric ID for each record Every provider can also report the number of records

returned as the _COUNT column its value is the same for all rows

Here is an example result set for the query in the previous section

_ID _COUNT NAME NUMBER

44 3 Alan Vain 212 555 1234

13 3 Bully Pulpit 425 555 6677

53 3 Rex Cars 201 555 4433

The retrieved data is exposed by a Cursor object that can be used to iterate backward or forward

through the result set You can use this object only to read the data To add modify or delete data

you must use a ContentResolver object

Reading retrieved data

The Cursor object returned by a query provides access to a recordset of results If you have queried

for a specific record by ID this set will contain only one value Otherwise it can contain multiple

values (If there are no matches it can also be empty) You can read data from specific fields in the

record but you must know the data type of the field because the Cursor object has a separate method

for reading each type of data mdash such as getString() getInt() and getFloat() (However for most types

if you call the method for reading strings the Cursor object will give you the String representation of

the data) The Cursor lets you request the column name from the index of the column or the index

number from the column name

The following snippet demonstrates reading names and phone numbers from the query illustrated

earlier

import androidproviderContactsPeople private void getColumnData(Cursor cur) if (curmoveToFirst()) String name String phoneNumber int nameColumn = curgetColumnIndex(PeopleNAME) int phoneColumn = curgetColumnIndex(PeopleNUMBER) String imagePath do Get the field values name = curgetString(nameColumn) phoneNumber = curgetString(phoneColumn) Do something with the values while (curmoveToNext())

If a query can return binary data such as an image or sound the data may be directly entered in the

table or the table entry for that data may be a string specifying a content URI that you can use to get

the data In general smaller amounts of data (say from 20 to 50K or less) are most often directly

entered in the table and can be read by calling CursorgetBlob() It returns a byte array

If the table entry is a content URI you should never try to open and read the file directly (for one thing

permissions problems can make this fail) Instead you should call ContentResolveropenInputStream()

to get an InputStream object that you can use to read the data

Modifying Data

Data kept by a content provider can be modified by

Adding new records

Adding new values to existing records

Batch updating existing records

Deleting records

All data modification is accomplished using ContentResolver methods Some content providers require

a more restrictive permission for writing data than they do for reading it If you dont have permission to

write to a content provider the ContentResolver methods will fail

Adding records

To add a new record to a content provider first set up a map of key-value pairs in a ContentValues

object where each key matches the name of a column in the content provider and the value is the

desired value for the new record in that column Then call ContentResolverinsert() and pass it the URI

of the provider and the ContentValues map This method returns the full URI of the new record mdash that

is the providers URI with the appended ID for the new record You can then use this URI to query and

get a Cursor over the new record and to further modify the record Heres an example

import androidproviderContactsPeople import androidcontentContentResolver import androidcontentContentValues ContentValues values = new ContentValues() Add Abraham Lincoln to contacts and make him a favorite valuesput(PeopleNAME Abraham Lincoln) 1 = the new contact is added to favorites 0 = the new contact is not added to favorites valuesput(PeopleSTARRED 1) Uri uri = getContentResolver()insert(PeopleCONTENT_URI values)

Adding new values

Once a record exists you can add new information to it or modify existing information For example

the next step in the example above would be to add contact information mdash like a phone number or an

IM or e-mail address mdash to the new entry

The best way to add to a record in the Contacts database is to append the name of the table where the

new data goes to the URI for the record then use the amended URI to add the new data values Each

Contacts table exposes a name for this purpose as a CONTENT_DIRECTORY constant The following

code continues the previous example by adding a phone number and e-mail address for the record

just created

Uri phoneUri = null Uri emailUri = null Add a phone number for Abraham Lincoln Begin with the URI for the new record just returned by insert() it ends with the _ID of the new record so we dont have to add the ID ourselves Then append the designation for the phone table to this URI and use the resulting URI to insert the phone number phoneUri = UriwithAppendedPath(uri PeoplePhonesCONTENT_DIRECTORY) valuesclear() valuesput(PeoplePhonesTYPE PeoplePhonesTYPE_MOBILE) valuesput(PeoplePhonesNUMBER 1233214567) getContentResolver()insert(phoneUri values) Now add an email address in the same way emailUri = UriwithAppendedPath(uri PeopleContactMethodsCONTENT_DIRECTORY) valuesclear() ContactMethodsKIND is used to distinguish different kinds of contact methods such as email IM etc valuesput(PeopleContactMethodsKIND ContactsKIND_EMAIL) valuesput(PeopleContactMethodsDATA testexamplecom) valuesput(PeopleContactMethodsTYPE PeopleContactMethodsTYPE_HOME) getContentResolver()insert(emailUri values)

You can place small amounts of binary data into a table by calling the version of ContentValuesput()

that takes a byte array That would work for a small icon-like image or a short audio clip for example

However if you have a large amount of binary data to add such as a photograph or a complete song

put a content URI for the data in the table and call ContentResolveropenOutputStream() with the files

URI (That causes the content provider to store the data in a file and record the file path in a hidden

field of the record)

In this regard the MediaStore content provider the main provider that dispenses image audio and

video data employs a special convention The same URI that is used with query() or managedQuery()

to get meta-information about the binary data (such as the caption of a photograph or the date it was

taken) is used with openInputStream() to get the data itself Similarly the same URI that is used with

insert() to put meta-information into a MediaStore record is used with openOutputStream() to place the

binary data there The following code snippet illustrates this convention

import androidproviderMediaStoreImagesMedia import androidcontentContentValues import javaioOutputStream Save the name and description of an image in a ContentValues map ContentValues values = new ContentValues(3) valuesput(MediaDISPLAY_NAME road_trip_1) valuesput(MediaDESCRIPTION Day 1 trip to Los Angeles) valuesput(MediaMIME_TYPE imagejpeg) Add a new record without the bitmap but with the values just set insert() returns the URI of the new record Uri uri = getContentResolver()insert(MediaEXTERNAL_CONTENT_URI values) Now get a handle to the file for that record and save the data into it Here sourceBitmap is a Bitmap object representing the file to save to the database try OutputStream outStream = getContentResolver()openOutputStream(uri) sourceBitmapcompress(BitmapCompressFormatJPEG 50 outStream) outStreamclose() catch (Exception e) Loge(TAG exception while writing image e)

Batch updating records

To batch update a group of records (for example to change NY to New York in all fields) call the

ContentResolverupdate() method with the columns and values to change

Deleting a record

To delete a single record call ContentResolverdelete() with the URI of a specific row

To delete multiple rows call ContentResolverdelete() with the URI of the type of record to delete (for

example androidproviderContactsPeopleCONTENT_URI) and an SQL WHERE clause defining

which rows to delete (Caution Be sure to include a valid WHERE clause if youre deleting a general

type or you risk deleting more records than you intended)

Creating a Content Provider

To create a content provider you must

Set up a system for storing the data Most content providers store their data using Androids file

storage methods or SQLite databases but you can store your data any way you want Android

provides the SQLiteOpenHelper class to help you create a database and SQLiteDatabase to manage

it

Extend the ContentProvider class to provide access to the data

Declare the content provider in the manifest file for your application (AndroidManifestxml)

The following sections have notes on the last two of these tasks

Extending the ContentProvider class

You define a ContentProvider subclass to expose your data to others using the conventions expected

by ContentResolver and Cursor objects Principally this means implementing six abstract methods

declared in the ContentProvider class

query()

insert()

update()

delete()

getType()

onCreate()

The query() method must return a Cursor object that can iterate over the requested data Cursor itself

is an interface but Android provides some ready-made Cursor objects that you can use For example

SQLiteCursor can iterate over data stored in an SQLite database You get the Cursor object by calling

any of the SQLiteDatabase classs query() methods There are other Cursor implementations mdash such

as MatrixCursor mdash for data not stored in a database

Because these ContentProvider methods can be called from various ContentResolver objects in

different processes and threads they must be implemented in a thread-safe manner

As a courtesy you might also want to call ContentResolvernotifyChange() to notify listeners when

there are modifications to the data

Beyond defining the subclass itself there are other steps you should take to simplify the work of clients

and make the class more accessible

Define a public static final Uri named CONTENT_URI This is the string that represents the full content

URI that your content provider handles You must define a unique string for this value The best

solution is to use the fully-qualified class name of the content provider (made lowercase) So for

example the URI for a TransportationProvider class could be defined as follows

public static final Uri CONTENT_URI = Uriparse(contentcomexamplecodelabtransportationprovider)

If the provider has subtables also define CONTENT_URI constants for each of the subtables These

URIs should all have the same authority (since that identifies the content provider) and be

distinguished only by their paths For example

contentcomexamplecodelabtransportationprovidertrain

contentcomexamplecodelabtransportationproviderairdomestic

contentcomexamplecodelabtransportationproviderairinternational

For an overview of content URIs see the Content URI Summary at the end of this document

Define the column names that the content provider will return to clients If you are using an underlying

database these column names are typically identical to the SQL database column names they

represent Also define public static String constants that clients can use to specify the columns in

queries and other instructions

Be sure to include an integer column named _id (with the constant _ID) for the IDs of the records

You should have this field whether or not you have another field (such as a URL) that is also unique

among all records If youre using the SQLite database the _ID field should be the following type

INTEGER PRIMARY KEY AUTOINCREMENT

The AUTOINCREMENT descriptor is optional But without it SQLite increments an ID counter field to

the next number above the largest existing number in the column If you delete the last row the next

row added will have the same ID as the deleted row AUTOINCREMENT avoids this by having SQLite

increment to the next largest value whether deleted or not

Carefully document the data type of each column Clients need this information to read the data

If you are handling a new data type you must define a new MIME type to return in your

implementation of ContentProvidergetType() The type depends in part on whether or not the content

URI submitted to getType() limits the request to a specific record Theres one form of the MIME type

for a single record and another for multiple records Use the Uri methods to help determine what is

being requested Here is the general format for each type

o For a single record vndandroidcursoritemvndyourcompanynamecontenttype

For example a request for train record 122 like this URI

contentcomexampletransportationprovidertrains122

might return this MIME type

vndandroidcursoritemvndexamplerail

o For multiple records vndandroidcursordirvndyourcompanynamecontenttype

For example a request for all train records like the following URI

contentcomexampletransportationprovidertrains

might return this MIME type

vndandroidcursordirvndexamplerail

If you are exposing byte data thats too big to put in the table itself mdash such as a large bitmap file mdash the

field that exposes the data to clients should actually contain a content URI string This is the field that

gives clients access to the data file The record should also have another field named _data that lists

the exact file path on the device for that file This field is not intended to be read by the client but by

the ContentResolver The client will call ContentResolveropenInputStream() on the user-facing field

holding the URI for the item The ContentResolver will request the _data field for that record and

because it has higher permissions than a client it should be able to access that file directly and return

a read wrapper for the file to the client

For an example of a private content provider implementation see the NodePadProvider class in the

Notepad sample application that ships with the SDK

Declaring the content provider

To let the Android system know about the content provider youve developed declare it with a

ltprovidergt element in the applications AndroidManifestxml file Content providers that are not

declared in the manifest are not visible to the Android system

The name attribute is the fully qualified name of the ContentProvider subclass The authorities attribute

is the authority part of the content URI that identifies the provider For example if the ContentProvider

subclass is AutoInfoProvider the ltprovidergt element might look like this

ltprovider androidname=comexampleautosAutoInfoProvider androidauthorities=comexampleautosautoinfoprovider gt ltprovidergt

Note that the authorities attribute omits the path part of a content URI For example if

AutoInfoProvider controlled subtables for different types of autos or different manufacturers

contentcomexampleautosautoinfoproviderhonda

contentcomexampleautosautoinfoprovidergmcompact

contentcomexampleautosautoinfoprovidergmsuv

those paths would not be declared in the manifest The authority is what identifies the provider not the

path your provider can interpret the path part of the URI in any way you choose

Other ltprovidergt attributes can set permissions to read and write data provide for an icon and text

that can be displayed to users enable and disable the provider and so on Set the multiprocess

attribute to true if data does not need to be synchronized between multiple running versions of the

content provider This permits an instance of the provider to be created in each client process

eliminating the need to perform IPC

Content URI Summary

Here is a recap of the important parts of a content URI

A Standard prefix indicating that the data is controlled by a content provider Its never modified

B The authority part of the URI it identifies the content provider For third-party applications this should

be a fully-qualified class name (reduced to lowercase) to ensure uniqueness The authority is declared

in the ltprovidergt elements authorities attribute

ltprovider androidname=TransportationProvider androidauthorities=comexampletransportationprovider gt

C The path that the content provider uses to determine what kind of data is being requested This can be

zero or more segments long If the content provider exposes only one type of data (only trains for

example) it can be absent If the provider exposes several types including subtypes it can be several

segments long mdash for example landbus landtrain seaship and seasubmarine to give four

possibilities

D The ID of the specific record being requested if any This is the _ID value of the requested record If

the request is not limited to a single record this segment and the trailing slash are omitted

contentcomexampletransportationprovidertrains

Intent and intent filters

Three of the core components of an application mdash activities services and broadcast receivers mdash 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 mdash 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 ContextstartActivity() or ActivitystartActivityForResult() to launch an

activity or get an existing activity to do something new (It can also be passed to ActivitysetResult() to

return information to the activity that called startActivityForResult())

An Intent object is passed to ContextstartService() to initiate a service or deliver new instructions to an

ongoing service Similarly an intent can be passed to ContextbindService() to establish a connection

between the calling component and a target service It can optionally initiate the service if its not

already running

Intent objects passed to any of the broadcast methods (such as ContextsendBroadcast()

ContextsendOrderedBroadcast() or ContextsendStickyBroadcast()) 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 mdash how it resolves which component should receive an intent message For

intents that dont explicitly name a target component this process involves testing the Intent object

against intent filters associated with potential targets

Intent Objects

An Intent object is a bundle of information It contains information of interest to the component that

receives the intent (such as the action to be taken and the data to act on) plus information of interest to

the Android system (such as the category of component that should handle the intent and instructions

on how to launch a target activity) Principally it can contain the following

Component name

The name of the component that should handle the intent This field is a ComponentName

object mdash a combination of the fully qualified class name of the target component (for example

comexampleprojectappFreneticActivity) and the package name set in the manifest file of the

application where the component resides (for example comexampleproject) The package

part of the component name and the package name set in the manifest do not necessarily have

to match

The component name is optional If it is set the Intent object is delivered to an instance of the

designated class If it is not set Android uses other information in the Intent object to locate a

suitable target mdash see Intent Resolution later in this document

The component name is set by setComponent() setClass() or setClassName() and read by

getComponent()

Action

A string naming the action to be performed mdash or in the case of broadcast intents the action

that took place and is being reported The Intent class defines a number of action constants

including these

Constant Target

component

Action

ACTION_CALL activity Initiate a phone call

ACTION_EDIT activity Display data for the user to edit

ACTION_MAIN activity Start up as the initial activity of a task

with no data input and no returned

output

ACTION_SYNC activity Synchronize data on a server with

data on the mobile device

ACTION_BATTERY_LOW broadcast

receiver

A warning that the battery is low

ACTION_HEADSET_PLUG broadcast

receiver

A headset has been plugged into the

device or unplugged from it

ACTION_SCREEN_ON broadcast

receiver

The screen has been turned on

ACTION_TIMEZONE_CHANGED broadcast

receiver

The setting for the time zone has

changed

See the Intent class description for a list of pre-defined constants for generic actions Other

actions are defined elsewhere in the Android API You can also define your own action strings

for activating the components in your application Those you invent should include the

application package as a prefix mdash for example comexampleprojectSHOW_COLOR

The action largely determines how the rest of the intent is structured mdash particularly the data and

extras fields mdash much as a method name determines a set of arguments and a return value For

this reason its a good idea to use action names that are as specific as possible and to couple

them tightly to the other fields of the intent In other words instead of defining an action in

isolation define an entire protocol for the Intent objects your components can handle

The action in an Intent object is set by the setAction() method and read by getAction()

Data

The URI of the data to be acted on and the MIME type of that data Different actions are paired

with different kinds of data specifications For example if the action field is ACTION_EDIT the

data field would contain the URI of the document to be displayed for editing If the action is

ACTION_CALL the data field would be a tel URI with the number to call Similarly if the action

is ACTION_VIEW and the data field is an http URI the receiving activity would be called upon

to download and display whatever data the URI refers to

When matching an intent to a component that is capable of handling the data its often

important to know the type of data (its MIME type) in addition to its URI For example a

component able to display image data should not be called upon to play an audio file

In many cases the data type can be inferred from the URI mdash particularly content URIs which

indicate that the data is located on the device and controlled by a content provider (see the

separate discussion on content providers) But the type can also be explicitly set in the Intent

object The setData() method specifies data only as a URI setType() specifies it only as a

MIME type and setDataAndType() specifies it as both a URI and a MIME type The URI is read

by getData() and the type by getType()

Category

A string containing additional information about the kind of component that should handle the

intent Any number of category descriptions can be placed in an Intent object As it does for

actions the Intent class defines several category constants including these

Constant Meaning

CATEGORY_BROWSABLE The target activity can be safely invoked by the browser to

display data referenced by a link mdash for example an image or

an e-mail message

CATEGORY_GADGET The activity can be embedded inside of another activity that

hosts gadgets

CATEGORY_HOME The activity displays the home screen the first screen the

user sees when the device is turned on or when the HOME

key is pressed

CATEGORY_LAUNCHER The activity can be the initial activity of a task and is listed in

the top-level application launcher

CATEGORY_PREFERENCE The target activity is a preference panel

See the Intent class description for the full list of categories

The addCategory() method places a category in an Intent object removeCategory() deletes a

category previously added and getCategories() gets the set of all categories currently in the

object

Extras

Key-value pairs for additional information that should be delivered to the component handling

the intent Just as some actions are paired with particular kinds of data URIs some are paired

with particular extras For example an ACTION_TIMEZONE_CHANGED intent has a time-

zone extra that identifies the new time zone and ACTION_HEADSET_PLUG has a state

extra indicating whether the headset is now plugged in or unplugged as well as a name extra

for the type of headset If you were to invent a SHOW_COLOR action the color value would be

set in an extra key-value pair

The Intent object has a series of put() methods for inserting various types of extra data and a

similar set of get() methods for reading the data These methods parallel those for Bundle

objects In fact the extras can be installed and read as a Bundle using the putExtras() and

getExtras() methods

Flags

Flags of various sorts Many instruct the Android system how to launch an activity (for example

which task the activity should belong to) and how to treat it after its launched (for example

whether it belongs in the list of recent activities) All these flags are defined in the Intent class

The Android system and the applications that come with the platform employ Intent objects both to

send out system-originated broadcasts and to activate system-defined components To see how to

structure an intent to activate a system component consult the list of intents in the reference

Intent Resolution

Intents can be divided into two groups

Explicit intents designate the target component by its name (the component name field mentioned

earlier has a value set) Since component names would generally not be known to developers of other

applications explicit intents are typically used for application-internal messages mdash such as an activity

starting a subordinate service or launching a sister activity

Implicit intents do not name a target (the field for the component name is blank) Implicit intents are

often used to activate components in other applications

Android delivers an explicit intent to an instance of the designated target class Nothing in the Intent

object other than the component name matters for determining which component should get the intent

A different strategy is needed for implicit intents In the absence of a designated target the Android

system must find the best component (or components) to handle the intent mdash a single activity or

service to perform the requested action or the set of broadcast receivers to respond to the broadcast

announcement It does so by comparing the contents of the Intent object to intent filters structures

associated with components that can potentially receive intents Filters advertise the capabilities of a

component and delimit the intents it can handle They open the component to the possibility of

receiving implicit intents of the advertised type If a component does not have any intent filters it can

receive only explicit intents A component with filters can receive both explicit and implicit intents

Only three aspects of an Intent object are consulted when the object is tested against an intent filter

action

data (both URI and data type)

category

The extras and flags play no part in resolving which component receives an intent

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 mdash but only unwanted implicit intents (those that dont 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

components 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 mdash 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 Pads filters are described in the Note Pad Example

section later)

Filters and security

An intent filter cannot be relied on for security While it opens a component to receiving only certain

kinds of implicit intents it does nothing to prevent explicit intents from targeting the component Even

though a filter restricts the intents a component will be asked to handle to certain actions and data

sources someone could always put together an explicit intent with a different action and data source

and name the component as the target

An intent filter is an instance of the IntentFilter class However since the Android system must know

about the capabilities of a component before it can launch that component intent filters are generally

not set up in Java code but in the applications manifest file (AndroidManifestxml) as ltintent-filtergt

elements (The one exception would be filters for broadcast receivers that are registered dynamically

by calling ContextregisterReceiver() they are directly created as IntentFilter objects)

A filter has fields that parallel the action data and category fields of an Intent object An implicit intent

is tested against the filter in all three areas To be delivered to the component that owns the filter it

must pass all three tests If it fails even one of them the Android system wont deliver it to the

component mdash at least not on the basis of that filter However since a component can have multiple

intent filters an intent that does not pass through one of a components filters might make it through on

another

Each of the three tests is described in detail below

Action test

An ltintent-filtergt element in the manifest file lists actions as ltactiongt subelements For

example

ltintent-filter gt ltaction androidname=comexampleprojectSHOW_CURRENT gt ltaction androidname=comexampleprojectSHOW_RECENT gt ltaction androidname=comexampleprojectSHOW_PENDING gt ltintent-filtergt

As the example shows while an Intent object names just a single action a filter may list more

than one The list cannot be empty a filter must contain at least one ltactiongt element or it will

block all intents

To pass this test the action specified in the Intent object must match one of the actions listed in

the filter If the object or the filter does not specify an action the results are as follows

If the filter fails to list any actions there is nothing for an intent to match so all intents fail the

test No intents can get through the filter

On the other hand an Intent object that doesnt specify an action automatically passes the test

mdash as long as the filter contains at least one action

Category test

An ltintent-filtergt element also lists categories as subelements For example

ltintent-filter gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryBROWSABLE gt ltintent-filtergt

Note that the constants described earlier for actions and categories are not used in the manifest

file The full string values are used instead For instance the

androidintentcategoryBROWSABLE string in the example above corresponds to the

CATEGORY_BROWSABLE constant mentioned earlier in this document Similarly the string

androidintentactionEDIT corresponds to the ACTION_EDIT constant

For an intent to pass the category test every category in the Intent object must match a

category in the filter The filter can list additional categories but it cannot omit any that are in the

intent

In principle therefore an Intent object with no categories should always pass this test

regardless of whats in the filter Thats mostly true However with one exception Android treats

all implicit intents passed to startActivity() as if they contained at least one category

androidintentcategoryDEFAULT (the CATEGORY_DEFAULT constant) Therefore activities

that are willing to receive implicit intents must include androidintentcategoryDEFAULT in

their intent filters (Filters with androidintentactionMAIN and

androidintentcategoryLAUNCHER settings are the exception They mark activities that begin

new tasks and that are represented on the launcher screen They can include

androidintentcategoryDEFAULT in the list of categories but dont need to) See Using intent

matching later for more on these filters)

Data test

Like the action and categories the data specification for an intent filter is contained in a

subelement And as in those cases the subelement can appear multiple times or not at all For

example

ltintent-filter gt ltdata androidmimeType=videompeg androidscheme=http gt ltdata androidmimeType=audiompeg androidscheme=http gt ltintent-filtergt

Each ltdatagt element can specify a URI and a data type (MIME media type) There are

separate attributes mdash scheme host port and path mdash for each part of the URI

schemehostportpath

For example in the following URI

contentcomexampleproject200foldersubfolderetc

the scheme is content the host is comexampleproject the port is 200 and the path is

foldersubfolderetc The host and port together constitute the URI authority if a host is not

specified the port is ignored

Each of these attributes is optional but they are not independent of each other For an authority

to be meaningful a scheme must also be specified For a path to be meaningful both a scheme

and an authority must be specified

When the URI in an Intent object is compared to a URI specification in a filter its compared

only to the parts of the URI actually mentioned in the filter For example if a filter specifies only

a scheme all URIs with that scheme match the filter If a filter specifies a scheme and an

authority but no path all URIs with the same scheme and authority match regardless of their

paths If a filter specifies a scheme an authority and a path only URIs with the same scheme

authority and path match However a path specification in the filter can contain wildcards to

require only a partial match of the path

The type attribute of a ltdatagt element specifies the MIME type of the data Its more common in

filters than a URI Both the Intent object and the filter can use a wildcard for the subtype field

mdash for example text or audio mdash indicating any subtype matches

The data test compares both the URI and the data type in the Intent object to a URI and data

type specified in the filter The rules are as follows

a An Intent object that contains neither a URI nor a data type passes the test only if the filter

likewise does not specify any URIs or data types

b An Intent object that contains a URI but no data type (and a type cannot be inferred from the

URI) passes the test only if its URI matches a URI in the filter and the filter likewise does not

specify a type This will be the case only for URIs like mailto and tel that do not refer to actual

data

c An Intent object that contains a data type but not a URI passes the test only if the filter lists the

same data type and similarly does not specify a URI

d An Intent object that contains both a URI and a data type (or a data type can be inferred from

the URI) passes the data type part of the test only if its type matches a type listed in the filter It

passes the URI part of the test either if its URI matches a URI in the filter or if it has a content

or file URI and the filter does not specify a URI In other words a component is presumed to

support content and file data if its filter lists only a data type

If an intent can pass through the filters of more than one activity or service the user may be asked

which component to activate An exception is raised if no target can be found

Common cases

The last rule shown above for the data test rule (d) reflects the expectation that components are able

to get local data from a file or content provider Therefore their filters can list just a data type and do

not need to explicitly name the content and file schemes This is a typical case A ltdatagt element like

the following for example tells Android that the component can get image data from a content

provider and display it

ltdata androidmimeType=image gt

Since most available data is dispensed by content providers filters that specify a data type but not a

URI are perhaps the most common

Another common configuration is filters with a scheme and a data type For example a ltdatagt

element like the following tells Android that the component can get video data from the network and

display it

ltdata androidscheme=http androidtype=video gt

Consider for example what the browser application does when the user follows a link on a web page

It first tries to display the data (as it could if the link was to an HTML page) If it cant display the data it

puts together an implicit intent with the scheme and data type and tries to start an activity that can do

the job If there are no takers it asks the download manager to download the data That puts it under

the control of a content provider so a potentially larger pool of activities (those with filters that just

name a data type) can respond

Most applications also have a way to start fresh without a reference to any particular data Activities

that can initiate applications have filters with androidintentactionMAIN specified as the action If

they are to be represented in the application launcher they also specify the

androidintentcategoryLAUNCHER category

ltintent-filter gt ltaction androidname=code androidintentactionMAIN gt ltcategory androidname=code androidintentcategoryLAUNCHER gt ltintent-filtergt

Using intent matching

Intents are matched against intent filters not only to discover a target component to activate but also

to discover something about the set of components on the device For example the Android system

populates the application launcher the top-level screen that shows the applications that are available

for the user to launch by finding all the activities with intent filters that specify the

androidintentactionMAIN action and androidintentcategoryLAUNCHER category (as illustrated

in the previous section) It then displays the icons and labels of those activities in the launcher

Similarly it discovers the home screen by looking for the activity with androidintentcategoryHOME

in its filter

Your application can use intent matching is a similar way The PackageManager has a set of query()

methods that return all components that can accept a particular intent and a similar series of

resolve() methods that determine the best component to respond to an intent For example

queryIntentActivities() returns a list of all activities that can perform the intent passed as an argument

and queryIntentServices() returns a similar list of services Neither method activates the components

they just list the ones that can respond Theres a similar method queryBroadcastReceivers() for

broadcast receivers

Note Pad Example

The Note Pad sample application enables users to browse through a list of notes view details about

individual items in the list edit the items and add a new item to the list This section looks at the intent

filters declared in its manifest file (If youre working offline in the SDK you can find all the source files

for this sample application including its manifest file at ltsdkgtsamplesNotePadindexhtml If youre

viewing the documentation online the source files are in the Tutorials and Sample Code section here)

In its manifest file the Note Pad application declares three activities each with at least one intent filter

It also declares a content provider that manages the note data Here is the manifest file in its entirety

ltmanifest xmlnsandroid=httpschemasandroidcomapkresandroid package=comexampleandroidnotepadgt ltapplication androidicon=drawableapp_notes androidlabel=stringapp_name gt ltprovider androidname=NotePadProvider androidauthorities=comgoogleproviderNotePad gt ltactivity androidname=NotesList androidlabel=stringtitle_notes_listgt ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltactivity androidname=NoteEditor androidtheme=androidstyleThemeLight androidlabel=stringtitle_note gt ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltactivitygt

ltactivity androidname=TitleEditor androidlabel=stringtitle_edit_title androidtheme=androidstyleThemeDialoggt ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltapplicationgt ltmanifestgt

The first activity NotesList is distinguished from the other activities by the fact that it operates on a

directory of notes (the note list) rather than on a single note It would generally serve as the initial user

interface into the application It can do three things as described by its three intent filters

1 ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt

This filter declares the main entry point into the Note Pad application The standard MAIN action is an

entry point that does not require any other information in the Intent (no data specification for example)

and the LAUNCHER category says that this entry point should be listed in the application launcher

2 ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

This filter declares the things that the activity can do on a directory of notes It can allow the user to

view or edit the directory (via the VIEW and EDIT actions) or to pick a particular note from the

directory (via the PICK action)

The mimeType attribute of the ltdatagt element specifies the kind of data that these actions operate on

It indicates that the activity can get a Cursor over zero or more items (vndandroidcursordir) from a

content provider that holds Note Pad data (vndgooglenote) The Intent object that launches the

activity would include a content URI specifying the exact data of this type that the activity should open

Note also the DEFAULT category supplied in this filter Its there because the ContextstartActivity()

and ActivitystartActivityForResult() methods treat all intents as if they contained the DEFAULT

category mdash with just two exceptions

o Intents that explicitly name the target activity

o Intents consisting of the MAIN action and LAUNCHER category

Therefore the DEFAULT category is required for all filters mdash except for those with the MAIN action

and LAUNCHER category (Intent filters are not consulted for explicit intents)

3 ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

This filter describes the activitys ability to return a note selected by the user without requiring any

specification of the directory the user should choose from The GET_CONTENT action is similar to the

PICK action In both cases the activity returns the URI for a note selected by the user (In each case

its returned to the activity that called startActivityForResult() to start the NoteList activity) Here

however the caller specifies the type of data desired instead of the directory of data the user will be

picking from

The data type vndandroidcursoritemvndgooglenote indicates the type of data the activity can

return mdash a URI for a single note From the returned URI the caller can get a Cursor for exactly one

item (vndandroidcursoritem) from the content provider that holds Note Pad data (vndgooglenote)

In other words for the PICK action in the previous filter the data type indicates the type of data the

activity could display to the user For the GET_CONTENT filter it indicates the type of data the activity

can return to the caller

Given these capabilities the following intents will resolve to the NotesList activity

action androidintentactionMAIN

Launches the activity with no data specified

action androidintentactionMAIN

category androidintentcategoryLAUNCHER

Launches the activity with no data selected specified This is the actual intent used by the

Launcher to populate its top-level list All activities with filters that match this action and

category are added to the list

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of all the notes under

contentcomgoogleproviderNotePadnotes The user can then browse through the list and

get information about the items in it

action androidintentactionPICK

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of the notes under

contentcomgoogleproviderNotePadnotes The user can then pick a note from the list and

the activity will return the URI for that item back to the activity that started the NoteList activity

action androidintentactionGET_CONTENT

data type vndandroidcursoritemvndgooglenote

Asks the activity to supply a single item of Note Pad data

The second activity NoteEditor shows users a single note entry and allows them to edit it It can do

two things as described by its two intent filters

1 ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The first primary purpose of this activity is to enable the user to interact with a single note ampmdash to

either VIEW the note or EDIT it (The EDIT_NOTE category is a synonym for EDIT) The intent would

contain the URI for data matching the MIME type vndandroidcursoritemvndgooglenote mdash that is

the URI for a single specific note It would typically be a URI that was returned by the PICK or

GET_CONTENT actions of the NoteList activity

As before this filter lists the DEFAULT category so that the activity can be launched by intents that

dont explicitly specify the NoteEditor class

2 ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

The secondary purpose of this activity is to enable the user to create a new note which it will INSERT

into an existing directory of notes The intent would contain the URI for data matching the MIME type

vndandroidcursordirvndgooglenote mdash that is the URI for the directory where the note should be

placed

Given these capabilities the following intents will resolve to the NoteEditor activity

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID (For details on how content

URIs specify individual members of a group see Content Providers)

action androidintentactionEDIT

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID and to let the user edit it If

the user saves the changes the activity updates the data for the note in the content provider

action androidintentactionINSERT

data contentcomgoogleproviderNotePadnotes

Asks the activity to create a new empty note in the notes list at

contentcomgoogleproviderNotePadnotes and allow the user to edit it If the user saves the

note its URI is returned to the caller

The last activity TitleEditor enables the user to edit the title of a note This could be implemented by

directly invoking the activity (by explicitly setting its component name in the Intent) without using an

intent filter But here we take the opportunity to show how to publish alternative operations on existing

data

ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The single intent filter for this activity uses a custom action called

comandroidnotepadactionEDIT_TITLE It must be invoked on a specific note (data type

vndandroidcursoritemvndgooglenote) like the previous VIEW and EDIT actions However here the

activity displays the title contained in the note data not the content of the note itself

In addition to supporting the usual DEFAULT category the title editor also supports two other standard

categories ALTERNATIVE and SELECTED_ALTERNATIVE These categories identify activities that

can be presented to users in a menu of options (much as the LAUNCHER category identifies activities

that should be presented to user in the application launcher) Note that the filter also supplies an

explicit label (via androidlabel=stringresolve_title) to better control what users see when

presented with this activity as an alternative action to the data they are currently viewing (For more

information on these categories and building options menus see the

PackageManagerqueryIntentActivityOptions() and MenuaddIntentOptions() methods)

Given these capabilities the following intent will resolve to the TitleEditor activity

action comandroidnotepadactionEDIT_TITLE

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the title associated with note ID and allow the user to edit the title

Processes and Threads

When an application component starts and the application does not have any other components

running the Android system starts a new Linux process for the application with a single thread of

execution By default all components of the same application run in the same process and thread

(called the main thread) If an application component starts and there already exists a process for

that application (because another component from the application exists) then the component is

started within that process and uses the same thread of execution However you can arrange for

different components in your application to run in separate processes and you can create additional

threads for any process

This document discusses how processes and threads work in an Android application

Processes

By default all components of the same application run in the same process and most applications

should not change this However if you find that you need to control which process a certain

component belongs to you can do so in the manifest file

The manifest entry for each type of component elementmdashltactivitygt ltservicegt ltreceivergt and

ltprovidergtmdashsupports an androidprocess attribute that can specify a process in which that component

should run You can set this attribute so that each component runs in its own process or so that some

components share a process while others do not You can also set androidprocess so that

components of different applications run in the same processmdashprovided that the applications share the

same Linux user ID and are signed with the same certificates

The ltapplicationgt element also supports an androidprocess attribute to set a default value that

applies to all components

Android might 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 thats killed are consequently destroyed A process is started again for those components

when theres again work for them to do

When deciding which processes to kill the Android system weighs their relative importance to the

user For example it more readily shuts down a process hosting activities that are no longer visible on

screen compared to a process hosting visible activities The decision whether to terminate a process

therefore depends on the state of the components running in that process The rules used to decide

which processes to terminate is discussed below

Process lifecycle

The Android system tries to maintain an application process for as long as possible but eventually

needs to remove old processes to reclaim memory for new or more important processes To determine

which processes to keep and which to kill the system places each process into an importance

hierarchy based on the components running in the process and the state of those components

Processes with the lowest importance are eliminated first then those with the next lowest importance

and so on as necessary to recover system resources

There are five levels in the importance hierarchy The following list presents the different types of

processes in order of importance (the first process is most important and is killed last)

1 Foreground process

A process that is required for what the user is currently doing A process is considered to be in the

foreground if any of the following conditions are true

o It hosts an Activity that the user is interacting with (the Activitys onResume() method has been called)

o It hosts a Service thats bound to the activity that the user is interacting with

o It hosts a Service thats running in the foregroundmdashthe service has called startForeground()

o It hosts a Service thats executing one of its lifecycle callbacks (onCreate() onStart() or onDestroy())

o It hosts a BroadcastReceiver thats executing its onReceive() method

Generally only a few foreground processes exist at any given time They are killed only as a last

resortmdashif memory is so low that they cannot all continue to run Generally at that point the device has

reached a memory paging state so killing some foreground processes is required to keep the user

interface responsive

2 Visible process

A process that doesnt have any foreground components but still can affect what the user sees on

screen A process is considered to be visible if either of the following conditions are true

o It hosts an Activity that is not in the foreground but is still visible to the user (its onPause() method has

been called) This might occur for example if the foreground activity started a dialog which allows the

previous activity to be seen behind it

o It hosts a Service thats bound to a visible (or foreground) activity

A visible process is considered extremely important and will not be killed unless doing so is required to

keep all foreground processes running

3 Service process

A process that is running a service that has been started with the startService() method and does not

fall into either of the two higher categories Although service processes are not directly tied to anything

the user sees they are generally doing things that the user cares about (such as playing music in the

background or downloading data on the network) so the system keeps them running unless theres

not enough memory to retain them along with all foreground and visible processes

4 Background process

A process holding an activity thats not currently visible to the user (the activitys onStop() method has

been called) These processes have no direct impact on the user experience and the system can kill

them at any time to reclaim memory for a foreground visible or service process Usually there are

many background processes running so they are kept in an LRU (least recently used) list to ensure

that the process with the activity that was most recently seen by the user is the last to be killed If an

activity implements its lifecycle methods correctly and saves its current state killing its process will not

have a visible effect on the user experience because when the user navigates back to the activity the

activity restores all of its visible state See the Activities document for information about saving and

restoring state

5 Empty process

A process that doesnt hold any active application components The only reason to keep this kind of

process alive is for caching purposes to improve startup time the next time a component needs to run

in it The system often kills these processes in order to balance overall system resources between

process caches and the underlying kernel caches

Android ranks a process at the highest level it can based upon the importance of the components

currently active in the process For example if a process hosts a service and a visible activity the

process is ranked as a visible process not a service process

In addition a processs ranking might be increased because other processes are dependent on itmdasha

process that is serving another process can never be ranked lower than the process it is serving For

example if a content provider in process A is serving a client in process B or if a service in process A

is bound to a component in process B process A is always considered at least as important as

process B

Because a process running a service is ranked higher than a process with background activities an

activity that initiates a long-running operation might do well to start a service for that operation rather

than simply create a worker threadmdashparticularly if the operation will likely outlast the activity For

example an activity thats uploading a picture to a web site should start a service to perform the

upload so that the upload can continue in the background even if the user leaves the activity Using a

service guarantees that the operation will have at least service process priority regardless of what

happens to the activity This is the same reason that broadcast receivers should employ services

rather than simply put time-consuming operations in a thread

Threads

When an application is launched the system creates a thread of execution for the application called

main This thread is very important because it is in charge of dispatching events to the appropriate

user interface widgets including drawing events It is also the thread in which your application interacts

with components from the Android UI toolkit (components from the androidwidget and androidview

packages) As such the main thread is also sometimes called the UI thread

The system does not create a separate thread for each instance of a component All components that

run in the same process are instantiated in the UI thread and system calls to each component are

dispatched from that thread Consequently methods that respond to system callbacks (such as

onKeyDown() to report user actions or a lifecycle callback method) always run in the UI thread of the

process

For instance when the user touches a button on the screen your apps UI thread dispatches the touch

event to the widget which in turn sets its pressed state and posts an invalidate request to the event

queue The UI thread dequeues the request and notifies the widget that it should redraw itself

When your app performs intensive work in response to user interaction this single thread model can

yield poor performance unless you implement your application properly Specifically if everything is

happening in the UI thread performing long operations such as network access or database queries

will block the whole UI When the thread is blocked no events can be dispatched including drawing

events From the users perspective the application appears to hang Even worse if the UI thread is

blocked for more than a few seconds (about 5 seconds currently) the user is presented with the

infamous application not responding (ANR) dialog The user might then decide to quit your

application and uninstall it if they are unhappy

Additionally the Andoid UI toolkit is not thread-safe So you must not manipulate your UI from a

worker threadmdashyou must do all manipulation to your user interface from the UI thread Thus there are

simply two rules to Androids single thread model

1 Do not block the UI thread

2 Do not access the Android UI toolkit from outside the UI thread

Worker threads

Because of the single thread model described above its vital to the responsiveness of your

applications UI that you do not block the UI thread If you have operations to perform that are not

instantaneous you should make sure to do them in separate threads (background or worker

threads)

For example below is some code for a click listener that downloads an image from a separate thread

and displays it in an ImageView

public void onClick(View v) new Thread(new Runnable() public void run() Bitmap b = loadImageFromNetwork(httpexamplecomimagepng) mImageViewsetImageBitmap(b) )start()

At first this seems to work fine because it creates a new thread to handle the network operation

However it violates the second rule of the single-threaded model do not access the Android UI toolkit

from outside the UI threadmdashthis sample modifies the ImageView from the worker thread instead of the

UI thread This can result in undefined and unexpected behavior which can be difficult and time-

consuming to track down

To fix this problem Android offers several ways to access the UI thread from other threads Here is a

list of methods that can help

ActivityrunOnUiThread(Runnable)

Viewpost(Runnable)

ViewpostDelayed(Runnable long)

For example you can fix the above code by using the Viewpost(Runnable) method

public void onClick(View v) new Thread(new Runnable() public void run() final Bitmap bitmap = loadImageFromNetwork(httpexamplecomimagepng) mImageViewpost(new Runnable() public void run() mImageViewsetImageBitmap(bitmap) ) )start()

Now this implementation is thread-safe the network operation is done from a separate thread while

the ImageView is manipulated from the UI thread

However as the complexity of the operation grows this kind of code can get complicated and difficult

to maintain To handle more complex interactions with a worker thread you might consider using a

Handler in your worker thread to process messages delivered from the UI thread Perhaps the best

solution though is to extend the AsyncTask class which simplifies the execution of worker thread

tasks that need to interact with the UI

Using AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface It performs the blocking

operations in a worker thread and then publishes the results on the UI thread without requiring you to

handle threads andor handlers yourself

To use it you must subclass AsyncTask and implement the doInBackground() callback method which

runs in a pool of background threads To update your UI you should implement onPostExecute()

which delivers the result from doInBackground() and runs in the UI thread so you can safely update

your UI You can then run the task by calling execute() from the UI thread

For example you can implement the previous example using AsyncTask this way

public void onClick(View v) new DownloadImageTask()execute(httpexamplecomimagepng) private class DownloadImageTask extends AsyncTaskltString Void Bitmapgt The system calls this to perform work in a worker thread and delivers it the parameters given to AsyncTaskexecute() protected Bitmap doInBackground(String urls) return loadImageFromNetwork(urls[0])

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 11: 03 services

There are multiple ways to implement a bound service and the implementation is more complicated

than a started service so the bound service discussion appears in a separate document about Bound

Services

Sending Notifications to the User

Once running a service can notify the user of events using Toast Notifications or Status Bar

Notifications

A toast notification is a message that appears on the surface of the current window for a moment then

disappears while a status bar notification provides an icon in the status bar with a message which the

user can select in order to take an action (such as start an activity)

Usually a status bar notification is the best technique when some background work has completed

(such as a file completed downloading) and the user can now act on it When the user selects the

notification from the expanded view the notification can start an activity (such as to view the

downloaded file)

See the Toast Notifications or Status Bar Notifications developer guides for more information

Running a Service in the Foreground

A foreground service is a service thats considered to be something the user is actively aware of and

thus not a candidate for the system to kill when low on memory A foreground service must provide a

notification for the status bar which is placed under the Ongoing heading which means that the

notification cannot be dismissed unless the service is either stopped or removed from the foreground

For example a music player that plays music from a service should be set to run in the foreground

because the user is explicitly aware of its operation The notification in the status bar might indicate the

current song and allow the user to launch an activity to interact with the music player

To request that your service run in the foreground call startForeground() This method takes two

parameters an integer that uniquely identifies the notification and the Notification for the status bar

For example

Notification notification = new Notification(Rdrawableicon getText(Rstringticker_text) SystemcurrentTimeMillis()) Intent notificationIntent = new Intent(this ExampleActivityclass) PendingIntent pendingIntent = PendingIntentgetActivity(this 0 notificationIntent 0) notificationsetLatestEventInfo(this getText(Rstringnotification_title) getText(Rstringnotification_message) pendingIntent) startForeground(ONGOING_NOTIFICATION notification)

To remove the service from the foreground call stopForeground() This method takes a boolean

indicating whether to remove the status bar notification as well This method does not stop the service

However if you stop the service while its still running in the foreground then the notification is also

removed

Note The methods startForeground() and stopForeground() were introduced in Android 20 (API

Level 5) In order to run your service in the foreground on older versions of the platform you must

use the previous setForeground() methodmdashsee the startForeground() documentation for

information about how to provide backward compatibility

For more information about notifications see Creating Status Bar Notifications

Managing the Lifecycle of a Service

The lifecycle of a service is much simpler than that of an activity However its even more important

that you pay close attention to how your service is created and destroyed because a service can run

in the background without the user being aware

The service lifecyclemdashfrom when its created to when its destroyedmdashcan follow two different paths

A started service

The service is created when another component calls startService() The service then runs indefinitely

and must stop itself by calling stopSelf() Another component can also stop the service by calling

stopService() When the service is stopped the system destroys it

A bound service

The service is created when another component (a client) calls bindService() The client then

communicates with the service through an IBinder interface The client can close the connection by

calling unbindService() Multiple clients can bind to the same service and when all of them unbind the

system destroys the service (The service does not need to stop itself)

These two paths are not entirely separate That is you can bind to a service that was already started

with startService() For example a background music service could be started by calling startService()

with an Intent that identifies the music to play Later possibly when the user wants to exercise some

control over the player or get information about the current song an activity can bind to the service by

calling bindService() In cases like this stopService() or stopSelf() does not actually stop the service

until all clients unbind

Implementing the lifecycle callbacks

Like an activity a service has lifecycle callback methods that you can implement to monitor changes in

the services state and perform work at the appropriate times The following skeleton service

demonstrates each of the lifecycle methods

Figure 2 The service lifecycle The diagram on the left shows the lifecycle when the service is created

with startService() and the diagram on the right shows the lifecycle when the service is created with

bindService()

public class ExampleService extends Service int mStartMode indicates how to behave if the service is killed IBinder mBinder interface for clients that bind boolean mAllowRebind indicates whether onRebind should be used Override public void onCreate() The service is being created Override public int onStartCommand(Intent intent int flags int startId) The service is starting due to a call to startService() return mStartMode Override public IBinder onBind(Intent intent) A client is binding to the service with bindService() return mBinder Override public boolean onUnbind(Intent intent) All clients have unbound with unbindService()

return mAllowRebind Override public void onRebind(Intent intent) A client is binding to the service with bindService() after onUnbind() has already been called Override public void onDestroy() The service is no longer used and is being destroyed

Note Unlike the activity lifecycle callback methods you are not required to call the superclass

implementation of these callback methods

By implementing these methods you can monitor two nested loops of the services lifecycle

The entire lifetime of a service happens between the time onCreate() is called and the time

onDestroy() returns Like an activity a service does its initial setup in onCreate() and releases all

remaining resources in onDestroy() For example a music playback service could create the thread

where the music will be played in onCreate() then stop the thread in onDestroy()

The onCreate() and onDestroy() methods are called for all services whether theyre created by

startService() or bindService()

The active lifetime of a service begins with a call to either onStartCommand() or onBind() Each

method is handed the Intent that was passed to either startService() or bindService() respectively

If the service is started the active lifetime ends the same time that the entire lifetime ends (the service

is still active even after onStartCommand() returns) If the service is bound the active lifetime ends

when onUnbind() returns

Note Although a started service is stopped by a call to either stopSelf() or stopService() there is

not a respective callback for the service (theres no onStop() callback) So unless the service is

bound to a client the system destroys it when the service is stoppedmdashonDestroy() is the only

callback received

Figure 2 illustrates the typical callback methods for a service Although the figure separates services

that are created by startService() from those created by bindService() keep in mind that any service

no matter how its started can potentially allow clients to bind to it So a service that was initially

started with onStartCommand() (by a client calling startService()) can still receive a call to onBind()

(when a client calls bindService())

For more information about creating a service that provides binding see the Bound Services

document which includes more information about the onRebind() callback method in the section about

Managing the Lifecycle of a Bound Service

Bound Services

A bound service is the server in a client-server interface A bound service allows components (such as

activities) to bind to the service send requests receive responses and even perform interprocess

communication (IPC) A bound service typically lives only while it serves another application

component and does not run in the background indefinitely

This document shows you how to create a bound service including how to bind to the service from

other application components However you should also refer to the Services document for additional

information about services in general such as how to deliver notifications from a service set the

service to run in the foreground and more

The Basics

A bound service is an implementation of the Service class that allows other applications to bind to it

and interact with it To provide binding for a service you must implement the onBind() callback

method This method returns an IBinder object that defines the programming interface that clients can

use to interact with the service

Binding to a Started Service

As discussed in the Services document you can create a service that is both started and bound That

is the service can be started by calling startService() which allows the service to run indefinitely and

also allow a client to bind to the service by calling bindService()

If you do allow your service to be started and bound then when the service has been started the

system does not destroy the service when all clients unbind Instead you must explicitly stop the

service by calling stopSelf() or stopService()

Although you should usually implement either onBind() or onStartCommand() its sometimes

necessary to implement both For example a music player might find it useful to allow its service to run

indefinitely and also provide binding This way an activity can start the service to play some music and

the music continues to play even if the user leaves the application Then when the user returns to the

application the activity can bind to the service to regain control of playback

Be sure to read the section about Managing the Lifecycle of a Bound Service for more information

about the service lifecycle when adding binding to a started service

A client can bind to the service by calling bindService() When it does it must provide an

implementation of ServiceConnection which monitors the connection with the service The

bindService() method returns immediately without a value but when the Android system creates the

connection between the client and service it calls onServiceConnected() on the ServiceConnection to

deliver the IBinder that the client can use to communicate with the service

Multiple clients can connect to the service at once However the system calls your services onBind()

method to retrieve the IBinder only when the first client binds The system then delivers the same

IBinder to any additional clients that bind without calling onBind() again

When the last client unbinds from the service the system destroys the service (unless the service was

also started by startService())

When you implement your bound service the most important part is defining the interface that your

onBind() callback method returns There are a few different ways you can define your services IBinder

interface and the following section discusses each technique

Creating a Bound Service

When creating a service that provides binding you must provide an IBinder that provides the

programming interface that clients can use to interact with the service There are three ways you can

define the interface

Extending the Binder class

If your service is private to your own application and runs in the same process as the client

(which is common) you should create your interface by extending the Binder class and

returning an instance of it from onBind() The client receives the Binder and can use it to directly

access public methods available in either the Binder implementation or even the Service

This is the preferred technique when your service is merely a background worker for your own

application The only reason you would not create your interface this way is because your

service is used by other applications or across separate processes

Using a Messenger

If you need your interface to work across different processes you can create an interface for the

service with a Messenger In this manner the service defines a Handler that responds to

different types of Message objects This Handler is the basis for a Messenger that can then

share an IBinder with the client allowing the client to send commands to the service using

Message objects Additionally the client can define a Messenger of its own so the service can

send messages back

This is the simplest way to perform interprocess communication (IPC) because the Messenger

queues all requests into a single thread so that you dont have to design your service to be

thread-safe

Using AIDL

AIDL (Android Interface Definition Language) performs all the work to decompose objects into

primitives that the operating system can understand and marshall them across processes to

perform IPC The previous technique using a Messenger is actually based on AIDL as its

underlying structure As mentioned above the Messenger creates a queue of all the client

requests in a single thread so the service receives requests one at a time If however you

want your service to handle multiple requests simultaneously then you can use AIDL directly In

this case your service must be capable of multi-threading and be built thread-safe

To use AIDL directly you must create an aidl file that defines the programming interface The

Android SDK tools use this file to generate an abstract class that implements the interface and

handles IPC which you can then extend within your service

Note Most applications should not use AIDL to create a bound service because it may require

multithreading capabilities and can result in a more complicated implementation As such AIDL is

not suitable for most applications and this document does not discuss how to use it for your

service If youre certain that you need to use AIDL directly see the AIDL document

Extending the Binder class

If your service is used only by the local application and does not need to work across processes then

you can implement your own Binder class that provides your client direct access to public methods in

the service

Note This works only if the client and service are in the same application and process which is

most common For example this would work well for a music application that needs to bind an

activity to its own service thats playing music in the background

Heres how to set it up

1 In your service create an instance of Binder that either

o contains public methods that the client can call

o returns the current Service instance which has public methods the client can call

o or returns an instance of another class hosted by the service with public methods the client can call

2 Return this instance of Binder from the onBind() callback method

3 In the client receive the Binder from the onServiceConnected() callback method and make calls to the

bound service using the methods provided

Note The reason the service and client must be in the same application is so the client can cast

the returned object and properly call its APIs The service and client must also be in the same

process because this technique does not perform any marshalling across processes

For example heres a service that provides clients access to methods in the service through a Binder

implementation

public class LocalService extends Service

Binder given to clients

private final IBinder mBinder = new LocalBinder()

Random number generator

private final Random mGenerator = new Random()

Class used for the client Binder Because we know this service always

runs in the same process as its clients we dont need to deal with IPC

public class LocalBinder extends Binder

LocalService getService()

Return this instance of LocalService so clients can call public methods

return LocalServicethis

Override

public IBinder onBind(Intent intent)

return mBinder

method for clients

public int getRandomNumber()

return mGeneratornextInt(100)

The LocalBinder provides the getService() method for clients to retrieve the current instance of

LocalService This allows clients to call public methods in the service For example clients can call

getRandomNumber() from the service

Heres an activity that binds to LocalService and calls getRandomNumber() when a button is clicked

public class BindingActivity extends Activity

LocalService mService

boolean mBound = false

Override

protected void onCreate(Bundle savedInstanceState)

superonCreate(savedInstanceState)

setContentView(Rlayoutmain)

Override

protected void onStart()

superonStart()

Bind to LocalService

Intent intent = new Intent(this LocalServiceclass)

bindService(intent mConnection ContextBIND_AUTO_CREATE)

Override

protected void onStop()

superonStop()

Unbind from the service

if (mBound)

unbindService(mConnection)

mBound = false

Called when a button is clicked (the button in the layout file attaches to

this method with the androidonClick attribute)

public void onButtonClick(View v)

if (mBound)

Call a method from the LocalService

However if this call were something that might hang then this request should

occur in a separate thread to avoid slowing down the activity performance

int num = mServicegetRandomNumber()

ToastmakeText(this number + num ToastLENGTH_SHORT)show()

Defines callbacks for service binding passed to bindService()

private ServiceConnection mConnection = new ServiceConnection()

Override

public void onServiceConnected(ComponentName className

IBinder service)

Weve bound to LocalService cast the IBinder and get LocalService instance

LocalBinder binder = (LocalBinder) service

mService = bindergetService()

mBound = true

Override

public void onServiceDisconnected(ComponentName arg0)

mBound = false

The above sample shows how the client binds to the service using an implementation of

ServiceConnection and the onServiceConnected() callback The next section provides more

information about this process of binding to the service

Note The example above doesnt explicitly unbind from the service but all clients should unbind

at an appropriate time (such as when the activity pauses)

For more sample code see the LocalServicejava class and the LocalServiceActivitiesjava class in

ApiDemos

Using a Messenger

Compared to AIDL

When you need to perform IPC using a Messenger for your interface is simpler than implementing it

with AIDL because Messenger queues all calls to the service whereas a pure AIDL interface sends

simultaneous requests to the service which must then handle multi-threading

For most applications the service doesnt need to perform multi-threading so using a Messenger

allows the service to handle one call at a time If its important that your service be multi-threaded then

you should use AIDL to define your interface

If you need your service to communicate with remote processes then you can use a Messenger to

provide the interface for your service This technique allows you to perform interprocess

communication (IPC) without the need to use AIDL

Heres a summary of how to use a Messenger

The service implements a Handler that receives a callback for each call from a client

The Handler is used to create a Messenger object (which is a reference to the Handler)

The Messenger creates an IBinder that the service returns to clients from onBind()

Clients use the IBinder to instantiate the Messenger (that references the services Handler) which the

client uses to send Message objects to the service

The service receives each Message in its Handlermdashspecifically in the handleMessage() method

In this way there are no methods for the client to call on the service Instead the client delivers

messages (Message objects) that the service receives in its Handler

Heres a simple example service that uses a Messenger interface

public class MessengerService extends Service Command to the service to display a message static final int MSG_SAY_HELLO = 1 Handler of incoming messages from clients class IncomingHandler extends Handler Override public void handleMessage(Message msg) switch (msgwhat) case MSG_SAY_HELLO ToastmakeText(getApplicationContext() hello ToastLENGTH_SHORT)show() break default superhandleMessage(msg) Target we publish for clients to send messages to IncomingHandler final Messenger mMessenger = new Messenger(new IncomingHandler()) When binding to the service we return an interface to our messenger for sending messages to the service Override public IBinder onBind(Intent intent) ToastmakeText(getApplicationContext() binding ToastLENGTH_SHORT)show() return mMessengergetBinder()

Notice that the handleMessage() method in the Handler is where the service receives the incoming

Message and decides what to do based on the what member

All that a client needs to do is create a Messenger based on the IBinder returned by the service and

send a message using send() For example heres a simple activity that binds to the service and

delivers the MSG_SAY_HELLO message to the service

public class ActivityMessenger extends Activity Messenger for communicating with the service Messenger mService = null Flag indicating whether we have called bind on the service boolean mBound Class for interacting with the main interface of the service private ServiceConnection mConnection = new ServiceConnection() public void onServiceConnected(ComponentName className IBinder service) This is called when the connection with the service has been established giving us the object we can use to interact with the service We are communicating with the service using a Messenger so here we get a client-side representation of that from the raw IBinder object mService = new Messenger(service) mBound = true public void onServiceDisconnected(ComponentName className) This is called when the connection with the service has been unexpectedly disconnected -- that is its process crashed mService = null mBound = false public void sayHello(View v) if (mBound) return Create and send a message to the service using a supported what value Message msg = Messageobtain(null MessengerServiceMSG_SAY_HELLO 0 0) try mServicesend(msg) catch (RemoteException e) eprintStackTrace() Override protected void onCreate(Bundle savedInstanceState) superonCreate(savedInstanceState) setContentView(Rlayoutmain)

Override protected void onStart() superonStart() Bind to the service bindService(new Intent(this MessengerServiceclass) mConnection ContextBIND_AUTO_CREATE) Override protected void onStop() superonStop() Unbind from the service if (mBound) unbindService(mConnection) mBound = false

Notice that this example does not show how the service can respond to the client If you want the

service to respond then you need to also create a Messenger in the client Then when the client

receives the onServiceConnected() callback it sends a Message to the service that includes the

clients Messenger in the replyTo parameter of the send() method

You can see an example of how to provide two-way messaging in the MessengerServicejava (service)

and MessengerServiceActivitiesjava (client) samples

Binding to a Service

Application components (clients) can bind to a service by calling bindService() The Android system

then calls the services onBind() method which returns an IBinder for interacting with the service

The binding is asynchronous bindService() returns immediately and does not return the IBinder to the

client To receive the IBinder the client must create an instance of ServiceConnection and pass it to

bindService() The ServiceConnection includes a callback method that the system calls to deliver the

IBinder

Note Only activities services and content providers can bind to a servicemdashyou cannot bind to a

service from a broadcast receiver

So to bind to a service from your client you must

1 Implement ServiceConnection

Your implementation must override two callback methods

onServiceConnected()

The system calls this to deliver the IBinder returned by the services onBind() method

onServiceDisconnected()

The Android system calls this when the connection to the service is unexpectedly lost such as

when the service has crashed or has been killed This is not called when the client unbinds

2 Call bindService() passing the ServiceConnection implementation

3 When the system calls your onServiceConnected() callback method you can begin making calls to the

service using the methods defined by the interface

4 To disconnect from the service call unbindService()

When your client is destroyed it will unbind from the service but you should always unbind when

youre done interacting with the service or when your activity pauses so that the service can shutdown

while its not being used (Appropriate times to bind and unbind is discussed more below)

For example the following snippet connects the client to the service created above by extending the

Binder class so all it must do is cast the returned IBinder to the LocalService class and request the

LocalService instance

LocalService mService private ServiceConnection mConnection = new ServiceConnection() Called when the connection with the service is established public void onServiceConnected(ComponentName className IBinder service) Because we have bound to an explicit service that is running in our own process we can cast its IBinder to a concrete class and directly access it LocalBinder binder = (LocalBinder) service mService = bindergetService() mBound = true Called when the connection with the service disconnects unexpectedly public void onServiceDisconnected(ComponentName className) Loge(TAG onServiceDisconnected) mBound = false

With this ServiceConnection the client can bind to a service by passing this it to bindService() For

example

Intent intent = new Intent(this LocalServiceclass) bindService(intent mConnection ContextBIND_AUTO_CREATE)

The first parameter of bindService() is an Intent that explicitly names the service to bind (thought the

intent could be implicit)

The second parameter is the ServiceConnection object

The third parameter is a flag indicating options for the binding It should usually be

BIND_AUTO_CREATE in order to create the service if its not already alive Other possible values are

BIND_DEBUG_UNBIND and BIND_NOT_FOREGROUND or 0 for none

Additional notes

Here are some important notes about binding to a service

You should always trap DeadObjectException exceptions which are thrown when the connection has

broken This is the only exception thrown by remote methods

Objects are reference counted across processes

You should usually pair the binding and unbinding during matching bring-up and tear-down moments

of the clients lifecycle For example

o If you only need to interact with the service while your activity is visible you should bind during

onStart() and unbind during onStop()

o If you want your activity to receive responses even while it is stopped in the background then you can

bind during onCreate() and unbind during onDestroy() Beware that this implies that your activity needs

to use the service the entire time its running (even in the background) so if the service is in another

process then you increase the weight of the process and it becomes more likely that the system will

kill it

Note You should usually not bind and unbind during your activitys onResume() and onPause()

because these callbacks occur at every lifecycle transition and you should keep the processing that

occurs at these transitions to a minimum Also if multiple activities in your application bind to the same

service and there is a transition between two of those activities the service may be destroyed and

recreated as the current activity unbinds (during pause) before the next one binds (during resume)

(This activity transition for how activities coordinate their lifecycles is described in the Activities

document)

For more sample code showing how to bind to a service see the RemoteServicejava class in

ApiDemos

Managing the Lifecycle of a Bound Service

Figure 1 The lifecycle for a service

that is started and also allows binding

When a service is unbound from all

clients the Android system destroys it

(unless it was also started with

onStartCommand()) As such you

dont have to manage the lifecycle of

your service if its purely a bound

servicemdashthe Android system manages

it for you based on whether it is bound

to any clients

However if you choose to implement

the onStartCommand() callback

method then you must explicitly stop

the service because the service is

now considered to be started In this

case the service runs until the service

stops itself with stopSelf() or another

component calls stopService()

regardless of whether it is bound to

any clients

Additionally if your service is started and accepts binding then when the system calls your onUnbind()

method you can optionally return true if you would like to receive a call to onRebind() the next time a

client binds to the service (instead of receiving a call to onBind()) onRebind() returns void but the

client still receives the IBinder in its onServiceConnected() callback Below figure 1 illustrates the logic

for this kind of lifecycle

For more information about the lifecycle of an started service see the Services document

Content Providers

Content providers store and retrieve data and make it accessible to all applications Theyre the only

way to share data across applications theres no common storage area that all Android packages can

access

Android ships with a number of content providers for common data types (audio video images

personal contact information and so on) You can see some of them listed in the androidprovider

package You can query these providers for the data they contain (although for some you must

acquire the proper permission to read the data)

If you want to make your own data public you have two options You can create your own content

provider (a ContentProvider subclass) or you can add the data to an existing provider mdash if theres one

that controls the same type of data and you have permission to write to it

This document is an introduction to using content providers After a brief discussion of the

fundamentals it explores how to query a content provider how to modify data controlled by a provider

and how to create a content provider of your own

Content Provider Basics

How a content provider actually stores its data under the covers is up to its designer But all content

providers implement a common interface for querying the provider and returning results mdash as well as

for adding altering and deleting data Its an interface that clients use indirectly most generally

through ContentResolver objects You get a ContentResolver by calling getContentResolver() from

within the implementation of an Activity or other application component

ContentResolver cr = getContentResolver()

You can then use the ContentResolvers methods to interact with whatever content providers youre

interested in When a query is initiated the Android system identifies the content provider thats the

target of the query and makes sure that it is up and running The system instantiates all

ContentProvider objects you never need to do it on your own In fact you never deal directly with

ContentProvider objects at all Typically theres just a single instance of each type of ContentProvider

But it can communicate with multiple ContentResolver objects in different applications and processes

The interaction between processes is handled by the ContentResolver and ContentProvider classes

The data model

Content providers expose their data as a simple table on a database model where each row is a

record and each column is data of a particular type and meaning For example information about

people and their phone numbers might be exposed as follows

_ID NUMBER NUMBER_KEY LABEL NAME TYPE

13 (425) 555 6677 425 555 6677 Kirkland office Bully Pulpit TYPE_WORK

44 (212) 555-1234 212 555 1234 NY apartment Alan Vain TYPE_HOME

45 (212) 555-6657 212 555 6657 Downtown office Alan Vain TYPE_MOBILE

53 2015554433 201 555 4433 Love Nest Rex Cars TYPE_HOME

Every record includes a numeric _ID field that uniquely identifies the record within the table IDs can be

used to match records in related tables mdash for example to find a persons phone number in one table

and pictures of that person in another

A query returns a Cursor object that can move from record to record and column to column to read the

contents of each field It has specialized methods for reading each type of data So to read a field you

must know what type of data the field contains (Theres more on query results and Cursor objects

later)

URIs

Each content provider exposes a public URI (wrapped as a Uri object) that uniquely identifies its data

set A content provider that controls multiple data sets (multiple tables) exposes a separate URI for

each one All URIs for providers begin with the string content The content scheme identifies the

data as being controlled by a content provider

If youre defining a content provider its a good idea to also define a constant for its URI to simplify

client code and make future updates cleaner Android defines CONTENT_URI constants for all the

providers that come with the platform For example the URI for the table that matches phone numbers

to people and the URI for the table that holds pictures of people (both controlled by the Contacts

content provider) are

androidproviderContactsPhonesCONTENT_URI

androidproviderContactsPhotosCONTENT_URI

The URI constant is used in all interactions with the content provider Every ContentResolver method

takes the URI as its first argument Its what identifies which provider the ContentResolver should talk

to and which table of the provider is being targeted

Querying a Content Provider

You need three pieces of information to query a content provider

The URI that identifies the provider

The names of the data fields you want to receive

The data types for those fields

If youre querying a particular record you also need the ID for that record

Making the query

To query a content provider you can use either the ContentResolverquery() method or the

ActivitymanagedQuery() method Both methods take the same set of arguments and both return a

Cursor object However managedQuery() causes the activity to manage the life cycle of the Cursor A

managed Cursor handles all of the niceties such as unloading itself when the activity pauses and

requerying itself when the activity restarts You can ask an Activity to begin managing an unmanaged

Cursor object for you by calling ActivitystartManagingCursor()

The first argument to either query() or managedQuery() is the provider URI mdash the CONTENT_URI

constant that identifies a particular ContentProvider and data set (see URIs earlier)

To restrict a query to just one record you can append the _ID value for that record to the URI mdash that

is place a string matching the ID as the last segment of the path part of the URI For example if the ID

is 23 the URI would be

content 23

There are some helper methods particularly ContentUriswithAppendedId() and

UriwithAppendedPath() that make it easy to append an ID to a URI Both are static methods that

return a Uri object with the ID added So for example if you were looking for record 23 in the database

of people contacts you might construct a query as follows

import androidproviderContactsPeople import androidcontentContentUris import androidnetUri import androiddatabaseCursor Use the ContentUris method to produce the base URI for the contact with _ID == 23 Uri myPerson = ContentUriswithAppendedId(PeopleCONTENT_URI 23) Alternatively use the Uri method to produce the base URI It takes a string rather than an integer Uri myPerson = UriwithAppendedPath(PeopleCONTENT_URI 23) Then query for this specific record Cursor cur = managedQuery(myPerson null null null null)

The other arguments to the query() and managedQuery() methods delimit the query in more detail

They are

The names of the data columns that should be returned A null value returns all columns Otherwise

only columns that are listed by name are returned All the content providers that come with the

platform define constants for their columns For example the androidproviderContactsPhones class

defines constants for the names of the columns in the phone table illustrated earlier ampmdash _ID

NUMBER NUMBER_KEY NAME and so on

A filter detailing which rows to return formatted as an SQL WHERE clause (excluding the WHERE

itself) A null value returns all rows (unless the URI limits the query to a single record)

Selection arguments

A sorting order for the rows that are returned formatted as an SQL ORDER BY clause (excluding the

ORDER BY itself) A null value returns the records in the default order for the table which may be

unordered

Lets look at an example query to retrieve a list of contact names and their primary phone numbers

import androidproviderContactsPeople import androiddatabaseCursor Form an array specifying which columns to return String[] projection = new String[] People_ID People_COUNT PeopleNAME PeopleNUMBER Get the base URI for the People table in the Contacts content provider Uri contacts = PeopleCONTENT_URI Make the query Cursor managedCursor = managedQuery(contacts projection Which columns to return null Which rows to return (all rows) null Selection arguments (none) Put the results in ascending order by name PeopleNAME + ASC)

This query retrieves data from the People table of the Contacts content provider It gets the name

primary phone number and unique record ID for each contact It also reports the number of records

that are returned as the _COUNT field of each record

The constants for the names of the columns are defined in various interfaces mdash _ID and _COUNT in

BaseColumns NAME in PeopleColumns and NUMBER in PhoneColumns The ContactsPeople

class implements each of these interfaces which is why the code example above could refer to them

using just the class name

What a query returns

A query returns a set of zero or more database records The names of the columns their default order

and their data types are specific to each content provider But every provider has an _ID column

which holds a unique numeric ID for each record Every provider can also report the number of records

returned as the _COUNT column its value is the same for all rows

Here is an example result set for the query in the previous section

_ID _COUNT NAME NUMBER

44 3 Alan Vain 212 555 1234

13 3 Bully Pulpit 425 555 6677

53 3 Rex Cars 201 555 4433

The retrieved data is exposed by a Cursor object that can be used to iterate backward or forward

through the result set You can use this object only to read the data To add modify or delete data

you must use a ContentResolver object

Reading retrieved data

The Cursor object returned by a query provides access to a recordset of results If you have queried

for a specific record by ID this set will contain only one value Otherwise it can contain multiple

values (If there are no matches it can also be empty) You can read data from specific fields in the

record but you must know the data type of the field because the Cursor object has a separate method

for reading each type of data mdash such as getString() getInt() and getFloat() (However for most types

if you call the method for reading strings the Cursor object will give you the String representation of

the data) The Cursor lets you request the column name from the index of the column or the index

number from the column name

The following snippet demonstrates reading names and phone numbers from the query illustrated

earlier

import androidproviderContactsPeople private void getColumnData(Cursor cur) if (curmoveToFirst()) String name String phoneNumber int nameColumn = curgetColumnIndex(PeopleNAME) int phoneColumn = curgetColumnIndex(PeopleNUMBER) String imagePath do Get the field values name = curgetString(nameColumn) phoneNumber = curgetString(phoneColumn) Do something with the values while (curmoveToNext())

If a query can return binary data such as an image or sound the data may be directly entered in the

table or the table entry for that data may be a string specifying a content URI that you can use to get

the data In general smaller amounts of data (say from 20 to 50K or less) are most often directly

entered in the table and can be read by calling CursorgetBlob() It returns a byte array

If the table entry is a content URI you should never try to open and read the file directly (for one thing

permissions problems can make this fail) Instead you should call ContentResolveropenInputStream()

to get an InputStream object that you can use to read the data

Modifying Data

Data kept by a content provider can be modified by

Adding new records

Adding new values to existing records

Batch updating existing records

Deleting records

All data modification is accomplished using ContentResolver methods Some content providers require

a more restrictive permission for writing data than they do for reading it If you dont have permission to

write to a content provider the ContentResolver methods will fail

Adding records

To add a new record to a content provider first set up a map of key-value pairs in a ContentValues

object where each key matches the name of a column in the content provider and the value is the

desired value for the new record in that column Then call ContentResolverinsert() and pass it the URI

of the provider and the ContentValues map This method returns the full URI of the new record mdash that

is the providers URI with the appended ID for the new record You can then use this URI to query and

get a Cursor over the new record and to further modify the record Heres an example

import androidproviderContactsPeople import androidcontentContentResolver import androidcontentContentValues ContentValues values = new ContentValues() Add Abraham Lincoln to contacts and make him a favorite valuesput(PeopleNAME Abraham Lincoln) 1 = the new contact is added to favorites 0 = the new contact is not added to favorites valuesput(PeopleSTARRED 1) Uri uri = getContentResolver()insert(PeopleCONTENT_URI values)

Adding new values

Once a record exists you can add new information to it or modify existing information For example

the next step in the example above would be to add contact information mdash like a phone number or an

IM or e-mail address mdash to the new entry

The best way to add to a record in the Contacts database is to append the name of the table where the

new data goes to the URI for the record then use the amended URI to add the new data values Each

Contacts table exposes a name for this purpose as a CONTENT_DIRECTORY constant The following

code continues the previous example by adding a phone number and e-mail address for the record

just created

Uri phoneUri = null Uri emailUri = null Add a phone number for Abraham Lincoln Begin with the URI for the new record just returned by insert() it ends with the _ID of the new record so we dont have to add the ID ourselves Then append the designation for the phone table to this URI and use the resulting URI to insert the phone number phoneUri = UriwithAppendedPath(uri PeoplePhonesCONTENT_DIRECTORY) valuesclear() valuesput(PeoplePhonesTYPE PeoplePhonesTYPE_MOBILE) valuesput(PeoplePhonesNUMBER 1233214567) getContentResolver()insert(phoneUri values) Now add an email address in the same way emailUri = UriwithAppendedPath(uri PeopleContactMethodsCONTENT_DIRECTORY) valuesclear() ContactMethodsKIND is used to distinguish different kinds of contact methods such as email IM etc valuesput(PeopleContactMethodsKIND ContactsKIND_EMAIL) valuesput(PeopleContactMethodsDATA testexamplecom) valuesput(PeopleContactMethodsTYPE PeopleContactMethodsTYPE_HOME) getContentResolver()insert(emailUri values)

You can place small amounts of binary data into a table by calling the version of ContentValuesput()

that takes a byte array That would work for a small icon-like image or a short audio clip for example

However if you have a large amount of binary data to add such as a photograph or a complete song

put a content URI for the data in the table and call ContentResolveropenOutputStream() with the files

URI (That causes the content provider to store the data in a file and record the file path in a hidden

field of the record)

In this regard the MediaStore content provider the main provider that dispenses image audio and

video data employs a special convention The same URI that is used with query() or managedQuery()

to get meta-information about the binary data (such as the caption of a photograph or the date it was

taken) is used with openInputStream() to get the data itself Similarly the same URI that is used with

insert() to put meta-information into a MediaStore record is used with openOutputStream() to place the

binary data there The following code snippet illustrates this convention

import androidproviderMediaStoreImagesMedia import androidcontentContentValues import javaioOutputStream Save the name and description of an image in a ContentValues map ContentValues values = new ContentValues(3) valuesput(MediaDISPLAY_NAME road_trip_1) valuesput(MediaDESCRIPTION Day 1 trip to Los Angeles) valuesput(MediaMIME_TYPE imagejpeg) Add a new record without the bitmap but with the values just set insert() returns the URI of the new record Uri uri = getContentResolver()insert(MediaEXTERNAL_CONTENT_URI values) Now get a handle to the file for that record and save the data into it Here sourceBitmap is a Bitmap object representing the file to save to the database try OutputStream outStream = getContentResolver()openOutputStream(uri) sourceBitmapcompress(BitmapCompressFormatJPEG 50 outStream) outStreamclose() catch (Exception e) Loge(TAG exception while writing image e)

Batch updating records

To batch update a group of records (for example to change NY to New York in all fields) call the

ContentResolverupdate() method with the columns and values to change

Deleting a record

To delete a single record call ContentResolverdelete() with the URI of a specific row

To delete multiple rows call ContentResolverdelete() with the URI of the type of record to delete (for

example androidproviderContactsPeopleCONTENT_URI) and an SQL WHERE clause defining

which rows to delete (Caution Be sure to include a valid WHERE clause if youre deleting a general

type or you risk deleting more records than you intended)

Creating a Content Provider

To create a content provider you must

Set up a system for storing the data Most content providers store their data using Androids file

storage methods or SQLite databases but you can store your data any way you want Android

provides the SQLiteOpenHelper class to help you create a database and SQLiteDatabase to manage

it

Extend the ContentProvider class to provide access to the data

Declare the content provider in the manifest file for your application (AndroidManifestxml)

The following sections have notes on the last two of these tasks

Extending the ContentProvider class

You define a ContentProvider subclass to expose your data to others using the conventions expected

by ContentResolver and Cursor objects Principally this means implementing six abstract methods

declared in the ContentProvider class

query()

insert()

update()

delete()

getType()

onCreate()

The query() method must return a Cursor object that can iterate over the requested data Cursor itself

is an interface but Android provides some ready-made Cursor objects that you can use For example

SQLiteCursor can iterate over data stored in an SQLite database You get the Cursor object by calling

any of the SQLiteDatabase classs query() methods There are other Cursor implementations mdash such

as MatrixCursor mdash for data not stored in a database

Because these ContentProvider methods can be called from various ContentResolver objects in

different processes and threads they must be implemented in a thread-safe manner

As a courtesy you might also want to call ContentResolvernotifyChange() to notify listeners when

there are modifications to the data

Beyond defining the subclass itself there are other steps you should take to simplify the work of clients

and make the class more accessible

Define a public static final Uri named CONTENT_URI This is the string that represents the full content

URI that your content provider handles You must define a unique string for this value The best

solution is to use the fully-qualified class name of the content provider (made lowercase) So for

example the URI for a TransportationProvider class could be defined as follows

public static final Uri CONTENT_URI = Uriparse(contentcomexamplecodelabtransportationprovider)

If the provider has subtables also define CONTENT_URI constants for each of the subtables These

URIs should all have the same authority (since that identifies the content provider) and be

distinguished only by their paths For example

contentcomexamplecodelabtransportationprovidertrain

contentcomexamplecodelabtransportationproviderairdomestic

contentcomexamplecodelabtransportationproviderairinternational

For an overview of content URIs see the Content URI Summary at the end of this document

Define the column names that the content provider will return to clients If you are using an underlying

database these column names are typically identical to the SQL database column names they

represent Also define public static String constants that clients can use to specify the columns in

queries and other instructions

Be sure to include an integer column named _id (with the constant _ID) for the IDs of the records

You should have this field whether or not you have another field (such as a URL) that is also unique

among all records If youre using the SQLite database the _ID field should be the following type

INTEGER PRIMARY KEY AUTOINCREMENT

The AUTOINCREMENT descriptor is optional But without it SQLite increments an ID counter field to

the next number above the largest existing number in the column If you delete the last row the next

row added will have the same ID as the deleted row AUTOINCREMENT avoids this by having SQLite

increment to the next largest value whether deleted or not

Carefully document the data type of each column Clients need this information to read the data

If you are handling a new data type you must define a new MIME type to return in your

implementation of ContentProvidergetType() The type depends in part on whether or not the content

URI submitted to getType() limits the request to a specific record Theres one form of the MIME type

for a single record and another for multiple records Use the Uri methods to help determine what is

being requested Here is the general format for each type

o For a single record vndandroidcursoritemvndyourcompanynamecontenttype

For example a request for train record 122 like this URI

contentcomexampletransportationprovidertrains122

might return this MIME type

vndandroidcursoritemvndexamplerail

o For multiple records vndandroidcursordirvndyourcompanynamecontenttype

For example a request for all train records like the following URI

contentcomexampletransportationprovidertrains

might return this MIME type

vndandroidcursordirvndexamplerail

If you are exposing byte data thats too big to put in the table itself mdash such as a large bitmap file mdash the

field that exposes the data to clients should actually contain a content URI string This is the field that

gives clients access to the data file The record should also have another field named _data that lists

the exact file path on the device for that file This field is not intended to be read by the client but by

the ContentResolver The client will call ContentResolveropenInputStream() on the user-facing field

holding the URI for the item The ContentResolver will request the _data field for that record and

because it has higher permissions than a client it should be able to access that file directly and return

a read wrapper for the file to the client

For an example of a private content provider implementation see the NodePadProvider class in the

Notepad sample application that ships with the SDK

Declaring the content provider

To let the Android system know about the content provider youve developed declare it with a

ltprovidergt element in the applications AndroidManifestxml file Content providers that are not

declared in the manifest are not visible to the Android system

The name attribute is the fully qualified name of the ContentProvider subclass The authorities attribute

is the authority part of the content URI that identifies the provider For example if the ContentProvider

subclass is AutoInfoProvider the ltprovidergt element might look like this

ltprovider androidname=comexampleautosAutoInfoProvider androidauthorities=comexampleautosautoinfoprovider gt ltprovidergt

Note that the authorities attribute omits the path part of a content URI For example if

AutoInfoProvider controlled subtables for different types of autos or different manufacturers

contentcomexampleautosautoinfoproviderhonda

contentcomexampleautosautoinfoprovidergmcompact

contentcomexampleautosautoinfoprovidergmsuv

those paths would not be declared in the manifest The authority is what identifies the provider not the

path your provider can interpret the path part of the URI in any way you choose

Other ltprovidergt attributes can set permissions to read and write data provide for an icon and text

that can be displayed to users enable and disable the provider and so on Set the multiprocess

attribute to true if data does not need to be synchronized between multiple running versions of the

content provider This permits an instance of the provider to be created in each client process

eliminating the need to perform IPC

Content URI Summary

Here is a recap of the important parts of a content URI

A Standard prefix indicating that the data is controlled by a content provider Its never modified

B The authority part of the URI it identifies the content provider For third-party applications this should

be a fully-qualified class name (reduced to lowercase) to ensure uniqueness The authority is declared

in the ltprovidergt elements authorities attribute

ltprovider androidname=TransportationProvider androidauthorities=comexampletransportationprovider gt

C The path that the content provider uses to determine what kind of data is being requested This can be

zero or more segments long If the content provider exposes only one type of data (only trains for

example) it can be absent If the provider exposes several types including subtypes it can be several

segments long mdash for example landbus landtrain seaship and seasubmarine to give four

possibilities

D The ID of the specific record being requested if any This is the _ID value of the requested record If

the request is not limited to a single record this segment and the trailing slash are omitted

contentcomexampletransportationprovidertrains

Intent and intent filters

Three of the core components of an application mdash activities services and broadcast receivers mdash 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 mdash 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 ContextstartActivity() or ActivitystartActivityForResult() to launch an

activity or get an existing activity to do something new (It can also be passed to ActivitysetResult() to

return information to the activity that called startActivityForResult())

An Intent object is passed to ContextstartService() to initiate a service or deliver new instructions to an

ongoing service Similarly an intent can be passed to ContextbindService() to establish a connection

between the calling component and a target service It can optionally initiate the service if its not

already running

Intent objects passed to any of the broadcast methods (such as ContextsendBroadcast()

ContextsendOrderedBroadcast() or ContextsendStickyBroadcast()) 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 mdash how it resolves which component should receive an intent message For

intents that dont explicitly name a target component this process involves testing the Intent object

against intent filters associated with potential targets

Intent Objects

An Intent object is a bundle of information It contains information of interest to the component that

receives the intent (such as the action to be taken and the data to act on) plus information of interest to

the Android system (such as the category of component that should handle the intent and instructions

on how to launch a target activity) Principally it can contain the following

Component name

The name of the component that should handle the intent This field is a ComponentName

object mdash a combination of the fully qualified class name of the target component (for example

comexampleprojectappFreneticActivity) and the package name set in the manifest file of the

application where the component resides (for example comexampleproject) The package

part of the component name and the package name set in the manifest do not necessarily have

to match

The component name is optional If it is set the Intent object is delivered to an instance of the

designated class If it is not set Android uses other information in the Intent object to locate a

suitable target mdash see Intent Resolution later in this document

The component name is set by setComponent() setClass() or setClassName() and read by

getComponent()

Action

A string naming the action to be performed mdash or in the case of broadcast intents the action

that took place and is being reported The Intent class defines a number of action constants

including these

Constant Target

component

Action

ACTION_CALL activity Initiate a phone call

ACTION_EDIT activity Display data for the user to edit

ACTION_MAIN activity Start up as the initial activity of a task

with no data input and no returned

output

ACTION_SYNC activity Synchronize data on a server with

data on the mobile device

ACTION_BATTERY_LOW broadcast

receiver

A warning that the battery is low

ACTION_HEADSET_PLUG broadcast

receiver

A headset has been plugged into the

device or unplugged from it

ACTION_SCREEN_ON broadcast

receiver

The screen has been turned on

ACTION_TIMEZONE_CHANGED broadcast

receiver

The setting for the time zone has

changed

See the Intent class description for a list of pre-defined constants for generic actions Other

actions are defined elsewhere in the Android API You can also define your own action strings

for activating the components in your application Those you invent should include the

application package as a prefix mdash for example comexampleprojectSHOW_COLOR

The action largely determines how the rest of the intent is structured mdash particularly the data and

extras fields mdash much as a method name determines a set of arguments and a return value For

this reason its a good idea to use action names that are as specific as possible and to couple

them tightly to the other fields of the intent In other words instead of defining an action in

isolation define an entire protocol for the Intent objects your components can handle

The action in an Intent object is set by the setAction() method and read by getAction()

Data

The URI of the data to be acted on and the MIME type of that data Different actions are paired

with different kinds of data specifications For example if the action field is ACTION_EDIT the

data field would contain the URI of the document to be displayed for editing If the action is

ACTION_CALL the data field would be a tel URI with the number to call Similarly if the action

is ACTION_VIEW and the data field is an http URI the receiving activity would be called upon

to download and display whatever data the URI refers to

When matching an intent to a component that is capable of handling the data its often

important to know the type of data (its MIME type) in addition to its URI For example a

component able to display image data should not be called upon to play an audio file

In many cases the data type can be inferred from the URI mdash particularly content URIs which

indicate that the data is located on the device and controlled by a content provider (see the

separate discussion on content providers) But the type can also be explicitly set in the Intent

object The setData() method specifies data only as a URI setType() specifies it only as a

MIME type and setDataAndType() specifies it as both a URI and a MIME type The URI is read

by getData() and the type by getType()

Category

A string containing additional information about the kind of component that should handle the

intent Any number of category descriptions can be placed in an Intent object As it does for

actions the Intent class defines several category constants including these

Constant Meaning

CATEGORY_BROWSABLE The target activity can be safely invoked by the browser to

display data referenced by a link mdash for example an image or

an e-mail message

CATEGORY_GADGET The activity can be embedded inside of another activity that

hosts gadgets

CATEGORY_HOME The activity displays the home screen the first screen the

user sees when the device is turned on or when the HOME

key is pressed

CATEGORY_LAUNCHER The activity can be the initial activity of a task and is listed in

the top-level application launcher

CATEGORY_PREFERENCE The target activity is a preference panel

See the Intent class description for the full list of categories

The addCategory() method places a category in an Intent object removeCategory() deletes a

category previously added and getCategories() gets the set of all categories currently in the

object

Extras

Key-value pairs for additional information that should be delivered to the component handling

the intent Just as some actions are paired with particular kinds of data URIs some are paired

with particular extras For example an ACTION_TIMEZONE_CHANGED intent has a time-

zone extra that identifies the new time zone and ACTION_HEADSET_PLUG has a state

extra indicating whether the headset is now plugged in or unplugged as well as a name extra

for the type of headset If you were to invent a SHOW_COLOR action the color value would be

set in an extra key-value pair

The Intent object has a series of put() methods for inserting various types of extra data and a

similar set of get() methods for reading the data These methods parallel those for Bundle

objects In fact the extras can be installed and read as a Bundle using the putExtras() and

getExtras() methods

Flags

Flags of various sorts Many instruct the Android system how to launch an activity (for example

which task the activity should belong to) and how to treat it after its launched (for example

whether it belongs in the list of recent activities) All these flags are defined in the Intent class

The Android system and the applications that come with the platform employ Intent objects both to

send out system-originated broadcasts and to activate system-defined components To see how to

structure an intent to activate a system component consult the list of intents in the reference

Intent Resolution

Intents can be divided into two groups

Explicit intents designate the target component by its name (the component name field mentioned

earlier has a value set) Since component names would generally not be known to developers of other

applications explicit intents are typically used for application-internal messages mdash such as an activity

starting a subordinate service or launching a sister activity

Implicit intents do not name a target (the field for the component name is blank) Implicit intents are

often used to activate components in other applications

Android delivers an explicit intent to an instance of the designated target class Nothing in the Intent

object other than the component name matters for determining which component should get the intent

A different strategy is needed for implicit intents In the absence of a designated target the Android

system must find the best component (or components) to handle the intent mdash a single activity or

service to perform the requested action or the set of broadcast receivers to respond to the broadcast

announcement It does so by comparing the contents of the Intent object to intent filters structures

associated with components that can potentially receive intents Filters advertise the capabilities of a

component and delimit the intents it can handle They open the component to the possibility of

receiving implicit intents of the advertised type If a component does not have any intent filters it can

receive only explicit intents A component with filters can receive both explicit and implicit intents

Only three aspects of an Intent object are consulted when the object is tested against an intent filter

action

data (both URI and data type)

category

The extras and flags play no part in resolving which component receives an intent

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 mdash but only unwanted implicit intents (those that dont 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

components 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 mdash 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 Pads filters are described in the Note Pad Example

section later)

Filters and security

An intent filter cannot be relied on for security While it opens a component to receiving only certain

kinds of implicit intents it does nothing to prevent explicit intents from targeting the component Even

though a filter restricts the intents a component will be asked to handle to certain actions and data

sources someone could always put together an explicit intent with a different action and data source

and name the component as the target

An intent filter is an instance of the IntentFilter class However since the Android system must know

about the capabilities of a component before it can launch that component intent filters are generally

not set up in Java code but in the applications manifest file (AndroidManifestxml) as ltintent-filtergt

elements (The one exception would be filters for broadcast receivers that are registered dynamically

by calling ContextregisterReceiver() they are directly created as IntentFilter objects)

A filter has fields that parallel the action data and category fields of an Intent object An implicit intent

is tested against the filter in all three areas To be delivered to the component that owns the filter it

must pass all three tests If it fails even one of them the Android system wont deliver it to the

component mdash at least not on the basis of that filter However since a component can have multiple

intent filters an intent that does not pass through one of a components filters might make it through on

another

Each of the three tests is described in detail below

Action test

An ltintent-filtergt element in the manifest file lists actions as ltactiongt subelements For

example

ltintent-filter gt ltaction androidname=comexampleprojectSHOW_CURRENT gt ltaction androidname=comexampleprojectSHOW_RECENT gt ltaction androidname=comexampleprojectSHOW_PENDING gt ltintent-filtergt

As the example shows while an Intent object names just a single action a filter may list more

than one The list cannot be empty a filter must contain at least one ltactiongt element or it will

block all intents

To pass this test the action specified in the Intent object must match one of the actions listed in

the filter If the object or the filter does not specify an action the results are as follows

If the filter fails to list any actions there is nothing for an intent to match so all intents fail the

test No intents can get through the filter

On the other hand an Intent object that doesnt specify an action automatically passes the test

mdash as long as the filter contains at least one action

Category test

An ltintent-filtergt element also lists categories as subelements For example

ltintent-filter gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryBROWSABLE gt ltintent-filtergt

Note that the constants described earlier for actions and categories are not used in the manifest

file The full string values are used instead For instance the

androidintentcategoryBROWSABLE string in the example above corresponds to the

CATEGORY_BROWSABLE constant mentioned earlier in this document Similarly the string

androidintentactionEDIT corresponds to the ACTION_EDIT constant

For an intent to pass the category test every category in the Intent object must match a

category in the filter The filter can list additional categories but it cannot omit any that are in the

intent

In principle therefore an Intent object with no categories should always pass this test

regardless of whats in the filter Thats mostly true However with one exception Android treats

all implicit intents passed to startActivity() as if they contained at least one category

androidintentcategoryDEFAULT (the CATEGORY_DEFAULT constant) Therefore activities

that are willing to receive implicit intents must include androidintentcategoryDEFAULT in

their intent filters (Filters with androidintentactionMAIN and

androidintentcategoryLAUNCHER settings are the exception They mark activities that begin

new tasks and that are represented on the launcher screen They can include

androidintentcategoryDEFAULT in the list of categories but dont need to) See Using intent

matching later for more on these filters)

Data test

Like the action and categories the data specification for an intent filter is contained in a

subelement And as in those cases the subelement can appear multiple times or not at all For

example

ltintent-filter gt ltdata androidmimeType=videompeg androidscheme=http gt ltdata androidmimeType=audiompeg androidscheme=http gt ltintent-filtergt

Each ltdatagt element can specify a URI and a data type (MIME media type) There are

separate attributes mdash scheme host port and path mdash for each part of the URI

schemehostportpath

For example in the following URI

contentcomexampleproject200foldersubfolderetc

the scheme is content the host is comexampleproject the port is 200 and the path is

foldersubfolderetc The host and port together constitute the URI authority if a host is not

specified the port is ignored

Each of these attributes is optional but they are not independent of each other For an authority

to be meaningful a scheme must also be specified For a path to be meaningful both a scheme

and an authority must be specified

When the URI in an Intent object is compared to a URI specification in a filter its compared

only to the parts of the URI actually mentioned in the filter For example if a filter specifies only

a scheme all URIs with that scheme match the filter If a filter specifies a scheme and an

authority but no path all URIs with the same scheme and authority match regardless of their

paths If a filter specifies a scheme an authority and a path only URIs with the same scheme

authority and path match However a path specification in the filter can contain wildcards to

require only a partial match of the path

The type attribute of a ltdatagt element specifies the MIME type of the data Its more common in

filters than a URI Both the Intent object and the filter can use a wildcard for the subtype field

mdash for example text or audio mdash indicating any subtype matches

The data test compares both the URI and the data type in the Intent object to a URI and data

type specified in the filter The rules are as follows

a An Intent object that contains neither a URI nor a data type passes the test only if the filter

likewise does not specify any URIs or data types

b An Intent object that contains a URI but no data type (and a type cannot be inferred from the

URI) passes the test only if its URI matches a URI in the filter and the filter likewise does not

specify a type This will be the case only for URIs like mailto and tel that do not refer to actual

data

c An Intent object that contains a data type but not a URI passes the test only if the filter lists the

same data type and similarly does not specify a URI

d An Intent object that contains both a URI and a data type (or a data type can be inferred from

the URI) passes the data type part of the test only if its type matches a type listed in the filter It

passes the URI part of the test either if its URI matches a URI in the filter or if it has a content

or file URI and the filter does not specify a URI In other words a component is presumed to

support content and file data if its filter lists only a data type

If an intent can pass through the filters of more than one activity or service the user may be asked

which component to activate An exception is raised if no target can be found

Common cases

The last rule shown above for the data test rule (d) reflects the expectation that components are able

to get local data from a file or content provider Therefore their filters can list just a data type and do

not need to explicitly name the content and file schemes This is a typical case A ltdatagt element like

the following for example tells Android that the component can get image data from a content

provider and display it

ltdata androidmimeType=image gt

Since most available data is dispensed by content providers filters that specify a data type but not a

URI are perhaps the most common

Another common configuration is filters with a scheme and a data type For example a ltdatagt

element like the following tells Android that the component can get video data from the network and

display it

ltdata androidscheme=http androidtype=video gt

Consider for example what the browser application does when the user follows a link on a web page

It first tries to display the data (as it could if the link was to an HTML page) If it cant display the data it

puts together an implicit intent with the scheme and data type and tries to start an activity that can do

the job If there are no takers it asks the download manager to download the data That puts it under

the control of a content provider so a potentially larger pool of activities (those with filters that just

name a data type) can respond

Most applications also have a way to start fresh without a reference to any particular data Activities

that can initiate applications have filters with androidintentactionMAIN specified as the action If

they are to be represented in the application launcher they also specify the

androidintentcategoryLAUNCHER category

ltintent-filter gt ltaction androidname=code androidintentactionMAIN gt ltcategory androidname=code androidintentcategoryLAUNCHER gt ltintent-filtergt

Using intent matching

Intents are matched against intent filters not only to discover a target component to activate but also

to discover something about the set of components on the device For example the Android system

populates the application launcher the top-level screen that shows the applications that are available

for the user to launch by finding all the activities with intent filters that specify the

androidintentactionMAIN action and androidintentcategoryLAUNCHER category (as illustrated

in the previous section) It then displays the icons and labels of those activities in the launcher

Similarly it discovers the home screen by looking for the activity with androidintentcategoryHOME

in its filter

Your application can use intent matching is a similar way The PackageManager has a set of query()

methods that return all components that can accept a particular intent and a similar series of

resolve() methods that determine the best component to respond to an intent For example

queryIntentActivities() returns a list of all activities that can perform the intent passed as an argument

and queryIntentServices() returns a similar list of services Neither method activates the components

they just list the ones that can respond Theres a similar method queryBroadcastReceivers() for

broadcast receivers

Note Pad Example

The Note Pad sample application enables users to browse through a list of notes view details about

individual items in the list edit the items and add a new item to the list This section looks at the intent

filters declared in its manifest file (If youre working offline in the SDK you can find all the source files

for this sample application including its manifest file at ltsdkgtsamplesNotePadindexhtml If youre

viewing the documentation online the source files are in the Tutorials and Sample Code section here)

In its manifest file the Note Pad application declares three activities each with at least one intent filter

It also declares a content provider that manages the note data Here is the manifest file in its entirety

ltmanifest xmlnsandroid=httpschemasandroidcomapkresandroid package=comexampleandroidnotepadgt ltapplication androidicon=drawableapp_notes androidlabel=stringapp_name gt ltprovider androidname=NotePadProvider androidauthorities=comgoogleproviderNotePad gt ltactivity androidname=NotesList androidlabel=stringtitle_notes_listgt ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltactivity androidname=NoteEditor androidtheme=androidstyleThemeLight androidlabel=stringtitle_note gt ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltactivitygt

ltactivity androidname=TitleEditor androidlabel=stringtitle_edit_title androidtheme=androidstyleThemeDialoggt ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltapplicationgt ltmanifestgt

The first activity NotesList is distinguished from the other activities by the fact that it operates on a

directory of notes (the note list) rather than on a single note It would generally serve as the initial user

interface into the application It can do three things as described by its three intent filters

1 ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt

This filter declares the main entry point into the Note Pad application The standard MAIN action is an

entry point that does not require any other information in the Intent (no data specification for example)

and the LAUNCHER category says that this entry point should be listed in the application launcher

2 ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

This filter declares the things that the activity can do on a directory of notes It can allow the user to

view or edit the directory (via the VIEW and EDIT actions) or to pick a particular note from the

directory (via the PICK action)

The mimeType attribute of the ltdatagt element specifies the kind of data that these actions operate on

It indicates that the activity can get a Cursor over zero or more items (vndandroidcursordir) from a

content provider that holds Note Pad data (vndgooglenote) The Intent object that launches the

activity would include a content URI specifying the exact data of this type that the activity should open

Note also the DEFAULT category supplied in this filter Its there because the ContextstartActivity()

and ActivitystartActivityForResult() methods treat all intents as if they contained the DEFAULT

category mdash with just two exceptions

o Intents that explicitly name the target activity

o Intents consisting of the MAIN action and LAUNCHER category

Therefore the DEFAULT category is required for all filters mdash except for those with the MAIN action

and LAUNCHER category (Intent filters are not consulted for explicit intents)

3 ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

This filter describes the activitys ability to return a note selected by the user without requiring any

specification of the directory the user should choose from The GET_CONTENT action is similar to the

PICK action In both cases the activity returns the URI for a note selected by the user (In each case

its returned to the activity that called startActivityForResult() to start the NoteList activity) Here

however the caller specifies the type of data desired instead of the directory of data the user will be

picking from

The data type vndandroidcursoritemvndgooglenote indicates the type of data the activity can

return mdash a URI for a single note From the returned URI the caller can get a Cursor for exactly one

item (vndandroidcursoritem) from the content provider that holds Note Pad data (vndgooglenote)

In other words for the PICK action in the previous filter the data type indicates the type of data the

activity could display to the user For the GET_CONTENT filter it indicates the type of data the activity

can return to the caller

Given these capabilities the following intents will resolve to the NotesList activity

action androidintentactionMAIN

Launches the activity with no data specified

action androidintentactionMAIN

category androidintentcategoryLAUNCHER

Launches the activity with no data selected specified This is the actual intent used by the

Launcher to populate its top-level list All activities with filters that match this action and

category are added to the list

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of all the notes under

contentcomgoogleproviderNotePadnotes The user can then browse through the list and

get information about the items in it

action androidintentactionPICK

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of the notes under

contentcomgoogleproviderNotePadnotes The user can then pick a note from the list and

the activity will return the URI for that item back to the activity that started the NoteList activity

action androidintentactionGET_CONTENT

data type vndandroidcursoritemvndgooglenote

Asks the activity to supply a single item of Note Pad data

The second activity NoteEditor shows users a single note entry and allows them to edit it It can do

two things as described by its two intent filters

1 ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The first primary purpose of this activity is to enable the user to interact with a single note ampmdash to

either VIEW the note or EDIT it (The EDIT_NOTE category is a synonym for EDIT) The intent would

contain the URI for data matching the MIME type vndandroidcursoritemvndgooglenote mdash that is

the URI for a single specific note It would typically be a URI that was returned by the PICK or

GET_CONTENT actions of the NoteList activity

As before this filter lists the DEFAULT category so that the activity can be launched by intents that

dont explicitly specify the NoteEditor class

2 ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

The secondary purpose of this activity is to enable the user to create a new note which it will INSERT

into an existing directory of notes The intent would contain the URI for data matching the MIME type

vndandroidcursordirvndgooglenote mdash that is the URI for the directory where the note should be

placed

Given these capabilities the following intents will resolve to the NoteEditor activity

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID (For details on how content

URIs specify individual members of a group see Content Providers)

action androidintentactionEDIT

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID and to let the user edit it If

the user saves the changes the activity updates the data for the note in the content provider

action androidintentactionINSERT

data contentcomgoogleproviderNotePadnotes

Asks the activity to create a new empty note in the notes list at

contentcomgoogleproviderNotePadnotes and allow the user to edit it If the user saves the

note its URI is returned to the caller

The last activity TitleEditor enables the user to edit the title of a note This could be implemented by

directly invoking the activity (by explicitly setting its component name in the Intent) without using an

intent filter But here we take the opportunity to show how to publish alternative operations on existing

data

ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The single intent filter for this activity uses a custom action called

comandroidnotepadactionEDIT_TITLE It must be invoked on a specific note (data type

vndandroidcursoritemvndgooglenote) like the previous VIEW and EDIT actions However here the

activity displays the title contained in the note data not the content of the note itself

In addition to supporting the usual DEFAULT category the title editor also supports two other standard

categories ALTERNATIVE and SELECTED_ALTERNATIVE These categories identify activities that

can be presented to users in a menu of options (much as the LAUNCHER category identifies activities

that should be presented to user in the application launcher) Note that the filter also supplies an

explicit label (via androidlabel=stringresolve_title) to better control what users see when

presented with this activity as an alternative action to the data they are currently viewing (For more

information on these categories and building options menus see the

PackageManagerqueryIntentActivityOptions() and MenuaddIntentOptions() methods)

Given these capabilities the following intent will resolve to the TitleEditor activity

action comandroidnotepadactionEDIT_TITLE

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the title associated with note ID and allow the user to edit the title

Processes and Threads

When an application component starts and the application does not have any other components

running the Android system starts a new Linux process for the application with a single thread of

execution By default all components of the same application run in the same process and thread

(called the main thread) If an application component starts and there already exists a process for

that application (because another component from the application exists) then the component is

started within that process and uses the same thread of execution However you can arrange for

different components in your application to run in separate processes and you can create additional

threads for any process

This document discusses how processes and threads work in an Android application

Processes

By default all components of the same application run in the same process and most applications

should not change this However if you find that you need to control which process a certain

component belongs to you can do so in the manifest file

The manifest entry for each type of component elementmdashltactivitygt ltservicegt ltreceivergt and

ltprovidergtmdashsupports an androidprocess attribute that can specify a process in which that component

should run You can set this attribute so that each component runs in its own process or so that some

components share a process while others do not You can also set androidprocess so that

components of different applications run in the same processmdashprovided that the applications share the

same Linux user ID and are signed with the same certificates

The ltapplicationgt element also supports an androidprocess attribute to set a default value that

applies to all components

Android might 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 thats killed are consequently destroyed A process is started again for those components

when theres again work for them to do

When deciding which processes to kill the Android system weighs their relative importance to the

user For example it more readily shuts down a process hosting activities that are no longer visible on

screen compared to a process hosting visible activities The decision whether to terminate a process

therefore depends on the state of the components running in that process The rules used to decide

which processes to terminate is discussed below

Process lifecycle

The Android system tries to maintain an application process for as long as possible but eventually

needs to remove old processes to reclaim memory for new or more important processes To determine

which processes to keep and which to kill the system places each process into an importance

hierarchy based on the components running in the process and the state of those components

Processes with the lowest importance are eliminated first then those with the next lowest importance

and so on as necessary to recover system resources

There are five levels in the importance hierarchy The following list presents the different types of

processes in order of importance (the first process is most important and is killed last)

1 Foreground process

A process that is required for what the user is currently doing A process is considered to be in the

foreground if any of the following conditions are true

o It hosts an Activity that the user is interacting with (the Activitys onResume() method has been called)

o It hosts a Service thats bound to the activity that the user is interacting with

o It hosts a Service thats running in the foregroundmdashthe service has called startForeground()

o It hosts a Service thats executing one of its lifecycle callbacks (onCreate() onStart() or onDestroy())

o It hosts a BroadcastReceiver thats executing its onReceive() method

Generally only a few foreground processes exist at any given time They are killed only as a last

resortmdashif memory is so low that they cannot all continue to run Generally at that point the device has

reached a memory paging state so killing some foreground processes is required to keep the user

interface responsive

2 Visible process

A process that doesnt have any foreground components but still can affect what the user sees on

screen A process is considered to be visible if either of the following conditions are true

o It hosts an Activity that is not in the foreground but is still visible to the user (its onPause() method has

been called) This might occur for example if the foreground activity started a dialog which allows the

previous activity to be seen behind it

o It hosts a Service thats bound to a visible (or foreground) activity

A visible process is considered extremely important and will not be killed unless doing so is required to

keep all foreground processes running

3 Service process

A process that is running a service that has been started with the startService() method and does not

fall into either of the two higher categories Although service processes are not directly tied to anything

the user sees they are generally doing things that the user cares about (such as playing music in the

background or downloading data on the network) so the system keeps them running unless theres

not enough memory to retain them along with all foreground and visible processes

4 Background process

A process holding an activity thats not currently visible to the user (the activitys onStop() method has

been called) These processes have no direct impact on the user experience and the system can kill

them at any time to reclaim memory for a foreground visible or service process Usually there are

many background processes running so they are kept in an LRU (least recently used) list to ensure

that the process with the activity that was most recently seen by the user is the last to be killed If an

activity implements its lifecycle methods correctly and saves its current state killing its process will not

have a visible effect on the user experience because when the user navigates back to the activity the

activity restores all of its visible state See the Activities document for information about saving and

restoring state

5 Empty process

A process that doesnt hold any active application components The only reason to keep this kind of

process alive is for caching purposes to improve startup time the next time a component needs to run

in it The system often kills these processes in order to balance overall system resources between

process caches and the underlying kernel caches

Android ranks a process at the highest level it can based upon the importance of the components

currently active in the process For example if a process hosts a service and a visible activity the

process is ranked as a visible process not a service process

In addition a processs ranking might be increased because other processes are dependent on itmdasha

process that is serving another process can never be ranked lower than the process it is serving For

example if a content provider in process A is serving a client in process B or if a service in process A

is bound to a component in process B process A is always considered at least as important as

process B

Because a process running a service is ranked higher than a process with background activities an

activity that initiates a long-running operation might do well to start a service for that operation rather

than simply create a worker threadmdashparticularly if the operation will likely outlast the activity For

example an activity thats uploading a picture to a web site should start a service to perform the

upload so that the upload can continue in the background even if the user leaves the activity Using a

service guarantees that the operation will have at least service process priority regardless of what

happens to the activity This is the same reason that broadcast receivers should employ services

rather than simply put time-consuming operations in a thread

Threads

When an application is launched the system creates a thread of execution for the application called

main This thread is very important because it is in charge of dispatching events to the appropriate

user interface widgets including drawing events It is also the thread in which your application interacts

with components from the Android UI toolkit (components from the androidwidget and androidview

packages) As such the main thread is also sometimes called the UI thread

The system does not create a separate thread for each instance of a component All components that

run in the same process are instantiated in the UI thread and system calls to each component are

dispatched from that thread Consequently methods that respond to system callbacks (such as

onKeyDown() to report user actions or a lifecycle callback method) always run in the UI thread of the

process

For instance when the user touches a button on the screen your apps UI thread dispatches the touch

event to the widget which in turn sets its pressed state and posts an invalidate request to the event

queue The UI thread dequeues the request and notifies the widget that it should redraw itself

When your app performs intensive work in response to user interaction this single thread model can

yield poor performance unless you implement your application properly Specifically if everything is

happening in the UI thread performing long operations such as network access or database queries

will block the whole UI When the thread is blocked no events can be dispatched including drawing

events From the users perspective the application appears to hang Even worse if the UI thread is

blocked for more than a few seconds (about 5 seconds currently) the user is presented with the

infamous application not responding (ANR) dialog The user might then decide to quit your

application and uninstall it if they are unhappy

Additionally the Andoid UI toolkit is not thread-safe So you must not manipulate your UI from a

worker threadmdashyou must do all manipulation to your user interface from the UI thread Thus there are

simply two rules to Androids single thread model

1 Do not block the UI thread

2 Do not access the Android UI toolkit from outside the UI thread

Worker threads

Because of the single thread model described above its vital to the responsiveness of your

applications UI that you do not block the UI thread If you have operations to perform that are not

instantaneous you should make sure to do them in separate threads (background or worker

threads)

For example below is some code for a click listener that downloads an image from a separate thread

and displays it in an ImageView

public void onClick(View v) new Thread(new Runnable() public void run() Bitmap b = loadImageFromNetwork(httpexamplecomimagepng) mImageViewsetImageBitmap(b) )start()

At first this seems to work fine because it creates a new thread to handle the network operation

However it violates the second rule of the single-threaded model do not access the Android UI toolkit

from outside the UI threadmdashthis sample modifies the ImageView from the worker thread instead of the

UI thread This can result in undefined and unexpected behavior which can be difficult and time-

consuming to track down

To fix this problem Android offers several ways to access the UI thread from other threads Here is a

list of methods that can help

ActivityrunOnUiThread(Runnable)

Viewpost(Runnable)

ViewpostDelayed(Runnable long)

For example you can fix the above code by using the Viewpost(Runnable) method

public void onClick(View v) new Thread(new Runnable() public void run() final Bitmap bitmap = loadImageFromNetwork(httpexamplecomimagepng) mImageViewpost(new Runnable() public void run() mImageViewsetImageBitmap(bitmap) ) )start()

Now this implementation is thread-safe the network operation is done from a separate thread while

the ImageView is manipulated from the UI thread

However as the complexity of the operation grows this kind of code can get complicated and difficult

to maintain To handle more complex interactions with a worker thread you might consider using a

Handler in your worker thread to process messages delivered from the UI thread Perhaps the best

solution though is to extend the AsyncTask class which simplifies the execution of worker thread

tasks that need to interact with the UI

Using AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface It performs the blocking

operations in a worker thread and then publishes the results on the UI thread without requiring you to

handle threads andor handlers yourself

To use it you must subclass AsyncTask and implement the doInBackground() callback method which

runs in a pool of background threads To update your UI you should implement onPostExecute()

which delivers the result from doInBackground() and runs in the UI thread so you can safely update

your UI You can then run the task by calling execute() from the UI thread

For example you can implement the previous example using AsyncTask this way

public void onClick(View v) new DownloadImageTask()execute(httpexamplecomimagepng) private class DownloadImageTask extends AsyncTaskltString Void Bitmapgt The system calls this to perform work in a worker thread and delivers it the parameters given to AsyncTaskexecute() protected Bitmap doInBackground(String urls) return loadImageFromNetwork(urls[0])

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 12: 03 services

However if you stop the service while its still running in the foreground then the notification is also

removed

Note The methods startForeground() and stopForeground() were introduced in Android 20 (API

Level 5) In order to run your service in the foreground on older versions of the platform you must

use the previous setForeground() methodmdashsee the startForeground() documentation for

information about how to provide backward compatibility

For more information about notifications see Creating Status Bar Notifications

Managing the Lifecycle of a Service

The lifecycle of a service is much simpler than that of an activity However its even more important

that you pay close attention to how your service is created and destroyed because a service can run

in the background without the user being aware

The service lifecyclemdashfrom when its created to when its destroyedmdashcan follow two different paths

A started service

The service is created when another component calls startService() The service then runs indefinitely

and must stop itself by calling stopSelf() Another component can also stop the service by calling

stopService() When the service is stopped the system destroys it

A bound service

The service is created when another component (a client) calls bindService() The client then

communicates with the service through an IBinder interface The client can close the connection by

calling unbindService() Multiple clients can bind to the same service and when all of them unbind the

system destroys the service (The service does not need to stop itself)

These two paths are not entirely separate That is you can bind to a service that was already started

with startService() For example a background music service could be started by calling startService()

with an Intent that identifies the music to play Later possibly when the user wants to exercise some

control over the player or get information about the current song an activity can bind to the service by

calling bindService() In cases like this stopService() or stopSelf() does not actually stop the service

until all clients unbind

Implementing the lifecycle callbacks

Like an activity a service has lifecycle callback methods that you can implement to monitor changes in

the services state and perform work at the appropriate times The following skeleton service

demonstrates each of the lifecycle methods

Figure 2 The service lifecycle The diagram on the left shows the lifecycle when the service is created

with startService() and the diagram on the right shows the lifecycle when the service is created with

bindService()

public class ExampleService extends Service int mStartMode indicates how to behave if the service is killed IBinder mBinder interface for clients that bind boolean mAllowRebind indicates whether onRebind should be used Override public void onCreate() The service is being created Override public int onStartCommand(Intent intent int flags int startId) The service is starting due to a call to startService() return mStartMode Override public IBinder onBind(Intent intent) A client is binding to the service with bindService() return mBinder Override public boolean onUnbind(Intent intent) All clients have unbound with unbindService()

return mAllowRebind Override public void onRebind(Intent intent) A client is binding to the service with bindService() after onUnbind() has already been called Override public void onDestroy() The service is no longer used and is being destroyed

Note Unlike the activity lifecycle callback methods you are not required to call the superclass

implementation of these callback methods

By implementing these methods you can monitor two nested loops of the services lifecycle

The entire lifetime of a service happens between the time onCreate() is called and the time

onDestroy() returns Like an activity a service does its initial setup in onCreate() and releases all

remaining resources in onDestroy() For example a music playback service could create the thread

where the music will be played in onCreate() then stop the thread in onDestroy()

The onCreate() and onDestroy() methods are called for all services whether theyre created by

startService() or bindService()

The active lifetime of a service begins with a call to either onStartCommand() or onBind() Each

method is handed the Intent that was passed to either startService() or bindService() respectively

If the service is started the active lifetime ends the same time that the entire lifetime ends (the service

is still active even after onStartCommand() returns) If the service is bound the active lifetime ends

when onUnbind() returns

Note Although a started service is stopped by a call to either stopSelf() or stopService() there is

not a respective callback for the service (theres no onStop() callback) So unless the service is

bound to a client the system destroys it when the service is stoppedmdashonDestroy() is the only

callback received

Figure 2 illustrates the typical callback methods for a service Although the figure separates services

that are created by startService() from those created by bindService() keep in mind that any service

no matter how its started can potentially allow clients to bind to it So a service that was initially

started with onStartCommand() (by a client calling startService()) can still receive a call to onBind()

(when a client calls bindService())

For more information about creating a service that provides binding see the Bound Services

document which includes more information about the onRebind() callback method in the section about

Managing the Lifecycle of a Bound Service

Bound Services

A bound service is the server in a client-server interface A bound service allows components (such as

activities) to bind to the service send requests receive responses and even perform interprocess

communication (IPC) A bound service typically lives only while it serves another application

component and does not run in the background indefinitely

This document shows you how to create a bound service including how to bind to the service from

other application components However you should also refer to the Services document for additional

information about services in general such as how to deliver notifications from a service set the

service to run in the foreground and more

The Basics

A bound service is an implementation of the Service class that allows other applications to bind to it

and interact with it To provide binding for a service you must implement the onBind() callback

method This method returns an IBinder object that defines the programming interface that clients can

use to interact with the service

Binding to a Started Service

As discussed in the Services document you can create a service that is both started and bound That

is the service can be started by calling startService() which allows the service to run indefinitely and

also allow a client to bind to the service by calling bindService()

If you do allow your service to be started and bound then when the service has been started the

system does not destroy the service when all clients unbind Instead you must explicitly stop the

service by calling stopSelf() or stopService()

Although you should usually implement either onBind() or onStartCommand() its sometimes

necessary to implement both For example a music player might find it useful to allow its service to run

indefinitely and also provide binding This way an activity can start the service to play some music and

the music continues to play even if the user leaves the application Then when the user returns to the

application the activity can bind to the service to regain control of playback

Be sure to read the section about Managing the Lifecycle of a Bound Service for more information

about the service lifecycle when adding binding to a started service

A client can bind to the service by calling bindService() When it does it must provide an

implementation of ServiceConnection which monitors the connection with the service The

bindService() method returns immediately without a value but when the Android system creates the

connection between the client and service it calls onServiceConnected() on the ServiceConnection to

deliver the IBinder that the client can use to communicate with the service

Multiple clients can connect to the service at once However the system calls your services onBind()

method to retrieve the IBinder only when the first client binds The system then delivers the same

IBinder to any additional clients that bind without calling onBind() again

When the last client unbinds from the service the system destroys the service (unless the service was

also started by startService())

When you implement your bound service the most important part is defining the interface that your

onBind() callback method returns There are a few different ways you can define your services IBinder

interface and the following section discusses each technique

Creating a Bound Service

When creating a service that provides binding you must provide an IBinder that provides the

programming interface that clients can use to interact with the service There are three ways you can

define the interface

Extending the Binder class

If your service is private to your own application and runs in the same process as the client

(which is common) you should create your interface by extending the Binder class and

returning an instance of it from onBind() The client receives the Binder and can use it to directly

access public methods available in either the Binder implementation or even the Service

This is the preferred technique when your service is merely a background worker for your own

application The only reason you would not create your interface this way is because your

service is used by other applications or across separate processes

Using a Messenger

If you need your interface to work across different processes you can create an interface for the

service with a Messenger In this manner the service defines a Handler that responds to

different types of Message objects This Handler is the basis for a Messenger that can then

share an IBinder with the client allowing the client to send commands to the service using

Message objects Additionally the client can define a Messenger of its own so the service can

send messages back

This is the simplest way to perform interprocess communication (IPC) because the Messenger

queues all requests into a single thread so that you dont have to design your service to be

thread-safe

Using AIDL

AIDL (Android Interface Definition Language) performs all the work to decompose objects into

primitives that the operating system can understand and marshall them across processes to

perform IPC The previous technique using a Messenger is actually based on AIDL as its

underlying structure As mentioned above the Messenger creates a queue of all the client

requests in a single thread so the service receives requests one at a time If however you

want your service to handle multiple requests simultaneously then you can use AIDL directly In

this case your service must be capable of multi-threading and be built thread-safe

To use AIDL directly you must create an aidl file that defines the programming interface The

Android SDK tools use this file to generate an abstract class that implements the interface and

handles IPC which you can then extend within your service

Note Most applications should not use AIDL to create a bound service because it may require

multithreading capabilities and can result in a more complicated implementation As such AIDL is

not suitable for most applications and this document does not discuss how to use it for your

service If youre certain that you need to use AIDL directly see the AIDL document

Extending the Binder class

If your service is used only by the local application and does not need to work across processes then

you can implement your own Binder class that provides your client direct access to public methods in

the service

Note This works only if the client and service are in the same application and process which is

most common For example this would work well for a music application that needs to bind an

activity to its own service thats playing music in the background

Heres how to set it up

1 In your service create an instance of Binder that either

o contains public methods that the client can call

o returns the current Service instance which has public methods the client can call

o or returns an instance of another class hosted by the service with public methods the client can call

2 Return this instance of Binder from the onBind() callback method

3 In the client receive the Binder from the onServiceConnected() callback method and make calls to the

bound service using the methods provided

Note The reason the service and client must be in the same application is so the client can cast

the returned object and properly call its APIs The service and client must also be in the same

process because this technique does not perform any marshalling across processes

For example heres a service that provides clients access to methods in the service through a Binder

implementation

public class LocalService extends Service

Binder given to clients

private final IBinder mBinder = new LocalBinder()

Random number generator

private final Random mGenerator = new Random()

Class used for the client Binder Because we know this service always

runs in the same process as its clients we dont need to deal with IPC

public class LocalBinder extends Binder

LocalService getService()

Return this instance of LocalService so clients can call public methods

return LocalServicethis

Override

public IBinder onBind(Intent intent)

return mBinder

method for clients

public int getRandomNumber()

return mGeneratornextInt(100)

The LocalBinder provides the getService() method for clients to retrieve the current instance of

LocalService This allows clients to call public methods in the service For example clients can call

getRandomNumber() from the service

Heres an activity that binds to LocalService and calls getRandomNumber() when a button is clicked

public class BindingActivity extends Activity

LocalService mService

boolean mBound = false

Override

protected void onCreate(Bundle savedInstanceState)

superonCreate(savedInstanceState)

setContentView(Rlayoutmain)

Override

protected void onStart()

superonStart()

Bind to LocalService

Intent intent = new Intent(this LocalServiceclass)

bindService(intent mConnection ContextBIND_AUTO_CREATE)

Override

protected void onStop()

superonStop()

Unbind from the service

if (mBound)

unbindService(mConnection)

mBound = false

Called when a button is clicked (the button in the layout file attaches to

this method with the androidonClick attribute)

public void onButtonClick(View v)

if (mBound)

Call a method from the LocalService

However if this call were something that might hang then this request should

occur in a separate thread to avoid slowing down the activity performance

int num = mServicegetRandomNumber()

ToastmakeText(this number + num ToastLENGTH_SHORT)show()

Defines callbacks for service binding passed to bindService()

private ServiceConnection mConnection = new ServiceConnection()

Override

public void onServiceConnected(ComponentName className

IBinder service)

Weve bound to LocalService cast the IBinder and get LocalService instance

LocalBinder binder = (LocalBinder) service

mService = bindergetService()

mBound = true

Override

public void onServiceDisconnected(ComponentName arg0)

mBound = false

The above sample shows how the client binds to the service using an implementation of

ServiceConnection and the onServiceConnected() callback The next section provides more

information about this process of binding to the service

Note The example above doesnt explicitly unbind from the service but all clients should unbind

at an appropriate time (such as when the activity pauses)

For more sample code see the LocalServicejava class and the LocalServiceActivitiesjava class in

ApiDemos

Using a Messenger

Compared to AIDL

When you need to perform IPC using a Messenger for your interface is simpler than implementing it

with AIDL because Messenger queues all calls to the service whereas a pure AIDL interface sends

simultaneous requests to the service which must then handle multi-threading

For most applications the service doesnt need to perform multi-threading so using a Messenger

allows the service to handle one call at a time If its important that your service be multi-threaded then

you should use AIDL to define your interface

If you need your service to communicate with remote processes then you can use a Messenger to

provide the interface for your service This technique allows you to perform interprocess

communication (IPC) without the need to use AIDL

Heres a summary of how to use a Messenger

The service implements a Handler that receives a callback for each call from a client

The Handler is used to create a Messenger object (which is a reference to the Handler)

The Messenger creates an IBinder that the service returns to clients from onBind()

Clients use the IBinder to instantiate the Messenger (that references the services Handler) which the

client uses to send Message objects to the service

The service receives each Message in its Handlermdashspecifically in the handleMessage() method

In this way there are no methods for the client to call on the service Instead the client delivers

messages (Message objects) that the service receives in its Handler

Heres a simple example service that uses a Messenger interface

public class MessengerService extends Service Command to the service to display a message static final int MSG_SAY_HELLO = 1 Handler of incoming messages from clients class IncomingHandler extends Handler Override public void handleMessage(Message msg) switch (msgwhat) case MSG_SAY_HELLO ToastmakeText(getApplicationContext() hello ToastLENGTH_SHORT)show() break default superhandleMessage(msg) Target we publish for clients to send messages to IncomingHandler final Messenger mMessenger = new Messenger(new IncomingHandler()) When binding to the service we return an interface to our messenger for sending messages to the service Override public IBinder onBind(Intent intent) ToastmakeText(getApplicationContext() binding ToastLENGTH_SHORT)show() return mMessengergetBinder()

Notice that the handleMessage() method in the Handler is where the service receives the incoming

Message and decides what to do based on the what member

All that a client needs to do is create a Messenger based on the IBinder returned by the service and

send a message using send() For example heres a simple activity that binds to the service and

delivers the MSG_SAY_HELLO message to the service

public class ActivityMessenger extends Activity Messenger for communicating with the service Messenger mService = null Flag indicating whether we have called bind on the service boolean mBound Class for interacting with the main interface of the service private ServiceConnection mConnection = new ServiceConnection() public void onServiceConnected(ComponentName className IBinder service) This is called when the connection with the service has been established giving us the object we can use to interact with the service We are communicating with the service using a Messenger so here we get a client-side representation of that from the raw IBinder object mService = new Messenger(service) mBound = true public void onServiceDisconnected(ComponentName className) This is called when the connection with the service has been unexpectedly disconnected -- that is its process crashed mService = null mBound = false public void sayHello(View v) if (mBound) return Create and send a message to the service using a supported what value Message msg = Messageobtain(null MessengerServiceMSG_SAY_HELLO 0 0) try mServicesend(msg) catch (RemoteException e) eprintStackTrace() Override protected void onCreate(Bundle savedInstanceState) superonCreate(savedInstanceState) setContentView(Rlayoutmain)

Override protected void onStart() superonStart() Bind to the service bindService(new Intent(this MessengerServiceclass) mConnection ContextBIND_AUTO_CREATE) Override protected void onStop() superonStop() Unbind from the service if (mBound) unbindService(mConnection) mBound = false

Notice that this example does not show how the service can respond to the client If you want the

service to respond then you need to also create a Messenger in the client Then when the client

receives the onServiceConnected() callback it sends a Message to the service that includes the

clients Messenger in the replyTo parameter of the send() method

You can see an example of how to provide two-way messaging in the MessengerServicejava (service)

and MessengerServiceActivitiesjava (client) samples

Binding to a Service

Application components (clients) can bind to a service by calling bindService() The Android system

then calls the services onBind() method which returns an IBinder for interacting with the service

The binding is asynchronous bindService() returns immediately and does not return the IBinder to the

client To receive the IBinder the client must create an instance of ServiceConnection and pass it to

bindService() The ServiceConnection includes a callback method that the system calls to deliver the

IBinder

Note Only activities services and content providers can bind to a servicemdashyou cannot bind to a

service from a broadcast receiver

So to bind to a service from your client you must

1 Implement ServiceConnection

Your implementation must override two callback methods

onServiceConnected()

The system calls this to deliver the IBinder returned by the services onBind() method

onServiceDisconnected()

The Android system calls this when the connection to the service is unexpectedly lost such as

when the service has crashed or has been killed This is not called when the client unbinds

2 Call bindService() passing the ServiceConnection implementation

3 When the system calls your onServiceConnected() callback method you can begin making calls to the

service using the methods defined by the interface

4 To disconnect from the service call unbindService()

When your client is destroyed it will unbind from the service but you should always unbind when

youre done interacting with the service or when your activity pauses so that the service can shutdown

while its not being used (Appropriate times to bind and unbind is discussed more below)

For example the following snippet connects the client to the service created above by extending the

Binder class so all it must do is cast the returned IBinder to the LocalService class and request the

LocalService instance

LocalService mService private ServiceConnection mConnection = new ServiceConnection() Called when the connection with the service is established public void onServiceConnected(ComponentName className IBinder service) Because we have bound to an explicit service that is running in our own process we can cast its IBinder to a concrete class and directly access it LocalBinder binder = (LocalBinder) service mService = bindergetService() mBound = true Called when the connection with the service disconnects unexpectedly public void onServiceDisconnected(ComponentName className) Loge(TAG onServiceDisconnected) mBound = false

With this ServiceConnection the client can bind to a service by passing this it to bindService() For

example

Intent intent = new Intent(this LocalServiceclass) bindService(intent mConnection ContextBIND_AUTO_CREATE)

The first parameter of bindService() is an Intent that explicitly names the service to bind (thought the

intent could be implicit)

The second parameter is the ServiceConnection object

The third parameter is a flag indicating options for the binding It should usually be

BIND_AUTO_CREATE in order to create the service if its not already alive Other possible values are

BIND_DEBUG_UNBIND and BIND_NOT_FOREGROUND or 0 for none

Additional notes

Here are some important notes about binding to a service

You should always trap DeadObjectException exceptions which are thrown when the connection has

broken This is the only exception thrown by remote methods

Objects are reference counted across processes

You should usually pair the binding and unbinding during matching bring-up and tear-down moments

of the clients lifecycle For example

o If you only need to interact with the service while your activity is visible you should bind during

onStart() and unbind during onStop()

o If you want your activity to receive responses even while it is stopped in the background then you can

bind during onCreate() and unbind during onDestroy() Beware that this implies that your activity needs

to use the service the entire time its running (even in the background) so if the service is in another

process then you increase the weight of the process and it becomes more likely that the system will

kill it

Note You should usually not bind and unbind during your activitys onResume() and onPause()

because these callbacks occur at every lifecycle transition and you should keep the processing that

occurs at these transitions to a minimum Also if multiple activities in your application bind to the same

service and there is a transition between two of those activities the service may be destroyed and

recreated as the current activity unbinds (during pause) before the next one binds (during resume)

(This activity transition for how activities coordinate their lifecycles is described in the Activities

document)

For more sample code showing how to bind to a service see the RemoteServicejava class in

ApiDemos

Managing the Lifecycle of a Bound Service

Figure 1 The lifecycle for a service

that is started and also allows binding

When a service is unbound from all

clients the Android system destroys it

(unless it was also started with

onStartCommand()) As such you

dont have to manage the lifecycle of

your service if its purely a bound

servicemdashthe Android system manages

it for you based on whether it is bound

to any clients

However if you choose to implement

the onStartCommand() callback

method then you must explicitly stop

the service because the service is

now considered to be started In this

case the service runs until the service

stops itself with stopSelf() or another

component calls stopService()

regardless of whether it is bound to

any clients

Additionally if your service is started and accepts binding then when the system calls your onUnbind()

method you can optionally return true if you would like to receive a call to onRebind() the next time a

client binds to the service (instead of receiving a call to onBind()) onRebind() returns void but the

client still receives the IBinder in its onServiceConnected() callback Below figure 1 illustrates the logic

for this kind of lifecycle

For more information about the lifecycle of an started service see the Services document

Content Providers

Content providers store and retrieve data and make it accessible to all applications Theyre the only

way to share data across applications theres no common storage area that all Android packages can

access

Android ships with a number of content providers for common data types (audio video images

personal contact information and so on) You can see some of them listed in the androidprovider

package You can query these providers for the data they contain (although for some you must

acquire the proper permission to read the data)

If you want to make your own data public you have two options You can create your own content

provider (a ContentProvider subclass) or you can add the data to an existing provider mdash if theres one

that controls the same type of data and you have permission to write to it

This document is an introduction to using content providers After a brief discussion of the

fundamentals it explores how to query a content provider how to modify data controlled by a provider

and how to create a content provider of your own

Content Provider Basics

How a content provider actually stores its data under the covers is up to its designer But all content

providers implement a common interface for querying the provider and returning results mdash as well as

for adding altering and deleting data Its an interface that clients use indirectly most generally

through ContentResolver objects You get a ContentResolver by calling getContentResolver() from

within the implementation of an Activity or other application component

ContentResolver cr = getContentResolver()

You can then use the ContentResolvers methods to interact with whatever content providers youre

interested in When a query is initiated the Android system identifies the content provider thats the

target of the query and makes sure that it is up and running The system instantiates all

ContentProvider objects you never need to do it on your own In fact you never deal directly with

ContentProvider objects at all Typically theres just a single instance of each type of ContentProvider

But it can communicate with multiple ContentResolver objects in different applications and processes

The interaction between processes is handled by the ContentResolver and ContentProvider classes

The data model

Content providers expose their data as a simple table on a database model where each row is a

record and each column is data of a particular type and meaning For example information about

people and their phone numbers might be exposed as follows

_ID NUMBER NUMBER_KEY LABEL NAME TYPE

13 (425) 555 6677 425 555 6677 Kirkland office Bully Pulpit TYPE_WORK

44 (212) 555-1234 212 555 1234 NY apartment Alan Vain TYPE_HOME

45 (212) 555-6657 212 555 6657 Downtown office Alan Vain TYPE_MOBILE

53 2015554433 201 555 4433 Love Nest Rex Cars TYPE_HOME

Every record includes a numeric _ID field that uniquely identifies the record within the table IDs can be

used to match records in related tables mdash for example to find a persons phone number in one table

and pictures of that person in another

A query returns a Cursor object that can move from record to record and column to column to read the

contents of each field It has specialized methods for reading each type of data So to read a field you

must know what type of data the field contains (Theres more on query results and Cursor objects

later)

URIs

Each content provider exposes a public URI (wrapped as a Uri object) that uniquely identifies its data

set A content provider that controls multiple data sets (multiple tables) exposes a separate URI for

each one All URIs for providers begin with the string content The content scheme identifies the

data as being controlled by a content provider

If youre defining a content provider its a good idea to also define a constant for its URI to simplify

client code and make future updates cleaner Android defines CONTENT_URI constants for all the

providers that come with the platform For example the URI for the table that matches phone numbers

to people and the URI for the table that holds pictures of people (both controlled by the Contacts

content provider) are

androidproviderContactsPhonesCONTENT_URI

androidproviderContactsPhotosCONTENT_URI

The URI constant is used in all interactions with the content provider Every ContentResolver method

takes the URI as its first argument Its what identifies which provider the ContentResolver should talk

to and which table of the provider is being targeted

Querying a Content Provider

You need three pieces of information to query a content provider

The URI that identifies the provider

The names of the data fields you want to receive

The data types for those fields

If youre querying a particular record you also need the ID for that record

Making the query

To query a content provider you can use either the ContentResolverquery() method or the

ActivitymanagedQuery() method Both methods take the same set of arguments and both return a

Cursor object However managedQuery() causes the activity to manage the life cycle of the Cursor A

managed Cursor handles all of the niceties such as unloading itself when the activity pauses and

requerying itself when the activity restarts You can ask an Activity to begin managing an unmanaged

Cursor object for you by calling ActivitystartManagingCursor()

The first argument to either query() or managedQuery() is the provider URI mdash the CONTENT_URI

constant that identifies a particular ContentProvider and data set (see URIs earlier)

To restrict a query to just one record you can append the _ID value for that record to the URI mdash that

is place a string matching the ID as the last segment of the path part of the URI For example if the ID

is 23 the URI would be

content 23

There are some helper methods particularly ContentUriswithAppendedId() and

UriwithAppendedPath() that make it easy to append an ID to a URI Both are static methods that

return a Uri object with the ID added So for example if you were looking for record 23 in the database

of people contacts you might construct a query as follows

import androidproviderContactsPeople import androidcontentContentUris import androidnetUri import androiddatabaseCursor Use the ContentUris method to produce the base URI for the contact with _ID == 23 Uri myPerson = ContentUriswithAppendedId(PeopleCONTENT_URI 23) Alternatively use the Uri method to produce the base URI It takes a string rather than an integer Uri myPerson = UriwithAppendedPath(PeopleCONTENT_URI 23) Then query for this specific record Cursor cur = managedQuery(myPerson null null null null)

The other arguments to the query() and managedQuery() methods delimit the query in more detail

They are

The names of the data columns that should be returned A null value returns all columns Otherwise

only columns that are listed by name are returned All the content providers that come with the

platform define constants for their columns For example the androidproviderContactsPhones class

defines constants for the names of the columns in the phone table illustrated earlier ampmdash _ID

NUMBER NUMBER_KEY NAME and so on

A filter detailing which rows to return formatted as an SQL WHERE clause (excluding the WHERE

itself) A null value returns all rows (unless the URI limits the query to a single record)

Selection arguments

A sorting order for the rows that are returned formatted as an SQL ORDER BY clause (excluding the

ORDER BY itself) A null value returns the records in the default order for the table which may be

unordered

Lets look at an example query to retrieve a list of contact names and their primary phone numbers

import androidproviderContactsPeople import androiddatabaseCursor Form an array specifying which columns to return String[] projection = new String[] People_ID People_COUNT PeopleNAME PeopleNUMBER Get the base URI for the People table in the Contacts content provider Uri contacts = PeopleCONTENT_URI Make the query Cursor managedCursor = managedQuery(contacts projection Which columns to return null Which rows to return (all rows) null Selection arguments (none) Put the results in ascending order by name PeopleNAME + ASC)

This query retrieves data from the People table of the Contacts content provider It gets the name

primary phone number and unique record ID for each contact It also reports the number of records

that are returned as the _COUNT field of each record

The constants for the names of the columns are defined in various interfaces mdash _ID and _COUNT in

BaseColumns NAME in PeopleColumns and NUMBER in PhoneColumns The ContactsPeople

class implements each of these interfaces which is why the code example above could refer to them

using just the class name

What a query returns

A query returns a set of zero or more database records The names of the columns their default order

and their data types are specific to each content provider But every provider has an _ID column

which holds a unique numeric ID for each record Every provider can also report the number of records

returned as the _COUNT column its value is the same for all rows

Here is an example result set for the query in the previous section

_ID _COUNT NAME NUMBER

44 3 Alan Vain 212 555 1234

13 3 Bully Pulpit 425 555 6677

53 3 Rex Cars 201 555 4433

The retrieved data is exposed by a Cursor object that can be used to iterate backward or forward

through the result set You can use this object only to read the data To add modify or delete data

you must use a ContentResolver object

Reading retrieved data

The Cursor object returned by a query provides access to a recordset of results If you have queried

for a specific record by ID this set will contain only one value Otherwise it can contain multiple

values (If there are no matches it can also be empty) You can read data from specific fields in the

record but you must know the data type of the field because the Cursor object has a separate method

for reading each type of data mdash such as getString() getInt() and getFloat() (However for most types

if you call the method for reading strings the Cursor object will give you the String representation of

the data) The Cursor lets you request the column name from the index of the column or the index

number from the column name

The following snippet demonstrates reading names and phone numbers from the query illustrated

earlier

import androidproviderContactsPeople private void getColumnData(Cursor cur) if (curmoveToFirst()) String name String phoneNumber int nameColumn = curgetColumnIndex(PeopleNAME) int phoneColumn = curgetColumnIndex(PeopleNUMBER) String imagePath do Get the field values name = curgetString(nameColumn) phoneNumber = curgetString(phoneColumn) Do something with the values while (curmoveToNext())

If a query can return binary data such as an image or sound the data may be directly entered in the

table or the table entry for that data may be a string specifying a content URI that you can use to get

the data In general smaller amounts of data (say from 20 to 50K or less) are most often directly

entered in the table and can be read by calling CursorgetBlob() It returns a byte array

If the table entry is a content URI you should never try to open and read the file directly (for one thing

permissions problems can make this fail) Instead you should call ContentResolveropenInputStream()

to get an InputStream object that you can use to read the data

Modifying Data

Data kept by a content provider can be modified by

Adding new records

Adding new values to existing records

Batch updating existing records

Deleting records

All data modification is accomplished using ContentResolver methods Some content providers require

a more restrictive permission for writing data than they do for reading it If you dont have permission to

write to a content provider the ContentResolver methods will fail

Adding records

To add a new record to a content provider first set up a map of key-value pairs in a ContentValues

object where each key matches the name of a column in the content provider and the value is the

desired value for the new record in that column Then call ContentResolverinsert() and pass it the URI

of the provider and the ContentValues map This method returns the full URI of the new record mdash that

is the providers URI with the appended ID for the new record You can then use this URI to query and

get a Cursor over the new record and to further modify the record Heres an example

import androidproviderContactsPeople import androidcontentContentResolver import androidcontentContentValues ContentValues values = new ContentValues() Add Abraham Lincoln to contacts and make him a favorite valuesput(PeopleNAME Abraham Lincoln) 1 = the new contact is added to favorites 0 = the new contact is not added to favorites valuesput(PeopleSTARRED 1) Uri uri = getContentResolver()insert(PeopleCONTENT_URI values)

Adding new values

Once a record exists you can add new information to it or modify existing information For example

the next step in the example above would be to add contact information mdash like a phone number or an

IM or e-mail address mdash to the new entry

The best way to add to a record in the Contacts database is to append the name of the table where the

new data goes to the URI for the record then use the amended URI to add the new data values Each

Contacts table exposes a name for this purpose as a CONTENT_DIRECTORY constant The following

code continues the previous example by adding a phone number and e-mail address for the record

just created

Uri phoneUri = null Uri emailUri = null Add a phone number for Abraham Lincoln Begin with the URI for the new record just returned by insert() it ends with the _ID of the new record so we dont have to add the ID ourselves Then append the designation for the phone table to this URI and use the resulting URI to insert the phone number phoneUri = UriwithAppendedPath(uri PeoplePhonesCONTENT_DIRECTORY) valuesclear() valuesput(PeoplePhonesTYPE PeoplePhonesTYPE_MOBILE) valuesput(PeoplePhonesNUMBER 1233214567) getContentResolver()insert(phoneUri values) Now add an email address in the same way emailUri = UriwithAppendedPath(uri PeopleContactMethodsCONTENT_DIRECTORY) valuesclear() ContactMethodsKIND is used to distinguish different kinds of contact methods such as email IM etc valuesput(PeopleContactMethodsKIND ContactsKIND_EMAIL) valuesput(PeopleContactMethodsDATA testexamplecom) valuesput(PeopleContactMethodsTYPE PeopleContactMethodsTYPE_HOME) getContentResolver()insert(emailUri values)

You can place small amounts of binary data into a table by calling the version of ContentValuesput()

that takes a byte array That would work for a small icon-like image or a short audio clip for example

However if you have a large amount of binary data to add such as a photograph or a complete song

put a content URI for the data in the table and call ContentResolveropenOutputStream() with the files

URI (That causes the content provider to store the data in a file and record the file path in a hidden

field of the record)

In this regard the MediaStore content provider the main provider that dispenses image audio and

video data employs a special convention The same URI that is used with query() or managedQuery()

to get meta-information about the binary data (such as the caption of a photograph or the date it was

taken) is used with openInputStream() to get the data itself Similarly the same URI that is used with

insert() to put meta-information into a MediaStore record is used with openOutputStream() to place the

binary data there The following code snippet illustrates this convention

import androidproviderMediaStoreImagesMedia import androidcontentContentValues import javaioOutputStream Save the name and description of an image in a ContentValues map ContentValues values = new ContentValues(3) valuesput(MediaDISPLAY_NAME road_trip_1) valuesput(MediaDESCRIPTION Day 1 trip to Los Angeles) valuesput(MediaMIME_TYPE imagejpeg) Add a new record without the bitmap but with the values just set insert() returns the URI of the new record Uri uri = getContentResolver()insert(MediaEXTERNAL_CONTENT_URI values) Now get a handle to the file for that record and save the data into it Here sourceBitmap is a Bitmap object representing the file to save to the database try OutputStream outStream = getContentResolver()openOutputStream(uri) sourceBitmapcompress(BitmapCompressFormatJPEG 50 outStream) outStreamclose() catch (Exception e) Loge(TAG exception while writing image e)

Batch updating records

To batch update a group of records (for example to change NY to New York in all fields) call the

ContentResolverupdate() method with the columns and values to change

Deleting a record

To delete a single record call ContentResolverdelete() with the URI of a specific row

To delete multiple rows call ContentResolverdelete() with the URI of the type of record to delete (for

example androidproviderContactsPeopleCONTENT_URI) and an SQL WHERE clause defining

which rows to delete (Caution Be sure to include a valid WHERE clause if youre deleting a general

type or you risk deleting more records than you intended)

Creating a Content Provider

To create a content provider you must

Set up a system for storing the data Most content providers store their data using Androids file

storage methods or SQLite databases but you can store your data any way you want Android

provides the SQLiteOpenHelper class to help you create a database and SQLiteDatabase to manage

it

Extend the ContentProvider class to provide access to the data

Declare the content provider in the manifest file for your application (AndroidManifestxml)

The following sections have notes on the last two of these tasks

Extending the ContentProvider class

You define a ContentProvider subclass to expose your data to others using the conventions expected

by ContentResolver and Cursor objects Principally this means implementing six abstract methods

declared in the ContentProvider class

query()

insert()

update()

delete()

getType()

onCreate()

The query() method must return a Cursor object that can iterate over the requested data Cursor itself

is an interface but Android provides some ready-made Cursor objects that you can use For example

SQLiteCursor can iterate over data stored in an SQLite database You get the Cursor object by calling

any of the SQLiteDatabase classs query() methods There are other Cursor implementations mdash such

as MatrixCursor mdash for data not stored in a database

Because these ContentProvider methods can be called from various ContentResolver objects in

different processes and threads they must be implemented in a thread-safe manner

As a courtesy you might also want to call ContentResolvernotifyChange() to notify listeners when

there are modifications to the data

Beyond defining the subclass itself there are other steps you should take to simplify the work of clients

and make the class more accessible

Define a public static final Uri named CONTENT_URI This is the string that represents the full content

URI that your content provider handles You must define a unique string for this value The best

solution is to use the fully-qualified class name of the content provider (made lowercase) So for

example the URI for a TransportationProvider class could be defined as follows

public static final Uri CONTENT_URI = Uriparse(contentcomexamplecodelabtransportationprovider)

If the provider has subtables also define CONTENT_URI constants for each of the subtables These

URIs should all have the same authority (since that identifies the content provider) and be

distinguished only by their paths For example

contentcomexamplecodelabtransportationprovidertrain

contentcomexamplecodelabtransportationproviderairdomestic

contentcomexamplecodelabtransportationproviderairinternational

For an overview of content URIs see the Content URI Summary at the end of this document

Define the column names that the content provider will return to clients If you are using an underlying

database these column names are typically identical to the SQL database column names they

represent Also define public static String constants that clients can use to specify the columns in

queries and other instructions

Be sure to include an integer column named _id (with the constant _ID) for the IDs of the records

You should have this field whether or not you have another field (such as a URL) that is also unique

among all records If youre using the SQLite database the _ID field should be the following type

INTEGER PRIMARY KEY AUTOINCREMENT

The AUTOINCREMENT descriptor is optional But without it SQLite increments an ID counter field to

the next number above the largest existing number in the column If you delete the last row the next

row added will have the same ID as the deleted row AUTOINCREMENT avoids this by having SQLite

increment to the next largest value whether deleted or not

Carefully document the data type of each column Clients need this information to read the data

If you are handling a new data type you must define a new MIME type to return in your

implementation of ContentProvidergetType() The type depends in part on whether or not the content

URI submitted to getType() limits the request to a specific record Theres one form of the MIME type

for a single record and another for multiple records Use the Uri methods to help determine what is

being requested Here is the general format for each type

o For a single record vndandroidcursoritemvndyourcompanynamecontenttype

For example a request for train record 122 like this URI

contentcomexampletransportationprovidertrains122

might return this MIME type

vndandroidcursoritemvndexamplerail

o For multiple records vndandroidcursordirvndyourcompanynamecontenttype

For example a request for all train records like the following URI

contentcomexampletransportationprovidertrains

might return this MIME type

vndandroidcursordirvndexamplerail

If you are exposing byte data thats too big to put in the table itself mdash such as a large bitmap file mdash the

field that exposes the data to clients should actually contain a content URI string This is the field that

gives clients access to the data file The record should also have another field named _data that lists

the exact file path on the device for that file This field is not intended to be read by the client but by

the ContentResolver The client will call ContentResolveropenInputStream() on the user-facing field

holding the URI for the item The ContentResolver will request the _data field for that record and

because it has higher permissions than a client it should be able to access that file directly and return

a read wrapper for the file to the client

For an example of a private content provider implementation see the NodePadProvider class in the

Notepad sample application that ships with the SDK

Declaring the content provider

To let the Android system know about the content provider youve developed declare it with a

ltprovidergt element in the applications AndroidManifestxml file Content providers that are not

declared in the manifest are not visible to the Android system

The name attribute is the fully qualified name of the ContentProvider subclass The authorities attribute

is the authority part of the content URI that identifies the provider For example if the ContentProvider

subclass is AutoInfoProvider the ltprovidergt element might look like this

ltprovider androidname=comexampleautosAutoInfoProvider androidauthorities=comexampleautosautoinfoprovider gt ltprovidergt

Note that the authorities attribute omits the path part of a content URI For example if

AutoInfoProvider controlled subtables for different types of autos or different manufacturers

contentcomexampleautosautoinfoproviderhonda

contentcomexampleautosautoinfoprovidergmcompact

contentcomexampleautosautoinfoprovidergmsuv

those paths would not be declared in the manifest The authority is what identifies the provider not the

path your provider can interpret the path part of the URI in any way you choose

Other ltprovidergt attributes can set permissions to read and write data provide for an icon and text

that can be displayed to users enable and disable the provider and so on Set the multiprocess

attribute to true if data does not need to be synchronized between multiple running versions of the

content provider This permits an instance of the provider to be created in each client process

eliminating the need to perform IPC

Content URI Summary

Here is a recap of the important parts of a content URI

A Standard prefix indicating that the data is controlled by a content provider Its never modified

B The authority part of the URI it identifies the content provider For third-party applications this should

be a fully-qualified class name (reduced to lowercase) to ensure uniqueness The authority is declared

in the ltprovidergt elements authorities attribute

ltprovider androidname=TransportationProvider androidauthorities=comexampletransportationprovider gt

C The path that the content provider uses to determine what kind of data is being requested This can be

zero or more segments long If the content provider exposes only one type of data (only trains for

example) it can be absent If the provider exposes several types including subtypes it can be several

segments long mdash for example landbus landtrain seaship and seasubmarine to give four

possibilities

D The ID of the specific record being requested if any This is the _ID value of the requested record If

the request is not limited to a single record this segment and the trailing slash are omitted

contentcomexampletransportationprovidertrains

Intent and intent filters

Three of the core components of an application mdash activities services and broadcast receivers mdash 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 mdash 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 ContextstartActivity() or ActivitystartActivityForResult() to launch an

activity or get an existing activity to do something new (It can also be passed to ActivitysetResult() to

return information to the activity that called startActivityForResult())

An Intent object is passed to ContextstartService() to initiate a service or deliver new instructions to an

ongoing service Similarly an intent can be passed to ContextbindService() to establish a connection

between the calling component and a target service It can optionally initiate the service if its not

already running

Intent objects passed to any of the broadcast methods (such as ContextsendBroadcast()

ContextsendOrderedBroadcast() or ContextsendStickyBroadcast()) 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 mdash how it resolves which component should receive an intent message For

intents that dont explicitly name a target component this process involves testing the Intent object

against intent filters associated with potential targets

Intent Objects

An Intent object is a bundle of information It contains information of interest to the component that

receives the intent (such as the action to be taken and the data to act on) plus information of interest to

the Android system (such as the category of component that should handle the intent and instructions

on how to launch a target activity) Principally it can contain the following

Component name

The name of the component that should handle the intent This field is a ComponentName

object mdash a combination of the fully qualified class name of the target component (for example

comexampleprojectappFreneticActivity) and the package name set in the manifest file of the

application where the component resides (for example comexampleproject) The package

part of the component name and the package name set in the manifest do not necessarily have

to match

The component name is optional If it is set the Intent object is delivered to an instance of the

designated class If it is not set Android uses other information in the Intent object to locate a

suitable target mdash see Intent Resolution later in this document

The component name is set by setComponent() setClass() or setClassName() and read by

getComponent()

Action

A string naming the action to be performed mdash or in the case of broadcast intents the action

that took place and is being reported The Intent class defines a number of action constants

including these

Constant Target

component

Action

ACTION_CALL activity Initiate a phone call

ACTION_EDIT activity Display data for the user to edit

ACTION_MAIN activity Start up as the initial activity of a task

with no data input and no returned

output

ACTION_SYNC activity Synchronize data on a server with

data on the mobile device

ACTION_BATTERY_LOW broadcast

receiver

A warning that the battery is low

ACTION_HEADSET_PLUG broadcast

receiver

A headset has been plugged into the

device or unplugged from it

ACTION_SCREEN_ON broadcast

receiver

The screen has been turned on

ACTION_TIMEZONE_CHANGED broadcast

receiver

The setting for the time zone has

changed

See the Intent class description for a list of pre-defined constants for generic actions Other

actions are defined elsewhere in the Android API You can also define your own action strings

for activating the components in your application Those you invent should include the

application package as a prefix mdash for example comexampleprojectSHOW_COLOR

The action largely determines how the rest of the intent is structured mdash particularly the data and

extras fields mdash much as a method name determines a set of arguments and a return value For

this reason its a good idea to use action names that are as specific as possible and to couple

them tightly to the other fields of the intent In other words instead of defining an action in

isolation define an entire protocol for the Intent objects your components can handle

The action in an Intent object is set by the setAction() method and read by getAction()

Data

The URI of the data to be acted on and the MIME type of that data Different actions are paired

with different kinds of data specifications For example if the action field is ACTION_EDIT the

data field would contain the URI of the document to be displayed for editing If the action is

ACTION_CALL the data field would be a tel URI with the number to call Similarly if the action

is ACTION_VIEW and the data field is an http URI the receiving activity would be called upon

to download and display whatever data the URI refers to

When matching an intent to a component that is capable of handling the data its often

important to know the type of data (its MIME type) in addition to its URI For example a

component able to display image data should not be called upon to play an audio file

In many cases the data type can be inferred from the URI mdash particularly content URIs which

indicate that the data is located on the device and controlled by a content provider (see the

separate discussion on content providers) But the type can also be explicitly set in the Intent

object The setData() method specifies data only as a URI setType() specifies it only as a

MIME type and setDataAndType() specifies it as both a URI and a MIME type The URI is read

by getData() and the type by getType()

Category

A string containing additional information about the kind of component that should handle the

intent Any number of category descriptions can be placed in an Intent object As it does for

actions the Intent class defines several category constants including these

Constant Meaning

CATEGORY_BROWSABLE The target activity can be safely invoked by the browser to

display data referenced by a link mdash for example an image or

an e-mail message

CATEGORY_GADGET The activity can be embedded inside of another activity that

hosts gadgets

CATEGORY_HOME The activity displays the home screen the first screen the

user sees when the device is turned on or when the HOME

key is pressed

CATEGORY_LAUNCHER The activity can be the initial activity of a task and is listed in

the top-level application launcher

CATEGORY_PREFERENCE The target activity is a preference panel

See the Intent class description for the full list of categories

The addCategory() method places a category in an Intent object removeCategory() deletes a

category previously added and getCategories() gets the set of all categories currently in the

object

Extras

Key-value pairs for additional information that should be delivered to the component handling

the intent Just as some actions are paired with particular kinds of data URIs some are paired

with particular extras For example an ACTION_TIMEZONE_CHANGED intent has a time-

zone extra that identifies the new time zone and ACTION_HEADSET_PLUG has a state

extra indicating whether the headset is now plugged in or unplugged as well as a name extra

for the type of headset If you were to invent a SHOW_COLOR action the color value would be

set in an extra key-value pair

The Intent object has a series of put() methods for inserting various types of extra data and a

similar set of get() methods for reading the data These methods parallel those for Bundle

objects In fact the extras can be installed and read as a Bundle using the putExtras() and

getExtras() methods

Flags

Flags of various sorts Many instruct the Android system how to launch an activity (for example

which task the activity should belong to) and how to treat it after its launched (for example

whether it belongs in the list of recent activities) All these flags are defined in the Intent class

The Android system and the applications that come with the platform employ Intent objects both to

send out system-originated broadcasts and to activate system-defined components To see how to

structure an intent to activate a system component consult the list of intents in the reference

Intent Resolution

Intents can be divided into two groups

Explicit intents designate the target component by its name (the component name field mentioned

earlier has a value set) Since component names would generally not be known to developers of other

applications explicit intents are typically used for application-internal messages mdash such as an activity

starting a subordinate service or launching a sister activity

Implicit intents do not name a target (the field for the component name is blank) Implicit intents are

often used to activate components in other applications

Android delivers an explicit intent to an instance of the designated target class Nothing in the Intent

object other than the component name matters for determining which component should get the intent

A different strategy is needed for implicit intents In the absence of a designated target the Android

system must find the best component (or components) to handle the intent mdash a single activity or

service to perform the requested action or the set of broadcast receivers to respond to the broadcast

announcement It does so by comparing the contents of the Intent object to intent filters structures

associated with components that can potentially receive intents Filters advertise the capabilities of a

component and delimit the intents it can handle They open the component to the possibility of

receiving implicit intents of the advertised type If a component does not have any intent filters it can

receive only explicit intents A component with filters can receive both explicit and implicit intents

Only three aspects of an Intent object are consulted when the object is tested against an intent filter

action

data (both URI and data type)

category

The extras and flags play no part in resolving which component receives an intent

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 mdash but only unwanted implicit intents (those that dont 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

components 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 mdash 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 Pads filters are described in the Note Pad Example

section later)

Filters and security

An intent filter cannot be relied on for security While it opens a component to receiving only certain

kinds of implicit intents it does nothing to prevent explicit intents from targeting the component Even

though a filter restricts the intents a component will be asked to handle to certain actions and data

sources someone could always put together an explicit intent with a different action and data source

and name the component as the target

An intent filter is an instance of the IntentFilter class However since the Android system must know

about the capabilities of a component before it can launch that component intent filters are generally

not set up in Java code but in the applications manifest file (AndroidManifestxml) as ltintent-filtergt

elements (The one exception would be filters for broadcast receivers that are registered dynamically

by calling ContextregisterReceiver() they are directly created as IntentFilter objects)

A filter has fields that parallel the action data and category fields of an Intent object An implicit intent

is tested against the filter in all three areas To be delivered to the component that owns the filter it

must pass all three tests If it fails even one of them the Android system wont deliver it to the

component mdash at least not on the basis of that filter However since a component can have multiple

intent filters an intent that does not pass through one of a components filters might make it through on

another

Each of the three tests is described in detail below

Action test

An ltintent-filtergt element in the manifest file lists actions as ltactiongt subelements For

example

ltintent-filter gt ltaction androidname=comexampleprojectSHOW_CURRENT gt ltaction androidname=comexampleprojectSHOW_RECENT gt ltaction androidname=comexampleprojectSHOW_PENDING gt ltintent-filtergt

As the example shows while an Intent object names just a single action a filter may list more

than one The list cannot be empty a filter must contain at least one ltactiongt element or it will

block all intents

To pass this test the action specified in the Intent object must match one of the actions listed in

the filter If the object or the filter does not specify an action the results are as follows

If the filter fails to list any actions there is nothing for an intent to match so all intents fail the

test No intents can get through the filter

On the other hand an Intent object that doesnt specify an action automatically passes the test

mdash as long as the filter contains at least one action

Category test

An ltintent-filtergt element also lists categories as subelements For example

ltintent-filter gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryBROWSABLE gt ltintent-filtergt

Note that the constants described earlier for actions and categories are not used in the manifest

file The full string values are used instead For instance the

androidintentcategoryBROWSABLE string in the example above corresponds to the

CATEGORY_BROWSABLE constant mentioned earlier in this document Similarly the string

androidintentactionEDIT corresponds to the ACTION_EDIT constant

For an intent to pass the category test every category in the Intent object must match a

category in the filter The filter can list additional categories but it cannot omit any that are in the

intent

In principle therefore an Intent object with no categories should always pass this test

regardless of whats in the filter Thats mostly true However with one exception Android treats

all implicit intents passed to startActivity() as if they contained at least one category

androidintentcategoryDEFAULT (the CATEGORY_DEFAULT constant) Therefore activities

that are willing to receive implicit intents must include androidintentcategoryDEFAULT in

their intent filters (Filters with androidintentactionMAIN and

androidintentcategoryLAUNCHER settings are the exception They mark activities that begin

new tasks and that are represented on the launcher screen They can include

androidintentcategoryDEFAULT in the list of categories but dont need to) See Using intent

matching later for more on these filters)

Data test

Like the action and categories the data specification for an intent filter is contained in a

subelement And as in those cases the subelement can appear multiple times or not at all For

example

ltintent-filter gt ltdata androidmimeType=videompeg androidscheme=http gt ltdata androidmimeType=audiompeg androidscheme=http gt ltintent-filtergt

Each ltdatagt element can specify a URI and a data type (MIME media type) There are

separate attributes mdash scheme host port and path mdash for each part of the URI

schemehostportpath

For example in the following URI

contentcomexampleproject200foldersubfolderetc

the scheme is content the host is comexampleproject the port is 200 and the path is

foldersubfolderetc The host and port together constitute the URI authority if a host is not

specified the port is ignored

Each of these attributes is optional but they are not independent of each other For an authority

to be meaningful a scheme must also be specified For a path to be meaningful both a scheme

and an authority must be specified

When the URI in an Intent object is compared to a URI specification in a filter its compared

only to the parts of the URI actually mentioned in the filter For example if a filter specifies only

a scheme all URIs with that scheme match the filter If a filter specifies a scheme and an

authority but no path all URIs with the same scheme and authority match regardless of their

paths If a filter specifies a scheme an authority and a path only URIs with the same scheme

authority and path match However a path specification in the filter can contain wildcards to

require only a partial match of the path

The type attribute of a ltdatagt element specifies the MIME type of the data Its more common in

filters than a URI Both the Intent object and the filter can use a wildcard for the subtype field

mdash for example text or audio mdash indicating any subtype matches

The data test compares both the URI and the data type in the Intent object to a URI and data

type specified in the filter The rules are as follows

a An Intent object that contains neither a URI nor a data type passes the test only if the filter

likewise does not specify any URIs or data types

b An Intent object that contains a URI but no data type (and a type cannot be inferred from the

URI) passes the test only if its URI matches a URI in the filter and the filter likewise does not

specify a type This will be the case only for URIs like mailto and tel that do not refer to actual

data

c An Intent object that contains a data type but not a URI passes the test only if the filter lists the

same data type and similarly does not specify a URI

d An Intent object that contains both a URI and a data type (or a data type can be inferred from

the URI) passes the data type part of the test only if its type matches a type listed in the filter It

passes the URI part of the test either if its URI matches a URI in the filter or if it has a content

or file URI and the filter does not specify a URI In other words a component is presumed to

support content and file data if its filter lists only a data type

If an intent can pass through the filters of more than one activity or service the user may be asked

which component to activate An exception is raised if no target can be found

Common cases

The last rule shown above for the data test rule (d) reflects the expectation that components are able

to get local data from a file or content provider Therefore their filters can list just a data type and do

not need to explicitly name the content and file schemes This is a typical case A ltdatagt element like

the following for example tells Android that the component can get image data from a content

provider and display it

ltdata androidmimeType=image gt

Since most available data is dispensed by content providers filters that specify a data type but not a

URI are perhaps the most common

Another common configuration is filters with a scheme and a data type For example a ltdatagt

element like the following tells Android that the component can get video data from the network and

display it

ltdata androidscheme=http androidtype=video gt

Consider for example what the browser application does when the user follows a link on a web page

It first tries to display the data (as it could if the link was to an HTML page) If it cant display the data it

puts together an implicit intent with the scheme and data type and tries to start an activity that can do

the job If there are no takers it asks the download manager to download the data That puts it under

the control of a content provider so a potentially larger pool of activities (those with filters that just

name a data type) can respond

Most applications also have a way to start fresh without a reference to any particular data Activities

that can initiate applications have filters with androidintentactionMAIN specified as the action If

they are to be represented in the application launcher they also specify the

androidintentcategoryLAUNCHER category

ltintent-filter gt ltaction androidname=code androidintentactionMAIN gt ltcategory androidname=code androidintentcategoryLAUNCHER gt ltintent-filtergt

Using intent matching

Intents are matched against intent filters not only to discover a target component to activate but also

to discover something about the set of components on the device For example the Android system

populates the application launcher the top-level screen that shows the applications that are available

for the user to launch by finding all the activities with intent filters that specify the

androidintentactionMAIN action and androidintentcategoryLAUNCHER category (as illustrated

in the previous section) It then displays the icons and labels of those activities in the launcher

Similarly it discovers the home screen by looking for the activity with androidintentcategoryHOME

in its filter

Your application can use intent matching is a similar way The PackageManager has a set of query()

methods that return all components that can accept a particular intent and a similar series of

resolve() methods that determine the best component to respond to an intent For example

queryIntentActivities() returns a list of all activities that can perform the intent passed as an argument

and queryIntentServices() returns a similar list of services Neither method activates the components

they just list the ones that can respond Theres a similar method queryBroadcastReceivers() for

broadcast receivers

Note Pad Example

The Note Pad sample application enables users to browse through a list of notes view details about

individual items in the list edit the items and add a new item to the list This section looks at the intent

filters declared in its manifest file (If youre working offline in the SDK you can find all the source files

for this sample application including its manifest file at ltsdkgtsamplesNotePadindexhtml If youre

viewing the documentation online the source files are in the Tutorials and Sample Code section here)

In its manifest file the Note Pad application declares three activities each with at least one intent filter

It also declares a content provider that manages the note data Here is the manifest file in its entirety

ltmanifest xmlnsandroid=httpschemasandroidcomapkresandroid package=comexampleandroidnotepadgt ltapplication androidicon=drawableapp_notes androidlabel=stringapp_name gt ltprovider androidname=NotePadProvider androidauthorities=comgoogleproviderNotePad gt ltactivity androidname=NotesList androidlabel=stringtitle_notes_listgt ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltactivity androidname=NoteEditor androidtheme=androidstyleThemeLight androidlabel=stringtitle_note gt ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltactivitygt

ltactivity androidname=TitleEditor androidlabel=stringtitle_edit_title androidtheme=androidstyleThemeDialoggt ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltapplicationgt ltmanifestgt

The first activity NotesList is distinguished from the other activities by the fact that it operates on a

directory of notes (the note list) rather than on a single note It would generally serve as the initial user

interface into the application It can do three things as described by its three intent filters

1 ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt

This filter declares the main entry point into the Note Pad application The standard MAIN action is an

entry point that does not require any other information in the Intent (no data specification for example)

and the LAUNCHER category says that this entry point should be listed in the application launcher

2 ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

This filter declares the things that the activity can do on a directory of notes It can allow the user to

view or edit the directory (via the VIEW and EDIT actions) or to pick a particular note from the

directory (via the PICK action)

The mimeType attribute of the ltdatagt element specifies the kind of data that these actions operate on

It indicates that the activity can get a Cursor over zero or more items (vndandroidcursordir) from a

content provider that holds Note Pad data (vndgooglenote) The Intent object that launches the

activity would include a content URI specifying the exact data of this type that the activity should open

Note also the DEFAULT category supplied in this filter Its there because the ContextstartActivity()

and ActivitystartActivityForResult() methods treat all intents as if they contained the DEFAULT

category mdash with just two exceptions

o Intents that explicitly name the target activity

o Intents consisting of the MAIN action and LAUNCHER category

Therefore the DEFAULT category is required for all filters mdash except for those with the MAIN action

and LAUNCHER category (Intent filters are not consulted for explicit intents)

3 ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

This filter describes the activitys ability to return a note selected by the user without requiring any

specification of the directory the user should choose from The GET_CONTENT action is similar to the

PICK action In both cases the activity returns the URI for a note selected by the user (In each case

its returned to the activity that called startActivityForResult() to start the NoteList activity) Here

however the caller specifies the type of data desired instead of the directory of data the user will be

picking from

The data type vndandroidcursoritemvndgooglenote indicates the type of data the activity can

return mdash a URI for a single note From the returned URI the caller can get a Cursor for exactly one

item (vndandroidcursoritem) from the content provider that holds Note Pad data (vndgooglenote)

In other words for the PICK action in the previous filter the data type indicates the type of data the

activity could display to the user For the GET_CONTENT filter it indicates the type of data the activity

can return to the caller

Given these capabilities the following intents will resolve to the NotesList activity

action androidintentactionMAIN

Launches the activity with no data specified

action androidintentactionMAIN

category androidintentcategoryLAUNCHER

Launches the activity with no data selected specified This is the actual intent used by the

Launcher to populate its top-level list All activities with filters that match this action and

category are added to the list

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of all the notes under

contentcomgoogleproviderNotePadnotes The user can then browse through the list and

get information about the items in it

action androidintentactionPICK

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of the notes under

contentcomgoogleproviderNotePadnotes The user can then pick a note from the list and

the activity will return the URI for that item back to the activity that started the NoteList activity

action androidintentactionGET_CONTENT

data type vndandroidcursoritemvndgooglenote

Asks the activity to supply a single item of Note Pad data

The second activity NoteEditor shows users a single note entry and allows them to edit it It can do

two things as described by its two intent filters

1 ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The first primary purpose of this activity is to enable the user to interact with a single note ampmdash to

either VIEW the note or EDIT it (The EDIT_NOTE category is a synonym for EDIT) The intent would

contain the URI for data matching the MIME type vndandroidcursoritemvndgooglenote mdash that is

the URI for a single specific note It would typically be a URI that was returned by the PICK or

GET_CONTENT actions of the NoteList activity

As before this filter lists the DEFAULT category so that the activity can be launched by intents that

dont explicitly specify the NoteEditor class

2 ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

The secondary purpose of this activity is to enable the user to create a new note which it will INSERT

into an existing directory of notes The intent would contain the URI for data matching the MIME type

vndandroidcursordirvndgooglenote mdash that is the URI for the directory where the note should be

placed

Given these capabilities the following intents will resolve to the NoteEditor activity

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID (For details on how content

URIs specify individual members of a group see Content Providers)

action androidintentactionEDIT

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID and to let the user edit it If

the user saves the changes the activity updates the data for the note in the content provider

action androidintentactionINSERT

data contentcomgoogleproviderNotePadnotes

Asks the activity to create a new empty note in the notes list at

contentcomgoogleproviderNotePadnotes and allow the user to edit it If the user saves the

note its URI is returned to the caller

The last activity TitleEditor enables the user to edit the title of a note This could be implemented by

directly invoking the activity (by explicitly setting its component name in the Intent) without using an

intent filter But here we take the opportunity to show how to publish alternative operations on existing

data

ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The single intent filter for this activity uses a custom action called

comandroidnotepadactionEDIT_TITLE It must be invoked on a specific note (data type

vndandroidcursoritemvndgooglenote) like the previous VIEW and EDIT actions However here the

activity displays the title contained in the note data not the content of the note itself

In addition to supporting the usual DEFAULT category the title editor also supports two other standard

categories ALTERNATIVE and SELECTED_ALTERNATIVE These categories identify activities that

can be presented to users in a menu of options (much as the LAUNCHER category identifies activities

that should be presented to user in the application launcher) Note that the filter also supplies an

explicit label (via androidlabel=stringresolve_title) to better control what users see when

presented with this activity as an alternative action to the data they are currently viewing (For more

information on these categories and building options menus see the

PackageManagerqueryIntentActivityOptions() and MenuaddIntentOptions() methods)

Given these capabilities the following intent will resolve to the TitleEditor activity

action comandroidnotepadactionEDIT_TITLE

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the title associated with note ID and allow the user to edit the title

Processes and Threads

When an application component starts and the application does not have any other components

running the Android system starts a new Linux process for the application with a single thread of

execution By default all components of the same application run in the same process and thread

(called the main thread) If an application component starts and there already exists a process for

that application (because another component from the application exists) then the component is

started within that process and uses the same thread of execution However you can arrange for

different components in your application to run in separate processes and you can create additional

threads for any process

This document discusses how processes and threads work in an Android application

Processes

By default all components of the same application run in the same process and most applications

should not change this However if you find that you need to control which process a certain

component belongs to you can do so in the manifest file

The manifest entry for each type of component elementmdashltactivitygt ltservicegt ltreceivergt and

ltprovidergtmdashsupports an androidprocess attribute that can specify a process in which that component

should run You can set this attribute so that each component runs in its own process or so that some

components share a process while others do not You can also set androidprocess so that

components of different applications run in the same processmdashprovided that the applications share the

same Linux user ID and are signed with the same certificates

The ltapplicationgt element also supports an androidprocess attribute to set a default value that

applies to all components

Android might 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 thats killed are consequently destroyed A process is started again for those components

when theres again work for them to do

When deciding which processes to kill the Android system weighs their relative importance to the

user For example it more readily shuts down a process hosting activities that are no longer visible on

screen compared to a process hosting visible activities The decision whether to terminate a process

therefore depends on the state of the components running in that process The rules used to decide

which processes to terminate is discussed below

Process lifecycle

The Android system tries to maintain an application process for as long as possible but eventually

needs to remove old processes to reclaim memory for new or more important processes To determine

which processes to keep and which to kill the system places each process into an importance

hierarchy based on the components running in the process and the state of those components

Processes with the lowest importance are eliminated first then those with the next lowest importance

and so on as necessary to recover system resources

There are five levels in the importance hierarchy The following list presents the different types of

processes in order of importance (the first process is most important and is killed last)

1 Foreground process

A process that is required for what the user is currently doing A process is considered to be in the

foreground if any of the following conditions are true

o It hosts an Activity that the user is interacting with (the Activitys onResume() method has been called)

o It hosts a Service thats bound to the activity that the user is interacting with

o It hosts a Service thats running in the foregroundmdashthe service has called startForeground()

o It hosts a Service thats executing one of its lifecycle callbacks (onCreate() onStart() or onDestroy())

o It hosts a BroadcastReceiver thats executing its onReceive() method

Generally only a few foreground processes exist at any given time They are killed only as a last

resortmdashif memory is so low that they cannot all continue to run Generally at that point the device has

reached a memory paging state so killing some foreground processes is required to keep the user

interface responsive

2 Visible process

A process that doesnt have any foreground components but still can affect what the user sees on

screen A process is considered to be visible if either of the following conditions are true

o It hosts an Activity that is not in the foreground but is still visible to the user (its onPause() method has

been called) This might occur for example if the foreground activity started a dialog which allows the

previous activity to be seen behind it

o It hosts a Service thats bound to a visible (or foreground) activity

A visible process is considered extremely important and will not be killed unless doing so is required to

keep all foreground processes running

3 Service process

A process that is running a service that has been started with the startService() method and does not

fall into either of the two higher categories Although service processes are not directly tied to anything

the user sees they are generally doing things that the user cares about (such as playing music in the

background or downloading data on the network) so the system keeps them running unless theres

not enough memory to retain them along with all foreground and visible processes

4 Background process

A process holding an activity thats not currently visible to the user (the activitys onStop() method has

been called) These processes have no direct impact on the user experience and the system can kill

them at any time to reclaim memory for a foreground visible or service process Usually there are

many background processes running so they are kept in an LRU (least recently used) list to ensure

that the process with the activity that was most recently seen by the user is the last to be killed If an

activity implements its lifecycle methods correctly and saves its current state killing its process will not

have a visible effect on the user experience because when the user navigates back to the activity the

activity restores all of its visible state See the Activities document for information about saving and

restoring state

5 Empty process

A process that doesnt hold any active application components The only reason to keep this kind of

process alive is for caching purposes to improve startup time the next time a component needs to run

in it The system often kills these processes in order to balance overall system resources between

process caches and the underlying kernel caches

Android ranks a process at the highest level it can based upon the importance of the components

currently active in the process For example if a process hosts a service and a visible activity the

process is ranked as a visible process not a service process

In addition a processs ranking might be increased because other processes are dependent on itmdasha

process that is serving another process can never be ranked lower than the process it is serving For

example if a content provider in process A is serving a client in process B or if a service in process A

is bound to a component in process B process A is always considered at least as important as

process B

Because a process running a service is ranked higher than a process with background activities an

activity that initiates a long-running operation might do well to start a service for that operation rather

than simply create a worker threadmdashparticularly if the operation will likely outlast the activity For

example an activity thats uploading a picture to a web site should start a service to perform the

upload so that the upload can continue in the background even if the user leaves the activity Using a

service guarantees that the operation will have at least service process priority regardless of what

happens to the activity This is the same reason that broadcast receivers should employ services

rather than simply put time-consuming operations in a thread

Threads

When an application is launched the system creates a thread of execution for the application called

main This thread is very important because it is in charge of dispatching events to the appropriate

user interface widgets including drawing events It is also the thread in which your application interacts

with components from the Android UI toolkit (components from the androidwidget and androidview

packages) As such the main thread is also sometimes called the UI thread

The system does not create a separate thread for each instance of a component All components that

run in the same process are instantiated in the UI thread and system calls to each component are

dispatched from that thread Consequently methods that respond to system callbacks (such as

onKeyDown() to report user actions or a lifecycle callback method) always run in the UI thread of the

process

For instance when the user touches a button on the screen your apps UI thread dispatches the touch

event to the widget which in turn sets its pressed state and posts an invalidate request to the event

queue The UI thread dequeues the request and notifies the widget that it should redraw itself

When your app performs intensive work in response to user interaction this single thread model can

yield poor performance unless you implement your application properly Specifically if everything is

happening in the UI thread performing long operations such as network access or database queries

will block the whole UI When the thread is blocked no events can be dispatched including drawing

events From the users perspective the application appears to hang Even worse if the UI thread is

blocked for more than a few seconds (about 5 seconds currently) the user is presented with the

infamous application not responding (ANR) dialog The user might then decide to quit your

application and uninstall it if they are unhappy

Additionally the Andoid UI toolkit is not thread-safe So you must not manipulate your UI from a

worker threadmdashyou must do all manipulation to your user interface from the UI thread Thus there are

simply two rules to Androids single thread model

1 Do not block the UI thread

2 Do not access the Android UI toolkit from outside the UI thread

Worker threads

Because of the single thread model described above its vital to the responsiveness of your

applications UI that you do not block the UI thread If you have operations to perform that are not

instantaneous you should make sure to do them in separate threads (background or worker

threads)

For example below is some code for a click listener that downloads an image from a separate thread

and displays it in an ImageView

public void onClick(View v) new Thread(new Runnable() public void run() Bitmap b = loadImageFromNetwork(httpexamplecomimagepng) mImageViewsetImageBitmap(b) )start()

At first this seems to work fine because it creates a new thread to handle the network operation

However it violates the second rule of the single-threaded model do not access the Android UI toolkit

from outside the UI threadmdashthis sample modifies the ImageView from the worker thread instead of the

UI thread This can result in undefined and unexpected behavior which can be difficult and time-

consuming to track down

To fix this problem Android offers several ways to access the UI thread from other threads Here is a

list of methods that can help

ActivityrunOnUiThread(Runnable)

Viewpost(Runnable)

ViewpostDelayed(Runnable long)

For example you can fix the above code by using the Viewpost(Runnable) method

public void onClick(View v) new Thread(new Runnable() public void run() final Bitmap bitmap = loadImageFromNetwork(httpexamplecomimagepng) mImageViewpost(new Runnable() public void run() mImageViewsetImageBitmap(bitmap) ) )start()

Now this implementation is thread-safe the network operation is done from a separate thread while

the ImageView is manipulated from the UI thread

However as the complexity of the operation grows this kind of code can get complicated and difficult

to maintain To handle more complex interactions with a worker thread you might consider using a

Handler in your worker thread to process messages delivered from the UI thread Perhaps the best

solution though is to extend the AsyncTask class which simplifies the execution of worker thread

tasks that need to interact with the UI

Using AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface It performs the blocking

operations in a worker thread and then publishes the results on the UI thread without requiring you to

handle threads andor handlers yourself

To use it you must subclass AsyncTask and implement the doInBackground() callback method which

runs in a pool of background threads To update your UI you should implement onPostExecute()

which delivers the result from doInBackground() and runs in the UI thread so you can safely update

your UI You can then run the task by calling execute() from the UI thread

For example you can implement the previous example using AsyncTask this way

public void onClick(View v) new DownloadImageTask()execute(httpexamplecomimagepng) private class DownloadImageTask extends AsyncTaskltString Void Bitmapgt The system calls this to perform work in a worker thread and delivers it the parameters given to AsyncTaskexecute() protected Bitmap doInBackground(String urls) return loadImageFromNetwork(urls[0])

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 13: 03 services

Figure 2 The service lifecycle The diagram on the left shows the lifecycle when the service is created

with startService() and the diagram on the right shows the lifecycle when the service is created with

bindService()

public class ExampleService extends Service int mStartMode indicates how to behave if the service is killed IBinder mBinder interface for clients that bind boolean mAllowRebind indicates whether onRebind should be used Override public void onCreate() The service is being created Override public int onStartCommand(Intent intent int flags int startId) The service is starting due to a call to startService() return mStartMode Override public IBinder onBind(Intent intent) A client is binding to the service with bindService() return mBinder Override public boolean onUnbind(Intent intent) All clients have unbound with unbindService()

return mAllowRebind Override public void onRebind(Intent intent) A client is binding to the service with bindService() after onUnbind() has already been called Override public void onDestroy() The service is no longer used and is being destroyed

Note Unlike the activity lifecycle callback methods you are not required to call the superclass

implementation of these callback methods

By implementing these methods you can monitor two nested loops of the services lifecycle

The entire lifetime of a service happens between the time onCreate() is called and the time

onDestroy() returns Like an activity a service does its initial setup in onCreate() and releases all

remaining resources in onDestroy() For example a music playback service could create the thread

where the music will be played in onCreate() then stop the thread in onDestroy()

The onCreate() and onDestroy() methods are called for all services whether theyre created by

startService() or bindService()

The active lifetime of a service begins with a call to either onStartCommand() or onBind() Each

method is handed the Intent that was passed to either startService() or bindService() respectively

If the service is started the active lifetime ends the same time that the entire lifetime ends (the service

is still active even after onStartCommand() returns) If the service is bound the active lifetime ends

when onUnbind() returns

Note Although a started service is stopped by a call to either stopSelf() or stopService() there is

not a respective callback for the service (theres no onStop() callback) So unless the service is

bound to a client the system destroys it when the service is stoppedmdashonDestroy() is the only

callback received

Figure 2 illustrates the typical callback methods for a service Although the figure separates services

that are created by startService() from those created by bindService() keep in mind that any service

no matter how its started can potentially allow clients to bind to it So a service that was initially

started with onStartCommand() (by a client calling startService()) can still receive a call to onBind()

(when a client calls bindService())

For more information about creating a service that provides binding see the Bound Services

document which includes more information about the onRebind() callback method in the section about

Managing the Lifecycle of a Bound Service

Bound Services

A bound service is the server in a client-server interface A bound service allows components (such as

activities) to bind to the service send requests receive responses and even perform interprocess

communication (IPC) A bound service typically lives only while it serves another application

component and does not run in the background indefinitely

This document shows you how to create a bound service including how to bind to the service from

other application components However you should also refer to the Services document for additional

information about services in general such as how to deliver notifications from a service set the

service to run in the foreground and more

The Basics

A bound service is an implementation of the Service class that allows other applications to bind to it

and interact with it To provide binding for a service you must implement the onBind() callback

method This method returns an IBinder object that defines the programming interface that clients can

use to interact with the service

Binding to a Started Service

As discussed in the Services document you can create a service that is both started and bound That

is the service can be started by calling startService() which allows the service to run indefinitely and

also allow a client to bind to the service by calling bindService()

If you do allow your service to be started and bound then when the service has been started the

system does not destroy the service when all clients unbind Instead you must explicitly stop the

service by calling stopSelf() or stopService()

Although you should usually implement either onBind() or onStartCommand() its sometimes

necessary to implement both For example a music player might find it useful to allow its service to run

indefinitely and also provide binding This way an activity can start the service to play some music and

the music continues to play even if the user leaves the application Then when the user returns to the

application the activity can bind to the service to regain control of playback

Be sure to read the section about Managing the Lifecycle of a Bound Service for more information

about the service lifecycle when adding binding to a started service

A client can bind to the service by calling bindService() When it does it must provide an

implementation of ServiceConnection which monitors the connection with the service The

bindService() method returns immediately without a value but when the Android system creates the

connection between the client and service it calls onServiceConnected() on the ServiceConnection to

deliver the IBinder that the client can use to communicate with the service

Multiple clients can connect to the service at once However the system calls your services onBind()

method to retrieve the IBinder only when the first client binds The system then delivers the same

IBinder to any additional clients that bind without calling onBind() again

When the last client unbinds from the service the system destroys the service (unless the service was

also started by startService())

When you implement your bound service the most important part is defining the interface that your

onBind() callback method returns There are a few different ways you can define your services IBinder

interface and the following section discusses each technique

Creating a Bound Service

When creating a service that provides binding you must provide an IBinder that provides the

programming interface that clients can use to interact with the service There are three ways you can

define the interface

Extending the Binder class

If your service is private to your own application and runs in the same process as the client

(which is common) you should create your interface by extending the Binder class and

returning an instance of it from onBind() The client receives the Binder and can use it to directly

access public methods available in either the Binder implementation or even the Service

This is the preferred technique when your service is merely a background worker for your own

application The only reason you would not create your interface this way is because your

service is used by other applications or across separate processes

Using a Messenger

If you need your interface to work across different processes you can create an interface for the

service with a Messenger In this manner the service defines a Handler that responds to

different types of Message objects This Handler is the basis for a Messenger that can then

share an IBinder with the client allowing the client to send commands to the service using

Message objects Additionally the client can define a Messenger of its own so the service can

send messages back

This is the simplest way to perform interprocess communication (IPC) because the Messenger

queues all requests into a single thread so that you dont have to design your service to be

thread-safe

Using AIDL

AIDL (Android Interface Definition Language) performs all the work to decompose objects into

primitives that the operating system can understand and marshall them across processes to

perform IPC The previous technique using a Messenger is actually based on AIDL as its

underlying structure As mentioned above the Messenger creates a queue of all the client

requests in a single thread so the service receives requests one at a time If however you

want your service to handle multiple requests simultaneously then you can use AIDL directly In

this case your service must be capable of multi-threading and be built thread-safe

To use AIDL directly you must create an aidl file that defines the programming interface The

Android SDK tools use this file to generate an abstract class that implements the interface and

handles IPC which you can then extend within your service

Note Most applications should not use AIDL to create a bound service because it may require

multithreading capabilities and can result in a more complicated implementation As such AIDL is

not suitable for most applications and this document does not discuss how to use it for your

service If youre certain that you need to use AIDL directly see the AIDL document

Extending the Binder class

If your service is used only by the local application and does not need to work across processes then

you can implement your own Binder class that provides your client direct access to public methods in

the service

Note This works only if the client and service are in the same application and process which is

most common For example this would work well for a music application that needs to bind an

activity to its own service thats playing music in the background

Heres how to set it up

1 In your service create an instance of Binder that either

o contains public methods that the client can call

o returns the current Service instance which has public methods the client can call

o or returns an instance of another class hosted by the service with public methods the client can call

2 Return this instance of Binder from the onBind() callback method

3 In the client receive the Binder from the onServiceConnected() callback method and make calls to the

bound service using the methods provided

Note The reason the service and client must be in the same application is so the client can cast

the returned object and properly call its APIs The service and client must also be in the same

process because this technique does not perform any marshalling across processes

For example heres a service that provides clients access to methods in the service through a Binder

implementation

public class LocalService extends Service

Binder given to clients

private final IBinder mBinder = new LocalBinder()

Random number generator

private final Random mGenerator = new Random()

Class used for the client Binder Because we know this service always

runs in the same process as its clients we dont need to deal with IPC

public class LocalBinder extends Binder

LocalService getService()

Return this instance of LocalService so clients can call public methods

return LocalServicethis

Override

public IBinder onBind(Intent intent)

return mBinder

method for clients

public int getRandomNumber()

return mGeneratornextInt(100)

The LocalBinder provides the getService() method for clients to retrieve the current instance of

LocalService This allows clients to call public methods in the service For example clients can call

getRandomNumber() from the service

Heres an activity that binds to LocalService and calls getRandomNumber() when a button is clicked

public class BindingActivity extends Activity

LocalService mService

boolean mBound = false

Override

protected void onCreate(Bundle savedInstanceState)

superonCreate(savedInstanceState)

setContentView(Rlayoutmain)

Override

protected void onStart()

superonStart()

Bind to LocalService

Intent intent = new Intent(this LocalServiceclass)

bindService(intent mConnection ContextBIND_AUTO_CREATE)

Override

protected void onStop()

superonStop()

Unbind from the service

if (mBound)

unbindService(mConnection)

mBound = false

Called when a button is clicked (the button in the layout file attaches to

this method with the androidonClick attribute)

public void onButtonClick(View v)

if (mBound)

Call a method from the LocalService

However if this call were something that might hang then this request should

occur in a separate thread to avoid slowing down the activity performance

int num = mServicegetRandomNumber()

ToastmakeText(this number + num ToastLENGTH_SHORT)show()

Defines callbacks for service binding passed to bindService()

private ServiceConnection mConnection = new ServiceConnection()

Override

public void onServiceConnected(ComponentName className

IBinder service)

Weve bound to LocalService cast the IBinder and get LocalService instance

LocalBinder binder = (LocalBinder) service

mService = bindergetService()

mBound = true

Override

public void onServiceDisconnected(ComponentName arg0)

mBound = false

The above sample shows how the client binds to the service using an implementation of

ServiceConnection and the onServiceConnected() callback The next section provides more

information about this process of binding to the service

Note The example above doesnt explicitly unbind from the service but all clients should unbind

at an appropriate time (such as when the activity pauses)

For more sample code see the LocalServicejava class and the LocalServiceActivitiesjava class in

ApiDemos

Using a Messenger

Compared to AIDL

When you need to perform IPC using a Messenger for your interface is simpler than implementing it

with AIDL because Messenger queues all calls to the service whereas a pure AIDL interface sends

simultaneous requests to the service which must then handle multi-threading

For most applications the service doesnt need to perform multi-threading so using a Messenger

allows the service to handle one call at a time If its important that your service be multi-threaded then

you should use AIDL to define your interface

If you need your service to communicate with remote processes then you can use a Messenger to

provide the interface for your service This technique allows you to perform interprocess

communication (IPC) without the need to use AIDL

Heres a summary of how to use a Messenger

The service implements a Handler that receives a callback for each call from a client

The Handler is used to create a Messenger object (which is a reference to the Handler)

The Messenger creates an IBinder that the service returns to clients from onBind()

Clients use the IBinder to instantiate the Messenger (that references the services Handler) which the

client uses to send Message objects to the service

The service receives each Message in its Handlermdashspecifically in the handleMessage() method

In this way there are no methods for the client to call on the service Instead the client delivers

messages (Message objects) that the service receives in its Handler

Heres a simple example service that uses a Messenger interface

public class MessengerService extends Service Command to the service to display a message static final int MSG_SAY_HELLO = 1 Handler of incoming messages from clients class IncomingHandler extends Handler Override public void handleMessage(Message msg) switch (msgwhat) case MSG_SAY_HELLO ToastmakeText(getApplicationContext() hello ToastLENGTH_SHORT)show() break default superhandleMessage(msg) Target we publish for clients to send messages to IncomingHandler final Messenger mMessenger = new Messenger(new IncomingHandler()) When binding to the service we return an interface to our messenger for sending messages to the service Override public IBinder onBind(Intent intent) ToastmakeText(getApplicationContext() binding ToastLENGTH_SHORT)show() return mMessengergetBinder()

Notice that the handleMessage() method in the Handler is where the service receives the incoming

Message and decides what to do based on the what member

All that a client needs to do is create a Messenger based on the IBinder returned by the service and

send a message using send() For example heres a simple activity that binds to the service and

delivers the MSG_SAY_HELLO message to the service

public class ActivityMessenger extends Activity Messenger for communicating with the service Messenger mService = null Flag indicating whether we have called bind on the service boolean mBound Class for interacting with the main interface of the service private ServiceConnection mConnection = new ServiceConnection() public void onServiceConnected(ComponentName className IBinder service) This is called when the connection with the service has been established giving us the object we can use to interact with the service We are communicating with the service using a Messenger so here we get a client-side representation of that from the raw IBinder object mService = new Messenger(service) mBound = true public void onServiceDisconnected(ComponentName className) This is called when the connection with the service has been unexpectedly disconnected -- that is its process crashed mService = null mBound = false public void sayHello(View v) if (mBound) return Create and send a message to the service using a supported what value Message msg = Messageobtain(null MessengerServiceMSG_SAY_HELLO 0 0) try mServicesend(msg) catch (RemoteException e) eprintStackTrace() Override protected void onCreate(Bundle savedInstanceState) superonCreate(savedInstanceState) setContentView(Rlayoutmain)

Override protected void onStart() superonStart() Bind to the service bindService(new Intent(this MessengerServiceclass) mConnection ContextBIND_AUTO_CREATE) Override protected void onStop() superonStop() Unbind from the service if (mBound) unbindService(mConnection) mBound = false

Notice that this example does not show how the service can respond to the client If you want the

service to respond then you need to also create a Messenger in the client Then when the client

receives the onServiceConnected() callback it sends a Message to the service that includes the

clients Messenger in the replyTo parameter of the send() method

You can see an example of how to provide two-way messaging in the MessengerServicejava (service)

and MessengerServiceActivitiesjava (client) samples

Binding to a Service

Application components (clients) can bind to a service by calling bindService() The Android system

then calls the services onBind() method which returns an IBinder for interacting with the service

The binding is asynchronous bindService() returns immediately and does not return the IBinder to the

client To receive the IBinder the client must create an instance of ServiceConnection and pass it to

bindService() The ServiceConnection includes a callback method that the system calls to deliver the

IBinder

Note Only activities services and content providers can bind to a servicemdashyou cannot bind to a

service from a broadcast receiver

So to bind to a service from your client you must

1 Implement ServiceConnection

Your implementation must override two callback methods

onServiceConnected()

The system calls this to deliver the IBinder returned by the services onBind() method

onServiceDisconnected()

The Android system calls this when the connection to the service is unexpectedly lost such as

when the service has crashed or has been killed This is not called when the client unbinds

2 Call bindService() passing the ServiceConnection implementation

3 When the system calls your onServiceConnected() callback method you can begin making calls to the

service using the methods defined by the interface

4 To disconnect from the service call unbindService()

When your client is destroyed it will unbind from the service but you should always unbind when

youre done interacting with the service or when your activity pauses so that the service can shutdown

while its not being used (Appropriate times to bind and unbind is discussed more below)

For example the following snippet connects the client to the service created above by extending the

Binder class so all it must do is cast the returned IBinder to the LocalService class and request the

LocalService instance

LocalService mService private ServiceConnection mConnection = new ServiceConnection() Called when the connection with the service is established public void onServiceConnected(ComponentName className IBinder service) Because we have bound to an explicit service that is running in our own process we can cast its IBinder to a concrete class and directly access it LocalBinder binder = (LocalBinder) service mService = bindergetService() mBound = true Called when the connection with the service disconnects unexpectedly public void onServiceDisconnected(ComponentName className) Loge(TAG onServiceDisconnected) mBound = false

With this ServiceConnection the client can bind to a service by passing this it to bindService() For

example

Intent intent = new Intent(this LocalServiceclass) bindService(intent mConnection ContextBIND_AUTO_CREATE)

The first parameter of bindService() is an Intent that explicitly names the service to bind (thought the

intent could be implicit)

The second parameter is the ServiceConnection object

The third parameter is a flag indicating options for the binding It should usually be

BIND_AUTO_CREATE in order to create the service if its not already alive Other possible values are

BIND_DEBUG_UNBIND and BIND_NOT_FOREGROUND or 0 for none

Additional notes

Here are some important notes about binding to a service

You should always trap DeadObjectException exceptions which are thrown when the connection has

broken This is the only exception thrown by remote methods

Objects are reference counted across processes

You should usually pair the binding and unbinding during matching bring-up and tear-down moments

of the clients lifecycle For example

o If you only need to interact with the service while your activity is visible you should bind during

onStart() and unbind during onStop()

o If you want your activity to receive responses even while it is stopped in the background then you can

bind during onCreate() and unbind during onDestroy() Beware that this implies that your activity needs

to use the service the entire time its running (even in the background) so if the service is in another

process then you increase the weight of the process and it becomes more likely that the system will

kill it

Note You should usually not bind and unbind during your activitys onResume() and onPause()

because these callbacks occur at every lifecycle transition and you should keep the processing that

occurs at these transitions to a minimum Also if multiple activities in your application bind to the same

service and there is a transition between two of those activities the service may be destroyed and

recreated as the current activity unbinds (during pause) before the next one binds (during resume)

(This activity transition for how activities coordinate their lifecycles is described in the Activities

document)

For more sample code showing how to bind to a service see the RemoteServicejava class in

ApiDemos

Managing the Lifecycle of a Bound Service

Figure 1 The lifecycle for a service

that is started and also allows binding

When a service is unbound from all

clients the Android system destroys it

(unless it was also started with

onStartCommand()) As such you

dont have to manage the lifecycle of

your service if its purely a bound

servicemdashthe Android system manages

it for you based on whether it is bound

to any clients

However if you choose to implement

the onStartCommand() callback

method then you must explicitly stop

the service because the service is

now considered to be started In this

case the service runs until the service

stops itself with stopSelf() or another

component calls stopService()

regardless of whether it is bound to

any clients

Additionally if your service is started and accepts binding then when the system calls your onUnbind()

method you can optionally return true if you would like to receive a call to onRebind() the next time a

client binds to the service (instead of receiving a call to onBind()) onRebind() returns void but the

client still receives the IBinder in its onServiceConnected() callback Below figure 1 illustrates the logic

for this kind of lifecycle

For more information about the lifecycle of an started service see the Services document

Content Providers

Content providers store and retrieve data and make it accessible to all applications Theyre the only

way to share data across applications theres no common storage area that all Android packages can

access

Android ships with a number of content providers for common data types (audio video images

personal contact information and so on) You can see some of them listed in the androidprovider

package You can query these providers for the data they contain (although for some you must

acquire the proper permission to read the data)

If you want to make your own data public you have two options You can create your own content

provider (a ContentProvider subclass) or you can add the data to an existing provider mdash if theres one

that controls the same type of data and you have permission to write to it

This document is an introduction to using content providers After a brief discussion of the

fundamentals it explores how to query a content provider how to modify data controlled by a provider

and how to create a content provider of your own

Content Provider Basics

How a content provider actually stores its data under the covers is up to its designer But all content

providers implement a common interface for querying the provider and returning results mdash as well as

for adding altering and deleting data Its an interface that clients use indirectly most generally

through ContentResolver objects You get a ContentResolver by calling getContentResolver() from

within the implementation of an Activity or other application component

ContentResolver cr = getContentResolver()

You can then use the ContentResolvers methods to interact with whatever content providers youre

interested in When a query is initiated the Android system identifies the content provider thats the

target of the query and makes sure that it is up and running The system instantiates all

ContentProvider objects you never need to do it on your own In fact you never deal directly with

ContentProvider objects at all Typically theres just a single instance of each type of ContentProvider

But it can communicate with multiple ContentResolver objects in different applications and processes

The interaction between processes is handled by the ContentResolver and ContentProvider classes

The data model

Content providers expose their data as a simple table on a database model where each row is a

record and each column is data of a particular type and meaning For example information about

people and their phone numbers might be exposed as follows

_ID NUMBER NUMBER_KEY LABEL NAME TYPE

13 (425) 555 6677 425 555 6677 Kirkland office Bully Pulpit TYPE_WORK

44 (212) 555-1234 212 555 1234 NY apartment Alan Vain TYPE_HOME

45 (212) 555-6657 212 555 6657 Downtown office Alan Vain TYPE_MOBILE

53 2015554433 201 555 4433 Love Nest Rex Cars TYPE_HOME

Every record includes a numeric _ID field that uniquely identifies the record within the table IDs can be

used to match records in related tables mdash for example to find a persons phone number in one table

and pictures of that person in another

A query returns a Cursor object that can move from record to record and column to column to read the

contents of each field It has specialized methods for reading each type of data So to read a field you

must know what type of data the field contains (Theres more on query results and Cursor objects

later)

URIs

Each content provider exposes a public URI (wrapped as a Uri object) that uniquely identifies its data

set A content provider that controls multiple data sets (multiple tables) exposes a separate URI for

each one All URIs for providers begin with the string content The content scheme identifies the

data as being controlled by a content provider

If youre defining a content provider its a good idea to also define a constant for its URI to simplify

client code and make future updates cleaner Android defines CONTENT_URI constants for all the

providers that come with the platform For example the URI for the table that matches phone numbers

to people and the URI for the table that holds pictures of people (both controlled by the Contacts

content provider) are

androidproviderContactsPhonesCONTENT_URI

androidproviderContactsPhotosCONTENT_URI

The URI constant is used in all interactions with the content provider Every ContentResolver method

takes the URI as its first argument Its what identifies which provider the ContentResolver should talk

to and which table of the provider is being targeted

Querying a Content Provider

You need three pieces of information to query a content provider

The URI that identifies the provider

The names of the data fields you want to receive

The data types for those fields

If youre querying a particular record you also need the ID for that record

Making the query

To query a content provider you can use either the ContentResolverquery() method or the

ActivitymanagedQuery() method Both methods take the same set of arguments and both return a

Cursor object However managedQuery() causes the activity to manage the life cycle of the Cursor A

managed Cursor handles all of the niceties such as unloading itself when the activity pauses and

requerying itself when the activity restarts You can ask an Activity to begin managing an unmanaged

Cursor object for you by calling ActivitystartManagingCursor()

The first argument to either query() or managedQuery() is the provider URI mdash the CONTENT_URI

constant that identifies a particular ContentProvider and data set (see URIs earlier)

To restrict a query to just one record you can append the _ID value for that record to the URI mdash that

is place a string matching the ID as the last segment of the path part of the URI For example if the ID

is 23 the URI would be

content 23

There are some helper methods particularly ContentUriswithAppendedId() and

UriwithAppendedPath() that make it easy to append an ID to a URI Both are static methods that

return a Uri object with the ID added So for example if you were looking for record 23 in the database

of people contacts you might construct a query as follows

import androidproviderContactsPeople import androidcontentContentUris import androidnetUri import androiddatabaseCursor Use the ContentUris method to produce the base URI for the contact with _ID == 23 Uri myPerson = ContentUriswithAppendedId(PeopleCONTENT_URI 23) Alternatively use the Uri method to produce the base URI It takes a string rather than an integer Uri myPerson = UriwithAppendedPath(PeopleCONTENT_URI 23) Then query for this specific record Cursor cur = managedQuery(myPerson null null null null)

The other arguments to the query() and managedQuery() methods delimit the query in more detail

They are

The names of the data columns that should be returned A null value returns all columns Otherwise

only columns that are listed by name are returned All the content providers that come with the

platform define constants for their columns For example the androidproviderContactsPhones class

defines constants for the names of the columns in the phone table illustrated earlier ampmdash _ID

NUMBER NUMBER_KEY NAME and so on

A filter detailing which rows to return formatted as an SQL WHERE clause (excluding the WHERE

itself) A null value returns all rows (unless the URI limits the query to a single record)

Selection arguments

A sorting order for the rows that are returned formatted as an SQL ORDER BY clause (excluding the

ORDER BY itself) A null value returns the records in the default order for the table which may be

unordered

Lets look at an example query to retrieve a list of contact names and their primary phone numbers

import androidproviderContactsPeople import androiddatabaseCursor Form an array specifying which columns to return String[] projection = new String[] People_ID People_COUNT PeopleNAME PeopleNUMBER Get the base URI for the People table in the Contacts content provider Uri contacts = PeopleCONTENT_URI Make the query Cursor managedCursor = managedQuery(contacts projection Which columns to return null Which rows to return (all rows) null Selection arguments (none) Put the results in ascending order by name PeopleNAME + ASC)

This query retrieves data from the People table of the Contacts content provider It gets the name

primary phone number and unique record ID for each contact It also reports the number of records

that are returned as the _COUNT field of each record

The constants for the names of the columns are defined in various interfaces mdash _ID and _COUNT in

BaseColumns NAME in PeopleColumns and NUMBER in PhoneColumns The ContactsPeople

class implements each of these interfaces which is why the code example above could refer to them

using just the class name

What a query returns

A query returns a set of zero or more database records The names of the columns their default order

and their data types are specific to each content provider But every provider has an _ID column

which holds a unique numeric ID for each record Every provider can also report the number of records

returned as the _COUNT column its value is the same for all rows

Here is an example result set for the query in the previous section

_ID _COUNT NAME NUMBER

44 3 Alan Vain 212 555 1234

13 3 Bully Pulpit 425 555 6677

53 3 Rex Cars 201 555 4433

The retrieved data is exposed by a Cursor object that can be used to iterate backward or forward

through the result set You can use this object only to read the data To add modify or delete data

you must use a ContentResolver object

Reading retrieved data

The Cursor object returned by a query provides access to a recordset of results If you have queried

for a specific record by ID this set will contain only one value Otherwise it can contain multiple

values (If there are no matches it can also be empty) You can read data from specific fields in the

record but you must know the data type of the field because the Cursor object has a separate method

for reading each type of data mdash such as getString() getInt() and getFloat() (However for most types

if you call the method for reading strings the Cursor object will give you the String representation of

the data) The Cursor lets you request the column name from the index of the column or the index

number from the column name

The following snippet demonstrates reading names and phone numbers from the query illustrated

earlier

import androidproviderContactsPeople private void getColumnData(Cursor cur) if (curmoveToFirst()) String name String phoneNumber int nameColumn = curgetColumnIndex(PeopleNAME) int phoneColumn = curgetColumnIndex(PeopleNUMBER) String imagePath do Get the field values name = curgetString(nameColumn) phoneNumber = curgetString(phoneColumn) Do something with the values while (curmoveToNext())

If a query can return binary data such as an image or sound the data may be directly entered in the

table or the table entry for that data may be a string specifying a content URI that you can use to get

the data In general smaller amounts of data (say from 20 to 50K or less) are most often directly

entered in the table and can be read by calling CursorgetBlob() It returns a byte array

If the table entry is a content URI you should never try to open and read the file directly (for one thing

permissions problems can make this fail) Instead you should call ContentResolveropenInputStream()

to get an InputStream object that you can use to read the data

Modifying Data

Data kept by a content provider can be modified by

Adding new records

Adding new values to existing records

Batch updating existing records

Deleting records

All data modification is accomplished using ContentResolver methods Some content providers require

a more restrictive permission for writing data than they do for reading it If you dont have permission to

write to a content provider the ContentResolver methods will fail

Adding records

To add a new record to a content provider first set up a map of key-value pairs in a ContentValues

object where each key matches the name of a column in the content provider and the value is the

desired value for the new record in that column Then call ContentResolverinsert() and pass it the URI

of the provider and the ContentValues map This method returns the full URI of the new record mdash that

is the providers URI with the appended ID for the new record You can then use this URI to query and

get a Cursor over the new record and to further modify the record Heres an example

import androidproviderContactsPeople import androidcontentContentResolver import androidcontentContentValues ContentValues values = new ContentValues() Add Abraham Lincoln to contacts and make him a favorite valuesput(PeopleNAME Abraham Lincoln) 1 = the new contact is added to favorites 0 = the new contact is not added to favorites valuesput(PeopleSTARRED 1) Uri uri = getContentResolver()insert(PeopleCONTENT_URI values)

Adding new values

Once a record exists you can add new information to it or modify existing information For example

the next step in the example above would be to add contact information mdash like a phone number or an

IM or e-mail address mdash to the new entry

The best way to add to a record in the Contacts database is to append the name of the table where the

new data goes to the URI for the record then use the amended URI to add the new data values Each

Contacts table exposes a name for this purpose as a CONTENT_DIRECTORY constant The following

code continues the previous example by adding a phone number and e-mail address for the record

just created

Uri phoneUri = null Uri emailUri = null Add a phone number for Abraham Lincoln Begin with the URI for the new record just returned by insert() it ends with the _ID of the new record so we dont have to add the ID ourselves Then append the designation for the phone table to this URI and use the resulting URI to insert the phone number phoneUri = UriwithAppendedPath(uri PeoplePhonesCONTENT_DIRECTORY) valuesclear() valuesput(PeoplePhonesTYPE PeoplePhonesTYPE_MOBILE) valuesput(PeoplePhonesNUMBER 1233214567) getContentResolver()insert(phoneUri values) Now add an email address in the same way emailUri = UriwithAppendedPath(uri PeopleContactMethodsCONTENT_DIRECTORY) valuesclear() ContactMethodsKIND is used to distinguish different kinds of contact methods such as email IM etc valuesput(PeopleContactMethodsKIND ContactsKIND_EMAIL) valuesput(PeopleContactMethodsDATA testexamplecom) valuesput(PeopleContactMethodsTYPE PeopleContactMethodsTYPE_HOME) getContentResolver()insert(emailUri values)

You can place small amounts of binary data into a table by calling the version of ContentValuesput()

that takes a byte array That would work for a small icon-like image or a short audio clip for example

However if you have a large amount of binary data to add such as a photograph or a complete song

put a content URI for the data in the table and call ContentResolveropenOutputStream() with the files

URI (That causes the content provider to store the data in a file and record the file path in a hidden

field of the record)

In this regard the MediaStore content provider the main provider that dispenses image audio and

video data employs a special convention The same URI that is used with query() or managedQuery()

to get meta-information about the binary data (such as the caption of a photograph or the date it was

taken) is used with openInputStream() to get the data itself Similarly the same URI that is used with

insert() to put meta-information into a MediaStore record is used with openOutputStream() to place the

binary data there The following code snippet illustrates this convention

import androidproviderMediaStoreImagesMedia import androidcontentContentValues import javaioOutputStream Save the name and description of an image in a ContentValues map ContentValues values = new ContentValues(3) valuesput(MediaDISPLAY_NAME road_trip_1) valuesput(MediaDESCRIPTION Day 1 trip to Los Angeles) valuesput(MediaMIME_TYPE imagejpeg) Add a new record without the bitmap but with the values just set insert() returns the URI of the new record Uri uri = getContentResolver()insert(MediaEXTERNAL_CONTENT_URI values) Now get a handle to the file for that record and save the data into it Here sourceBitmap is a Bitmap object representing the file to save to the database try OutputStream outStream = getContentResolver()openOutputStream(uri) sourceBitmapcompress(BitmapCompressFormatJPEG 50 outStream) outStreamclose() catch (Exception e) Loge(TAG exception while writing image e)

Batch updating records

To batch update a group of records (for example to change NY to New York in all fields) call the

ContentResolverupdate() method with the columns and values to change

Deleting a record

To delete a single record call ContentResolverdelete() with the URI of a specific row

To delete multiple rows call ContentResolverdelete() with the URI of the type of record to delete (for

example androidproviderContactsPeopleCONTENT_URI) and an SQL WHERE clause defining

which rows to delete (Caution Be sure to include a valid WHERE clause if youre deleting a general

type or you risk deleting more records than you intended)

Creating a Content Provider

To create a content provider you must

Set up a system for storing the data Most content providers store their data using Androids file

storage methods or SQLite databases but you can store your data any way you want Android

provides the SQLiteOpenHelper class to help you create a database and SQLiteDatabase to manage

it

Extend the ContentProvider class to provide access to the data

Declare the content provider in the manifest file for your application (AndroidManifestxml)

The following sections have notes on the last two of these tasks

Extending the ContentProvider class

You define a ContentProvider subclass to expose your data to others using the conventions expected

by ContentResolver and Cursor objects Principally this means implementing six abstract methods

declared in the ContentProvider class

query()

insert()

update()

delete()

getType()

onCreate()

The query() method must return a Cursor object that can iterate over the requested data Cursor itself

is an interface but Android provides some ready-made Cursor objects that you can use For example

SQLiteCursor can iterate over data stored in an SQLite database You get the Cursor object by calling

any of the SQLiteDatabase classs query() methods There are other Cursor implementations mdash such

as MatrixCursor mdash for data not stored in a database

Because these ContentProvider methods can be called from various ContentResolver objects in

different processes and threads they must be implemented in a thread-safe manner

As a courtesy you might also want to call ContentResolvernotifyChange() to notify listeners when

there are modifications to the data

Beyond defining the subclass itself there are other steps you should take to simplify the work of clients

and make the class more accessible

Define a public static final Uri named CONTENT_URI This is the string that represents the full content

URI that your content provider handles You must define a unique string for this value The best

solution is to use the fully-qualified class name of the content provider (made lowercase) So for

example the URI for a TransportationProvider class could be defined as follows

public static final Uri CONTENT_URI = Uriparse(contentcomexamplecodelabtransportationprovider)

If the provider has subtables also define CONTENT_URI constants for each of the subtables These

URIs should all have the same authority (since that identifies the content provider) and be

distinguished only by their paths For example

contentcomexamplecodelabtransportationprovidertrain

contentcomexamplecodelabtransportationproviderairdomestic

contentcomexamplecodelabtransportationproviderairinternational

For an overview of content URIs see the Content URI Summary at the end of this document

Define the column names that the content provider will return to clients If you are using an underlying

database these column names are typically identical to the SQL database column names they

represent Also define public static String constants that clients can use to specify the columns in

queries and other instructions

Be sure to include an integer column named _id (with the constant _ID) for the IDs of the records

You should have this field whether or not you have another field (such as a URL) that is also unique

among all records If youre using the SQLite database the _ID field should be the following type

INTEGER PRIMARY KEY AUTOINCREMENT

The AUTOINCREMENT descriptor is optional But without it SQLite increments an ID counter field to

the next number above the largest existing number in the column If you delete the last row the next

row added will have the same ID as the deleted row AUTOINCREMENT avoids this by having SQLite

increment to the next largest value whether deleted or not

Carefully document the data type of each column Clients need this information to read the data

If you are handling a new data type you must define a new MIME type to return in your

implementation of ContentProvidergetType() The type depends in part on whether or not the content

URI submitted to getType() limits the request to a specific record Theres one form of the MIME type

for a single record and another for multiple records Use the Uri methods to help determine what is

being requested Here is the general format for each type

o For a single record vndandroidcursoritemvndyourcompanynamecontenttype

For example a request for train record 122 like this URI

contentcomexampletransportationprovidertrains122

might return this MIME type

vndandroidcursoritemvndexamplerail

o For multiple records vndandroidcursordirvndyourcompanynamecontenttype

For example a request for all train records like the following URI

contentcomexampletransportationprovidertrains

might return this MIME type

vndandroidcursordirvndexamplerail

If you are exposing byte data thats too big to put in the table itself mdash such as a large bitmap file mdash the

field that exposes the data to clients should actually contain a content URI string This is the field that

gives clients access to the data file The record should also have another field named _data that lists

the exact file path on the device for that file This field is not intended to be read by the client but by

the ContentResolver The client will call ContentResolveropenInputStream() on the user-facing field

holding the URI for the item The ContentResolver will request the _data field for that record and

because it has higher permissions than a client it should be able to access that file directly and return

a read wrapper for the file to the client

For an example of a private content provider implementation see the NodePadProvider class in the

Notepad sample application that ships with the SDK

Declaring the content provider

To let the Android system know about the content provider youve developed declare it with a

ltprovidergt element in the applications AndroidManifestxml file Content providers that are not

declared in the manifest are not visible to the Android system

The name attribute is the fully qualified name of the ContentProvider subclass The authorities attribute

is the authority part of the content URI that identifies the provider For example if the ContentProvider

subclass is AutoInfoProvider the ltprovidergt element might look like this

ltprovider androidname=comexampleautosAutoInfoProvider androidauthorities=comexampleautosautoinfoprovider gt ltprovidergt

Note that the authorities attribute omits the path part of a content URI For example if

AutoInfoProvider controlled subtables for different types of autos or different manufacturers

contentcomexampleautosautoinfoproviderhonda

contentcomexampleautosautoinfoprovidergmcompact

contentcomexampleautosautoinfoprovidergmsuv

those paths would not be declared in the manifest The authority is what identifies the provider not the

path your provider can interpret the path part of the URI in any way you choose

Other ltprovidergt attributes can set permissions to read and write data provide for an icon and text

that can be displayed to users enable and disable the provider and so on Set the multiprocess

attribute to true if data does not need to be synchronized between multiple running versions of the

content provider This permits an instance of the provider to be created in each client process

eliminating the need to perform IPC

Content URI Summary

Here is a recap of the important parts of a content URI

A Standard prefix indicating that the data is controlled by a content provider Its never modified

B The authority part of the URI it identifies the content provider For third-party applications this should

be a fully-qualified class name (reduced to lowercase) to ensure uniqueness The authority is declared

in the ltprovidergt elements authorities attribute

ltprovider androidname=TransportationProvider androidauthorities=comexampletransportationprovider gt

C The path that the content provider uses to determine what kind of data is being requested This can be

zero or more segments long If the content provider exposes only one type of data (only trains for

example) it can be absent If the provider exposes several types including subtypes it can be several

segments long mdash for example landbus landtrain seaship and seasubmarine to give four

possibilities

D The ID of the specific record being requested if any This is the _ID value of the requested record If

the request is not limited to a single record this segment and the trailing slash are omitted

contentcomexampletransportationprovidertrains

Intent and intent filters

Three of the core components of an application mdash activities services and broadcast receivers mdash 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 mdash 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 ContextstartActivity() or ActivitystartActivityForResult() to launch an

activity or get an existing activity to do something new (It can also be passed to ActivitysetResult() to

return information to the activity that called startActivityForResult())

An Intent object is passed to ContextstartService() to initiate a service or deliver new instructions to an

ongoing service Similarly an intent can be passed to ContextbindService() to establish a connection

between the calling component and a target service It can optionally initiate the service if its not

already running

Intent objects passed to any of the broadcast methods (such as ContextsendBroadcast()

ContextsendOrderedBroadcast() or ContextsendStickyBroadcast()) 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 mdash how it resolves which component should receive an intent message For

intents that dont explicitly name a target component this process involves testing the Intent object

against intent filters associated with potential targets

Intent Objects

An Intent object is a bundle of information It contains information of interest to the component that

receives the intent (such as the action to be taken and the data to act on) plus information of interest to

the Android system (such as the category of component that should handle the intent and instructions

on how to launch a target activity) Principally it can contain the following

Component name

The name of the component that should handle the intent This field is a ComponentName

object mdash a combination of the fully qualified class name of the target component (for example

comexampleprojectappFreneticActivity) and the package name set in the manifest file of the

application where the component resides (for example comexampleproject) The package

part of the component name and the package name set in the manifest do not necessarily have

to match

The component name is optional If it is set the Intent object is delivered to an instance of the

designated class If it is not set Android uses other information in the Intent object to locate a

suitable target mdash see Intent Resolution later in this document

The component name is set by setComponent() setClass() or setClassName() and read by

getComponent()

Action

A string naming the action to be performed mdash or in the case of broadcast intents the action

that took place and is being reported The Intent class defines a number of action constants

including these

Constant Target

component

Action

ACTION_CALL activity Initiate a phone call

ACTION_EDIT activity Display data for the user to edit

ACTION_MAIN activity Start up as the initial activity of a task

with no data input and no returned

output

ACTION_SYNC activity Synchronize data on a server with

data on the mobile device

ACTION_BATTERY_LOW broadcast

receiver

A warning that the battery is low

ACTION_HEADSET_PLUG broadcast

receiver

A headset has been plugged into the

device or unplugged from it

ACTION_SCREEN_ON broadcast

receiver

The screen has been turned on

ACTION_TIMEZONE_CHANGED broadcast

receiver

The setting for the time zone has

changed

See the Intent class description for a list of pre-defined constants for generic actions Other

actions are defined elsewhere in the Android API You can also define your own action strings

for activating the components in your application Those you invent should include the

application package as a prefix mdash for example comexampleprojectSHOW_COLOR

The action largely determines how the rest of the intent is structured mdash particularly the data and

extras fields mdash much as a method name determines a set of arguments and a return value For

this reason its a good idea to use action names that are as specific as possible and to couple

them tightly to the other fields of the intent In other words instead of defining an action in

isolation define an entire protocol for the Intent objects your components can handle

The action in an Intent object is set by the setAction() method and read by getAction()

Data

The URI of the data to be acted on and the MIME type of that data Different actions are paired

with different kinds of data specifications For example if the action field is ACTION_EDIT the

data field would contain the URI of the document to be displayed for editing If the action is

ACTION_CALL the data field would be a tel URI with the number to call Similarly if the action

is ACTION_VIEW and the data field is an http URI the receiving activity would be called upon

to download and display whatever data the URI refers to

When matching an intent to a component that is capable of handling the data its often

important to know the type of data (its MIME type) in addition to its URI For example a

component able to display image data should not be called upon to play an audio file

In many cases the data type can be inferred from the URI mdash particularly content URIs which

indicate that the data is located on the device and controlled by a content provider (see the

separate discussion on content providers) But the type can also be explicitly set in the Intent

object The setData() method specifies data only as a URI setType() specifies it only as a

MIME type and setDataAndType() specifies it as both a URI and a MIME type The URI is read

by getData() and the type by getType()

Category

A string containing additional information about the kind of component that should handle the

intent Any number of category descriptions can be placed in an Intent object As it does for

actions the Intent class defines several category constants including these

Constant Meaning

CATEGORY_BROWSABLE The target activity can be safely invoked by the browser to

display data referenced by a link mdash for example an image or

an e-mail message

CATEGORY_GADGET The activity can be embedded inside of another activity that

hosts gadgets

CATEGORY_HOME The activity displays the home screen the first screen the

user sees when the device is turned on or when the HOME

key is pressed

CATEGORY_LAUNCHER The activity can be the initial activity of a task and is listed in

the top-level application launcher

CATEGORY_PREFERENCE The target activity is a preference panel

See the Intent class description for the full list of categories

The addCategory() method places a category in an Intent object removeCategory() deletes a

category previously added and getCategories() gets the set of all categories currently in the

object

Extras

Key-value pairs for additional information that should be delivered to the component handling

the intent Just as some actions are paired with particular kinds of data URIs some are paired

with particular extras For example an ACTION_TIMEZONE_CHANGED intent has a time-

zone extra that identifies the new time zone and ACTION_HEADSET_PLUG has a state

extra indicating whether the headset is now plugged in or unplugged as well as a name extra

for the type of headset If you were to invent a SHOW_COLOR action the color value would be

set in an extra key-value pair

The Intent object has a series of put() methods for inserting various types of extra data and a

similar set of get() methods for reading the data These methods parallel those for Bundle

objects In fact the extras can be installed and read as a Bundle using the putExtras() and

getExtras() methods

Flags

Flags of various sorts Many instruct the Android system how to launch an activity (for example

which task the activity should belong to) and how to treat it after its launched (for example

whether it belongs in the list of recent activities) All these flags are defined in the Intent class

The Android system and the applications that come with the platform employ Intent objects both to

send out system-originated broadcasts and to activate system-defined components To see how to

structure an intent to activate a system component consult the list of intents in the reference

Intent Resolution

Intents can be divided into two groups

Explicit intents designate the target component by its name (the component name field mentioned

earlier has a value set) Since component names would generally not be known to developers of other

applications explicit intents are typically used for application-internal messages mdash such as an activity

starting a subordinate service or launching a sister activity

Implicit intents do not name a target (the field for the component name is blank) Implicit intents are

often used to activate components in other applications

Android delivers an explicit intent to an instance of the designated target class Nothing in the Intent

object other than the component name matters for determining which component should get the intent

A different strategy is needed for implicit intents In the absence of a designated target the Android

system must find the best component (or components) to handle the intent mdash a single activity or

service to perform the requested action or the set of broadcast receivers to respond to the broadcast

announcement It does so by comparing the contents of the Intent object to intent filters structures

associated with components that can potentially receive intents Filters advertise the capabilities of a

component and delimit the intents it can handle They open the component to the possibility of

receiving implicit intents of the advertised type If a component does not have any intent filters it can

receive only explicit intents A component with filters can receive both explicit and implicit intents

Only three aspects of an Intent object are consulted when the object is tested against an intent filter

action

data (both URI and data type)

category

The extras and flags play no part in resolving which component receives an intent

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 mdash but only unwanted implicit intents (those that dont 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

components 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 mdash 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 Pads filters are described in the Note Pad Example

section later)

Filters and security

An intent filter cannot be relied on for security While it opens a component to receiving only certain

kinds of implicit intents it does nothing to prevent explicit intents from targeting the component Even

though a filter restricts the intents a component will be asked to handle to certain actions and data

sources someone could always put together an explicit intent with a different action and data source

and name the component as the target

An intent filter is an instance of the IntentFilter class However since the Android system must know

about the capabilities of a component before it can launch that component intent filters are generally

not set up in Java code but in the applications manifest file (AndroidManifestxml) as ltintent-filtergt

elements (The one exception would be filters for broadcast receivers that are registered dynamically

by calling ContextregisterReceiver() they are directly created as IntentFilter objects)

A filter has fields that parallel the action data and category fields of an Intent object An implicit intent

is tested against the filter in all three areas To be delivered to the component that owns the filter it

must pass all three tests If it fails even one of them the Android system wont deliver it to the

component mdash at least not on the basis of that filter However since a component can have multiple

intent filters an intent that does not pass through one of a components filters might make it through on

another

Each of the three tests is described in detail below

Action test

An ltintent-filtergt element in the manifest file lists actions as ltactiongt subelements For

example

ltintent-filter gt ltaction androidname=comexampleprojectSHOW_CURRENT gt ltaction androidname=comexampleprojectSHOW_RECENT gt ltaction androidname=comexampleprojectSHOW_PENDING gt ltintent-filtergt

As the example shows while an Intent object names just a single action a filter may list more

than one The list cannot be empty a filter must contain at least one ltactiongt element or it will

block all intents

To pass this test the action specified in the Intent object must match one of the actions listed in

the filter If the object or the filter does not specify an action the results are as follows

If the filter fails to list any actions there is nothing for an intent to match so all intents fail the

test No intents can get through the filter

On the other hand an Intent object that doesnt specify an action automatically passes the test

mdash as long as the filter contains at least one action

Category test

An ltintent-filtergt element also lists categories as subelements For example

ltintent-filter gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryBROWSABLE gt ltintent-filtergt

Note that the constants described earlier for actions and categories are not used in the manifest

file The full string values are used instead For instance the

androidintentcategoryBROWSABLE string in the example above corresponds to the

CATEGORY_BROWSABLE constant mentioned earlier in this document Similarly the string

androidintentactionEDIT corresponds to the ACTION_EDIT constant

For an intent to pass the category test every category in the Intent object must match a

category in the filter The filter can list additional categories but it cannot omit any that are in the

intent

In principle therefore an Intent object with no categories should always pass this test

regardless of whats in the filter Thats mostly true However with one exception Android treats

all implicit intents passed to startActivity() as if they contained at least one category

androidintentcategoryDEFAULT (the CATEGORY_DEFAULT constant) Therefore activities

that are willing to receive implicit intents must include androidintentcategoryDEFAULT in

their intent filters (Filters with androidintentactionMAIN and

androidintentcategoryLAUNCHER settings are the exception They mark activities that begin

new tasks and that are represented on the launcher screen They can include

androidintentcategoryDEFAULT in the list of categories but dont need to) See Using intent

matching later for more on these filters)

Data test

Like the action and categories the data specification for an intent filter is contained in a

subelement And as in those cases the subelement can appear multiple times or not at all For

example

ltintent-filter gt ltdata androidmimeType=videompeg androidscheme=http gt ltdata androidmimeType=audiompeg androidscheme=http gt ltintent-filtergt

Each ltdatagt element can specify a URI and a data type (MIME media type) There are

separate attributes mdash scheme host port and path mdash for each part of the URI

schemehostportpath

For example in the following URI

contentcomexampleproject200foldersubfolderetc

the scheme is content the host is comexampleproject the port is 200 and the path is

foldersubfolderetc The host and port together constitute the URI authority if a host is not

specified the port is ignored

Each of these attributes is optional but they are not independent of each other For an authority

to be meaningful a scheme must also be specified For a path to be meaningful both a scheme

and an authority must be specified

When the URI in an Intent object is compared to a URI specification in a filter its compared

only to the parts of the URI actually mentioned in the filter For example if a filter specifies only

a scheme all URIs with that scheme match the filter If a filter specifies a scheme and an

authority but no path all URIs with the same scheme and authority match regardless of their

paths If a filter specifies a scheme an authority and a path only URIs with the same scheme

authority and path match However a path specification in the filter can contain wildcards to

require only a partial match of the path

The type attribute of a ltdatagt element specifies the MIME type of the data Its more common in

filters than a URI Both the Intent object and the filter can use a wildcard for the subtype field

mdash for example text or audio mdash indicating any subtype matches

The data test compares both the URI and the data type in the Intent object to a URI and data

type specified in the filter The rules are as follows

a An Intent object that contains neither a URI nor a data type passes the test only if the filter

likewise does not specify any URIs or data types

b An Intent object that contains a URI but no data type (and a type cannot be inferred from the

URI) passes the test only if its URI matches a URI in the filter and the filter likewise does not

specify a type This will be the case only for URIs like mailto and tel that do not refer to actual

data

c An Intent object that contains a data type but not a URI passes the test only if the filter lists the

same data type and similarly does not specify a URI

d An Intent object that contains both a URI and a data type (or a data type can be inferred from

the URI) passes the data type part of the test only if its type matches a type listed in the filter It

passes the URI part of the test either if its URI matches a URI in the filter or if it has a content

or file URI and the filter does not specify a URI In other words a component is presumed to

support content and file data if its filter lists only a data type

If an intent can pass through the filters of more than one activity or service the user may be asked

which component to activate An exception is raised if no target can be found

Common cases

The last rule shown above for the data test rule (d) reflects the expectation that components are able

to get local data from a file or content provider Therefore their filters can list just a data type and do

not need to explicitly name the content and file schemes This is a typical case A ltdatagt element like

the following for example tells Android that the component can get image data from a content

provider and display it

ltdata androidmimeType=image gt

Since most available data is dispensed by content providers filters that specify a data type but not a

URI are perhaps the most common

Another common configuration is filters with a scheme and a data type For example a ltdatagt

element like the following tells Android that the component can get video data from the network and

display it

ltdata androidscheme=http androidtype=video gt

Consider for example what the browser application does when the user follows a link on a web page

It first tries to display the data (as it could if the link was to an HTML page) If it cant display the data it

puts together an implicit intent with the scheme and data type and tries to start an activity that can do

the job If there are no takers it asks the download manager to download the data That puts it under

the control of a content provider so a potentially larger pool of activities (those with filters that just

name a data type) can respond

Most applications also have a way to start fresh without a reference to any particular data Activities

that can initiate applications have filters with androidintentactionMAIN specified as the action If

they are to be represented in the application launcher they also specify the

androidintentcategoryLAUNCHER category

ltintent-filter gt ltaction androidname=code androidintentactionMAIN gt ltcategory androidname=code androidintentcategoryLAUNCHER gt ltintent-filtergt

Using intent matching

Intents are matched against intent filters not only to discover a target component to activate but also

to discover something about the set of components on the device For example the Android system

populates the application launcher the top-level screen that shows the applications that are available

for the user to launch by finding all the activities with intent filters that specify the

androidintentactionMAIN action and androidintentcategoryLAUNCHER category (as illustrated

in the previous section) It then displays the icons and labels of those activities in the launcher

Similarly it discovers the home screen by looking for the activity with androidintentcategoryHOME

in its filter

Your application can use intent matching is a similar way The PackageManager has a set of query()

methods that return all components that can accept a particular intent and a similar series of

resolve() methods that determine the best component to respond to an intent For example

queryIntentActivities() returns a list of all activities that can perform the intent passed as an argument

and queryIntentServices() returns a similar list of services Neither method activates the components

they just list the ones that can respond Theres a similar method queryBroadcastReceivers() for

broadcast receivers

Note Pad Example

The Note Pad sample application enables users to browse through a list of notes view details about

individual items in the list edit the items and add a new item to the list This section looks at the intent

filters declared in its manifest file (If youre working offline in the SDK you can find all the source files

for this sample application including its manifest file at ltsdkgtsamplesNotePadindexhtml If youre

viewing the documentation online the source files are in the Tutorials and Sample Code section here)

In its manifest file the Note Pad application declares three activities each with at least one intent filter

It also declares a content provider that manages the note data Here is the manifest file in its entirety

ltmanifest xmlnsandroid=httpschemasandroidcomapkresandroid package=comexampleandroidnotepadgt ltapplication androidicon=drawableapp_notes androidlabel=stringapp_name gt ltprovider androidname=NotePadProvider androidauthorities=comgoogleproviderNotePad gt ltactivity androidname=NotesList androidlabel=stringtitle_notes_listgt ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltactivity androidname=NoteEditor androidtheme=androidstyleThemeLight androidlabel=stringtitle_note gt ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltactivitygt

ltactivity androidname=TitleEditor androidlabel=stringtitle_edit_title androidtheme=androidstyleThemeDialoggt ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltapplicationgt ltmanifestgt

The first activity NotesList is distinguished from the other activities by the fact that it operates on a

directory of notes (the note list) rather than on a single note It would generally serve as the initial user

interface into the application It can do three things as described by its three intent filters

1 ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt

This filter declares the main entry point into the Note Pad application The standard MAIN action is an

entry point that does not require any other information in the Intent (no data specification for example)

and the LAUNCHER category says that this entry point should be listed in the application launcher

2 ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

This filter declares the things that the activity can do on a directory of notes It can allow the user to

view or edit the directory (via the VIEW and EDIT actions) or to pick a particular note from the

directory (via the PICK action)

The mimeType attribute of the ltdatagt element specifies the kind of data that these actions operate on

It indicates that the activity can get a Cursor over zero or more items (vndandroidcursordir) from a

content provider that holds Note Pad data (vndgooglenote) The Intent object that launches the

activity would include a content URI specifying the exact data of this type that the activity should open

Note also the DEFAULT category supplied in this filter Its there because the ContextstartActivity()

and ActivitystartActivityForResult() methods treat all intents as if they contained the DEFAULT

category mdash with just two exceptions

o Intents that explicitly name the target activity

o Intents consisting of the MAIN action and LAUNCHER category

Therefore the DEFAULT category is required for all filters mdash except for those with the MAIN action

and LAUNCHER category (Intent filters are not consulted for explicit intents)

3 ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

This filter describes the activitys ability to return a note selected by the user without requiring any

specification of the directory the user should choose from The GET_CONTENT action is similar to the

PICK action In both cases the activity returns the URI for a note selected by the user (In each case

its returned to the activity that called startActivityForResult() to start the NoteList activity) Here

however the caller specifies the type of data desired instead of the directory of data the user will be

picking from

The data type vndandroidcursoritemvndgooglenote indicates the type of data the activity can

return mdash a URI for a single note From the returned URI the caller can get a Cursor for exactly one

item (vndandroidcursoritem) from the content provider that holds Note Pad data (vndgooglenote)

In other words for the PICK action in the previous filter the data type indicates the type of data the

activity could display to the user For the GET_CONTENT filter it indicates the type of data the activity

can return to the caller

Given these capabilities the following intents will resolve to the NotesList activity

action androidintentactionMAIN

Launches the activity with no data specified

action androidintentactionMAIN

category androidintentcategoryLAUNCHER

Launches the activity with no data selected specified This is the actual intent used by the

Launcher to populate its top-level list All activities with filters that match this action and

category are added to the list

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of all the notes under

contentcomgoogleproviderNotePadnotes The user can then browse through the list and

get information about the items in it

action androidintentactionPICK

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of the notes under

contentcomgoogleproviderNotePadnotes The user can then pick a note from the list and

the activity will return the URI for that item back to the activity that started the NoteList activity

action androidintentactionGET_CONTENT

data type vndandroidcursoritemvndgooglenote

Asks the activity to supply a single item of Note Pad data

The second activity NoteEditor shows users a single note entry and allows them to edit it It can do

two things as described by its two intent filters

1 ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The first primary purpose of this activity is to enable the user to interact with a single note ampmdash to

either VIEW the note or EDIT it (The EDIT_NOTE category is a synonym for EDIT) The intent would

contain the URI for data matching the MIME type vndandroidcursoritemvndgooglenote mdash that is

the URI for a single specific note It would typically be a URI that was returned by the PICK or

GET_CONTENT actions of the NoteList activity

As before this filter lists the DEFAULT category so that the activity can be launched by intents that

dont explicitly specify the NoteEditor class

2 ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

The secondary purpose of this activity is to enable the user to create a new note which it will INSERT

into an existing directory of notes The intent would contain the URI for data matching the MIME type

vndandroidcursordirvndgooglenote mdash that is the URI for the directory where the note should be

placed

Given these capabilities the following intents will resolve to the NoteEditor activity

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID (For details on how content

URIs specify individual members of a group see Content Providers)

action androidintentactionEDIT

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID and to let the user edit it If

the user saves the changes the activity updates the data for the note in the content provider

action androidintentactionINSERT

data contentcomgoogleproviderNotePadnotes

Asks the activity to create a new empty note in the notes list at

contentcomgoogleproviderNotePadnotes and allow the user to edit it If the user saves the

note its URI is returned to the caller

The last activity TitleEditor enables the user to edit the title of a note This could be implemented by

directly invoking the activity (by explicitly setting its component name in the Intent) without using an

intent filter But here we take the opportunity to show how to publish alternative operations on existing

data

ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The single intent filter for this activity uses a custom action called

comandroidnotepadactionEDIT_TITLE It must be invoked on a specific note (data type

vndandroidcursoritemvndgooglenote) like the previous VIEW and EDIT actions However here the

activity displays the title contained in the note data not the content of the note itself

In addition to supporting the usual DEFAULT category the title editor also supports two other standard

categories ALTERNATIVE and SELECTED_ALTERNATIVE These categories identify activities that

can be presented to users in a menu of options (much as the LAUNCHER category identifies activities

that should be presented to user in the application launcher) Note that the filter also supplies an

explicit label (via androidlabel=stringresolve_title) to better control what users see when

presented with this activity as an alternative action to the data they are currently viewing (For more

information on these categories and building options menus see the

PackageManagerqueryIntentActivityOptions() and MenuaddIntentOptions() methods)

Given these capabilities the following intent will resolve to the TitleEditor activity

action comandroidnotepadactionEDIT_TITLE

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the title associated with note ID and allow the user to edit the title

Processes and Threads

When an application component starts and the application does not have any other components

running the Android system starts a new Linux process for the application with a single thread of

execution By default all components of the same application run in the same process and thread

(called the main thread) If an application component starts and there already exists a process for

that application (because another component from the application exists) then the component is

started within that process and uses the same thread of execution However you can arrange for

different components in your application to run in separate processes and you can create additional

threads for any process

This document discusses how processes and threads work in an Android application

Processes

By default all components of the same application run in the same process and most applications

should not change this However if you find that you need to control which process a certain

component belongs to you can do so in the manifest file

The manifest entry for each type of component elementmdashltactivitygt ltservicegt ltreceivergt and

ltprovidergtmdashsupports an androidprocess attribute that can specify a process in which that component

should run You can set this attribute so that each component runs in its own process or so that some

components share a process while others do not You can also set androidprocess so that

components of different applications run in the same processmdashprovided that the applications share the

same Linux user ID and are signed with the same certificates

The ltapplicationgt element also supports an androidprocess attribute to set a default value that

applies to all components

Android might 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 thats killed are consequently destroyed A process is started again for those components

when theres again work for them to do

When deciding which processes to kill the Android system weighs their relative importance to the

user For example it more readily shuts down a process hosting activities that are no longer visible on

screen compared to a process hosting visible activities The decision whether to terminate a process

therefore depends on the state of the components running in that process The rules used to decide

which processes to terminate is discussed below

Process lifecycle

The Android system tries to maintain an application process for as long as possible but eventually

needs to remove old processes to reclaim memory for new or more important processes To determine

which processes to keep and which to kill the system places each process into an importance

hierarchy based on the components running in the process and the state of those components

Processes with the lowest importance are eliminated first then those with the next lowest importance

and so on as necessary to recover system resources

There are five levels in the importance hierarchy The following list presents the different types of

processes in order of importance (the first process is most important and is killed last)

1 Foreground process

A process that is required for what the user is currently doing A process is considered to be in the

foreground if any of the following conditions are true

o It hosts an Activity that the user is interacting with (the Activitys onResume() method has been called)

o It hosts a Service thats bound to the activity that the user is interacting with

o It hosts a Service thats running in the foregroundmdashthe service has called startForeground()

o It hosts a Service thats executing one of its lifecycle callbacks (onCreate() onStart() or onDestroy())

o It hosts a BroadcastReceiver thats executing its onReceive() method

Generally only a few foreground processes exist at any given time They are killed only as a last

resortmdashif memory is so low that they cannot all continue to run Generally at that point the device has

reached a memory paging state so killing some foreground processes is required to keep the user

interface responsive

2 Visible process

A process that doesnt have any foreground components but still can affect what the user sees on

screen A process is considered to be visible if either of the following conditions are true

o It hosts an Activity that is not in the foreground but is still visible to the user (its onPause() method has

been called) This might occur for example if the foreground activity started a dialog which allows the

previous activity to be seen behind it

o It hosts a Service thats bound to a visible (or foreground) activity

A visible process is considered extremely important and will not be killed unless doing so is required to

keep all foreground processes running

3 Service process

A process that is running a service that has been started with the startService() method and does not

fall into either of the two higher categories Although service processes are not directly tied to anything

the user sees they are generally doing things that the user cares about (such as playing music in the

background or downloading data on the network) so the system keeps them running unless theres

not enough memory to retain them along with all foreground and visible processes

4 Background process

A process holding an activity thats not currently visible to the user (the activitys onStop() method has

been called) These processes have no direct impact on the user experience and the system can kill

them at any time to reclaim memory for a foreground visible or service process Usually there are

many background processes running so they are kept in an LRU (least recently used) list to ensure

that the process with the activity that was most recently seen by the user is the last to be killed If an

activity implements its lifecycle methods correctly and saves its current state killing its process will not

have a visible effect on the user experience because when the user navigates back to the activity the

activity restores all of its visible state See the Activities document for information about saving and

restoring state

5 Empty process

A process that doesnt hold any active application components The only reason to keep this kind of

process alive is for caching purposes to improve startup time the next time a component needs to run

in it The system often kills these processes in order to balance overall system resources between

process caches and the underlying kernel caches

Android ranks a process at the highest level it can based upon the importance of the components

currently active in the process For example if a process hosts a service and a visible activity the

process is ranked as a visible process not a service process

In addition a processs ranking might be increased because other processes are dependent on itmdasha

process that is serving another process can never be ranked lower than the process it is serving For

example if a content provider in process A is serving a client in process B or if a service in process A

is bound to a component in process B process A is always considered at least as important as

process B

Because a process running a service is ranked higher than a process with background activities an

activity that initiates a long-running operation might do well to start a service for that operation rather

than simply create a worker threadmdashparticularly if the operation will likely outlast the activity For

example an activity thats uploading a picture to a web site should start a service to perform the

upload so that the upload can continue in the background even if the user leaves the activity Using a

service guarantees that the operation will have at least service process priority regardless of what

happens to the activity This is the same reason that broadcast receivers should employ services

rather than simply put time-consuming operations in a thread

Threads

When an application is launched the system creates a thread of execution for the application called

main This thread is very important because it is in charge of dispatching events to the appropriate

user interface widgets including drawing events It is also the thread in which your application interacts

with components from the Android UI toolkit (components from the androidwidget and androidview

packages) As such the main thread is also sometimes called the UI thread

The system does not create a separate thread for each instance of a component All components that

run in the same process are instantiated in the UI thread and system calls to each component are

dispatched from that thread Consequently methods that respond to system callbacks (such as

onKeyDown() to report user actions or a lifecycle callback method) always run in the UI thread of the

process

For instance when the user touches a button on the screen your apps UI thread dispatches the touch

event to the widget which in turn sets its pressed state and posts an invalidate request to the event

queue The UI thread dequeues the request and notifies the widget that it should redraw itself

When your app performs intensive work in response to user interaction this single thread model can

yield poor performance unless you implement your application properly Specifically if everything is

happening in the UI thread performing long operations such as network access or database queries

will block the whole UI When the thread is blocked no events can be dispatched including drawing

events From the users perspective the application appears to hang Even worse if the UI thread is

blocked for more than a few seconds (about 5 seconds currently) the user is presented with the

infamous application not responding (ANR) dialog The user might then decide to quit your

application and uninstall it if they are unhappy

Additionally the Andoid UI toolkit is not thread-safe So you must not manipulate your UI from a

worker threadmdashyou must do all manipulation to your user interface from the UI thread Thus there are

simply two rules to Androids single thread model

1 Do not block the UI thread

2 Do not access the Android UI toolkit from outside the UI thread

Worker threads

Because of the single thread model described above its vital to the responsiveness of your

applications UI that you do not block the UI thread If you have operations to perform that are not

instantaneous you should make sure to do them in separate threads (background or worker

threads)

For example below is some code for a click listener that downloads an image from a separate thread

and displays it in an ImageView

public void onClick(View v) new Thread(new Runnable() public void run() Bitmap b = loadImageFromNetwork(httpexamplecomimagepng) mImageViewsetImageBitmap(b) )start()

At first this seems to work fine because it creates a new thread to handle the network operation

However it violates the second rule of the single-threaded model do not access the Android UI toolkit

from outside the UI threadmdashthis sample modifies the ImageView from the worker thread instead of the

UI thread This can result in undefined and unexpected behavior which can be difficult and time-

consuming to track down

To fix this problem Android offers several ways to access the UI thread from other threads Here is a

list of methods that can help

ActivityrunOnUiThread(Runnable)

Viewpost(Runnable)

ViewpostDelayed(Runnable long)

For example you can fix the above code by using the Viewpost(Runnable) method

public void onClick(View v) new Thread(new Runnable() public void run() final Bitmap bitmap = loadImageFromNetwork(httpexamplecomimagepng) mImageViewpost(new Runnable() public void run() mImageViewsetImageBitmap(bitmap) ) )start()

Now this implementation is thread-safe the network operation is done from a separate thread while

the ImageView is manipulated from the UI thread

However as the complexity of the operation grows this kind of code can get complicated and difficult

to maintain To handle more complex interactions with a worker thread you might consider using a

Handler in your worker thread to process messages delivered from the UI thread Perhaps the best

solution though is to extend the AsyncTask class which simplifies the execution of worker thread

tasks that need to interact with the UI

Using AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface It performs the blocking

operations in a worker thread and then publishes the results on the UI thread without requiring you to

handle threads andor handlers yourself

To use it you must subclass AsyncTask and implement the doInBackground() callback method which

runs in a pool of background threads To update your UI you should implement onPostExecute()

which delivers the result from doInBackground() and runs in the UI thread so you can safely update

your UI You can then run the task by calling execute() from the UI thread

For example you can implement the previous example using AsyncTask this way

public void onClick(View v) new DownloadImageTask()execute(httpexamplecomimagepng) private class DownloadImageTask extends AsyncTaskltString Void Bitmapgt The system calls this to perform work in a worker thread and delivers it the parameters given to AsyncTaskexecute() protected Bitmap doInBackground(String urls) return loadImageFromNetwork(urls[0])

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 14: 03 services

return mAllowRebind Override public void onRebind(Intent intent) A client is binding to the service with bindService() after onUnbind() has already been called Override public void onDestroy() The service is no longer used and is being destroyed

Note Unlike the activity lifecycle callback methods you are not required to call the superclass

implementation of these callback methods

By implementing these methods you can monitor two nested loops of the services lifecycle

The entire lifetime of a service happens between the time onCreate() is called and the time

onDestroy() returns Like an activity a service does its initial setup in onCreate() and releases all

remaining resources in onDestroy() For example a music playback service could create the thread

where the music will be played in onCreate() then stop the thread in onDestroy()

The onCreate() and onDestroy() methods are called for all services whether theyre created by

startService() or bindService()

The active lifetime of a service begins with a call to either onStartCommand() or onBind() Each

method is handed the Intent that was passed to either startService() or bindService() respectively

If the service is started the active lifetime ends the same time that the entire lifetime ends (the service

is still active even after onStartCommand() returns) If the service is bound the active lifetime ends

when onUnbind() returns

Note Although a started service is stopped by a call to either stopSelf() or stopService() there is

not a respective callback for the service (theres no onStop() callback) So unless the service is

bound to a client the system destroys it when the service is stoppedmdashonDestroy() is the only

callback received

Figure 2 illustrates the typical callback methods for a service Although the figure separates services

that are created by startService() from those created by bindService() keep in mind that any service

no matter how its started can potentially allow clients to bind to it So a service that was initially

started with onStartCommand() (by a client calling startService()) can still receive a call to onBind()

(when a client calls bindService())

For more information about creating a service that provides binding see the Bound Services

document which includes more information about the onRebind() callback method in the section about

Managing the Lifecycle of a Bound Service

Bound Services

A bound service is the server in a client-server interface A bound service allows components (such as

activities) to bind to the service send requests receive responses and even perform interprocess

communication (IPC) A bound service typically lives only while it serves another application

component and does not run in the background indefinitely

This document shows you how to create a bound service including how to bind to the service from

other application components However you should also refer to the Services document for additional

information about services in general such as how to deliver notifications from a service set the

service to run in the foreground and more

The Basics

A bound service is an implementation of the Service class that allows other applications to bind to it

and interact with it To provide binding for a service you must implement the onBind() callback

method This method returns an IBinder object that defines the programming interface that clients can

use to interact with the service

Binding to a Started Service

As discussed in the Services document you can create a service that is both started and bound That

is the service can be started by calling startService() which allows the service to run indefinitely and

also allow a client to bind to the service by calling bindService()

If you do allow your service to be started and bound then when the service has been started the

system does not destroy the service when all clients unbind Instead you must explicitly stop the

service by calling stopSelf() or stopService()

Although you should usually implement either onBind() or onStartCommand() its sometimes

necessary to implement both For example a music player might find it useful to allow its service to run

indefinitely and also provide binding This way an activity can start the service to play some music and

the music continues to play even if the user leaves the application Then when the user returns to the

application the activity can bind to the service to regain control of playback

Be sure to read the section about Managing the Lifecycle of a Bound Service for more information

about the service lifecycle when adding binding to a started service

A client can bind to the service by calling bindService() When it does it must provide an

implementation of ServiceConnection which monitors the connection with the service The

bindService() method returns immediately without a value but when the Android system creates the

connection between the client and service it calls onServiceConnected() on the ServiceConnection to

deliver the IBinder that the client can use to communicate with the service

Multiple clients can connect to the service at once However the system calls your services onBind()

method to retrieve the IBinder only when the first client binds The system then delivers the same

IBinder to any additional clients that bind without calling onBind() again

When the last client unbinds from the service the system destroys the service (unless the service was

also started by startService())

When you implement your bound service the most important part is defining the interface that your

onBind() callback method returns There are a few different ways you can define your services IBinder

interface and the following section discusses each technique

Creating a Bound Service

When creating a service that provides binding you must provide an IBinder that provides the

programming interface that clients can use to interact with the service There are three ways you can

define the interface

Extending the Binder class

If your service is private to your own application and runs in the same process as the client

(which is common) you should create your interface by extending the Binder class and

returning an instance of it from onBind() The client receives the Binder and can use it to directly

access public methods available in either the Binder implementation or even the Service

This is the preferred technique when your service is merely a background worker for your own

application The only reason you would not create your interface this way is because your

service is used by other applications or across separate processes

Using a Messenger

If you need your interface to work across different processes you can create an interface for the

service with a Messenger In this manner the service defines a Handler that responds to

different types of Message objects This Handler is the basis for a Messenger that can then

share an IBinder with the client allowing the client to send commands to the service using

Message objects Additionally the client can define a Messenger of its own so the service can

send messages back

This is the simplest way to perform interprocess communication (IPC) because the Messenger

queues all requests into a single thread so that you dont have to design your service to be

thread-safe

Using AIDL

AIDL (Android Interface Definition Language) performs all the work to decompose objects into

primitives that the operating system can understand and marshall them across processes to

perform IPC The previous technique using a Messenger is actually based on AIDL as its

underlying structure As mentioned above the Messenger creates a queue of all the client

requests in a single thread so the service receives requests one at a time If however you

want your service to handle multiple requests simultaneously then you can use AIDL directly In

this case your service must be capable of multi-threading and be built thread-safe

To use AIDL directly you must create an aidl file that defines the programming interface The

Android SDK tools use this file to generate an abstract class that implements the interface and

handles IPC which you can then extend within your service

Note Most applications should not use AIDL to create a bound service because it may require

multithreading capabilities and can result in a more complicated implementation As such AIDL is

not suitable for most applications and this document does not discuss how to use it for your

service If youre certain that you need to use AIDL directly see the AIDL document

Extending the Binder class

If your service is used only by the local application and does not need to work across processes then

you can implement your own Binder class that provides your client direct access to public methods in

the service

Note This works only if the client and service are in the same application and process which is

most common For example this would work well for a music application that needs to bind an

activity to its own service thats playing music in the background

Heres how to set it up

1 In your service create an instance of Binder that either

o contains public methods that the client can call

o returns the current Service instance which has public methods the client can call

o or returns an instance of another class hosted by the service with public methods the client can call

2 Return this instance of Binder from the onBind() callback method

3 In the client receive the Binder from the onServiceConnected() callback method and make calls to the

bound service using the methods provided

Note The reason the service and client must be in the same application is so the client can cast

the returned object and properly call its APIs The service and client must also be in the same

process because this technique does not perform any marshalling across processes

For example heres a service that provides clients access to methods in the service through a Binder

implementation

public class LocalService extends Service

Binder given to clients

private final IBinder mBinder = new LocalBinder()

Random number generator

private final Random mGenerator = new Random()

Class used for the client Binder Because we know this service always

runs in the same process as its clients we dont need to deal with IPC

public class LocalBinder extends Binder

LocalService getService()

Return this instance of LocalService so clients can call public methods

return LocalServicethis

Override

public IBinder onBind(Intent intent)

return mBinder

method for clients

public int getRandomNumber()

return mGeneratornextInt(100)

The LocalBinder provides the getService() method for clients to retrieve the current instance of

LocalService This allows clients to call public methods in the service For example clients can call

getRandomNumber() from the service

Heres an activity that binds to LocalService and calls getRandomNumber() when a button is clicked

public class BindingActivity extends Activity

LocalService mService

boolean mBound = false

Override

protected void onCreate(Bundle savedInstanceState)

superonCreate(savedInstanceState)

setContentView(Rlayoutmain)

Override

protected void onStart()

superonStart()

Bind to LocalService

Intent intent = new Intent(this LocalServiceclass)

bindService(intent mConnection ContextBIND_AUTO_CREATE)

Override

protected void onStop()

superonStop()

Unbind from the service

if (mBound)

unbindService(mConnection)

mBound = false

Called when a button is clicked (the button in the layout file attaches to

this method with the androidonClick attribute)

public void onButtonClick(View v)

if (mBound)

Call a method from the LocalService

However if this call were something that might hang then this request should

occur in a separate thread to avoid slowing down the activity performance

int num = mServicegetRandomNumber()

ToastmakeText(this number + num ToastLENGTH_SHORT)show()

Defines callbacks for service binding passed to bindService()

private ServiceConnection mConnection = new ServiceConnection()

Override

public void onServiceConnected(ComponentName className

IBinder service)

Weve bound to LocalService cast the IBinder and get LocalService instance

LocalBinder binder = (LocalBinder) service

mService = bindergetService()

mBound = true

Override

public void onServiceDisconnected(ComponentName arg0)

mBound = false

The above sample shows how the client binds to the service using an implementation of

ServiceConnection and the onServiceConnected() callback The next section provides more

information about this process of binding to the service

Note The example above doesnt explicitly unbind from the service but all clients should unbind

at an appropriate time (such as when the activity pauses)

For more sample code see the LocalServicejava class and the LocalServiceActivitiesjava class in

ApiDemos

Using a Messenger

Compared to AIDL

When you need to perform IPC using a Messenger for your interface is simpler than implementing it

with AIDL because Messenger queues all calls to the service whereas a pure AIDL interface sends

simultaneous requests to the service which must then handle multi-threading

For most applications the service doesnt need to perform multi-threading so using a Messenger

allows the service to handle one call at a time If its important that your service be multi-threaded then

you should use AIDL to define your interface

If you need your service to communicate with remote processes then you can use a Messenger to

provide the interface for your service This technique allows you to perform interprocess

communication (IPC) without the need to use AIDL

Heres a summary of how to use a Messenger

The service implements a Handler that receives a callback for each call from a client

The Handler is used to create a Messenger object (which is a reference to the Handler)

The Messenger creates an IBinder that the service returns to clients from onBind()

Clients use the IBinder to instantiate the Messenger (that references the services Handler) which the

client uses to send Message objects to the service

The service receives each Message in its Handlermdashspecifically in the handleMessage() method

In this way there are no methods for the client to call on the service Instead the client delivers

messages (Message objects) that the service receives in its Handler

Heres a simple example service that uses a Messenger interface

public class MessengerService extends Service Command to the service to display a message static final int MSG_SAY_HELLO = 1 Handler of incoming messages from clients class IncomingHandler extends Handler Override public void handleMessage(Message msg) switch (msgwhat) case MSG_SAY_HELLO ToastmakeText(getApplicationContext() hello ToastLENGTH_SHORT)show() break default superhandleMessage(msg) Target we publish for clients to send messages to IncomingHandler final Messenger mMessenger = new Messenger(new IncomingHandler()) When binding to the service we return an interface to our messenger for sending messages to the service Override public IBinder onBind(Intent intent) ToastmakeText(getApplicationContext() binding ToastLENGTH_SHORT)show() return mMessengergetBinder()

Notice that the handleMessage() method in the Handler is where the service receives the incoming

Message and decides what to do based on the what member

All that a client needs to do is create a Messenger based on the IBinder returned by the service and

send a message using send() For example heres a simple activity that binds to the service and

delivers the MSG_SAY_HELLO message to the service

public class ActivityMessenger extends Activity Messenger for communicating with the service Messenger mService = null Flag indicating whether we have called bind on the service boolean mBound Class for interacting with the main interface of the service private ServiceConnection mConnection = new ServiceConnection() public void onServiceConnected(ComponentName className IBinder service) This is called when the connection with the service has been established giving us the object we can use to interact with the service We are communicating with the service using a Messenger so here we get a client-side representation of that from the raw IBinder object mService = new Messenger(service) mBound = true public void onServiceDisconnected(ComponentName className) This is called when the connection with the service has been unexpectedly disconnected -- that is its process crashed mService = null mBound = false public void sayHello(View v) if (mBound) return Create and send a message to the service using a supported what value Message msg = Messageobtain(null MessengerServiceMSG_SAY_HELLO 0 0) try mServicesend(msg) catch (RemoteException e) eprintStackTrace() Override protected void onCreate(Bundle savedInstanceState) superonCreate(savedInstanceState) setContentView(Rlayoutmain)

Override protected void onStart() superonStart() Bind to the service bindService(new Intent(this MessengerServiceclass) mConnection ContextBIND_AUTO_CREATE) Override protected void onStop() superonStop() Unbind from the service if (mBound) unbindService(mConnection) mBound = false

Notice that this example does not show how the service can respond to the client If you want the

service to respond then you need to also create a Messenger in the client Then when the client

receives the onServiceConnected() callback it sends a Message to the service that includes the

clients Messenger in the replyTo parameter of the send() method

You can see an example of how to provide two-way messaging in the MessengerServicejava (service)

and MessengerServiceActivitiesjava (client) samples

Binding to a Service

Application components (clients) can bind to a service by calling bindService() The Android system

then calls the services onBind() method which returns an IBinder for interacting with the service

The binding is asynchronous bindService() returns immediately and does not return the IBinder to the

client To receive the IBinder the client must create an instance of ServiceConnection and pass it to

bindService() The ServiceConnection includes a callback method that the system calls to deliver the

IBinder

Note Only activities services and content providers can bind to a servicemdashyou cannot bind to a

service from a broadcast receiver

So to bind to a service from your client you must

1 Implement ServiceConnection

Your implementation must override two callback methods

onServiceConnected()

The system calls this to deliver the IBinder returned by the services onBind() method

onServiceDisconnected()

The Android system calls this when the connection to the service is unexpectedly lost such as

when the service has crashed or has been killed This is not called when the client unbinds

2 Call bindService() passing the ServiceConnection implementation

3 When the system calls your onServiceConnected() callback method you can begin making calls to the

service using the methods defined by the interface

4 To disconnect from the service call unbindService()

When your client is destroyed it will unbind from the service but you should always unbind when

youre done interacting with the service or when your activity pauses so that the service can shutdown

while its not being used (Appropriate times to bind and unbind is discussed more below)

For example the following snippet connects the client to the service created above by extending the

Binder class so all it must do is cast the returned IBinder to the LocalService class and request the

LocalService instance

LocalService mService private ServiceConnection mConnection = new ServiceConnection() Called when the connection with the service is established public void onServiceConnected(ComponentName className IBinder service) Because we have bound to an explicit service that is running in our own process we can cast its IBinder to a concrete class and directly access it LocalBinder binder = (LocalBinder) service mService = bindergetService() mBound = true Called when the connection with the service disconnects unexpectedly public void onServiceDisconnected(ComponentName className) Loge(TAG onServiceDisconnected) mBound = false

With this ServiceConnection the client can bind to a service by passing this it to bindService() For

example

Intent intent = new Intent(this LocalServiceclass) bindService(intent mConnection ContextBIND_AUTO_CREATE)

The first parameter of bindService() is an Intent that explicitly names the service to bind (thought the

intent could be implicit)

The second parameter is the ServiceConnection object

The third parameter is a flag indicating options for the binding It should usually be

BIND_AUTO_CREATE in order to create the service if its not already alive Other possible values are

BIND_DEBUG_UNBIND and BIND_NOT_FOREGROUND or 0 for none

Additional notes

Here are some important notes about binding to a service

You should always trap DeadObjectException exceptions which are thrown when the connection has

broken This is the only exception thrown by remote methods

Objects are reference counted across processes

You should usually pair the binding and unbinding during matching bring-up and tear-down moments

of the clients lifecycle For example

o If you only need to interact with the service while your activity is visible you should bind during

onStart() and unbind during onStop()

o If you want your activity to receive responses even while it is stopped in the background then you can

bind during onCreate() and unbind during onDestroy() Beware that this implies that your activity needs

to use the service the entire time its running (even in the background) so if the service is in another

process then you increase the weight of the process and it becomes more likely that the system will

kill it

Note You should usually not bind and unbind during your activitys onResume() and onPause()

because these callbacks occur at every lifecycle transition and you should keep the processing that

occurs at these transitions to a minimum Also if multiple activities in your application bind to the same

service and there is a transition between two of those activities the service may be destroyed and

recreated as the current activity unbinds (during pause) before the next one binds (during resume)

(This activity transition for how activities coordinate their lifecycles is described in the Activities

document)

For more sample code showing how to bind to a service see the RemoteServicejava class in

ApiDemos

Managing the Lifecycle of a Bound Service

Figure 1 The lifecycle for a service

that is started and also allows binding

When a service is unbound from all

clients the Android system destroys it

(unless it was also started with

onStartCommand()) As such you

dont have to manage the lifecycle of

your service if its purely a bound

servicemdashthe Android system manages

it for you based on whether it is bound

to any clients

However if you choose to implement

the onStartCommand() callback

method then you must explicitly stop

the service because the service is

now considered to be started In this

case the service runs until the service

stops itself with stopSelf() or another

component calls stopService()

regardless of whether it is bound to

any clients

Additionally if your service is started and accepts binding then when the system calls your onUnbind()

method you can optionally return true if you would like to receive a call to onRebind() the next time a

client binds to the service (instead of receiving a call to onBind()) onRebind() returns void but the

client still receives the IBinder in its onServiceConnected() callback Below figure 1 illustrates the logic

for this kind of lifecycle

For more information about the lifecycle of an started service see the Services document

Content Providers

Content providers store and retrieve data and make it accessible to all applications Theyre the only

way to share data across applications theres no common storage area that all Android packages can

access

Android ships with a number of content providers for common data types (audio video images

personal contact information and so on) You can see some of them listed in the androidprovider

package You can query these providers for the data they contain (although for some you must

acquire the proper permission to read the data)

If you want to make your own data public you have two options You can create your own content

provider (a ContentProvider subclass) or you can add the data to an existing provider mdash if theres one

that controls the same type of data and you have permission to write to it

This document is an introduction to using content providers After a brief discussion of the

fundamentals it explores how to query a content provider how to modify data controlled by a provider

and how to create a content provider of your own

Content Provider Basics

How a content provider actually stores its data under the covers is up to its designer But all content

providers implement a common interface for querying the provider and returning results mdash as well as

for adding altering and deleting data Its an interface that clients use indirectly most generally

through ContentResolver objects You get a ContentResolver by calling getContentResolver() from

within the implementation of an Activity or other application component

ContentResolver cr = getContentResolver()

You can then use the ContentResolvers methods to interact with whatever content providers youre

interested in When a query is initiated the Android system identifies the content provider thats the

target of the query and makes sure that it is up and running The system instantiates all

ContentProvider objects you never need to do it on your own In fact you never deal directly with

ContentProvider objects at all Typically theres just a single instance of each type of ContentProvider

But it can communicate with multiple ContentResolver objects in different applications and processes

The interaction between processes is handled by the ContentResolver and ContentProvider classes

The data model

Content providers expose their data as a simple table on a database model where each row is a

record and each column is data of a particular type and meaning For example information about

people and their phone numbers might be exposed as follows

_ID NUMBER NUMBER_KEY LABEL NAME TYPE

13 (425) 555 6677 425 555 6677 Kirkland office Bully Pulpit TYPE_WORK

44 (212) 555-1234 212 555 1234 NY apartment Alan Vain TYPE_HOME

45 (212) 555-6657 212 555 6657 Downtown office Alan Vain TYPE_MOBILE

53 2015554433 201 555 4433 Love Nest Rex Cars TYPE_HOME

Every record includes a numeric _ID field that uniquely identifies the record within the table IDs can be

used to match records in related tables mdash for example to find a persons phone number in one table

and pictures of that person in another

A query returns a Cursor object that can move from record to record and column to column to read the

contents of each field It has specialized methods for reading each type of data So to read a field you

must know what type of data the field contains (Theres more on query results and Cursor objects

later)

URIs

Each content provider exposes a public URI (wrapped as a Uri object) that uniquely identifies its data

set A content provider that controls multiple data sets (multiple tables) exposes a separate URI for

each one All URIs for providers begin with the string content The content scheme identifies the

data as being controlled by a content provider

If youre defining a content provider its a good idea to also define a constant for its URI to simplify

client code and make future updates cleaner Android defines CONTENT_URI constants for all the

providers that come with the platform For example the URI for the table that matches phone numbers

to people and the URI for the table that holds pictures of people (both controlled by the Contacts

content provider) are

androidproviderContactsPhonesCONTENT_URI

androidproviderContactsPhotosCONTENT_URI

The URI constant is used in all interactions with the content provider Every ContentResolver method

takes the URI as its first argument Its what identifies which provider the ContentResolver should talk

to and which table of the provider is being targeted

Querying a Content Provider

You need three pieces of information to query a content provider

The URI that identifies the provider

The names of the data fields you want to receive

The data types for those fields

If youre querying a particular record you also need the ID for that record

Making the query

To query a content provider you can use either the ContentResolverquery() method or the

ActivitymanagedQuery() method Both methods take the same set of arguments and both return a

Cursor object However managedQuery() causes the activity to manage the life cycle of the Cursor A

managed Cursor handles all of the niceties such as unloading itself when the activity pauses and

requerying itself when the activity restarts You can ask an Activity to begin managing an unmanaged

Cursor object for you by calling ActivitystartManagingCursor()

The first argument to either query() or managedQuery() is the provider URI mdash the CONTENT_URI

constant that identifies a particular ContentProvider and data set (see URIs earlier)

To restrict a query to just one record you can append the _ID value for that record to the URI mdash that

is place a string matching the ID as the last segment of the path part of the URI For example if the ID

is 23 the URI would be

content 23

There are some helper methods particularly ContentUriswithAppendedId() and

UriwithAppendedPath() that make it easy to append an ID to a URI Both are static methods that

return a Uri object with the ID added So for example if you were looking for record 23 in the database

of people contacts you might construct a query as follows

import androidproviderContactsPeople import androidcontentContentUris import androidnetUri import androiddatabaseCursor Use the ContentUris method to produce the base URI for the contact with _ID == 23 Uri myPerson = ContentUriswithAppendedId(PeopleCONTENT_URI 23) Alternatively use the Uri method to produce the base URI It takes a string rather than an integer Uri myPerson = UriwithAppendedPath(PeopleCONTENT_URI 23) Then query for this specific record Cursor cur = managedQuery(myPerson null null null null)

The other arguments to the query() and managedQuery() methods delimit the query in more detail

They are

The names of the data columns that should be returned A null value returns all columns Otherwise

only columns that are listed by name are returned All the content providers that come with the

platform define constants for their columns For example the androidproviderContactsPhones class

defines constants for the names of the columns in the phone table illustrated earlier ampmdash _ID

NUMBER NUMBER_KEY NAME and so on

A filter detailing which rows to return formatted as an SQL WHERE clause (excluding the WHERE

itself) A null value returns all rows (unless the URI limits the query to a single record)

Selection arguments

A sorting order for the rows that are returned formatted as an SQL ORDER BY clause (excluding the

ORDER BY itself) A null value returns the records in the default order for the table which may be

unordered

Lets look at an example query to retrieve a list of contact names and their primary phone numbers

import androidproviderContactsPeople import androiddatabaseCursor Form an array specifying which columns to return String[] projection = new String[] People_ID People_COUNT PeopleNAME PeopleNUMBER Get the base URI for the People table in the Contacts content provider Uri contacts = PeopleCONTENT_URI Make the query Cursor managedCursor = managedQuery(contacts projection Which columns to return null Which rows to return (all rows) null Selection arguments (none) Put the results in ascending order by name PeopleNAME + ASC)

This query retrieves data from the People table of the Contacts content provider It gets the name

primary phone number and unique record ID for each contact It also reports the number of records

that are returned as the _COUNT field of each record

The constants for the names of the columns are defined in various interfaces mdash _ID and _COUNT in

BaseColumns NAME in PeopleColumns and NUMBER in PhoneColumns The ContactsPeople

class implements each of these interfaces which is why the code example above could refer to them

using just the class name

What a query returns

A query returns a set of zero or more database records The names of the columns their default order

and their data types are specific to each content provider But every provider has an _ID column

which holds a unique numeric ID for each record Every provider can also report the number of records

returned as the _COUNT column its value is the same for all rows

Here is an example result set for the query in the previous section

_ID _COUNT NAME NUMBER

44 3 Alan Vain 212 555 1234

13 3 Bully Pulpit 425 555 6677

53 3 Rex Cars 201 555 4433

The retrieved data is exposed by a Cursor object that can be used to iterate backward or forward

through the result set You can use this object only to read the data To add modify or delete data

you must use a ContentResolver object

Reading retrieved data

The Cursor object returned by a query provides access to a recordset of results If you have queried

for a specific record by ID this set will contain only one value Otherwise it can contain multiple

values (If there are no matches it can also be empty) You can read data from specific fields in the

record but you must know the data type of the field because the Cursor object has a separate method

for reading each type of data mdash such as getString() getInt() and getFloat() (However for most types

if you call the method for reading strings the Cursor object will give you the String representation of

the data) The Cursor lets you request the column name from the index of the column or the index

number from the column name

The following snippet demonstrates reading names and phone numbers from the query illustrated

earlier

import androidproviderContactsPeople private void getColumnData(Cursor cur) if (curmoveToFirst()) String name String phoneNumber int nameColumn = curgetColumnIndex(PeopleNAME) int phoneColumn = curgetColumnIndex(PeopleNUMBER) String imagePath do Get the field values name = curgetString(nameColumn) phoneNumber = curgetString(phoneColumn) Do something with the values while (curmoveToNext())

If a query can return binary data such as an image or sound the data may be directly entered in the

table or the table entry for that data may be a string specifying a content URI that you can use to get

the data In general smaller amounts of data (say from 20 to 50K or less) are most often directly

entered in the table and can be read by calling CursorgetBlob() It returns a byte array

If the table entry is a content URI you should never try to open and read the file directly (for one thing

permissions problems can make this fail) Instead you should call ContentResolveropenInputStream()

to get an InputStream object that you can use to read the data

Modifying Data

Data kept by a content provider can be modified by

Adding new records

Adding new values to existing records

Batch updating existing records

Deleting records

All data modification is accomplished using ContentResolver methods Some content providers require

a more restrictive permission for writing data than they do for reading it If you dont have permission to

write to a content provider the ContentResolver methods will fail

Adding records

To add a new record to a content provider first set up a map of key-value pairs in a ContentValues

object where each key matches the name of a column in the content provider and the value is the

desired value for the new record in that column Then call ContentResolverinsert() and pass it the URI

of the provider and the ContentValues map This method returns the full URI of the new record mdash that

is the providers URI with the appended ID for the new record You can then use this URI to query and

get a Cursor over the new record and to further modify the record Heres an example

import androidproviderContactsPeople import androidcontentContentResolver import androidcontentContentValues ContentValues values = new ContentValues() Add Abraham Lincoln to contacts and make him a favorite valuesput(PeopleNAME Abraham Lincoln) 1 = the new contact is added to favorites 0 = the new contact is not added to favorites valuesput(PeopleSTARRED 1) Uri uri = getContentResolver()insert(PeopleCONTENT_URI values)

Adding new values

Once a record exists you can add new information to it or modify existing information For example

the next step in the example above would be to add contact information mdash like a phone number or an

IM or e-mail address mdash to the new entry

The best way to add to a record in the Contacts database is to append the name of the table where the

new data goes to the URI for the record then use the amended URI to add the new data values Each

Contacts table exposes a name for this purpose as a CONTENT_DIRECTORY constant The following

code continues the previous example by adding a phone number and e-mail address for the record

just created

Uri phoneUri = null Uri emailUri = null Add a phone number for Abraham Lincoln Begin with the URI for the new record just returned by insert() it ends with the _ID of the new record so we dont have to add the ID ourselves Then append the designation for the phone table to this URI and use the resulting URI to insert the phone number phoneUri = UriwithAppendedPath(uri PeoplePhonesCONTENT_DIRECTORY) valuesclear() valuesput(PeoplePhonesTYPE PeoplePhonesTYPE_MOBILE) valuesput(PeoplePhonesNUMBER 1233214567) getContentResolver()insert(phoneUri values) Now add an email address in the same way emailUri = UriwithAppendedPath(uri PeopleContactMethodsCONTENT_DIRECTORY) valuesclear() ContactMethodsKIND is used to distinguish different kinds of contact methods such as email IM etc valuesput(PeopleContactMethodsKIND ContactsKIND_EMAIL) valuesput(PeopleContactMethodsDATA testexamplecom) valuesput(PeopleContactMethodsTYPE PeopleContactMethodsTYPE_HOME) getContentResolver()insert(emailUri values)

You can place small amounts of binary data into a table by calling the version of ContentValuesput()

that takes a byte array That would work for a small icon-like image or a short audio clip for example

However if you have a large amount of binary data to add such as a photograph or a complete song

put a content URI for the data in the table and call ContentResolveropenOutputStream() with the files

URI (That causes the content provider to store the data in a file and record the file path in a hidden

field of the record)

In this regard the MediaStore content provider the main provider that dispenses image audio and

video data employs a special convention The same URI that is used with query() or managedQuery()

to get meta-information about the binary data (such as the caption of a photograph or the date it was

taken) is used with openInputStream() to get the data itself Similarly the same URI that is used with

insert() to put meta-information into a MediaStore record is used with openOutputStream() to place the

binary data there The following code snippet illustrates this convention

import androidproviderMediaStoreImagesMedia import androidcontentContentValues import javaioOutputStream Save the name and description of an image in a ContentValues map ContentValues values = new ContentValues(3) valuesput(MediaDISPLAY_NAME road_trip_1) valuesput(MediaDESCRIPTION Day 1 trip to Los Angeles) valuesput(MediaMIME_TYPE imagejpeg) Add a new record without the bitmap but with the values just set insert() returns the URI of the new record Uri uri = getContentResolver()insert(MediaEXTERNAL_CONTENT_URI values) Now get a handle to the file for that record and save the data into it Here sourceBitmap is a Bitmap object representing the file to save to the database try OutputStream outStream = getContentResolver()openOutputStream(uri) sourceBitmapcompress(BitmapCompressFormatJPEG 50 outStream) outStreamclose() catch (Exception e) Loge(TAG exception while writing image e)

Batch updating records

To batch update a group of records (for example to change NY to New York in all fields) call the

ContentResolverupdate() method with the columns and values to change

Deleting a record

To delete a single record call ContentResolverdelete() with the URI of a specific row

To delete multiple rows call ContentResolverdelete() with the URI of the type of record to delete (for

example androidproviderContactsPeopleCONTENT_URI) and an SQL WHERE clause defining

which rows to delete (Caution Be sure to include a valid WHERE clause if youre deleting a general

type or you risk deleting more records than you intended)

Creating a Content Provider

To create a content provider you must

Set up a system for storing the data Most content providers store their data using Androids file

storage methods or SQLite databases but you can store your data any way you want Android

provides the SQLiteOpenHelper class to help you create a database and SQLiteDatabase to manage

it

Extend the ContentProvider class to provide access to the data

Declare the content provider in the manifest file for your application (AndroidManifestxml)

The following sections have notes on the last two of these tasks

Extending the ContentProvider class

You define a ContentProvider subclass to expose your data to others using the conventions expected

by ContentResolver and Cursor objects Principally this means implementing six abstract methods

declared in the ContentProvider class

query()

insert()

update()

delete()

getType()

onCreate()

The query() method must return a Cursor object that can iterate over the requested data Cursor itself

is an interface but Android provides some ready-made Cursor objects that you can use For example

SQLiteCursor can iterate over data stored in an SQLite database You get the Cursor object by calling

any of the SQLiteDatabase classs query() methods There are other Cursor implementations mdash such

as MatrixCursor mdash for data not stored in a database

Because these ContentProvider methods can be called from various ContentResolver objects in

different processes and threads they must be implemented in a thread-safe manner

As a courtesy you might also want to call ContentResolvernotifyChange() to notify listeners when

there are modifications to the data

Beyond defining the subclass itself there are other steps you should take to simplify the work of clients

and make the class more accessible

Define a public static final Uri named CONTENT_URI This is the string that represents the full content

URI that your content provider handles You must define a unique string for this value The best

solution is to use the fully-qualified class name of the content provider (made lowercase) So for

example the URI for a TransportationProvider class could be defined as follows

public static final Uri CONTENT_URI = Uriparse(contentcomexamplecodelabtransportationprovider)

If the provider has subtables also define CONTENT_URI constants for each of the subtables These

URIs should all have the same authority (since that identifies the content provider) and be

distinguished only by their paths For example

contentcomexamplecodelabtransportationprovidertrain

contentcomexamplecodelabtransportationproviderairdomestic

contentcomexamplecodelabtransportationproviderairinternational

For an overview of content URIs see the Content URI Summary at the end of this document

Define the column names that the content provider will return to clients If you are using an underlying

database these column names are typically identical to the SQL database column names they

represent Also define public static String constants that clients can use to specify the columns in

queries and other instructions

Be sure to include an integer column named _id (with the constant _ID) for the IDs of the records

You should have this field whether or not you have another field (such as a URL) that is also unique

among all records If youre using the SQLite database the _ID field should be the following type

INTEGER PRIMARY KEY AUTOINCREMENT

The AUTOINCREMENT descriptor is optional But without it SQLite increments an ID counter field to

the next number above the largest existing number in the column If you delete the last row the next

row added will have the same ID as the deleted row AUTOINCREMENT avoids this by having SQLite

increment to the next largest value whether deleted or not

Carefully document the data type of each column Clients need this information to read the data

If you are handling a new data type you must define a new MIME type to return in your

implementation of ContentProvidergetType() The type depends in part on whether or not the content

URI submitted to getType() limits the request to a specific record Theres one form of the MIME type

for a single record and another for multiple records Use the Uri methods to help determine what is

being requested Here is the general format for each type

o For a single record vndandroidcursoritemvndyourcompanynamecontenttype

For example a request for train record 122 like this URI

contentcomexampletransportationprovidertrains122

might return this MIME type

vndandroidcursoritemvndexamplerail

o For multiple records vndandroidcursordirvndyourcompanynamecontenttype

For example a request for all train records like the following URI

contentcomexampletransportationprovidertrains

might return this MIME type

vndandroidcursordirvndexamplerail

If you are exposing byte data thats too big to put in the table itself mdash such as a large bitmap file mdash the

field that exposes the data to clients should actually contain a content URI string This is the field that

gives clients access to the data file The record should also have another field named _data that lists

the exact file path on the device for that file This field is not intended to be read by the client but by

the ContentResolver The client will call ContentResolveropenInputStream() on the user-facing field

holding the URI for the item The ContentResolver will request the _data field for that record and

because it has higher permissions than a client it should be able to access that file directly and return

a read wrapper for the file to the client

For an example of a private content provider implementation see the NodePadProvider class in the

Notepad sample application that ships with the SDK

Declaring the content provider

To let the Android system know about the content provider youve developed declare it with a

ltprovidergt element in the applications AndroidManifestxml file Content providers that are not

declared in the manifest are not visible to the Android system

The name attribute is the fully qualified name of the ContentProvider subclass The authorities attribute

is the authority part of the content URI that identifies the provider For example if the ContentProvider

subclass is AutoInfoProvider the ltprovidergt element might look like this

ltprovider androidname=comexampleautosAutoInfoProvider androidauthorities=comexampleautosautoinfoprovider gt ltprovidergt

Note that the authorities attribute omits the path part of a content URI For example if

AutoInfoProvider controlled subtables for different types of autos or different manufacturers

contentcomexampleautosautoinfoproviderhonda

contentcomexampleautosautoinfoprovidergmcompact

contentcomexampleautosautoinfoprovidergmsuv

those paths would not be declared in the manifest The authority is what identifies the provider not the

path your provider can interpret the path part of the URI in any way you choose

Other ltprovidergt attributes can set permissions to read and write data provide for an icon and text

that can be displayed to users enable and disable the provider and so on Set the multiprocess

attribute to true if data does not need to be synchronized between multiple running versions of the

content provider This permits an instance of the provider to be created in each client process

eliminating the need to perform IPC

Content URI Summary

Here is a recap of the important parts of a content URI

A Standard prefix indicating that the data is controlled by a content provider Its never modified

B The authority part of the URI it identifies the content provider For third-party applications this should

be a fully-qualified class name (reduced to lowercase) to ensure uniqueness The authority is declared

in the ltprovidergt elements authorities attribute

ltprovider androidname=TransportationProvider androidauthorities=comexampletransportationprovider gt

C The path that the content provider uses to determine what kind of data is being requested This can be

zero or more segments long If the content provider exposes only one type of data (only trains for

example) it can be absent If the provider exposes several types including subtypes it can be several

segments long mdash for example landbus landtrain seaship and seasubmarine to give four

possibilities

D The ID of the specific record being requested if any This is the _ID value of the requested record If

the request is not limited to a single record this segment and the trailing slash are omitted

contentcomexampletransportationprovidertrains

Intent and intent filters

Three of the core components of an application mdash activities services and broadcast receivers mdash 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 mdash 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 ContextstartActivity() or ActivitystartActivityForResult() to launch an

activity or get an existing activity to do something new (It can also be passed to ActivitysetResult() to

return information to the activity that called startActivityForResult())

An Intent object is passed to ContextstartService() to initiate a service or deliver new instructions to an

ongoing service Similarly an intent can be passed to ContextbindService() to establish a connection

between the calling component and a target service It can optionally initiate the service if its not

already running

Intent objects passed to any of the broadcast methods (such as ContextsendBroadcast()

ContextsendOrderedBroadcast() or ContextsendStickyBroadcast()) 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 mdash how it resolves which component should receive an intent message For

intents that dont explicitly name a target component this process involves testing the Intent object

against intent filters associated with potential targets

Intent Objects

An Intent object is a bundle of information It contains information of interest to the component that

receives the intent (such as the action to be taken and the data to act on) plus information of interest to

the Android system (such as the category of component that should handle the intent and instructions

on how to launch a target activity) Principally it can contain the following

Component name

The name of the component that should handle the intent This field is a ComponentName

object mdash a combination of the fully qualified class name of the target component (for example

comexampleprojectappFreneticActivity) and the package name set in the manifest file of the

application where the component resides (for example comexampleproject) The package

part of the component name and the package name set in the manifest do not necessarily have

to match

The component name is optional If it is set the Intent object is delivered to an instance of the

designated class If it is not set Android uses other information in the Intent object to locate a

suitable target mdash see Intent Resolution later in this document

The component name is set by setComponent() setClass() or setClassName() and read by

getComponent()

Action

A string naming the action to be performed mdash or in the case of broadcast intents the action

that took place and is being reported The Intent class defines a number of action constants

including these

Constant Target

component

Action

ACTION_CALL activity Initiate a phone call

ACTION_EDIT activity Display data for the user to edit

ACTION_MAIN activity Start up as the initial activity of a task

with no data input and no returned

output

ACTION_SYNC activity Synchronize data on a server with

data on the mobile device

ACTION_BATTERY_LOW broadcast

receiver

A warning that the battery is low

ACTION_HEADSET_PLUG broadcast

receiver

A headset has been plugged into the

device or unplugged from it

ACTION_SCREEN_ON broadcast

receiver

The screen has been turned on

ACTION_TIMEZONE_CHANGED broadcast

receiver

The setting for the time zone has

changed

See the Intent class description for a list of pre-defined constants for generic actions Other

actions are defined elsewhere in the Android API You can also define your own action strings

for activating the components in your application Those you invent should include the

application package as a prefix mdash for example comexampleprojectSHOW_COLOR

The action largely determines how the rest of the intent is structured mdash particularly the data and

extras fields mdash much as a method name determines a set of arguments and a return value For

this reason its a good idea to use action names that are as specific as possible and to couple

them tightly to the other fields of the intent In other words instead of defining an action in

isolation define an entire protocol for the Intent objects your components can handle

The action in an Intent object is set by the setAction() method and read by getAction()

Data

The URI of the data to be acted on and the MIME type of that data Different actions are paired

with different kinds of data specifications For example if the action field is ACTION_EDIT the

data field would contain the URI of the document to be displayed for editing If the action is

ACTION_CALL the data field would be a tel URI with the number to call Similarly if the action

is ACTION_VIEW and the data field is an http URI the receiving activity would be called upon

to download and display whatever data the URI refers to

When matching an intent to a component that is capable of handling the data its often

important to know the type of data (its MIME type) in addition to its URI For example a

component able to display image data should not be called upon to play an audio file

In many cases the data type can be inferred from the URI mdash particularly content URIs which

indicate that the data is located on the device and controlled by a content provider (see the

separate discussion on content providers) But the type can also be explicitly set in the Intent

object The setData() method specifies data only as a URI setType() specifies it only as a

MIME type and setDataAndType() specifies it as both a URI and a MIME type The URI is read

by getData() and the type by getType()

Category

A string containing additional information about the kind of component that should handle the

intent Any number of category descriptions can be placed in an Intent object As it does for

actions the Intent class defines several category constants including these

Constant Meaning

CATEGORY_BROWSABLE The target activity can be safely invoked by the browser to

display data referenced by a link mdash for example an image or

an e-mail message

CATEGORY_GADGET The activity can be embedded inside of another activity that

hosts gadgets

CATEGORY_HOME The activity displays the home screen the first screen the

user sees when the device is turned on or when the HOME

key is pressed

CATEGORY_LAUNCHER The activity can be the initial activity of a task and is listed in

the top-level application launcher

CATEGORY_PREFERENCE The target activity is a preference panel

See the Intent class description for the full list of categories

The addCategory() method places a category in an Intent object removeCategory() deletes a

category previously added and getCategories() gets the set of all categories currently in the

object

Extras

Key-value pairs for additional information that should be delivered to the component handling

the intent Just as some actions are paired with particular kinds of data URIs some are paired

with particular extras For example an ACTION_TIMEZONE_CHANGED intent has a time-

zone extra that identifies the new time zone and ACTION_HEADSET_PLUG has a state

extra indicating whether the headset is now plugged in or unplugged as well as a name extra

for the type of headset If you were to invent a SHOW_COLOR action the color value would be

set in an extra key-value pair

The Intent object has a series of put() methods for inserting various types of extra data and a

similar set of get() methods for reading the data These methods parallel those for Bundle

objects In fact the extras can be installed and read as a Bundle using the putExtras() and

getExtras() methods

Flags

Flags of various sorts Many instruct the Android system how to launch an activity (for example

which task the activity should belong to) and how to treat it after its launched (for example

whether it belongs in the list of recent activities) All these flags are defined in the Intent class

The Android system and the applications that come with the platform employ Intent objects both to

send out system-originated broadcasts and to activate system-defined components To see how to

structure an intent to activate a system component consult the list of intents in the reference

Intent Resolution

Intents can be divided into two groups

Explicit intents designate the target component by its name (the component name field mentioned

earlier has a value set) Since component names would generally not be known to developers of other

applications explicit intents are typically used for application-internal messages mdash such as an activity

starting a subordinate service or launching a sister activity

Implicit intents do not name a target (the field for the component name is blank) Implicit intents are

often used to activate components in other applications

Android delivers an explicit intent to an instance of the designated target class Nothing in the Intent

object other than the component name matters for determining which component should get the intent

A different strategy is needed for implicit intents In the absence of a designated target the Android

system must find the best component (or components) to handle the intent mdash a single activity or

service to perform the requested action or the set of broadcast receivers to respond to the broadcast

announcement It does so by comparing the contents of the Intent object to intent filters structures

associated with components that can potentially receive intents Filters advertise the capabilities of a

component and delimit the intents it can handle They open the component to the possibility of

receiving implicit intents of the advertised type If a component does not have any intent filters it can

receive only explicit intents A component with filters can receive both explicit and implicit intents

Only three aspects of an Intent object are consulted when the object is tested against an intent filter

action

data (both URI and data type)

category

The extras and flags play no part in resolving which component receives an intent

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 mdash but only unwanted implicit intents (those that dont 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

components 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 mdash 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 Pads filters are described in the Note Pad Example

section later)

Filters and security

An intent filter cannot be relied on for security While it opens a component to receiving only certain

kinds of implicit intents it does nothing to prevent explicit intents from targeting the component Even

though a filter restricts the intents a component will be asked to handle to certain actions and data

sources someone could always put together an explicit intent with a different action and data source

and name the component as the target

An intent filter is an instance of the IntentFilter class However since the Android system must know

about the capabilities of a component before it can launch that component intent filters are generally

not set up in Java code but in the applications manifest file (AndroidManifestxml) as ltintent-filtergt

elements (The one exception would be filters for broadcast receivers that are registered dynamically

by calling ContextregisterReceiver() they are directly created as IntentFilter objects)

A filter has fields that parallel the action data and category fields of an Intent object An implicit intent

is tested against the filter in all three areas To be delivered to the component that owns the filter it

must pass all three tests If it fails even one of them the Android system wont deliver it to the

component mdash at least not on the basis of that filter However since a component can have multiple

intent filters an intent that does not pass through one of a components filters might make it through on

another

Each of the three tests is described in detail below

Action test

An ltintent-filtergt element in the manifest file lists actions as ltactiongt subelements For

example

ltintent-filter gt ltaction androidname=comexampleprojectSHOW_CURRENT gt ltaction androidname=comexampleprojectSHOW_RECENT gt ltaction androidname=comexampleprojectSHOW_PENDING gt ltintent-filtergt

As the example shows while an Intent object names just a single action a filter may list more

than one The list cannot be empty a filter must contain at least one ltactiongt element or it will

block all intents

To pass this test the action specified in the Intent object must match one of the actions listed in

the filter If the object or the filter does not specify an action the results are as follows

If the filter fails to list any actions there is nothing for an intent to match so all intents fail the

test No intents can get through the filter

On the other hand an Intent object that doesnt specify an action automatically passes the test

mdash as long as the filter contains at least one action

Category test

An ltintent-filtergt element also lists categories as subelements For example

ltintent-filter gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryBROWSABLE gt ltintent-filtergt

Note that the constants described earlier for actions and categories are not used in the manifest

file The full string values are used instead For instance the

androidintentcategoryBROWSABLE string in the example above corresponds to the

CATEGORY_BROWSABLE constant mentioned earlier in this document Similarly the string

androidintentactionEDIT corresponds to the ACTION_EDIT constant

For an intent to pass the category test every category in the Intent object must match a

category in the filter The filter can list additional categories but it cannot omit any that are in the

intent

In principle therefore an Intent object with no categories should always pass this test

regardless of whats in the filter Thats mostly true However with one exception Android treats

all implicit intents passed to startActivity() as if they contained at least one category

androidintentcategoryDEFAULT (the CATEGORY_DEFAULT constant) Therefore activities

that are willing to receive implicit intents must include androidintentcategoryDEFAULT in

their intent filters (Filters with androidintentactionMAIN and

androidintentcategoryLAUNCHER settings are the exception They mark activities that begin

new tasks and that are represented on the launcher screen They can include

androidintentcategoryDEFAULT in the list of categories but dont need to) See Using intent

matching later for more on these filters)

Data test

Like the action and categories the data specification for an intent filter is contained in a

subelement And as in those cases the subelement can appear multiple times or not at all For

example

ltintent-filter gt ltdata androidmimeType=videompeg androidscheme=http gt ltdata androidmimeType=audiompeg androidscheme=http gt ltintent-filtergt

Each ltdatagt element can specify a URI and a data type (MIME media type) There are

separate attributes mdash scheme host port and path mdash for each part of the URI

schemehostportpath

For example in the following URI

contentcomexampleproject200foldersubfolderetc

the scheme is content the host is comexampleproject the port is 200 and the path is

foldersubfolderetc The host and port together constitute the URI authority if a host is not

specified the port is ignored

Each of these attributes is optional but they are not independent of each other For an authority

to be meaningful a scheme must also be specified For a path to be meaningful both a scheme

and an authority must be specified

When the URI in an Intent object is compared to a URI specification in a filter its compared

only to the parts of the URI actually mentioned in the filter For example if a filter specifies only

a scheme all URIs with that scheme match the filter If a filter specifies a scheme and an

authority but no path all URIs with the same scheme and authority match regardless of their

paths If a filter specifies a scheme an authority and a path only URIs with the same scheme

authority and path match However a path specification in the filter can contain wildcards to

require only a partial match of the path

The type attribute of a ltdatagt element specifies the MIME type of the data Its more common in

filters than a URI Both the Intent object and the filter can use a wildcard for the subtype field

mdash for example text or audio mdash indicating any subtype matches

The data test compares both the URI and the data type in the Intent object to a URI and data

type specified in the filter The rules are as follows

a An Intent object that contains neither a URI nor a data type passes the test only if the filter

likewise does not specify any URIs or data types

b An Intent object that contains a URI but no data type (and a type cannot be inferred from the

URI) passes the test only if its URI matches a URI in the filter and the filter likewise does not

specify a type This will be the case only for URIs like mailto and tel that do not refer to actual

data

c An Intent object that contains a data type but not a URI passes the test only if the filter lists the

same data type and similarly does not specify a URI

d An Intent object that contains both a URI and a data type (or a data type can be inferred from

the URI) passes the data type part of the test only if its type matches a type listed in the filter It

passes the URI part of the test either if its URI matches a URI in the filter or if it has a content

or file URI and the filter does not specify a URI In other words a component is presumed to

support content and file data if its filter lists only a data type

If an intent can pass through the filters of more than one activity or service the user may be asked

which component to activate An exception is raised if no target can be found

Common cases

The last rule shown above for the data test rule (d) reflects the expectation that components are able

to get local data from a file or content provider Therefore their filters can list just a data type and do

not need to explicitly name the content and file schemes This is a typical case A ltdatagt element like

the following for example tells Android that the component can get image data from a content

provider and display it

ltdata androidmimeType=image gt

Since most available data is dispensed by content providers filters that specify a data type but not a

URI are perhaps the most common

Another common configuration is filters with a scheme and a data type For example a ltdatagt

element like the following tells Android that the component can get video data from the network and

display it

ltdata androidscheme=http androidtype=video gt

Consider for example what the browser application does when the user follows a link on a web page

It first tries to display the data (as it could if the link was to an HTML page) If it cant display the data it

puts together an implicit intent with the scheme and data type and tries to start an activity that can do

the job If there are no takers it asks the download manager to download the data That puts it under

the control of a content provider so a potentially larger pool of activities (those with filters that just

name a data type) can respond

Most applications also have a way to start fresh without a reference to any particular data Activities

that can initiate applications have filters with androidintentactionMAIN specified as the action If

they are to be represented in the application launcher they also specify the

androidintentcategoryLAUNCHER category

ltintent-filter gt ltaction androidname=code androidintentactionMAIN gt ltcategory androidname=code androidintentcategoryLAUNCHER gt ltintent-filtergt

Using intent matching

Intents are matched against intent filters not only to discover a target component to activate but also

to discover something about the set of components on the device For example the Android system

populates the application launcher the top-level screen that shows the applications that are available

for the user to launch by finding all the activities with intent filters that specify the

androidintentactionMAIN action and androidintentcategoryLAUNCHER category (as illustrated

in the previous section) It then displays the icons and labels of those activities in the launcher

Similarly it discovers the home screen by looking for the activity with androidintentcategoryHOME

in its filter

Your application can use intent matching is a similar way The PackageManager has a set of query()

methods that return all components that can accept a particular intent and a similar series of

resolve() methods that determine the best component to respond to an intent For example

queryIntentActivities() returns a list of all activities that can perform the intent passed as an argument

and queryIntentServices() returns a similar list of services Neither method activates the components

they just list the ones that can respond Theres a similar method queryBroadcastReceivers() for

broadcast receivers

Note Pad Example

The Note Pad sample application enables users to browse through a list of notes view details about

individual items in the list edit the items and add a new item to the list This section looks at the intent

filters declared in its manifest file (If youre working offline in the SDK you can find all the source files

for this sample application including its manifest file at ltsdkgtsamplesNotePadindexhtml If youre

viewing the documentation online the source files are in the Tutorials and Sample Code section here)

In its manifest file the Note Pad application declares three activities each with at least one intent filter

It also declares a content provider that manages the note data Here is the manifest file in its entirety

ltmanifest xmlnsandroid=httpschemasandroidcomapkresandroid package=comexampleandroidnotepadgt ltapplication androidicon=drawableapp_notes androidlabel=stringapp_name gt ltprovider androidname=NotePadProvider androidauthorities=comgoogleproviderNotePad gt ltactivity androidname=NotesList androidlabel=stringtitle_notes_listgt ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltactivity androidname=NoteEditor androidtheme=androidstyleThemeLight androidlabel=stringtitle_note gt ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltactivitygt

ltactivity androidname=TitleEditor androidlabel=stringtitle_edit_title androidtheme=androidstyleThemeDialoggt ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltapplicationgt ltmanifestgt

The first activity NotesList is distinguished from the other activities by the fact that it operates on a

directory of notes (the note list) rather than on a single note It would generally serve as the initial user

interface into the application It can do three things as described by its three intent filters

1 ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt

This filter declares the main entry point into the Note Pad application The standard MAIN action is an

entry point that does not require any other information in the Intent (no data specification for example)

and the LAUNCHER category says that this entry point should be listed in the application launcher

2 ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

This filter declares the things that the activity can do on a directory of notes It can allow the user to

view or edit the directory (via the VIEW and EDIT actions) or to pick a particular note from the

directory (via the PICK action)

The mimeType attribute of the ltdatagt element specifies the kind of data that these actions operate on

It indicates that the activity can get a Cursor over zero or more items (vndandroidcursordir) from a

content provider that holds Note Pad data (vndgooglenote) The Intent object that launches the

activity would include a content URI specifying the exact data of this type that the activity should open

Note also the DEFAULT category supplied in this filter Its there because the ContextstartActivity()

and ActivitystartActivityForResult() methods treat all intents as if they contained the DEFAULT

category mdash with just two exceptions

o Intents that explicitly name the target activity

o Intents consisting of the MAIN action and LAUNCHER category

Therefore the DEFAULT category is required for all filters mdash except for those with the MAIN action

and LAUNCHER category (Intent filters are not consulted for explicit intents)

3 ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

This filter describes the activitys ability to return a note selected by the user without requiring any

specification of the directory the user should choose from The GET_CONTENT action is similar to the

PICK action In both cases the activity returns the URI for a note selected by the user (In each case

its returned to the activity that called startActivityForResult() to start the NoteList activity) Here

however the caller specifies the type of data desired instead of the directory of data the user will be

picking from

The data type vndandroidcursoritemvndgooglenote indicates the type of data the activity can

return mdash a URI for a single note From the returned URI the caller can get a Cursor for exactly one

item (vndandroidcursoritem) from the content provider that holds Note Pad data (vndgooglenote)

In other words for the PICK action in the previous filter the data type indicates the type of data the

activity could display to the user For the GET_CONTENT filter it indicates the type of data the activity

can return to the caller

Given these capabilities the following intents will resolve to the NotesList activity

action androidintentactionMAIN

Launches the activity with no data specified

action androidintentactionMAIN

category androidintentcategoryLAUNCHER

Launches the activity with no data selected specified This is the actual intent used by the

Launcher to populate its top-level list All activities with filters that match this action and

category are added to the list

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of all the notes under

contentcomgoogleproviderNotePadnotes The user can then browse through the list and

get information about the items in it

action androidintentactionPICK

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of the notes under

contentcomgoogleproviderNotePadnotes The user can then pick a note from the list and

the activity will return the URI for that item back to the activity that started the NoteList activity

action androidintentactionGET_CONTENT

data type vndandroidcursoritemvndgooglenote

Asks the activity to supply a single item of Note Pad data

The second activity NoteEditor shows users a single note entry and allows them to edit it It can do

two things as described by its two intent filters

1 ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The first primary purpose of this activity is to enable the user to interact with a single note ampmdash to

either VIEW the note or EDIT it (The EDIT_NOTE category is a synonym for EDIT) The intent would

contain the URI for data matching the MIME type vndandroidcursoritemvndgooglenote mdash that is

the URI for a single specific note It would typically be a URI that was returned by the PICK or

GET_CONTENT actions of the NoteList activity

As before this filter lists the DEFAULT category so that the activity can be launched by intents that

dont explicitly specify the NoteEditor class

2 ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

The secondary purpose of this activity is to enable the user to create a new note which it will INSERT

into an existing directory of notes The intent would contain the URI for data matching the MIME type

vndandroidcursordirvndgooglenote mdash that is the URI for the directory where the note should be

placed

Given these capabilities the following intents will resolve to the NoteEditor activity

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID (For details on how content

URIs specify individual members of a group see Content Providers)

action androidintentactionEDIT

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID and to let the user edit it If

the user saves the changes the activity updates the data for the note in the content provider

action androidintentactionINSERT

data contentcomgoogleproviderNotePadnotes

Asks the activity to create a new empty note in the notes list at

contentcomgoogleproviderNotePadnotes and allow the user to edit it If the user saves the

note its URI is returned to the caller

The last activity TitleEditor enables the user to edit the title of a note This could be implemented by

directly invoking the activity (by explicitly setting its component name in the Intent) without using an

intent filter But here we take the opportunity to show how to publish alternative operations on existing

data

ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The single intent filter for this activity uses a custom action called

comandroidnotepadactionEDIT_TITLE It must be invoked on a specific note (data type

vndandroidcursoritemvndgooglenote) like the previous VIEW and EDIT actions However here the

activity displays the title contained in the note data not the content of the note itself

In addition to supporting the usual DEFAULT category the title editor also supports two other standard

categories ALTERNATIVE and SELECTED_ALTERNATIVE These categories identify activities that

can be presented to users in a menu of options (much as the LAUNCHER category identifies activities

that should be presented to user in the application launcher) Note that the filter also supplies an

explicit label (via androidlabel=stringresolve_title) to better control what users see when

presented with this activity as an alternative action to the data they are currently viewing (For more

information on these categories and building options menus see the

PackageManagerqueryIntentActivityOptions() and MenuaddIntentOptions() methods)

Given these capabilities the following intent will resolve to the TitleEditor activity

action comandroidnotepadactionEDIT_TITLE

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the title associated with note ID and allow the user to edit the title

Processes and Threads

When an application component starts and the application does not have any other components

running the Android system starts a new Linux process for the application with a single thread of

execution By default all components of the same application run in the same process and thread

(called the main thread) If an application component starts and there already exists a process for

that application (because another component from the application exists) then the component is

started within that process and uses the same thread of execution However you can arrange for

different components in your application to run in separate processes and you can create additional

threads for any process

This document discusses how processes and threads work in an Android application

Processes

By default all components of the same application run in the same process and most applications

should not change this However if you find that you need to control which process a certain

component belongs to you can do so in the manifest file

The manifest entry for each type of component elementmdashltactivitygt ltservicegt ltreceivergt and

ltprovidergtmdashsupports an androidprocess attribute that can specify a process in which that component

should run You can set this attribute so that each component runs in its own process or so that some

components share a process while others do not You can also set androidprocess so that

components of different applications run in the same processmdashprovided that the applications share the

same Linux user ID and are signed with the same certificates

The ltapplicationgt element also supports an androidprocess attribute to set a default value that

applies to all components

Android might 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 thats killed are consequently destroyed A process is started again for those components

when theres again work for them to do

When deciding which processes to kill the Android system weighs their relative importance to the

user For example it more readily shuts down a process hosting activities that are no longer visible on

screen compared to a process hosting visible activities The decision whether to terminate a process

therefore depends on the state of the components running in that process The rules used to decide

which processes to terminate is discussed below

Process lifecycle

The Android system tries to maintain an application process for as long as possible but eventually

needs to remove old processes to reclaim memory for new or more important processes To determine

which processes to keep and which to kill the system places each process into an importance

hierarchy based on the components running in the process and the state of those components

Processes with the lowest importance are eliminated first then those with the next lowest importance

and so on as necessary to recover system resources

There are five levels in the importance hierarchy The following list presents the different types of

processes in order of importance (the first process is most important and is killed last)

1 Foreground process

A process that is required for what the user is currently doing A process is considered to be in the

foreground if any of the following conditions are true

o It hosts an Activity that the user is interacting with (the Activitys onResume() method has been called)

o It hosts a Service thats bound to the activity that the user is interacting with

o It hosts a Service thats running in the foregroundmdashthe service has called startForeground()

o It hosts a Service thats executing one of its lifecycle callbacks (onCreate() onStart() or onDestroy())

o It hosts a BroadcastReceiver thats executing its onReceive() method

Generally only a few foreground processes exist at any given time They are killed only as a last

resortmdashif memory is so low that they cannot all continue to run Generally at that point the device has

reached a memory paging state so killing some foreground processes is required to keep the user

interface responsive

2 Visible process

A process that doesnt have any foreground components but still can affect what the user sees on

screen A process is considered to be visible if either of the following conditions are true

o It hosts an Activity that is not in the foreground but is still visible to the user (its onPause() method has

been called) This might occur for example if the foreground activity started a dialog which allows the

previous activity to be seen behind it

o It hosts a Service thats bound to a visible (or foreground) activity

A visible process is considered extremely important and will not be killed unless doing so is required to

keep all foreground processes running

3 Service process

A process that is running a service that has been started with the startService() method and does not

fall into either of the two higher categories Although service processes are not directly tied to anything

the user sees they are generally doing things that the user cares about (such as playing music in the

background or downloading data on the network) so the system keeps them running unless theres

not enough memory to retain them along with all foreground and visible processes

4 Background process

A process holding an activity thats not currently visible to the user (the activitys onStop() method has

been called) These processes have no direct impact on the user experience and the system can kill

them at any time to reclaim memory for a foreground visible or service process Usually there are

many background processes running so they are kept in an LRU (least recently used) list to ensure

that the process with the activity that was most recently seen by the user is the last to be killed If an

activity implements its lifecycle methods correctly and saves its current state killing its process will not

have a visible effect on the user experience because when the user navigates back to the activity the

activity restores all of its visible state See the Activities document for information about saving and

restoring state

5 Empty process

A process that doesnt hold any active application components The only reason to keep this kind of

process alive is for caching purposes to improve startup time the next time a component needs to run

in it The system often kills these processes in order to balance overall system resources between

process caches and the underlying kernel caches

Android ranks a process at the highest level it can based upon the importance of the components

currently active in the process For example if a process hosts a service and a visible activity the

process is ranked as a visible process not a service process

In addition a processs ranking might be increased because other processes are dependent on itmdasha

process that is serving another process can never be ranked lower than the process it is serving For

example if a content provider in process A is serving a client in process B or if a service in process A

is bound to a component in process B process A is always considered at least as important as

process B

Because a process running a service is ranked higher than a process with background activities an

activity that initiates a long-running operation might do well to start a service for that operation rather

than simply create a worker threadmdashparticularly if the operation will likely outlast the activity For

example an activity thats uploading a picture to a web site should start a service to perform the

upload so that the upload can continue in the background even if the user leaves the activity Using a

service guarantees that the operation will have at least service process priority regardless of what

happens to the activity This is the same reason that broadcast receivers should employ services

rather than simply put time-consuming operations in a thread

Threads

When an application is launched the system creates a thread of execution for the application called

main This thread is very important because it is in charge of dispatching events to the appropriate

user interface widgets including drawing events It is also the thread in which your application interacts

with components from the Android UI toolkit (components from the androidwidget and androidview

packages) As such the main thread is also sometimes called the UI thread

The system does not create a separate thread for each instance of a component All components that

run in the same process are instantiated in the UI thread and system calls to each component are

dispatched from that thread Consequently methods that respond to system callbacks (such as

onKeyDown() to report user actions or a lifecycle callback method) always run in the UI thread of the

process

For instance when the user touches a button on the screen your apps UI thread dispatches the touch

event to the widget which in turn sets its pressed state and posts an invalidate request to the event

queue The UI thread dequeues the request and notifies the widget that it should redraw itself

When your app performs intensive work in response to user interaction this single thread model can

yield poor performance unless you implement your application properly Specifically if everything is

happening in the UI thread performing long operations such as network access or database queries

will block the whole UI When the thread is blocked no events can be dispatched including drawing

events From the users perspective the application appears to hang Even worse if the UI thread is

blocked for more than a few seconds (about 5 seconds currently) the user is presented with the

infamous application not responding (ANR) dialog The user might then decide to quit your

application and uninstall it if they are unhappy

Additionally the Andoid UI toolkit is not thread-safe So you must not manipulate your UI from a

worker threadmdashyou must do all manipulation to your user interface from the UI thread Thus there are

simply two rules to Androids single thread model

1 Do not block the UI thread

2 Do not access the Android UI toolkit from outside the UI thread

Worker threads

Because of the single thread model described above its vital to the responsiveness of your

applications UI that you do not block the UI thread If you have operations to perform that are not

instantaneous you should make sure to do them in separate threads (background or worker

threads)

For example below is some code for a click listener that downloads an image from a separate thread

and displays it in an ImageView

public void onClick(View v) new Thread(new Runnable() public void run() Bitmap b = loadImageFromNetwork(httpexamplecomimagepng) mImageViewsetImageBitmap(b) )start()

At first this seems to work fine because it creates a new thread to handle the network operation

However it violates the second rule of the single-threaded model do not access the Android UI toolkit

from outside the UI threadmdashthis sample modifies the ImageView from the worker thread instead of the

UI thread This can result in undefined and unexpected behavior which can be difficult and time-

consuming to track down

To fix this problem Android offers several ways to access the UI thread from other threads Here is a

list of methods that can help

ActivityrunOnUiThread(Runnable)

Viewpost(Runnable)

ViewpostDelayed(Runnable long)

For example you can fix the above code by using the Viewpost(Runnable) method

public void onClick(View v) new Thread(new Runnable() public void run() final Bitmap bitmap = loadImageFromNetwork(httpexamplecomimagepng) mImageViewpost(new Runnable() public void run() mImageViewsetImageBitmap(bitmap) ) )start()

Now this implementation is thread-safe the network operation is done from a separate thread while

the ImageView is manipulated from the UI thread

However as the complexity of the operation grows this kind of code can get complicated and difficult

to maintain To handle more complex interactions with a worker thread you might consider using a

Handler in your worker thread to process messages delivered from the UI thread Perhaps the best

solution though is to extend the AsyncTask class which simplifies the execution of worker thread

tasks that need to interact with the UI

Using AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface It performs the blocking

operations in a worker thread and then publishes the results on the UI thread without requiring you to

handle threads andor handlers yourself

To use it you must subclass AsyncTask and implement the doInBackground() callback method which

runs in a pool of background threads To update your UI you should implement onPostExecute()

which delivers the result from doInBackground() and runs in the UI thread so you can safely update

your UI You can then run the task by calling execute() from the UI thread

For example you can implement the previous example using AsyncTask this way

public void onClick(View v) new DownloadImageTask()execute(httpexamplecomimagepng) private class DownloadImageTask extends AsyncTaskltString Void Bitmapgt The system calls this to perform work in a worker thread and delivers it the parameters given to AsyncTaskexecute() protected Bitmap doInBackground(String urls) return loadImageFromNetwork(urls[0])

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 15: 03 services

Bound Services

A bound service is the server in a client-server interface A bound service allows components (such as

activities) to bind to the service send requests receive responses and even perform interprocess

communication (IPC) A bound service typically lives only while it serves another application

component and does not run in the background indefinitely

This document shows you how to create a bound service including how to bind to the service from

other application components However you should also refer to the Services document for additional

information about services in general such as how to deliver notifications from a service set the

service to run in the foreground and more

The Basics

A bound service is an implementation of the Service class that allows other applications to bind to it

and interact with it To provide binding for a service you must implement the onBind() callback

method This method returns an IBinder object that defines the programming interface that clients can

use to interact with the service

Binding to a Started Service

As discussed in the Services document you can create a service that is both started and bound That

is the service can be started by calling startService() which allows the service to run indefinitely and

also allow a client to bind to the service by calling bindService()

If you do allow your service to be started and bound then when the service has been started the

system does not destroy the service when all clients unbind Instead you must explicitly stop the

service by calling stopSelf() or stopService()

Although you should usually implement either onBind() or onStartCommand() its sometimes

necessary to implement both For example a music player might find it useful to allow its service to run

indefinitely and also provide binding This way an activity can start the service to play some music and

the music continues to play even if the user leaves the application Then when the user returns to the

application the activity can bind to the service to regain control of playback

Be sure to read the section about Managing the Lifecycle of a Bound Service for more information

about the service lifecycle when adding binding to a started service

A client can bind to the service by calling bindService() When it does it must provide an

implementation of ServiceConnection which monitors the connection with the service The

bindService() method returns immediately without a value but when the Android system creates the

connection between the client and service it calls onServiceConnected() on the ServiceConnection to

deliver the IBinder that the client can use to communicate with the service

Multiple clients can connect to the service at once However the system calls your services onBind()

method to retrieve the IBinder only when the first client binds The system then delivers the same

IBinder to any additional clients that bind without calling onBind() again

When the last client unbinds from the service the system destroys the service (unless the service was

also started by startService())

When you implement your bound service the most important part is defining the interface that your

onBind() callback method returns There are a few different ways you can define your services IBinder

interface and the following section discusses each technique

Creating a Bound Service

When creating a service that provides binding you must provide an IBinder that provides the

programming interface that clients can use to interact with the service There are three ways you can

define the interface

Extending the Binder class

If your service is private to your own application and runs in the same process as the client

(which is common) you should create your interface by extending the Binder class and

returning an instance of it from onBind() The client receives the Binder and can use it to directly

access public methods available in either the Binder implementation or even the Service

This is the preferred technique when your service is merely a background worker for your own

application The only reason you would not create your interface this way is because your

service is used by other applications or across separate processes

Using a Messenger

If you need your interface to work across different processes you can create an interface for the

service with a Messenger In this manner the service defines a Handler that responds to

different types of Message objects This Handler is the basis for a Messenger that can then

share an IBinder with the client allowing the client to send commands to the service using

Message objects Additionally the client can define a Messenger of its own so the service can

send messages back

This is the simplest way to perform interprocess communication (IPC) because the Messenger

queues all requests into a single thread so that you dont have to design your service to be

thread-safe

Using AIDL

AIDL (Android Interface Definition Language) performs all the work to decompose objects into

primitives that the operating system can understand and marshall them across processes to

perform IPC The previous technique using a Messenger is actually based on AIDL as its

underlying structure As mentioned above the Messenger creates a queue of all the client

requests in a single thread so the service receives requests one at a time If however you

want your service to handle multiple requests simultaneously then you can use AIDL directly In

this case your service must be capable of multi-threading and be built thread-safe

To use AIDL directly you must create an aidl file that defines the programming interface The

Android SDK tools use this file to generate an abstract class that implements the interface and

handles IPC which you can then extend within your service

Note Most applications should not use AIDL to create a bound service because it may require

multithreading capabilities and can result in a more complicated implementation As such AIDL is

not suitable for most applications and this document does not discuss how to use it for your

service If youre certain that you need to use AIDL directly see the AIDL document

Extending the Binder class

If your service is used only by the local application and does not need to work across processes then

you can implement your own Binder class that provides your client direct access to public methods in

the service

Note This works only if the client and service are in the same application and process which is

most common For example this would work well for a music application that needs to bind an

activity to its own service thats playing music in the background

Heres how to set it up

1 In your service create an instance of Binder that either

o contains public methods that the client can call

o returns the current Service instance which has public methods the client can call

o or returns an instance of another class hosted by the service with public methods the client can call

2 Return this instance of Binder from the onBind() callback method

3 In the client receive the Binder from the onServiceConnected() callback method and make calls to the

bound service using the methods provided

Note The reason the service and client must be in the same application is so the client can cast

the returned object and properly call its APIs The service and client must also be in the same

process because this technique does not perform any marshalling across processes

For example heres a service that provides clients access to methods in the service through a Binder

implementation

public class LocalService extends Service

Binder given to clients

private final IBinder mBinder = new LocalBinder()

Random number generator

private final Random mGenerator = new Random()

Class used for the client Binder Because we know this service always

runs in the same process as its clients we dont need to deal with IPC

public class LocalBinder extends Binder

LocalService getService()

Return this instance of LocalService so clients can call public methods

return LocalServicethis

Override

public IBinder onBind(Intent intent)

return mBinder

method for clients

public int getRandomNumber()

return mGeneratornextInt(100)

The LocalBinder provides the getService() method for clients to retrieve the current instance of

LocalService This allows clients to call public methods in the service For example clients can call

getRandomNumber() from the service

Heres an activity that binds to LocalService and calls getRandomNumber() when a button is clicked

public class BindingActivity extends Activity

LocalService mService

boolean mBound = false

Override

protected void onCreate(Bundle savedInstanceState)

superonCreate(savedInstanceState)

setContentView(Rlayoutmain)

Override

protected void onStart()

superonStart()

Bind to LocalService

Intent intent = new Intent(this LocalServiceclass)

bindService(intent mConnection ContextBIND_AUTO_CREATE)

Override

protected void onStop()

superonStop()

Unbind from the service

if (mBound)

unbindService(mConnection)

mBound = false

Called when a button is clicked (the button in the layout file attaches to

this method with the androidonClick attribute)

public void onButtonClick(View v)

if (mBound)

Call a method from the LocalService

However if this call were something that might hang then this request should

occur in a separate thread to avoid slowing down the activity performance

int num = mServicegetRandomNumber()

ToastmakeText(this number + num ToastLENGTH_SHORT)show()

Defines callbacks for service binding passed to bindService()

private ServiceConnection mConnection = new ServiceConnection()

Override

public void onServiceConnected(ComponentName className

IBinder service)

Weve bound to LocalService cast the IBinder and get LocalService instance

LocalBinder binder = (LocalBinder) service

mService = bindergetService()

mBound = true

Override

public void onServiceDisconnected(ComponentName arg0)

mBound = false

The above sample shows how the client binds to the service using an implementation of

ServiceConnection and the onServiceConnected() callback The next section provides more

information about this process of binding to the service

Note The example above doesnt explicitly unbind from the service but all clients should unbind

at an appropriate time (such as when the activity pauses)

For more sample code see the LocalServicejava class and the LocalServiceActivitiesjava class in

ApiDemos

Using a Messenger

Compared to AIDL

When you need to perform IPC using a Messenger for your interface is simpler than implementing it

with AIDL because Messenger queues all calls to the service whereas a pure AIDL interface sends

simultaneous requests to the service which must then handle multi-threading

For most applications the service doesnt need to perform multi-threading so using a Messenger

allows the service to handle one call at a time If its important that your service be multi-threaded then

you should use AIDL to define your interface

If you need your service to communicate with remote processes then you can use a Messenger to

provide the interface for your service This technique allows you to perform interprocess

communication (IPC) without the need to use AIDL

Heres a summary of how to use a Messenger

The service implements a Handler that receives a callback for each call from a client

The Handler is used to create a Messenger object (which is a reference to the Handler)

The Messenger creates an IBinder that the service returns to clients from onBind()

Clients use the IBinder to instantiate the Messenger (that references the services Handler) which the

client uses to send Message objects to the service

The service receives each Message in its Handlermdashspecifically in the handleMessage() method

In this way there are no methods for the client to call on the service Instead the client delivers

messages (Message objects) that the service receives in its Handler

Heres a simple example service that uses a Messenger interface

public class MessengerService extends Service Command to the service to display a message static final int MSG_SAY_HELLO = 1 Handler of incoming messages from clients class IncomingHandler extends Handler Override public void handleMessage(Message msg) switch (msgwhat) case MSG_SAY_HELLO ToastmakeText(getApplicationContext() hello ToastLENGTH_SHORT)show() break default superhandleMessage(msg) Target we publish for clients to send messages to IncomingHandler final Messenger mMessenger = new Messenger(new IncomingHandler()) When binding to the service we return an interface to our messenger for sending messages to the service Override public IBinder onBind(Intent intent) ToastmakeText(getApplicationContext() binding ToastLENGTH_SHORT)show() return mMessengergetBinder()

Notice that the handleMessage() method in the Handler is where the service receives the incoming

Message and decides what to do based on the what member

All that a client needs to do is create a Messenger based on the IBinder returned by the service and

send a message using send() For example heres a simple activity that binds to the service and

delivers the MSG_SAY_HELLO message to the service

public class ActivityMessenger extends Activity Messenger for communicating with the service Messenger mService = null Flag indicating whether we have called bind on the service boolean mBound Class for interacting with the main interface of the service private ServiceConnection mConnection = new ServiceConnection() public void onServiceConnected(ComponentName className IBinder service) This is called when the connection with the service has been established giving us the object we can use to interact with the service We are communicating with the service using a Messenger so here we get a client-side representation of that from the raw IBinder object mService = new Messenger(service) mBound = true public void onServiceDisconnected(ComponentName className) This is called when the connection with the service has been unexpectedly disconnected -- that is its process crashed mService = null mBound = false public void sayHello(View v) if (mBound) return Create and send a message to the service using a supported what value Message msg = Messageobtain(null MessengerServiceMSG_SAY_HELLO 0 0) try mServicesend(msg) catch (RemoteException e) eprintStackTrace() Override protected void onCreate(Bundle savedInstanceState) superonCreate(savedInstanceState) setContentView(Rlayoutmain)

Override protected void onStart() superonStart() Bind to the service bindService(new Intent(this MessengerServiceclass) mConnection ContextBIND_AUTO_CREATE) Override protected void onStop() superonStop() Unbind from the service if (mBound) unbindService(mConnection) mBound = false

Notice that this example does not show how the service can respond to the client If you want the

service to respond then you need to also create a Messenger in the client Then when the client

receives the onServiceConnected() callback it sends a Message to the service that includes the

clients Messenger in the replyTo parameter of the send() method

You can see an example of how to provide two-way messaging in the MessengerServicejava (service)

and MessengerServiceActivitiesjava (client) samples

Binding to a Service

Application components (clients) can bind to a service by calling bindService() The Android system

then calls the services onBind() method which returns an IBinder for interacting with the service

The binding is asynchronous bindService() returns immediately and does not return the IBinder to the

client To receive the IBinder the client must create an instance of ServiceConnection and pass it to

bindService() The ServiceConnection includes a callback method that the system calls to deliver the

IBinder

Note Only activities services and content providers can bind to a servicemdashyou cannot bind to a

service from a broadcast receiver

So to bind to a service from your client you must

1 Implement ServiceConnection

Your implementation must override two callback methods

onServiceConnected()

The system calls this to deliver the IBinder returned by the services onBind() method

onServiceDisconnected()

The Android system calls this when the connection to the service is unexpectedly lost such as

when the service has crashed or has been killed This is not called when the client unbinds

2 Call bindService() passing the ServiceConnection implementation

3 When the system calls your onServiceConnected() callback method you can begin making calls to the

service using the methods defined by the interface

4 To disconnect from the service call unbindService()

When your client is destroyed it will unbind from the service but you should always unbind when

youre done interacting with the service or when your activity pauses so that the service can shutdown

while its not being used (Appropriate times to bind and unbind is discussed more below)

For example the following snippet connects the client to the service created above by extending the

Binder class so all it must do is cast the returned IBinder to the LocalService class and request the

LocalService instance

LocalService mService private ServiceConnection mConnection = new ServiceConnection() Called when the connection with the service is established public void onServiceConnected(ComponentName className IBinder service) Because we have bound to an explicit service that is running in our own process we can cast its IBinder to a concrete class and directly access it LocalBinder binder = (LocalBinder) service mService = bindergetService() mBound = true Called when the connection with the service disconnects unexpectedly public void onServiceDisconnected(ComponentName className) Loge(TAG onServiceDisconnected) mBound = false

With this ServiceConnection the client can bind to a service by passing this it to bindService() For

example

Intent intent = new Intent(this LocalServiceclass) bindService(intent mConnection ContextBIND_AUTO_CREATE)

The first parameter of bindService() is an Intent that explicitly names the service to bind (thought the

intent could be implicit)

The second parameter is the ServiceConnection object

The third parameter is a flag indicating options for the binding It should usually be

BIND_AUTO_CREATE in order to create the service if its not already alive Other possible values are

BIND_DEBUG_UNBIND and BIND_NOT_FOREGROUND or 0 for none

Additional notes

Here are some important notes about binding to a service

You should always trap DeadObjectException exceptions which are thrown when the connection has

broken This is the only exception thrown by remote methods

Objects are reference counted across processes

You should usually pair the binding and unbinding during matching bring-up and tear-down moments

of the clients lifecycle For example

o If you only need to interact with the service while your activity is visible you should bind during

onStart() and unbind during onStop()

o If you want your activity to receive responses even while it is stopped in the background then you can

bind during onCreate() and unbind during onDestroy() Beware that this implies that your activity needs

to use the service the entire time its running (even in the background) so if the service is in another

process then you increase the weight of the process and it becomes more likely that the system will

kill it

Note You should usually not bind and unbind during your activitys onResume() and onPause()

because these callbacks occur at every lifecycle transition and you should keep the processing that

occurs at these transitions to a minimum Also if multiple activities in your application bind to the same

service and there is a transition between two of those activities the service may be destroyed and

recreated as the current activity unbinds (during pause) before the next one binds (during resume)

(This activity transition for how activities coordinate their lifecycles is described in the Activities

document)

For more sample code showing how to bind to a service see the RemoteServicejava class in

ApiDemos

Managing the Lifecycle of a Bound Service

Figure 1 The lifecycle for a service

that is started and also allows binding

When a service is unbound from all

clients the Android system destroys it

(unless it was also started with

onStartCommand()) As such you

dont have to manage the lifecycle of

your service if its purely a bound

servicemdashthe Android system manages

it for you based on whether it is bound

to any clients

However if you choose to implement

the onStartCommand() callback

method then you must explicitly stop

the service because the service is

now considered to be started In this

case the service runs until the service

stops itself with stopSelf() or another

component calls stopService()

regardless of whether it is bound to

any clients

Additionally if your service is started and accepts binding then when the system calls your onUnbind()

method you can optionally return true if you would like to receive a call to onRebind() the next time a

client binds to the service (instead of receiving a call to onBind()) onRebind() returns void but the

client still receives the IBinder in its onServiceConnected() callback Below figure 1 illustrates the logic

for this kind of lifecycle

For more information about the lifecycle of an started service see the Services document

Content Providers

Content providers store and retrieve data and make it accessible to all applications Theyre the only

way to share data across applications theres no common storage area that all Android packages can

access

Android ships with a number of content providers for common data types (audio video images

personal contact information and so on) You can see some of them listed in the androidprovider

package You can query these providers for the data they contain (although for some you must

acquire the proper permission to read the data)

If you want to make your own data public you have two options You can create your own content

provider (a ContentProvider subclass) or you can add the data to an existing provider mdash if theres one

that controls the same type of data and you have permission to write to it

This document is an introduction to using content providers After a brief discussion of the

fundamentals it explores how to query a content provider how to modify data controlled by a provider

and how to create a content provider of your own

Content Provider Basics

How a content provider actually stores its data under the covers is up to its designer But all content

providers implement a common interface for querying the provider and returning results mdash as well as

for adding altering and deleting data Its an interface that clients use indirectly most generally

through ContentResolver objects You get a ContentResolver by calling getContentResolver() from

within the implementation of an Activity or other application component

ContentResolver cr = getContentResolver()

You can then use the ContentResolvers methods to interact with whatever content providers youre

interested in When a query is initiated the Android system identifies the content provider thats the

target of the query and makes sure that it is up and running The system instantiates all

ContentProvider objects you never need to do it on your own In fact you never deal directly with

ContentProvider objects at all Typically theres just a single instance of each type of ContentProvider

But it can communicate with multiple ContentResolver objects in different applications and processes

The interaction between processes is handled by the ContentResolver and ContentProvider classes

The data model

Content providers expose their data as a simple table on a database model where each row is a

record and each column is data of a particular type and meaning For example information about

people and their phone numbers might be exposed as follows

_ID NUMBER NUMBER_KEY LABEL NAME TYPE

13 (425) 555 6677 425 555 6677 Kirkland office Bully Pulpit TYPE_WORK

44 (212) 555-1234 212 555 1234 NY apartment Alan Vain TYPE_HOME

45 (212) 555-6657 212 555 6657 Downtown office Alan Vain TYPE_MOBILE

53 2015554433 201 555 4433 Love Nest Rex Cars TYPE_HOME

Every record includes a numeric _ID field that uniquely identifies the record within the table IDs can be

used to match records in related tables mdash for example to find a persons phone number in one table

and pictures of that person in another

A query returns a Cursor object that can move from record to record and column to column to read the

contents of each field It has specialized methods for reading each type of data So to read a field you

must know what type of data the field contains (Theres more on query results and Cursor objects

later)

URIs

Each content provider exposes a public URI (wrapped as a Uri object) that uniquely identifies its data

set A content provider that controls multiple data sets (multiple tables) exposes a separate URI for

each one All URIs for providers begin with the string content The content scheme identifies the

data as being controlled by a content provider

If youre defining a content provider its a good idea to also define a constant for its URI to simplify

client code and make future updates cleaner Android defines CONTENT_URI constants for all the

providers that come with the platform For example the URI for the table that matches phone numbers

to people and the URI for the table that holds pictures of people (both controlled by the Contacts

content provider) are

androidproviderContactsPhonesCONTENT_URI

androidproviderContactsPhotosCONTENT_URI

The URI constant is used in all interactions with the content provider Every ContentResolver method

takes the URI as its first argument Its what identifies which provider the ContentResolver should talk

to and which table of the provider is being targeted

Querying a Content Provider

You need three pieces of information to query a content provider

The URI that identifies the provider

The names of the data fields you want to receive

The data types for those fields

If youre querying a particular record you also need the ID for that record

Making the query

To query a content provider you can use either the ContentResolverquery() method or the

ActivitymanagedQuery() method Both methods take the same set of arguments and both return a

Cursor object However managedQuery() causes the activity to manage the life cycle of the Cursor A

managed Cursor handles all of the niceties such as unloading itself when the activity pauses and

requerying itself when the activity restarts You can ask an Activity to begin managing an unmanaged

Cursor object for you by calling ActivitystartManagingCursor()

The first argument to either query() or managedQuery() is the provider URI mdash the CONTENT_URI

constant that identifies a particular ContentProvider and data set (see URIs earlier)

To restrict a query to just one record you can append the _ID value for that record to the URI mdash that

is place a string matching the ID as the last segment of the path part of the URI For example if the ID

is 23 the URI would be

content 23

There are some helper methods particularly ContentUriswithAppendedId() and

UriwithAppendedPath() that make it easy to append an ID to a URI Both are static methods that

return a Uri object with the ID added So for example if you were looking for record 23 in the database

of people contacts you might construct a query as follows

import androidproviderContactsPeople import androidcontentContentUris import androidnetUri import androiddatabaseCursor Use the ContentUris method to produce the base URI for the contact with _ID == 23 Uri myPerson = ContentUriswithAppendedId(PeopleCONTENT_URI 23) Alternatively use the Uri method to produce the base URI It takes a string rather than an integer Uri myPerson = UriwithAppendedPath(PeopleCONTENT_URI 23) Then query for this specific record Cursor cur = managedQuery(myPerson null null null null)

The other arguments to the query() and managedQuery() methods delimit the query in more detail

They are

The names of the data columns that should be returned A null value returns all columns Otherwise

only columns that are listed by name are returned All the content providers that come with the

platform define constants for their columns For example the androidproviderContactsPhones class

defines constants for the names of the columns in the phone table illustrated earlier ampmdash _ID

NUMBER NUMBER_KEY NAME and so on

A filter detailing which rows to return formatted as an SQL WHERE clause (excluding the WHERE

itself) A null value returns all rows (unless the URI limits the query to a single record)

Selection arguments

A sorting order for the rows that are returned formatted as an SQL ORDER BY clause (excluding the

ORDER BY itself) A null value returns the records in the default order for the table which may be

unordered

Lets look at an example query to retrieve a list of contact names and their primary phone numbers

import androidproviderContactsPeople import androiddatabaseCursor Form an array specifying which columns to return String[] projection = new String[] People_ID People_COUNT PeopleNAME PeopleNUMBER Get the base URI for the People table in the Contacts content provider Uri contacts = PeopleCONTENT_URI Make the query Cursor managedCursor = managedQuery(contacts projection Which columns to return null Which rows to return (all rows) null Selection arguments (none) Put the results in ascending order by name PeopleNAME + ASC)

This query retrieves data from the People table of the Contacts content provider It gets the name

primary phone number and unique record ID for each contact It also reports the number of records

that are returned as the _COUNT field of each record

The constants for the names of the columns are defined in various interfaces mdash _ID and _COUNT in

BaseColumns NAME in PeopleColumns and NUMBER in PhoneColumns The ContactsPeople

class implements each of these interfaces which is why the code example above could refer to them

using just the class name

What a query returns

A query returns a set of zero or more database records The names of the columns their default order

and their data types are specific to each content provider But every provider has an _ID column

which holds a unique numeric ID for each record Every provider can also report the number of records

returned as the _COUNT column its value is the same for all rows

Here is an example result set for the query in the previous section

_ID _COUNT NAME NUMBER

44 3 Alan Vain 212 555 1234

13 3 Bully Pulpit 425 555 6677

53 3 Rex Cars 201 555 4433

The retrieved data is exposed by a Cursor object that can be used to iterate backward or forward

through the result set You can use this object only to read the data To add modify or delete data

you must use a ContentResolver object

Reading retrieved data

The Cursor object returned by a query provides access to a recordset of results If you have queried

for a specific record by ID this set will contain only one value Otherwise it can contain multiple

values (If there are no matches it can also be empty) You can read data from specific fields in the

record but you must know the data type of the field because the Cursor object has a separate method

for reading each type of data mdash such as getString() getInt() and getFloat() (However for most types

if you call the method for reading strings the Cursor object will give you the String representation of

the data) The Cursor lets you request the column name from the index of the column or the index

number from the column name

The following snippet demonstrates reading names and phone numbers from the query illustrated

earlier

import androidproviderContactsPeople private void getColumnData(Cursor cur) if (curmoveToFirst()) String name String phoneNumber int nameColumn = curgetColumnIndex(PeopleNAME) int phoneColumn = curgetColumnIndex(PeopleNUMBER) String imagePath do Get the field values name = curgetString(nameColumn) phoneNumber = curgetString(phoneColumn) Do something with the values while (curmoveToNext())

If a query can return binary data such as an image or sound the data may be directly entered in the

table or the table entry for that data may be a string specifying a content URI that you can use to get

the data In general smaller amounts of data (say from 20 to 50K or less) are most often directly

entered in the table and can be read by calling CursorgetBlob() It returns a byte array

If the table entry is a content URI you should never try to open and read the file directly (for one thing

permissions problems can make this fail) Instead you should call ContentResolveropenInputStream()

to get an InputStream object that you can use to read the data

Modifying Data

Data kept by a content provider can be modified by

Adding new records

Adding new values to existing records

Batch updating existing records

Deleting records

All data modification is accomplished using ContentResolver methods Some content providers require

a more restrictive permission for writing data than they do for reading it If you dont have permission to

write to a content provider the ContentResolver methods will fail

Adding records

To add a new record to a content provider first set up a map of key-value pairs in a ContentValues

object where each key matches the name of a column in the content provider and the value is the

desired value for the new record in that column Then call ContentResolverinsert() and pass it the URI

of the provider and the ContentValues map This method returns the full URI of the new record mdash that

is the providers URI with the appended ID for the new record You can then use this URI to query and

get a Cursor over the new record and to further modify the record Heres an example

import androidproviderContactsPeople import androidcontentContentResolver import androidcontentContentValues ContentValues values = new ContentValues() Add Abraham Lincoln to contacts and make him a favorite valuesput(PeopleNAME Abraham Lincoln) 1 = the new contact is added to favorites 0 = the new contact is not added to favorites valuesput(PeopleSTARRED 1) Uri uri = getContentResolver()insert(PeopleCONTENT_URI values)

Adding new values

Once a record exists you can add new information to it or modify existing information For example

the next step in the example above would be to add contact information mdash like a phone number or an

IM or e-mail address mdash to the new entry

The best way to add to a record in the Contacts database is to append the name of the table where the

new data goes to the URI for the record then use the amended URI to add the new data values Each

Contacts table exposes a name for this purpose as a CONTENT_DIRECTORY constant The following

code continues the previous example by adding a phone number and e-mail address for the record

just created

Uri phoneUri = null Uri emailUri = null Add a phone number for Abraham Lincoln Begin with the URI for the new record just returned by insert() it ends with the _ID of the new record so we dont have to add the ID ourselves Then append the designation for the phone table to this URI and use the resulting URI to insert the phone number phoneUri = UriwithAppendedPath(uri PeoplePhonesCONTENT_DIRECTORY) valuesclear() valuesput(PeoplePhonesTYPE PeoplePhonesTYPE_MOBILE) valuesput(PeoplePhonesNUMBER 1233214567) getContentResolver()insert(phoneUri values) Now add an email address in the same way emailUri = UriwithAppendedPath(uri PeopleContactMethodsCONTENT_DIRECTORY) valuesclear() ContactMethodsKIND is used to distinguish different kinds of contact methods such as email IM etc valuesput(PeopleContactMethodsKIND ContactsKIND_EMAIL) valuesput(PeopleContactMethodsDATA testexamplecom) valuesput(PeopleContactMethodsTYPE PeopleContactMethodsTYPE_HOME) getContentResolver()insert(emailUri values)

You can place small amounts of binary data into a table by calling the version of ContentValuesput()

that takes a byte array That would work for a small icon-like image or a short audio clip for example

However if you have a large amount of binary data to add such as a photograph or a complete song

put a content URI for the data in the table and call ContentResolveropenOutputStream() with the files

URI (That causes the content provider to store the data in a file and record the file path in a hidden

field of the record)

In this regard the MediaStore content provider the main provider that dispenses image audio and

video data employs a special convention The same URI that is used with query() or managedQuery()

to get meta-information about the binary data (such as the caption of a photograph or the date it was

taken) is used with openInputStream() to get the data itself Similarly the same URI that is used with

insert() to put meta-information into a MediaStore record is used with openOutputStream() to place the

binary data there The following code snippet illustrates this convention

import androidproviderMediaStoreImagesMedia import androidcontentContentValues import javaioOutputStream Save the name and description of an image in a ContentValues map ContentValues values = new ContentValues(3) valuesput(MediaDISPLAY_NAME road_trip_1) valuesput(MediaDESCRIPTION Day 1 trip to Los Angeles) valuesput(MediaMIME_TYPE imagejpeg) Add a new record without the bitmap but with the values just set insert() returns the URI of the new record Uri uri = getContentResolver()insert(MediaEXTERNAL_CONTENT_URI values) Now get a handle to the file for that record and save the data into it Here sourceBitmap is a Bitmap object representing the file to save to the database try OutputStream outStream = getContentResolver()openOutputStream(uri) sourceBitmapcompress(BitmapCompressFormatJPEG 50 outStream) outStreamclose() catch (Exception e) Loge(TAG exception while writing image e)

Batch updating records

To batch update a group of records (for example to change NY to New York in all fields) call the

ContentResolverupdate() method with the columns and values to change

Deleting a record

To delete a single record call ContentResolverdelete() with the URI of a specific row

To delete multiple rows call ContentResolverdelete() with the URI of the type of record to delete (for

example androidproviderContactsPeopleCONTENT_URI) and an SQL WHERE clause defining

which rows to delete (Caution Be sure to include a valid WHERE clause if youre deleting a general

type or you risk deleting more records than you intended)

Creating a Content Provider

To create a content provider you must

Set up a system for storing the data Most content providers store their data using Androids file

storage methods or SQLite databases but you can store your data any way you want Android

provides the SQLiteOpenHelper class to help you create a database and SQLiteDatabase to manage

it

Extend the ContentProvider class to provide access to the data

Declare the content provider in the manifest file for your application (AndroidManifestxml)

The following sections have notes on the last two of these tasks

Extending the ContentProvider class

You define a ContentProvider subclass to expose your data to others using the conventions expected

by ContentResolver and Cursor objects Principally this means implementing six abstract methods

declared in the ContentProvider class

query()

insert()

update()

delete()

getType()

onCreate()

The query() method must return a Cursor object that can iterate over the requested data Cursor itself

is an interface but Android provides some ready-made Cursor objects that you can use For example

SQLiteCursor can iterate over data stored in an SQLite database You get the Cursor object by calling

any of the SQLiteDatabase classs query() methods There are other Cursor implementations mdash such

as MatrixCursor mdash for data not stored in a database

Because these ContentProvider methods can be called from various ContentResolver objects in

different processes and threads they must be implemented in a thread-safe manner

As a courtesy you might also want to call ContentResolvernotifyChange() to notify listeners when

there are modifications to the data

Beyond defining the subclass itself there are other steps you should take to simplify the work of clients

and make the class more accessible

Define a public static final Uri named CONTENT_URI This is the string that represents the full content

URI that your content provider handles You must define a unique string for this value The best

solution is to use the fully-qualified class name of the content provider (made lowercase) So for

example the URI for a TransportationProvider class could be defined as follows

public static final Uri CONTENT_URI = Uriparse(contentcomexamplecodelabtransportationprovider)

If the provider has subtables also define CONTENT_URI constants for each of the subtables These

URIs should all have the same authority (since that identifies the content provider) and be

distinguished only by their paths For example

contentcomexamplecodelabtransportationprovidertrain

contentcomexamplecodelabtransportationproviderairdomestic

contentcomexamplecodelabtransportationproviderairinternational

For an overview of content URIs see the Content URI Summary at the end of this document

Define the column names that the content provider will return to clients If you are using an underlying

database these column names are typically identical to the SQL database column names they

represent Also define public static String constants that clients can use to specify the columns in

queries and other instructions

Be sure to include an integer column named _id (with the constant _ID) for the IDs of the records

You should have this field whether or not you have another field (such as a URL) that is also unique

among all records If youre using the SQLite database the _ID field should be the following type

INTEGER PRIMARY KEY AUTOINCREMENT

The AUTOINCREMENT descriptor is optional But without it SQLite increments an ID counter field to

the next number above the largest existing number in the column If you delete the last row the next

row added will have the same ID as the deleted row AUTOINCREMENT avoids this by having SQLite

increment to the next largest value whether deleted or not

Carefully document the data type of each column Clients need this information to read the data

If you are handling a new data type you must define a new MIME type to return in your

implementation of ContentProvidergetType() The type depends in part on whether or not the content

URI submitted to getType() limits the request to a specific record Theres one form of the MIME type

for a single record and another for multiple records Use the Uri methods to help determine what is

being requested Here is the general format for each type

o For a single record vndandroidcursoritemvndyourcompanynamecontenttype

For example a request for train record 122 like this URI

contentcomexampletransportationprovidertrains122

might return this MIME type

vndandroidcursoritemvndexamplerail

o For multiple records vndandroidcursordirvndyourcompanynamecontenttype

For example a request for all train records like the following URI

contentcomexampletransportationprovidertrains

might return this MIME type

vndandroidcursordirvndexamplerail

If you are exposing byte data thats too big to put in the table itself mdash such as a large bitmap file mdash the

field that exposes the data to clients should actually contain a content URI string This is the field that

gives clients access to the data file The record should also have another field named _data that lists

the exact file path on the device for that file This field is not intended to be read by the client but by

the ContentResolver The client will call ContentResolveropenInputStream() on the user-facing field

holding the URI for the item The ContentResolver will request the _data field for that record and

because it has higher permissions than a client it should be able to access that file directly and return

a read wrapper for the file to the client

For an example of a private content provider implementation see the NodePadProvider class in the

Notepad sample application that ships with the SDK

Declaring the content provider

To let the Android system know about the content provider youve developed declare it with a

ltprovidergt element in the applications AndroidManifestxml file Content providers that are not

declared in the manifest are not visible to the Android system

The name attribute is the fully qualified name of the ContentProvider subclass The authorities attribute

is the authority part of the content URI that identifies the provider For example if the ContentProvider

subclass is AutoInfoProvider the ltprovidergt element might look like this

ltprovider androidname=comexampleautosAutoInfoProvider androidauthorities=comexampleautosautoinfoprovider gt ltprovidergt

Note that the authorities attribute omits the path part of a content URI For example if

AutoInfoProvider controlled subtables for different types of autos or different manufacturers

contentcomexampleautosautoinfoproviderhonda

contentcomexampleautosautoinfoprovidergmcompact

contentcomexampleautosautoinfoprovidergmsuv

those paths would not be declared in the manifest The authority is what identifies the provider not the

path your provider can interpret the path part of the URI in any way you choose

Other ltprovidergt attributes can set permissions to read and write data provide for an icon and text

that can be displayed to users enable and disable the provider and so on Set the multiprocess

attribute to true if data does not need to be synchronized between multiple running versions of the

content provider This permits an instance of the provider to be created in each client process

eliminating the need to perform IPC

Content URI Summary

Here is a recap of the important parts of a content URI

A Standard prefix indicating that the data is controlled by a content provider Its never modified

B The authority part of the URI it identifies the content provider For third-party applications this should

be a fully-qualified class name (reduced to lowercase) to ensure uniqueness The authority is declared

in the ltprovidergt elements authorities attribute

ltprovider androidname=TransportationProvider androidauthorities=comexampletransportationprovider gt

C The path that the content provider uses to determine what kind of data is being requested This can be

zero or more segments long If the content provider exposes only one type of data (only trains for

example) it can be absent If the provider exposes several types including subtypes it can be several

segments long mdash for example landbus landtrain seaship and seasubmarine to give four

possibilities

D The ID of the specific record being requested if any This is the _ID value of the requested record If

the request is not limited to a single record this segment and the trailing slash are omitted

contentcomexampletransportationprovidertrains

Intent and intent filters

Three of the core components of an application mdash activities services and broadcast receivers mdash 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 mdash 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 ContextstartActivity() or ActivitystartActivityForResult() to launch an

activity or get an existing activity to do something new (It can also be passed to ActivitysetResult() to

return information to the activity that called startActivityForResult())

An Intent object is passed to ContextstartService() to initiate a service or deliver new instructions to an

ongoing service Similarly an intent can be passed to ContextbindService() to establish a connection

between the calling component and a target service It can optionally initiate the service if its not

already running

Intent objects passed to any of the broadcast methods (such as ContextsendBroadcast()

ContextsendOrderedBroadcast() or ContextsendStickyBroadcast()) 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 mdash how it resolves which component should receive an intent message For

intents that dont explicitly name a target component this process involves testing the Intent object

against intent filters associated with potential targets

Intent Objects

An Intent object is a bundle of information It contains information of interest to the component that

receives the intent (such as the action to be taken and the data to act on) plus information of interest to

the Android system (such as the category of component that should handle the intent and instructions

on how to launch a target activity) Principally it can contain the following

Component name

The name of the component that should handle the intent This field is a ComponentName

object mdash a combination of the fully qualified class name of the target component (for example

comexampleprojectappFreneticActivity) and the package name set in the manifest file of the

application where the component resides (for example comexampleproject) The package

part of the component name and the package name set in the manifest do not necessarily have

to match

The component name is optional If it is set the Intent object is delivered to an instance of the

designated class If it is not set Android uses other information in the Intent object to locate a

suitable target mdash see Intent Resolution later in this document

The component name is set by setComponent() setClass() or setClassName() and read by

getComponent()

Action

A string naming the action to be performed mdash or in the case of broadcast intents the action

that took place and is being reported The Intent class defines a number of action constants

including these

Constant Target

component

Action

ACTION_CALL activity Initiate a phone call

ACTION_EDIT activity Display data for the user to edit

ACTION_MAIN activity Start up as the initial activity of a task

with no data input and no returned

output

ACTION_SYNC activity Synchronize data on a server with

data on the mobile device

ACTION_BATTERY_LOW broadcast

receiver

A warning that the battery is low

ACTION_HEADSET_PLUG broadcast

receiver

A headset has been plugged into the

device or unplugged from it

ACTION_SCREEN_ON broadcast

receiver

The screen has been turned on

ACTION_TIMEZONE_CHANGED broadcast

receiver

The setting for the time zone has

changed

See the Intent class description for a list of pre-defined constants for generic actions Other

actions are defined elsewhere in the Android API You can also define your own action strings

for activating the components in your application Those you invent should include the

application package as a prefix mdash for example comexampleprojectSHOW_COLOR

The action largely determines how the rest of the intent is structured mdash particularly the data and

extras fields mdash much as a method name determines a set of arguments and a return value For

this reason its a good idea to use action names that are as specific as possible and to couple

them tightly to the other fields of the intent In other words instead of defining an action in

isolation define an entire protocol for the Intent objects your components can handle

The action in an Intent object is set by the setAction() method and read by getAction()

Data

The URI of the data to be acted on and the MIME type of that data Different actions are paired

with different kinds of data specifications For example if the action field is ACTION_EDIT the

data field would contain the URI of the document to be displayed for editing If the action is

ACTION_CALL the data field would be a tel URI with the number to call Similarly if the action

is ACTION_VIEW and the data field is an http URI the receiving activity would be called upon

to download and display whatever data the URI refers to

When matching an intent to a component that is capable of handling the data its often

important to know the type of data (its MIME type) in addition to its URI For example a

component able to display image data should not be called upon to play an audio file

In many cases the data type can be inferred from the URI mdash particularly content URIs which

indicate that the data is located on the device and controlled by a content provider (see the

separate discussion on content providers) But the type can also be explicitly set in the Intent

object The setData() method specifies data only as a URI setType() specifies it only as a

MIME type and setDataAndType() specifies it as both a URI and a MIME type The URI is read

by getData() and the type by getType()

Category

A string containing additional information about the kind of component that should handle the

intent Any number of category descriptions can be placed in an Intent object As it does for

actions the Intent class defines several category constants including these

Constant Meaning

CATEGORY_BROWSABLE The target activity can be safely invoked by the browser to

display data referenced by a link mdash for example an image or

an e-mail message

CATEGORY_GADGET The activity can be embedded inside of another activity that

hosts gadgets

CATEGORY_HOME The activity displays the home screen the first screen the

user sees when the device is turned on or when the HOME

key is pressed

CATEGORY_LAUNCHER The activity can be the initial activity of a task and is listed in

the top-level application launcher

CATEGORY_PREFERENCE The target activity is a preference panel

See the Intent class description for the full list of categories

The addCategory() method places a category in an Intent object removeCategory() deletes a

category previously added and getCategories() gets the set of all categories currently in the

object

Extras

Key-value pairs for additional information that should be delivered to the component handling

the intent Just as some actions are paired with particular kinds of data URIs some are paired

with particular extras For example an ACTION_TIMEZONE_CHANGED intent has a time-

zone extra that identifies the new time zone and ACTION_HEADSET_PLUG has a state

extra indicating whether the headset is now plugged in or unplugged as well as a name extra

for the type of headset If you were to invent a SHOW_COLOR action the color value would be

set in an extra key-value pair

The Intent object has a series of put() methods for inserting various types of extra data and a

similar set of get() methods for reading the data These methods parallel those for Bundle

objects In fact the extras can be installed and read as a Bundle using the putExtras() and

getExtras() methods

Flags

Flags of various sorts Many instruct the Android system how to launch an activity (for example

which task the activity should belong to) and how to treat it after its launched (for example

whether it belongs in the list of recent activities) All these flags are defined in the Intent class

The Android system and the applications that come with the platform employ Intent objects both to

send out system-originated broadcasts and to activate system-defined components To see how to

structure an intent to activate a system component consult the list of intents in the reference

Intent Resolution

Intents can be divided into two groups

Explicit intents designate the target component by its name (the component name field mentioned

earlier has a value set) Since component names would generally not be known to developers of other

applications explicit intents are typically used for application-internal messages mdash such as an activity

starting a subordinate service or launching a sister activity

Implicit intents do not name a target (the field for the component name is blank) Implicit intents are

often used to activate components in other applications

Android delivers an explicit intent to an instance of the designated target class Nothing in the Intent

object other than the component name matters for determining which component should get the intent

A different strategy is needed for implicit intents In the absence of a designated target the Android

system must find the best component (or components) to handle the intent mdash a single activity or

service to perform the requested action or the set of broadcast receivers to respond to the broadcast

announcement It does so by comparing the contents of the Intent object to intent filters structures

associated with components that can potentially receive intents Filters advertise the capabilities of a

component and delimit the intents it can handle They open the component to the possibility of

receiving implicit intents of the advertised type If a component does not have any intent filters it can

receive only explicit intents A component with filters can receive both explicit and implicit intents

Only three aspects of an Intent object are consulted when the object is tested against an intent filter

action

data (both URI and data type)

category

The extras and flags play no part in resolving which component receives an intent

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 mdash but only unwanted implicit intents (those that dont 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

components 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 mdash 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 Pads filters are described in the Note Pad Example

section later)

Filters and security

An intent filter cannot be relied on for security While it opens a component to receiving only certain

kinds of implicit intents it does nothing to prevent explicit intents from targeting the component Even

though a filter restricts the intents a component will be asked to handle to certain actions and data

sources someone could always put together an explicit intent with a different action and data source

and name the component as the target

An intent filter is an instance of the IntentFilter class However since the Android system must know

about the capabilities of a component before it can launch that component intent filters are generally

not set up in Java code but in the applications manifest file (AndroidManifestxml) as ltintent-filtergt

elements (The one exception would be filters for broadcast receivers that are registered dynamically

by calling ContextregisterReceiver() they are directly created as IntentFilter objects)

A filter has fields that parallel the action data and category fields of an Intent object An implicit intent

is tested against the filter in all three areas To be delivered to the component that owns the filter it

must pass all three tests If it fails even one of them the Android system wont deliver it to the

component mdash at least not on the basis of that filter However since a component can have multiple

intent filters an intent that does not pass through one of a components filters might make it through on

another

Each of the three tests is described in detail below

Action test

An ltintent-filtergt element in the manifest file lists actions as ltactiongt subelements For

example

ltintent-filter gt ltaction androidname=comexampleprojectSHOW_CURRENT gt ltaction androidname=comexampleprojectSHOW_RECENT gt ltaction androidname=comexampleprojectSHOW_PENDING gt ltintent-filtergt

As the example shows while an Intent object names just a single action a filter may list more

than one The list cannot be empty a filter must contain at least one ltactiongt element or it will

block all intents

To pass this test the action specified in the Intent object must match one of the actions listed in

the filter If the object or the filter does not specify an action the results are as follows

If the filter fails to list any actions there is nothing for an intent to match so all intents fail the

test No intents can get through the filter

On the other hand an Intent object that doesnt specify an action automatically passes the test

mdash as long as the filter contains at least one action

Category test

An ltintent-filtergt element also lists categories as subelements For example

ltintent-filter gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryBROWSABLE gt ltintent-filtergt

Note that the constants described earlier for actions and categories are not used in the manifest

file The full string values are used instead For instance the

androidintentcategoryBROWSABLE string in the example above corresponds to the

CATEGORY_BROWSABLE constant mentioned earlier in this document Similarly the string

androidintentactionEDIT corresponds to the ACTION_EDIT constant

For an intent to pass the category test every category in the Intent object must match a

category in the filter The filter can list additional categories but it cannot omit any that are in the

intent

In principle therefore an Intent object with no categories should always pass this test

regardless of whats in the filter Thats mostly true However with one exception Android treats

all implicit intents passed to startActivity() as if they contained at least one category

androidintentcategoryDEFAULT (the CATEGORY_DEFAULT constant) Therefore activities

that are willing to receive implicit intents must include androidintentcategoryDEFAULT in

their intent filters (Filters with androidintentactionMAIN and

androidintentcategoryLAUNCHER settings are the exception They mark activities that begin

new tasks and that are represented on the launcher screen They can include

androidintentcategoryDEFAULT in the list of categories but dont need to) See Using intent

matching later for more on these filters)

Data test

Like the action and categories the data specification for an intent filter is contained in a

subelement And as in those cases the subelement can appear multiple times or not at all For

example

ltintent-filter gt ltdata androidmimeType=videompeg androidscheme=http gt ltdata androidmimeType=audiompeg androidscheme=http gt ltintent-filtergt

Each ltdatagt element can specify a URI and a data type (MIME media type) There are

separate attributes mdash scheme host port and path mdash for each part of the URI

schemehostportpath

For example in the following URI

contentcomexampleproject200foldersubfolderetc

the scheme is content the host is comexampleproject the port is 200 and the path is

foldersubfolderetc The host and port together constitute the URI authority if a host is not

specified the port is ignored

Each of these attributes is optional but they are not independent of each other For an authority

to be meaningful a scheme must also be specified For a path to be meaningful both a scheme

and an authority must be specified

When the URI in an Intent object is compared to a URI specification in a filter its compared

only to the parts of the URI actually mentioned in the filter For example if a filter specifies only

a scheme all URIs with that scheme match the filter If a filter specifies a scheme and an

authority but no path all URIs with the same scheme and authority match regardless of their

paths If a filter specifies a scheme an authority and a path only URIs with the same scheme

authority and path match However a path specification in the filter can contain wildcards to

require only a partial match of the path

The type attribute of a ltdatagt element specifies the MIME type of the data Its more common in

filters than a URI Both the Intent object and the filter can use a wildcard for the subtype field

mdash for example text or audio mdash indicating any subtype matches

The data test compares both the URI and the data type in the Intent object to a URI and data

type specified in the filter The rules are as follows

a An Intent object that contains neither a URI nor a data type passes the test only if the filter

likewise does not specify any URIs or data types

b An Intent object that contains a URI but no data type (and a type cannot be inferred from the

URI) passes the test only if its URI matches a URI in the filter and the filter likewise does not

specify a type This will be the case only for URIs like mailto and tel that do not refer to actual

data

c An Intent object that contains a data type but not a URI passes the test only if the filter lists the

same data type and similarly does not specify a URI

d An Intent object that contains both a URI and a data type (or a data type can be inferred from

the URI) passes the data type part of the test only if its type matches a type listed in the filter It

passes the URI part of the test either if its URI matches a URI in the filter or if it has a content

or file URI and the filter does not specify a URI In other words a component is presumed to

support content and file data if its filter lists only a data type

If an intent can pass through the filters of more than one activity or service the user may be asked

which component to activate An exception is raised if no target can be found

Common cases

The last rule shown above for the data test rule (d) reflects the expectation that components are able

to get local data from a file or content provider Therefore their filters can list just a data type and do

not need to explicitly name the content and file schemes This is a typical case A ltdatagt element like

the following for example tells Android that the component can get image data from a content

provider and display it

ltdata androidmimeType=image gt

Since most available data is dispensed by content providers filters that specify a data type but not a

URI are perhaps the most common

Another common configuration is filters with a scheme and a data type For example a ltdatagt

element like the following tells Android that the component can get video data from the network and

display it

ltdata androidscheme=http androidtype=video gt

Consider for example what the browser application does when the user follows a link on a web page

It first tries to display the data (as it could if the link was to an HTML page) If it cant display the data it

puts together an implicit intent with the scheme and data type and tries to start an activity that can do

the job If there are no takers it asks the download manager to download the data That puts it under

the control of a content provider so a potentially larger pool of activities (those with filters that just

name a data type) can respond

Most applications also have a way to start fresh without a reference to any particular data Activities

that can initiate applications have filters with androidintentactionMAIN specified as the action If

they are to be represented in the application launcher they also specify the

androidintentcategoryLAUNCHER category

ltintent-filter gt ltaction androidname=code androidintentactionMAIN gt ltcategory androidname=code androidintentcategoryLAUNCHER gt ltintent-filtergt

Using intent matching

Intents are matched against intent filters not only to discover a target component to activate but also

to discover something about the set of components on the device For example the Android system

populates the application launcher the top-level screen that shows the applications that are available

for the user to launch by finding all the activities with intent filters that specify the

androidintentactionMAIN action and androidintentcategoryLAUNCHER category (as illustrated

in the previous section) It then displays the icons and labels of those activities in the launcher

Similarly it discovers the home screen by looking for the activity with androidintentcategoryHOME

in its filter

Your application can use intent matching is a similar way The PackageManager has a set of query()

methods that return all components that can accept a particular intent and a similar series of

resolve() methods that determine the best component to respond to an intent For example

queryIntentActivities() returns a list of all activities that can perform the intent passed as an argument

and queryIntentServices() returns a similar list of services Neither method activates the components

they just list the ones that can respond Theres a similar method queryBroadcastReceivers() for

broadcast receivers

Note Pad Example

The Note Pad sample application enables users to browse through a list of notes view details about

individual items in the list edit the items and add a new item to the list This section looks at the intent

filters declared in its manifest file (If youre working offline in the SDK you can find all the source files

for this sample application including its manifest file at ltsdkgtsamplesNotePadindexhtml If youre

viewing the documentation online the source files are in the Tutorials and Sample Code section here)

In its manifest file the Note Pad application declares three activities each with at least one intent filter

It also declares a content provider that manages the note data Here is the manifest file in its entirety

ltmanifest xmlnsandroid=httpschemasandroidcomapkresandroid package=comexampleandroidnotepadgt ltapplication androidicon=drawableapp_notes androidlabel=stringapp_name gt ltprovider androidname=NotePadProvider androidauthorities=comgoogleproviderNotePad gt ltactivity androidname=NotesList androidlabel=stringtitle_notes_listgt ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltactivity androidname=NoteEditor androidtheme=androidstyleThemeLight androidlabel=stringtitle_note gt ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltactivitygt

ltactivity androidname=TitleEditor androidlabel=stringtitle_edit_title androidtheme=androidstyleThemeDialoggt ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltapplicationgt ltmanifestgt

The first activity NotesList is distinguished from the other activities by the fact that it operates on a

directory of notes (the note list) rather than on a single note It would generally serve as the initial user

interface into the application It can do three things as described by its three intent filters

1 ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt

This filter declares the main entry point into the Note Pad application The standard MAIN action is an

entry point that does not require any other information in the Intent (no data specification for example)

and the LAUNCHER category says that this entry point should be listed in the application launcher

2 ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

This filter declares the things that the activity can do on a directory of notes It can allow the user to

view or edit the directory (via the VIEW and EDIT actions) or to pick a particular note from the

directory (via the PICK action)

The mimeType attribute of the ltdatagt element specifies the kind of data that these actions operate on

It indicates that the activity can get a Cursor over zero or more items (vndandroidcursordir) from a

content provider that holds Note Pad data (vndgooglenote) The Intent object that launches the

activity would include a content URI specifying the exact data of this type that the activity should open

Note also the DEFAULT category supplied in this filter Its there because the ContextstartActivity()

and ActivitystartActivityForResult() methods treat all intents as if they contained the DEFAULT

category mdash with just two exceptions

o Intents that explicitly name the target activity

o Intents consisting of the MAIN action and LAUNCHER category

Therefore the DEFAULT category is required for all filters mdash except for those with the MAIN action

and LAUNCHER category (Intent filters are not consulted for explicit intents)

3 ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

This filter describes the activitys ability to return a note selected by the user without requiring any

specification of the directory the user should choose from The GET_CONTENT action is similar to the

PICK action In both cases the activity returns the URI for a note selected by the user (In each case

its returned to the activity that called startActivityForResult() to start the NoteList activity) Here

however the caller specifies the type of data desired instead of the directory of data the user will be

picking from

The data type vndandroidcursoritemvndgooglenote indicates the type of data the activity can

return mdash a URI for a single note From the returned URI the caller can get a Cursor for exactly one

item (vndandroidcursoritem) from the content provider that holds Note Pad data (vndgooglenote)

In other words for the PICK action in the previous filter the data type indicates the type of data the

activity could display to the user For the GET_CONTENT filter it indicates the type of data the activity

can return to the caller

Given these capabilities the following intents will resolve to the NotesList activity

action androidintentactionMAIN

Launches the activity with no data specified

action androidintentactionMAIN

category androidintentcategoryLAUNCHER

Launches the activity with no data selected specified This is the actual intent used by the

Launcher to populate its top-level list All activities with filters that match this action and

category are added to the list

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of all the notes under

contentcomgoogleproviderNotePadnotes The user can then browse through the list and

get information about the items in it

action androidintentactionPICK

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of the notes under

contentcomgoogleproviderNotePadnotes The user can then pick a note from the list and

the activity will return the URI for that item back to the activity that started the NoteList activity

action androidintentactionGET_CONTENT

data type vndandroidcursoritemvndgooglenote

Asks the activity to supply a single item of Note Pad data

The second activity NoteEditor shows users a single note entry and allows them to edit it It can do

two things as described by its two intent filters

1 ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The first primary purpose of this activity is to enable the user to interact with a single note ampmdash to

either VIEW the note or EDIT it (The EDIT_NOTE category is a synonym for EDIT) The intent would

contain the URI for data matching the MIME type vndandroidcursoritemvndgooglenote mdash that is

the URI for a single specific note It would typically be a URI that was returned by the PICK or

GET_CONTENT actions of the NoteList activity

As before this filter lists the DEFAULT category so that the activity can be launched by intents that

dont explicitly specify the NoteEditor class

2 ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

The secondary purpose of this activity is to enable the user to create a new note which it will INSERT

into an existing directory of notes The intent would contain the URI for data matching the MIME type

vndandroidcursordirvndgooglenote mdash that is the URI for the directory where the note should be

placed

Given these capabilities the following intents will resolve to the NoteEditor activity

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID (For details on how content

URIs specify individual members of a group see Content Providers)

action androidintentactionEDIT

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID and to let the user edit it If

the user saves the changes the activity updates the data for the note in the content provider

action androidintentactionINSERT

data contentcomgoogleproviderNotePadnotes

Asks the activity to create a new empty note in the notes list at

contentcomgoogleproviderNotePadnotes and allow the user to edit it If the user saves the

note its URI is returned to the caller

The last activity TitleEditor enables the user to edit the title of a note This could be implemented by

directly invoking the activity (by explicitly setting its component name in the Intent) without using an

intent filter But here we take the opportunity to show how to publish alternative operations on existing

data

ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The single intent filter for this activity uses a custom action called

comandroidnotepadactionEDIT_TITLE It must be invoked on a specific note (data type

vndandroidcursoritemvndgooglenote) like the previous VIEW and EDIT actions However here the

activity displays the title contained in the note data not the content of the note itself

In addition to supporting the usual DEFAULT category the title editor also supports two other standard

categories ALTERNATIVE and SELECTED_ALTERNATIVE These categories identify activities that

can be presented to users in a menu of options (much as the LAUNCHER category identifies activities

that should be presented to user in the application launcher) Note that the filter also supplies an

explicit label (via androidlabel=stringresolve_title) to better control what users see when

presented with this activity as an alternative action to the data they are currently viewing (For more

information on these categories and building options menus see the

PackageManagerqueryIntentActivityOptions() and MenuaddIntentOptions() methods)

Given these capabilities the following intent will resolve to the TitleEditor activity

action comandroidnotepadactionEDIT_TITLE

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the title associated with note ID and allow the user to edit the title

Processes and Threads

When an application component starts and the application does not have any other components

running the Android system starts a new Linux process for the application with a single thread of

execution By default all components of the same application run in the same process and thread

(called the main thread) If an application component starts and there already exists a process for

that application (because another component from the application exists) then the component is

started within that process and uses the same thread of execution However you can arrange for

different components in your application to run in separate processes and you can create additional

threads for any process

This document discusses how processes and threads work in an Android application

Processes

By default all components of the same application run in the same process and most applications

should not change this However if you find that you need to control which process a certain

component belongs to you can do so in the manifest file

The manifest entry for each type of component elementmdashltactivitygt ltservicegt ltreceivergt and

ltprovidergtmdashsupports an androidprocess attribute that can specify a process in which that component

should run You can set this attribute so that each component runs in its own process or so that some

components share a process while others do not You can also set androidprocess so that

components of different applications run in the same processmdashprovided that the applications share the

same Linux user ID and are signed with the same certificates

The ltapplicationgt element also supports an androidprocess attribute to set a default value that

applies to all components

Android might 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 thats killed are consequently destroyed A process is started again for those components

when theres again work for them to do

When deciding which processes to kill the Android system weighs their relative importance to the

user For example it more readily shuts down a process hosting activities that are no longer visible on

screen compared to a process hosting visible activities The decision whether to terminate a process

therefore depends on the state of the components running in that process The rules used to decide

which processes to terminate is discussed below

Process lifecycle

The Android system tries to maintain an application process for as long as possible but eventually

needs to remove old processes to reclaim memory for new or more important processes To determine

which processes to keep and which to kill the system places each process into an importance

hierarchy based on the components running in the process and the state of those components

Processes with the lowest importance are eliminated first then those with the next lowest importance

and so on as necessary to recover system resources

There are five levels in the importance hierarchy The following list presents the different types of

processes in order of importance (the first process is most important and is killed last)

1 Foreground process

A process that is required for what the user is currently doing A process is considered to be in the

foreground if any of the following conditions are true

o It hosts an Activity that the user is interacting with (the Activitys onResume() method has been called)

o It hosts a Service thats bound to the activity that the user is interacting with

o It hosts a Service thats running in the foregroundmdashthe service has called startForeground()

o It hosts a Service thats executing one of its lifecycle callbacks (onCreate() onStart() or onDestroy())

o It hosts a BroadcastReceiver thats executing its onReceive() method

Generally only a few foreground processes exist at any given time They are killed only as a last

resortmdashif memory is so low that they cannot all continue to run Generally at that point the device has

reached a memory paging state so killing some foreground processes is required to keep the user

interface responsive

2 Visible process

A process that doesnt have any foreground components but still can affect what the user sees on

screen A process is considered to be visible if either of the following conditions are true

o It hosts an Activity that is not in the foreground but is still visible to the user (its onPause() method has

been called) This might occur for example if the foreground activity started a dialog which allows the

previous activity to be seen behind it

o It hosts a Service thats bound to a visible (or foreground) activity

A visible process is considered extremely important and will not be killed unless doing so is required to

keep all foreground processes running

3 Service process

A process that is running a service that has been started with the startService() method and does not

fall into either of the two higher categories Although service processes are not directly tied to anything

the user sees they are generally doing things that the user cares about (such as playing music in the

background or downloading data on the network) so the system keeps them running unless theres

not enough memory to retain them along with all foreground and visible processes

4 Background process

A process holding an activity thats not currently visible to the user (the activitys onStop() method has

been called) These processes have no direct impact on the user experience and the system can kill

them at any time to reclaim memory for a foreground visible or service process Usually there are

many background processes running so they are kept in an LRU (least recently used) list to ensure

that the process with the activity that was most recently seen by the user is the last to be killed If an

activity implements its lifecycle methods correctly and saves its current state killing its process will not

have a visible effect on the user experience because when the user navigates back to the activity the

activity restores all of its visible state See the Activities document for information about saving and

restoring state

5 Empty process

A process that doesnt hold any active application components The only reason to keep this kind of

process alive is for caching purposes to improve startup time the next time a component needs to run

in it The system often kills these processes in order to balance overall system resources between

process caches and the underlying kernel caches

Android ranks a process at the highest level it can based upon the importance of the components

currently active in the process For example if a process hosts a service and a visible activity the

process is ranked as a visible process not a service process

In addition a processs ranking might be increased because other processes are dependent on itmdasha

process that is serving another process can never be ranked lower than the process it is serving For

example if a content provider in process A is serving a client in process B or if a service in process A

is bound to a component in process B process A is always considered at least as important as

process B

Because a process running a service is ranked higher than a process with background activities an

activity that initiates a long-running operation might do well to start a service for that operation rather

than simply create a worker threadmdashparticularly if the operation will likely outlast the activity For

example an activity thats uploading a picture to a web site should start a service to perform the

upload so that the upload can continue in the background even if the user leaves the activity Using a

service guarantees that the operation will have at least service process priority regardless of what

happens to the activity This is the same reason that broadcast receivers should employ services

rather than simply put time-consuming operations in a thread

Threads

When an application is launched the system creates a thread of execution for the application called

main This thread is very important because it is in charge of dispatching events to the appropriate

user interface widgets including drawing events It is also the thread in which your application interacts

with components from the Android UI toolkit (components from the androidwidget and androidview

packages) As such the main thread is also sometimes called the UI thread

The system does not create a separate thread for each instance of a component All components that

run in the same process are instantiated in the UI thread and system calls to each component are

dispatched from that thread Consequently methods that respond to system callbacks (such as

onKeyDown() to report user actions or a lifecycle callback method) always run in the UI thread of the

process

For instance when the user touches a button on the screen your apps UI thread dispatches the touch

event to the widget which in turn sets its pressed state and posts an invalidate request to the event

queue The UI thread dequeues the request and notifies the widget that it should redraw itself

When your app performs intensive work in response to user interaction this single thread model can

yield poor performance unless you implement your application properly Specifically if everything is

happening in the UI thread performing long operations such as network access or database queries

will block the whole UI When the thread is blocked no events can be dispatched including drawing

events From the users perspective the application appears to hang Even worse if the UI thread is

blocked for more than a few seconds (about 5 seconds currently) the user is presented with the

infamous application not responding (ANR) dialog The user might then decide to quit your

application and uninstall it if they are unhappy

Additionally the Andoid UI toolkit is not thread-safe So you must not manipulate your UI from a

worker threadmdashyou must do all manipulation to your user interface from the UI thread Thus there are

simply two rules to Androids single thread model

1 Do not block the UI thread

2 Do not access the Android UI toolkit from outside the UI thread

Worker threads

Because of the single thread model described above its vital to the responsiveness of your

applications UI that you do not block the UI thread If you have operations to perform that are not

instantaneous you should make sure to do them in separate threads (background or worker

threads)

For example below is some code for a click listener that downloads an image from a separate thread

and displays it in an ImageView

public void onClick(View v) new Thread(new Runnable() public void run() Bitmap b = loadImageFromNetwork(httpexamplecomimagepng) mImageViewsetImageBitmap(b) )start()

At first this seems to work fine because it creates a new thread to handle the network operation

However it violates the second rule of the single-threaded model do not access the Android UI toolkit

from outside the UI threadmdashthis sample modifies the ImageView from the worker thread instead of the

UI thread This can result in undefined and unexpected behavior which can be difficult and time-

consuming to track down

To fix this problem Android offers several ways to access the UI thread from other threads Here is a

list of methods that can help

ActivityrunOnUiThread(Runnable)

Viewpost(Runnable)

ViewpostDelayed(Runnable long)

For example you can fix the above code by using the Viewpost(Runnable) method

public void onClick(View v) new Thread(new Runnable() public void run() final Bitmap bitmap = loadImageFromNetwork(httpexamplecomimagepng) mImageViewpost(new Runnable() public void run() mImageViewsetImageBitmap(bitmap) ) )start()

Now this implementation is thread-safe the network operation is done from a separate thread while

the ImageView is manipulated from the UI thread

However as the complexity of the operation grows this kind of code can get complicated and difficult

to maintain To handle more complex interactions with a worker thread you might consider using a

Handler in your worker thread to process messages delivered from the UI thread Perhaps the best

solution though is to extend the AsyncTask class which simplifies the execution of worker thread

tasks that need to interact with the UI

Using AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface It performs the blocking

operations in a worker thread and then publishes the results on the UI thread without requiring you to

handle threads andor handlers yourself

To use it you must subclass AsyncTask and implement the doInBackground() callback method which

runs in a pool of background threads To update your UI you should implement onPostExecute()

which delivers the result from doInBackground() and runs in the UI thread so you can safely update

your UI You can then run the task by calling execute() from the UI thread

For example you can implement the previous example using AsyncTask this way

public void onClick(View v) new DownloadImageTask()execute(httpexamplecomimagepng) private class DownloadImageTask extends AsyncTaskltString Void Bitmapgt The system calls this to perform work in a worker thread and delivers it the parameters given to AsyncTaskexecute() protected Bitmap doInBackground(String urls) return loadImageFromNetwork(urls[0])

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 16: 03 services

When the last client unbinds from the service the system destroys the service (unless the service was

also started by startService())

When you implement your bound service the most important part is defining the interface that your

onBind() callback method returns There are a few different ways you can define your services IBinder

interface and the following section discusses each technique

Creating a Bound Service

When creating a service that provides binding you must provide an IBinder that provides the

programming interface that clients can use to interact with the service There are three ways you can

define the interface

Extending the Binder class

If your service is private to your own application and runs in the same process as the client

(which is common) you should create your interface by extending the Binder class and

returning an instance of it from onBind() The client receives the Binder and can use it to directly

access public methods available in either the Binder implementation or even the Service

This is the preferred technique when your service is merely a background worker for your own

application The only reason you would not create your interface this way is because your

service is used by other applications or across separate processes

Using a Messenger

If you need your interface to work across different processes you can create an interface for the

service with a Messenger In this manner the service defines a Handler that responds to

different types of Message objects This Handler is the basis for a Messenger that can then

share an IBinder with the client allowing the client to send commands to the service using

Message objects Additionally the client can define a Messenger of its own so the service can

send messages back

This is the simplest way to perform interprocess communication (IPC) because the Messenger

queues all requests into a single thread so that you dont have to design your service to be

thread-safe

Using AIDL

AIDL (Android Interface Definition Language) performs all the work to decompose objects into

primitives that the operating system can understand and marshall them across processes to

perform IPC The previous technique using a Messenger is actually based on AIDL as its

underlying structure As mentioned above the Messenger creates a queue of all the client

requests in a single thread so the service receives requests one at a time If however you

want your service to handle multiple requests simultaneously then you can use AIDL directly In

this case your service must be capable of multi-threading and be built thread-safe

To use AIDL directly you must create an aidl file that defines the programming interface The

Android SDK tools use this file to generate an abstract class that implements the interface and

handles IPC which you can then extend within your service

Note Most applications should not use AIDL to create a bound service because it may require

multithreading capabilities and can result in a more complicated implementation As such AIDL is

not suitable for most applications and this document does not discuss how to use it for your

service If youre certain that you need to use AIDL directly see the AIDL document

Extending the Binder class

If your service is used only by the local application and does not need to work across processes then

you can implement your own Binder class that provides your client direct access to public methods in

the service

Note This works only if the client and service are in the same application and process which is

most common For example this would work well for a music application that needs to bind an

activity to its own service thats playing music in the background

Heres how to set it up

1 In your service create an instance of Binder that either

o contains public methods that the client can call

o returns the current Service instance which has public methods the client can call

o or returns an instance of another class hosted by the service with public methods the client can call

2 Return this instance of Binder from the onBind() callback method

3 In the client receive the Binder from the onServiceConnected() callback method and make calls to the

bound service using the methods provided

Note The reason the service and client must be in the same application is so the client can cast

the returned object and properly call its APIs The service and client must also be in the same

process because this technique does not perform any marshalling across processes

For example heres a service that provides clients access to methods in the service through a Binder

implementation

public class LocalService extends Service

Binder given to clients

private final IBinder mBinder = new LocalBinder()

Random number generator

private final Random mGenerator = new Random()

Class used for the client Binder Because we know this service always

runs in the same process as its clients we dont need to deal with IPC

public class LocalBinder extends Binder

LocalService getService()

Return this instance of LocalService so clients can call public methods

return LocalServicethis

Override

public IBinder onBind(Intent intent)

return mBinder

method for clients

public int getRandomNumber()

return mGeneratornextInt(100)

The LocalBinder provides the getService() method for clients to retrieve the current instance of

LocalService This allows clients to call public methods in the service For example clients can call

getRandomNumber() from the service

Heres an activity that binds to LocalService and calls getRandomNumber() when a button is clicked

public class BindingActivity extends Activity

LocalService mService

boolean mBound = false

Override

protected void onCreate(Bundle savedInstanceState)

superonCreate(savedInstanceState)

setContentView(Rlayoutmain)

Override

protected void onStart()

superonStart()

Bind to LocalService

Intent intent = new Intent(this LocalServiceclass)

bindService(intent mConnection ContextBIND_AUTO_CREATE)

Override

protected void onStop()

superonStop()

Unbind from the service

if (mBound)

unbindService(mConnection)

mBound = false

Called when a button is clicked (the button in the layout file attaches to

this method with the androidonClick attribute)

public void onButtonClick(View v)

if (mBound)

Call a method from the LocalService

However if this call were something that might hang then this request should

occur in a separate thread to avoid slowing down the activity performance

int num = mServicegetRandomNumber()

ToastmakeText(this number + num ToastLENGTH_SHORT)show()

Defines callbacks for service binding passed to bindService()

private ServiceConnection mConnection = new ServiceConnection()

Override

public void onServiceConnected(ComponentName className

IBinder service)

Weve bound to LocalService cast the IBinder and get LocalService instance

LocalBinder binder = (LocalBinder) service

mService = bindergetService()

mBound = true

Override

public void onServiceDisconnected(ComponentName arg0)

mBound = false

The above sample shows how the client binds to the service using an implementation of

ServiceConnection and the onServiceConnected() callback The next section provides more

information about this process of binding to the service

Note The example above doesnt explicitly unbind from the service but all clients should unbind

at an appropriate time (such as when the activity pauses)

For more sample code see the LocalServicejava class and the LocalServiceActivitiesjava class in

ApiDemos

Using a Messenger

Compared to AIDL

When you need to perform IPC using a Messenger for your interface is simpler than implementing it

with AIDL because Messenger queues all calls to the service whereas a pure AIDL interface sends

simultaneous requests to the service which must then handle multi-threading

For most applications the service doesnt need to perform multi-threading so using a Messenger

allows the service to handle one call at a time If its important that your service be multi-threaded then

you should use AIDL to define your interface

If you need your service to communicate with remote processes then you can use a Messenger to

provide the interface for your service This technique allows you to perform interprocess

communication (IPC) without the need to use AIDL

Heres a summary of how to use a Messenger

The service implements a Handler that receives a callback for each call from a client

The Handler is used to create a Messenger object (which is a reference to the Handler)

The Messenger creates an IBinder that the service returns to clients from onBind()

Clients use the IBinder to instantiate the Messenger (that references the services Handler) which the

client uses to send Message objects to the service

The service receives each Message in its Handlermdashspecifically in the handleMessage() method

In this way there are no methods for the client to call on the service Instead the client delivers

messages (Message objects) that the service receives in its Handler

Heres a simple example service that uses a Messenger interface

public class MessengerService extends Service Command to the service to display a message static final int MSG_SAY_HELLO = 1 Handler of incoming messages from clients class IncomingHandler extends Handler Override public void handleMessage(Message msg) switch (msgwhat) case MSG_SAY_HELLO ToastmakeText(getApplicationContext() hello ToastLENGTH_SHORT)show() break default superhandleMessage(msg) Target we publish for clients to send messages to IncomingHandler final Messenger mMessenger = new Messenger(new IncomingHandler()) When binding to the service we return an interface to our messenger for sending messages to the service Override public IBinder onBind(Intent intent) ToastmakeText(getApplicationContext() binding ToastLENGTH_SHORT)show() return mMessengergetBinder()

Notice that the handleMessage() method in the Handler is where the service receives the incoming

Message and decides what to do based on the what member

All that a client needs to do is create a Messenger based on the IBinder returned by the service and

send a message using send() For example heres a simple activity that binds to the service and

delivers the MSG_SAY_HELLO message to the service

public class ActivityMessenger extends Activity Messenger for communicating with the service Messenger mService = null Flag indicating whether we have called bind on the service boolean mBound Class for interacting with the main interface of the service private ServiceConnection mConnection = new ServiceConnection() public void onServiceConnected(ComponentName className IBinder service) This is called when the connection with the service has been established giving us the object we can use to interact with the service We are communicating with the service using a Messenger so here we get a client-side representation of that from the raw IBinder object mService = new Messenger(service) mBound = true public void onServiceDisconnected(ComponentName className) This is called when the connection with the service has been unexpectedly disconnected -- that is its process crashed mService = null mBound = false public void sayHello(View v) if (mBound) return Create and send a message to the service using a supported what value Message msg = Messageobtain(null MessengerServiceMSG_SAY_HELLO 0 0) try mServicesend(msg) catch (RemoteException e) eprintStackTrace() Override protected void onCreate(Bundle savedInstanceState) superonCreate(savedInstanceState) setContentView(Rlayoutmain)

Override protected void onStart() superonStart() Bind to the service bindService(new Intent(this MessengerServiceclass) mConnection ContextBIND_AUTO_CREATE) Override protected void onStop() superonStop() Unbind from the service if (mBound) unbindService(mConnection) mBound = false

Notice that this example does not show how the service can respond to the client If you want the

service to respond then you need to also create a Messenger in the client Then when the client

receives the onServiceConnected() callback it sends a Message to the service that includes the

clients Messenger in the replyTo parameter of the send() method

You can see an example of how to provide two-way messaging in the MessengerServicejava (service)

and MessengerServiceActivitiesjava (client) samples

Binding to a Service

Application components (clients) can bind to a service by calling bindService() The Android system

then calls the services onBind() method which returns an IBinder for interacting with the service

The binding is asynchronous bindService() returns immediately and does not return the IBinder to the

client To receive the IBinder the client must create an instance of ServiceConnection and pass it to

bindService() The ServiceConnection includes a callback method that the system calls to deliver the

IBinder

Note Only activities services and content providers can bind to a servicemdashyou cannot bind to a

service from a broadcast receiver

So to bind to a service from your client you must

1 Implement ServiceConnection

Your implementation must override two callback methods

onServiceConnected()

The system calls this to deliver the IBinder returned by the services onBind() method

onServiceDisconnected()

The Android system calls this when the connection to the service is unexpectedly lost such as

when the service has crashed or has been killed This is not called when the client unbinds

2 Call bindService() passing the ServiceConnection implementation

3 When the system calls your onServiceConnected() callback method you can begin making calls to the

service using the methods defined by the interface

4 To disconnect from the service call unbindService()

When your client is destroyed it will unbind from the service but you should always unbind when

youre done interacting with the service or when your activity pauses so that the service can shutdown

while its not being used (Appropriate times to bind and unbind is discussed more below)

For example the following snippet connects the client to the service created above by extending the

Binder class so all it must do is cast the returned IBinder to the LocalService class and request the

LocalService instance

LocalService mService private ServiceConnection mConnection = new ServiceConnection() Called when the connection with the service is established public void onServiceConnected(ComponentName className IBinder service) Because we have bound to an explicit service that is running in our own process we can cast its IBinder to a concrete class and directly access it LocalBinder binder = (LocalBinder) service mService = bindergetService() mBound = true Called when the connection with the service disconnects unexpectedly public void onServiceDisconnected(ComponentName className) Loge(TAG onServiceDisconnected) mBound = false

With this ServiceConnection the client can bind to a service by passing this it to bindService() For

example

Intent intent = new Intent(this LocalServiceclass) bindService(intent mConnection ContextBIND_AUTO_CREATE)

The first parameter of bindService() is an Intent that explicitly names the service to bind (thought the

intent could be implicit)

The second parameter is the ServiceConnection object

The third parameter is a flag indicating options for the binding It should usually be

BIND_AUTO_CREATE in order to create the service if its not already alive Other possible values are

BIND_DEBUG_UNBIND and BIND_NOT_FOREGROUND or 0 for none

Additional notes

Here are some important notes about binding to a service

You should always trap DeadObjectException exceptions which are thrown when the connection has

broken This is the only exception thrown by remote methods

Objects are reference counted across processes

You should usually pair the binding and unbinding during matching bring-up and tear-down moments

of the clients lifecycle For example

o If you only need to interact with the service while your activity is visible you should bind during

onStart() and unbind during onStop()

o If you want your activity to receive responses even while it is stopped in the background then you can

bind during onCreate() and unbind during onDestroy() Beware that this implies that your activity needs

to use the service the entire time its running (even in the background) so if the service is in another

process then you increase the weight of the process and it becomes more likely that the system will

kill it

Note You should usually not bind and unbind during your activitys onResume() and onPause()

because these callbacks occur at every lifecycle transition and you should keep the processing that

occurs at these transitions to a minimum Also if multiple activities in your application bind to the same

service and there is a transition between two of those activities the service may be destroyed and

recreated as the current activity unbinds (during pause) before the next one binds (during resume)

(This activity transition for how activities coordinate their lifecycles is described in the Activities

document)

For more sample code showing how to bind to a service see the RemoteServicejava class in

ApiDemos

Managing the Lifecycle of a Bound Service

Figure 1 The lifecycle for a service

that is started and also allows binding

When a service is unbound from all

clients the Android system destroys it

(unless it was also started with

onStartCommand()) As such you

dont have to manage the lifecycle of

your service if its purely a bound

servicemdashthe Android system manages

it for you based on whether it is bound

to any clients

However if you choose to implement

the onStartCommand() callback

method then you must explicitly stop

the service because the service is

now considered to be started In this

case the service runs until the service

stops itself with stopSelf() or another

component calls stopService()

regardless of whether it is bound to

any clients

Additionally if your service is started and accepts binding then when the system calls your onUnbind()

method you can optionally return true if you would like to receive a call to onRebind() the next time a

client binds to the service (instead of receiving a call to onBind()) onRebind() returns void but the

client still receives the IBinder in its onServiceConnected() callback Below figure 1 illustrates the logic

for this kind of lifecycle

For more information about the lifecycle of an started service see the Services document

Content Providers

Content providers store and retrieve data and make it accessible to all applications Theyre the only

way to share data across applications theres no common storage area that all Android packages can

access

Android ships with a number of content providers for common data types (audio video images

personal contact information and so on) You can see some of them listed in the androidprovider

package You can query these providers for the data they contain (although for some you must

acquire the proper permission to read the data)

If you want to make your own data public you have two options You can create your own content

provider (a ContentProvider subclass) or you can add the data to an existing provider mdash if theres one

that controls the same type of data and you have permission to write to it

This document is an introduction to using content providers After a brief discussion of the

fundamentals it explores how to query a content provider how to modify data controlled by a provider

and how to create a content provider of your own

Content Provider Basics

How a content provider actually stores its data under the covers is up to its designer But all content

providers implement a common interface for querying the provider and returning results mdash as well as

for adding altering and deleting data Its an interface that clients use indirectly most generally

through ContentResolver objects You get a ContentResolver by calling getContentResolver() from

within the implementation of an Activity or other application component

ContentResolver cr = getContentResolver()

You can then use the ContentResolvers methods to interact with whatever content providers youre

interested in When a query is initiated the Android system identifies the content provider thats the

target of the query and makes sure that it is up and running The system instantiates all

ContentProvider objects you never need to do it on your own In fact you never deal directly with

ContentProvider objects at all Typically theres just a single instance of each type of ContentProvider

But it can communicate with multiple ContentResolver objects in different applications and processes

The interaction between processes is handled by the ContentResolver and ContentProvider classes

The data model

Content providers expose their data as a simple table on a database model where each row is a

record and each column is data of a particular type and meaning For example information about

people and their phone numbers might be exposed as follows

_ID NUMBER NUMBER_KEY LABEL NAME TYPE

13 (425) 555 6677 425 555 6677 Kirkland office Bully Pulpit TYPE_WORK

44 (212) 555-1234 212 555 1234 NY apartment Alan Vain TYPE_HOME

45 (212) 555-6657 212 555 6657 Downtown office Alan Vain TYPE_MOBILE

53 2015554433 201 555 4433 Love Nest Rex Cars TYPE_HOME

Every record includes a numeric _ID field that uniquely identifies the record within the table IDs can be

used to match records in related tables mdash for example to find a persons phone number in one table

and pictures of that person in another

A query returns a Cursor object that can move from record to record and column to column to read the

contents of each field It has specialized methods for reading each type of data So to read a field you

must know what type of data the field contains (Theres more on query results and Cursor objects

later)

URIs

Each content provider exposes a public URI (wrapped as a Uri object) that uniquely identifies its data

set A content provider that controls multiple data sets (multiple tables) exposes a separate URI for

each one All URIs for providers begin with the string content The content scheme identifies the

data as being controlled by a content provider

If youre defining a content provider its a good idea to also define a constant for its URI to simplify

client code and make future updates cleaner Android defines CONTENT_URI constants for all the

providers that come with the platform For example the URI for the table that matches phone numbers

to people and the URI for the table that holds pictures of people (both controlled by the Contacts

content provider) are

androidproviderContactsPhonesCONTENT_URI

androidproviderContactsPhotosCONTENT_URI

The URI constant is used in all interactions with the content provider Every ContentResolver method

takes the URI as its first argument Its what identifies which provider the ContentResolver should talk

to and which table of the provider is being targeted

Querying a Content Provider

You need three pieces of information to query a content provider

The URI that identifies the provider

The names of the data fields you want to receive

The data types for those fields

If youre querying a particular record you also need the ID for that record

Making the query

To query a content provider you can use either the ContentResolverquery() method or the

ActivitymanagedQuery() method Both methods take the same set of arguments and both return a

Cursor object However managedQuery() causes the activity to manage the life cycle of the Cursor A

managed Cursor handles all of the niceties such as unloading itself when the activity pauses and

requerying itself when the activity restarts You can ask an Activity to begin managing an unmanaged

Cursor object for you by calling ActivitystartManagingCursor()

The first argument to either query() or managedQuery() is the provider URI mdash the CONTENT_URI

constant that identifies a particular ContentProvider and data set (see URIs earlier)

To restrict a query to just one record you can append the _ID value for that record to the URI mdash that

is place a string matching the ID as the last segment of the path part of the URI For example if the ID

is 23 the URI would be

content 23

There are some helper methods particularly ContentUriswithAppendedId() and

UriwithAppendedPath() that make it easy to append an ID to a URI Both are static methods that

return a Uri object with the ID added So for example if you were looking for record 23 in the database

of people contacts you might construct a query as follows

import androidproviderContactsPeople import androidcontentContentUris import androidnetUri import androiddatabaseCursor Use the ContentUris method to produce the base URI for the contact with _ID == 23 Uri myPerson = ContentUriswithAppendedId(PeopleCONTENT_URI 23) Alternatively use the Uri method to produce the base URI It takes a string rather than an integer Uri myPerson = UriwithAppendedPath(PeopleCONTENT_URI 23) Then query for this specific record Cursor cur = managedQuery(myPerson null null null null)

The other arguments to the query() and managedQuery() methods delimit the query in more detail

They are

The names of the data columns that should be returned A null value returns all columns Otherwise

only columns that are listed by name are returned All the content providers that come with the

platform define constants for their columns For example the androidproviderContactsPhones class

defines constants for the names of the columns in the phone table illustrated earlier ampmdash _ID

NUMBER NUMBER_KEY NAME and so on

A filter detailing which rows to return formatted as an SQL WHERE clause (excluding the WHERE

itself) A null value returns all rows (unless the URI limits the query to a single record)

Selection arguments

A sorting order for the rows that are returned formatted as an SQL ORDER BY clause (excluding the

ORDER BY itself) A null value returns the records in the default order for the table which may be

unordered

Lets look at an example query to retrieve a list of contact names and their primary phone numbers

import androidproviderContactsPeople import androiddatabaseCursor Form an array specifying which columns to return String[] projection = new String[] People_ID People_COUNT PeopleNAME PeopleNUMBER Get the base URI for the People table in the Contacts content provider Uri contacts = PeopleCONTENT_URI Make the query Cursor managedCursor = managedQuery(contacts projection Which columns to return null Which rows to return (all rows) null Selection arguments (none) Put the results in ascending order by name PeopleNAME + ASC)

This query retrieves data from the People table of the Contacts content provider It gets the name

primary phone number and unique record ID for each contact It also reports the number of records

that are returned as the _COUNT field of each record

The constants for the names of the columns are defined in various interfaces mdash _ID and _COUNT in

BaseColumns NAME in PeopleColumns and NUMBER in PhoneColumns The ContactsPeople

class implements each of these interfaces which is why the code example above could refer to them

using just the class name

What a query returns

A query returns a set of zero or more database records The names of the columns their default order

and their data types are specific to each content provider But every provider has an _ID column

which holds a unique numeric ID for each record Every provider can also report the number of records

returned as the _COUNT column its value is the same for all rows

Here is an example result set for the query in the previous section

_ID _COUNT NAME NUMBER

44 3 Alan Vain 212 555 1234

13 3 Bully Pulpit 425 555 6677

53 3 Rex Cars 201 555 4433

The retrieved data is exposed by a Cursor object that can be used to iterate backward or forward

through the result set You can use this object only to read the data To add modify or delete data

you must use a ContentResolver object

Reading retrieved data

The Cursor object returned by a query provides access to a recordset of results If you have queried

for a specific record by ID this set will contain only one value Otherwise it can contain multiple

values (If there are no matches it can also be empty) You can read data from specific fields in the

record but you must know the data type of the field because the Cursor object has a separate method

for reading each type of data mdash such as getString() getInt() and getFloat() (However for most types

if you call the method for reading strings the Cursor object will give you the String representation of

the data) The Cursor lets you request the column name from the index of the column or the index

number from the column name

The following snippet demonstrates reading names and phone numbers from the query illustrated

earlier

import androidproviderContactsPeople private void getColumnData(Cursor cur) if (curmoveToFirst()) String name String phoneNumber int nameColumn = curgetColumnIndex(PeopleNAME) int phoneColumn = curgetColumnIndex(PeopleNUMBER) String imagePath do Get the field values name = curgetString(nameColumn) phoneNumber = curgetString(phoneColumn) Do something with the values while (curmoveToNext())

If a query can return binary data such as an image or sound the data may be directly entered in the

table or the table entry for that data may be a string specifying a content URI that you can use to get

the data In general smaller amounts of data (say from 20 to 50K or less) are most often directly

entered in the table and can be read by calling CursorgetBlob() It returns a byte array

If the table entry is a content URI you should never try to open and read the file directly (for one thing

permissions problems can make this fail) Instead you should call ContentResolveropenInputStream()

to get an InputStream object that you can use to read the data

Modifying Data

Data kept by a content provider can be modified by

Adding new records

Adding new values to existing records

Batch updating existing records

Deleting records

All data modification is accomplished using ContentResolver methods Some content providers require

a more restrictive permission for writing data than they do for reading it If you dont have permission to

write to a content provider the ContentResolver methods will fail

Adding records

To add a new record to a content provider first set up a map of key-value pairs in a ContentValues

object where each key matches the name of a column in the content provider and the value is the

desired value for the new record in that column Then call ContentResolverinsert() and pass it the URI

of the provider and the ContentValues map This method returns the full URI of the new record mdash that

is the providers URI with the appended ID for the new record You can then use this URI to query and

get a Cursor over the new record and to further modify the record Heres an example

import androidproviderContactsPeople import androidcontentContentResolver import androidcontentContentValues ContentValues values = new ContentValues() Add Abraham Lincoln to contacts and make him a favorite valuesput(PeopleNAME Abraham Lincoln) 1 = the new contact is added to favorites 0 = the new contact is not added to favorites valuesput(PeopleSTARRED 1) Uri uri = getContentResolver()insert(PeopleCONTENT_URI values)

Adding new values

Once a record exists you can add new information to it or modify existing information For example

the next step in the example above would be to add contact information mdash like a phone number or an

IM or e-mail address mdash to the new entry

The best way to add to a record in the Contacts database is to append the name of the table where the

new data goes to the URI for the record then use the amended URI to add the new data values Each

Contacts table exposes a name for this purpose as a CONTENT_DIRECTORY constant The following

code continues the previous example by adding a phone number and e-mail address for the record

just created

Uri phoneUri = null Uri emailUri = null Add a phone number for Abraham Lincoln Begin with the URI for the new record just returned by insert() it ends with the _ID of the new record so we dont have to add the ID ourselves Then append the designation for the phone table to this URI and use the resulting URI to insert the phone number phoneUri = UriwithAppendedPath(uri PeoplePhonesCONTENT_DIRECTORY) valuesclear() valuesput(PeoplePhonesTYPE PeoplePhonesTYPE_MOBILE) valuesput(PeoplePhonesNUMBER 1233214567) getContentResolver()insert(phoneUri values) Now add an email address in the same way emailUri = UriwithAppendedPath(uri PeopleContactMethodsCONTENT_DIRECTORY) valuesclear() ContactMethodsKIND is used to distinguish different kinds of contact methods such as email IM etc valuesput(PeopleContactMethodsKIND ContactsKIND_EMAIL) valuesput(PeopleContactMethodsDATA testexamplecom) valuesput(PeopleContactMethodsTYPE PeopleContactMethodsTYPE_HOME) getContentResolver()insert(emailUri values)

You can place small amounts of binary data into a table by calling the version of ContentValuesput()

that takes a byte array That would work for a small icon-like image or a short audio clip for example

However if you have a large amount of binary data to add such as a photograph or a complete song

put a content URI for the data in the table and call ContentResolveropenOutputStream() with the files

URI (That causes the content provider to store the data in a file and record the file path in a hidden

field of the record)

In this regard the MediaStore content provider the main provider that dispenses image audio and

video data employs a special convention The same URI that is used with query() or managedQuery()

to get meta-information about the binary data (such as the caption of a photograph or the date it was

taken) is used with openInputStream() to get the data itself Similarly the same URI that is used with

insert() to put meta-information into a MediaStore record is used with openOutputStream() to place the

binary data there The following code snippet illustrates this convention

import androidproviderMediaStoreImagesMedia import androidcontentContentValues import javaioOutputStream Save the name and description of an image in a ContentValues map ContentValues values = new ContentValues(3) valuesput(MediaDISPLAY_NAME road_trip_1) valuesput(MediaDESCRIPTION Day 1 trip to Los Angeles) valuesput(MediaMIME_TYPE imagejpeg) Add a new record without the bitmap but with the values just set insert() returns the URI of the new record Uri uri = getContentResolver()insert(MediaEXTERNAL_CONTENT_URI values) Now get a handle to the file for that record and save the data into it Here sourceBitmap is a Bitmap object representing the file to save to the database try OutputStream outStream = getContentResolver()openOutputStream(uri) sourceBitmapcompress(BitmapCompressFormatJPEG 50 outStream) outStreamclose() catch (Exception e) Loge(TAG exception while writing image e)

Batch updating records

To batch update a group of records (for example to change NY to New York in all fields) call the

ContentResolverupdate() method with the columns and values to change

Deleting a record

To delete a single record call ContentResolverdelete() with the URI of a specific row

To delete multiple rows call ContentResolverdelete() with the URI of the type of record to delete (for

example androidproviderContactsPeopleCONTENT_URI) and an SQL WHERE clause defining

which rows to delete (Caution Be sure to include a valid WHERE clause if youre deleting a general

type or you risk deleting more records than you intended)

Creating a Content Provider

To create a content provider you must

Set up a system for storing the data Most content providers store their data using Androids file

storage methods or SQLite databases but you can store your data any way you want Android

provides the SQLiteOpenHelper class to help you create a database and SQLiteDatabase to manage

it

Extend the ContentProvider class to provide access to the data

Declare the content provider in the manifest file for your application (AndroidManifestxml)

The following sections have notes on the last two of these tasks

Extending the ContentProvider class

You define a ContentProvider subclass to expose your data to others using the conventions expected

by ContentResolver and Cursor objects Principally this means implementing six abstract methods

declared in the ContentProvider class

query()

insert()

update()

delete()

getType()

onCreate()

The query() method must return a Cursor object that can iterate over the requested data Cursor itself

is an interface but Android provides some ready-made Cursor objects that you can use For example

SQLiteCursor can iterate over data stored in an SQLite database You get the Cursor object by calling

any of the SQLiteDatabase classs query() methods There are other Cursor implementations mdash such

as MatrixCursor mdash for data not stored in a database

Because these ContentProvider methods can be called from various ContentResolver objects in

different processes and threads they must be implemented in a thread-safe manner

As a courtesy you might also want to call ContentResolvernotifyChange() to notify listeners when

there are modifications to the data

Beyond defining the subclass itself there are other steps you should take to simplify the work of clients

and make the class more accessible

Define a public static final Uri named CONTENT_URI This is the string that represents the full content

URI that your content provider handles You must define a unique string for this value The best

solution is to use the fully-qualified class name of the content provider (made lowercase) So for

example the URI for a TransportationProvider class could be defined as follows

public static final Uri CONTENT_URI = Uriparse(contentcomexamplecodelabtransportationprovider)

If the provider has subtables also define CONTENT_URI constants for each of the subtables These

URIs should all have the same authority (since that identifies the content provider) and be

distinguished only by their paths For example

contentcomexamplecodelabtransportationprovidertrain

contentcomexamplecodelabtransportationproviderairdomestic

contentcomexamplecodelabtransportationproviderairinternational

For an overview of content URIs see the Content URI Summary at the end of this document

Define the column names that the content provider will return to clients If you are using an underlying

database these column names are typically identical to the SQL database column names they

represent Also define public static String constants that clients can use to specify the columns in

queries and other instructions

Be sure to include an integer column named _id (with the constant _ID) for the IDs of the records

You should have this field whether or not you have another field (such as a URL) that is also unique

among all records If youre using the SQLite database the _ID field should be the following type

INTEGER PRIMARY KEY AUTOINCREMENT

The AUTOINCREMENT descriptor is optional But without it SQLite increments an ID counter field to

the next number above the largest existing number in the column If you delete the last row the next

row added will have the same ID as the deleted row AUTOINCREMENT avoids this by having SQLite

increment to the next largest value whether deleted or not

Carefully document the data type of each column Clients need this information to read the data

If you are handling a new data type you must define a new MIME type to return in your

implementation of ContentProvidergetType() The type depends in part on whether or not the content

URI submitted to getType() limits the request to a specific record Theres one form of the MIME type

for a single record and another for multiple records Use the Uri methods to help determine what is

being requested Here is the general format for each type

o For a single record vndandroidcursoritemvndyourcompanynamecontenttype

For example a request for train record 122 like this URI

contentcomexampletransportationprovidertrains122

might return this MIME type

vndandroidcursoritemvndexamplerail

o For multiple records vndandroidcursordirvndyourcompanynamecontenttype

For example a request for all train records like the following URI

contentcomexampletransportationprovidertrains

might return this MIME type

vndandroidcursordirvndexamplerail

If you are exposing byte data thats too big to put in the table itself mdash such as a large bitmap file mdash the

field that exposes the data to clients should actually contain a content URI string This is the field that

gives clients access to the data file The record should also have another field named _data that lists

the exact file path on the device for that file This field is not intended to be read by the client but by

the ContentResolver The client will call ContentResolveropenInputStream() on the user-facing field

holding the URI for the item The ContentResolver will request the _data field for that record and

because it has higher permissions than a client it should be able to access that file directly and return

a read wrapper for the file to the client

For an example of a private content provider implementation see the NodePadProvider class in the

Notepad sample application that ships with the SDK

Declaring the content provider

To let the Android system know about the content provider youve developed declare it with a

ltprovidergt element in the applications AndroidManifestxml file Content providers that are not

declared in the manifest are not visible to the Android system

The name attribute is the fully qualified name of the ContentProvider subclass The authorities attribute

is the authority part of the content URI that identifies the provider For example if the ContentProvider

subclass is AutoInfoProvider the ltprovidergt element might look like this

ltprovider androidname=comexampleautosAutoInfoProvider androidauthorities=comexampleautosautoinfoprovider gt ltprovidergt

Note that the authorities attribute omits the path part of a content URI For example if

AutoInfoProvider controlled subtables for different types of autos or different manufacturers

contentcomexampleautosautoinfoproviderhonda

contentcomexampleautosautoinfoprovidergmcompact

contentcomexampleautosautoinfoprovidergmsuv

those paths would not be declared in the manifest The authority is what identifies the provider not the

path your provider can interpret the path part of the URI in any way you choose

Other ltprovidergt attributes can set permissions to read and write data provide for an icon and text

that can be displayed to users enable and disable the provider and so on Set the multiprocess

attribute to true if data does not need to be synchronized between multiple running versions of the

content provider This permits an instance of the provider to be created in each client process

eliminating the need to perform IPC

Content URI Summary

Here is a recap of the important parts of a content URI

A Standard prefix indicating that the data is controlled by a content provider Its never modified

B The authority part of the URI it identifies the content provider For third-party applications this should

be a fully-qualified class name (reduced to lowercase) to ensure uniqueness The authority is declared

in the ltprovidergt elements authorities attribute

ltprovider androidname=TransportationProvider androidauthorities=comexampletransportationprovider gt

C The path that the content provider uses to determine what kind of data is being requested This can be

zero or more segments long If the content provider exposes only one type of data (only trains for

example) it can be absent If the provider exposes several types including subtypes it can be several

segments long mdash for example landbus landtrain seaship and seasubmarine to give four

possibilities

D The ID of the specific record being requested if any This is the _ID value of the requested record If

the request is not limited to a single record this segment and the trailing slash are omitted

contentcomexampletransportationprovidertrains

Intent and intent filters

Three of the core components of an application mdash activities services and broadcast receivers mdash 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 mdash 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 ContextstartActivity() or ActivitystartActivityForResult() to launch an

activity or get an existing activity to do something new (It can also be passed to ActivitysetResult() to

return information to the activity that called startActivityForResult())

An Intent object is passed to ContextstartService() to initiate a service or deliver new instructions to an

ongoing service Similarly an intent can be passed to ContextbindService() to establish a connection

between the calling component and a target service It can optionally initiate the service if its not

already running

Intent objects passed to any of the broadcast methods (such as ContextsendBroadcast()

ContextsendOrderedBroadcast() or ContextsendStickyBroadcast()) 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 mdash how it resolves which component should receive an intent message For

intents that dont explicitly name a target component this process involves testing the Intent object

against intent filters associated with potential targets

Intent Objects

An Intent object is a bundle of information It contains information of interest to the component that

receives the intent (such as the action to be taken and the data to act on) plus information of interest to

the Android system (such as the category of component that should handle the intent and instructions

on how to launch a target activity) Principally it can contain the following

Component name

The name of the component that should handle the intent This field is a ComponentName

object mdash a combination of the fully qualified class name of the target component (for example

comexampleprojectappFreneticActivity) and the package name set in the manifest file of the

application where the component resides (for example comexampleproject) The package

part of the component name and the package name set in the manifest do not necessarily have

to match

The component name is optional If it is set the Intent object is delivered to an instance of the

designated class If it is not set Android uses other information in the Intent object to locate a

suitable target mdash see Intent Resolution later in this document

The component name is set by setComponent() setClass() or setClassName() and read by

getComponent()

Action

A string naming the action to be performed mdash or in the case of broadcast intents the action

that took place and is being reported The Intent class defines a number of action constants

including these

Constant Target

component

Action

ACTION_CALL activity Initiate a phone call

ACTION_EDIT activity Display data for the user to edit

ACTION_MAIN activity Start up as the initial activity of a task

with no data input and no returned

output

ACTION_SYNC activity Synchronize data on a server with

data on the mobile device

ACTION_BATTERY_LOW broadcast

receiver

A warning that the battery is low

ACTION_HEADSET_PLUG broadcast

receiver

A headset has been plugged into the

device or unplugged from it

ACTION_SCREEN_ON broadcast

receiver

The screen has been turned on

ACTION_TIMEZONE_CHANGED broadcast

receiver

The setting for the time zone has

changed

See the Intent class description for a list of pre-defined constants for generic actions Other

actions are defined elsewhere in the Android API You can also define your own action strings

for activating the components in your application Those you invent should include the

application package as a prefix mdash for example comexampleprojectSHOW_COLOR

The action largely determines how the rest of the intent is structured mdash particularly the data and

extras fields mdash much as a method name determines a set of arguments and a return value For

this reason its a good idea to use action names that are as specific as possible and to couple

them tightly to the other fields of the intent In other words instead of defining an action in

isolation define an entire protocol for the Intent objects your components can handle

The action in an Intent object is set by the setAction() method and read by getAction()

Data

The URI of the data to be acted on and the MIME type of that data Different actions are paired

with different kinds of data specifications For example if the action field is ACTION_EDIT the

data field would contain the URI of the document to be displayed for editing If the action is

ACTION_CALL the data field would be a tel URI with the number to call Similarly if the action

is ACTION_VIEW and the data field is an http URI the receiving activity would be called upon

to download and display whatever data the URI refers to

When matching an intent to a component that is capable of handling the data its often

important to know the type of data (its MIME type) in addition to its URI For example a

component able to display image data should not be called upon to play an audio file

In many cases the data type can be inferred from the URI mdash particularly content URIs which

indicate that the data is located on the device and controlled by a content provider (see the

separate discussion on content providers) But the type can also be explicitly set in the Intent

object The setData() method specifies data only as a URI setType() specifies it only as a

MIME type and setDataAndType() specifies it as both a URI and a MIME type The URI is read

by getData() and the type by getType()

Category

A string containing additional information about the kind of component that should handle the

intent Any number of category descriptions can be placed in an Intent object As it does for

actions the Intent class defines several category constants including these

Constant Meaning

CATEGORY_BROWSABLE The target activity can be safely invoked by the browser to

display data referenced by a link mdash for example an image or

an e-mail message

CATEGORY_GADGET The activity can be embedded inside of another activity that

hosts gadgets

CATEGORY_HOME The activity displays the home screen the first screen the

user sees when the device is turned on or when the HOME

key is pressed

CATEGORY_LAUNCHER The activity can be the initial activity of a task and is listed in

the top-level application launcher

CATEGORY_PREFERENCE The target activity is a preference panel

See the Intent class description for the full list of categories

The addCategory() method places a category in an Intent object removeCategory() deletes a

category previously added and getCategories() gets the set of all categories currently in the

object

Extras

Key-value pairs for additional information that should be delivered to the component handling

the intent Just as some actions are paired with particular kinds of data URIs some are paired

with particular extras For example an ACTION_TIMEZONE_CHANGED intent has a time-

zone extra that identifies the new time zone and ACTION_HEADSET_PLUG has a state

extra indicating whether the headset is now plugged in or unplugged as well as a name extra

for the type of headset If you were to invent a SHOW_COLOR action the color value would be

set in an extra key-value pair

The Intent object has a series of put() methods for inserting various types of extra data and a

similar set of get() methods for reading the data These methods parallel those for Bundle

objects In fact the extras can be installed and read as a Bundle using the putExtras() and

getExtras() methods

Flags

Flags of various sorts Many instruct the Android system how to launch an activity (for example

which task the activity should belong to) and how to treat it after its launched (for example

whether it belongs in the list of recent activities) All these flags are defined in the Intent class

The Android system and the applications that come with the platform employ Intent objects both to

send out system-originated broadcasts and to activate system-defined components To see how to

structure an intent to activate a system component consult the list of intents in the reference

Intent Resolution

Intents can be divided into two groups

Explicit intents designate the target component by its name (the component name field mentioned

earlier has a value set) Since component names would generally not be known to developers of other

applications explicit intents are typically used for application-internal messages mdash such as an activity

starting a subordinate service or launching a sister activity

Implicit intents do not name a target (the field for the component name is blank) Implicit intents are

often used to activate components in other applications

Android delivers an explicit intent to an instance of the designated target class Nothing in the Intent

object other than the component name matters for determining which component should get the intent

A different strategy is needed for implicit intents In the absence of a designated target the Android

system must find the best component (or components) to handle the intent mdash a single activity or

service to perform the requested action or the set of broadcast receivers to respond to the broadcast

announcement It does so by comparing the contents of the Intent object to intent filters structures

associated with components that can potentially receive intents Filters advertise the capabilities of a

component and delimit the intents it can handle They open the component to the possibility of

receiving implicit intents of the advertised type If a component does not have any intent filters it can

receive only explicit intents A component with filters can receive both explicit and implicit intents

Only three aspects of an Intent object are consulted when the object is tested against an intent filter

action

data (both URI and data type)

category

The extras and flags play no part in resolving which component receives an intent

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 mdash but only unwanted implicit intents (those that dont 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

components 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 mdash 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 Pads filters are described in the Note Pad Example

section later)

Filters and security

An intent filter cannot be relied on for security While it opens a component to receiving only certain

kinds of implicit intents it does nothing to prevent explicit intents from targeting the component Even

though a filter restricts the intents a component will be asked to handle to certain actions and data

sources someone could always put together an explicit intent with a different action and data source

and name the component as the target

An intent filter is an instance of the IntentFilter class However since the Android system must know

about the capabilities of a component before it can launch that component intent filters are generally

not set up in Java code but in the applications manifest file (AndroidManifestxml) as ltintent-filtergt

elements (The one exception would be filters for broadcast receivers that are registered dynamically

by calling ContextregisterReceiver() they are directly created as IntentFilter objects)

A filter has fields that parallel the action data and category fields of an Intent object An implicit intent

is tested against the filter in all three areas To be delivered to the component that owns the filter it

must pass all three tests If it fails even one of them the Android system wont deliver it to the

component mdash at least not on the basis of that filter However since a component can have multiple

intent filters an intent that does not pass through one of a components filters might make it through on

another

Each of the three tests is described in detail below

Action test

An ltintent-filtergt element in the manifest file lists actions as ltactiongt subelements For

example

ltintent-filter gt ltaction androidname=comexampleprojectSHOW_CURRENT gt ltaction androidname=comexampleprojectSHOW_RECENT gt ltaction androidname=comexampleprojectSHOW_PENDING gt ltintent-filtergt

As the example shows while an Intent object names just a single action a filter may list more

than one The list cannot be empty a filter must contain at least one ltactiongt element or it will

block all intents

To pass this test the action specified in the Intent object must match one of the actions listed in

the filter If the object or the filter does not specify an action the results are as follows

If the filter fails to list any actions there is nothing for an intent to match so all intents fail the

test No intents can get through the filter

On the other hand an Intent object that doesnt specify an action automatically passes the test

mdash as long as the filter contains at least one action

Category test

An ltintent-filtergt element also lists categories as subelements For example

ltintent-filter gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryBROWSABLE gt ltintent-filtergt

Note that the constants described earlier for actions and categories are not used in the manifest

file The full string values are used instead For instance the

androidintentcategoryBROWSABLE string in the example above corresponds to the

CATEGORY_BROWSABLE constant mentioned earlier in this document Similarly the string

androidintentactionEDIT corresponds to the ACTION_EDIT constant

For an intent to pass the category test every category in the Intent object must match a

category in the filter The filter can list additional categories but it cannot omit any that are in the

intent

In principle therefore an Intent object with no categories should always pass this test

regardless of whats in the filter Thats mostly true However with one exception Android treats

all implicit intents passed to startActivity() as if they contained at least one category

androidintentcategoryDEFAULT (the CATEGORY_DEFAULT constant) Therefore activities

that are willing to receive implicit intents must include androidintentcategoryDEFAULT in

their intent filters (Filters with androidintentactionMAIN and

androidintentcategoryLAUNCHER settings are the exception They mark activities that begin

new tasks and that are represented on the launcher screen They can include

androidintentcategoryDEFAULT in the list of categories but dont need to) See Using intent

matching later for more on these filters)

Data test

Like the action and categories the data specification for an intent filter is contained in a

subelement And as in those cases the subelement can appear multiple times or not at all For

example

ltintent-filter gt ltdata androidmimeType=videompeg androidscheme=http gt ltdata androidmimeType=audiompeg androidscheme=http gt ltintent-filtergt

Each ltdatagt element can specify a URI and a data type (MIME media type) There are

separate attributes mdash scheme host port and path mdash for each part of the URI

schemehostportpath

For example in the following URI

contentcomexampleproject200foldersubfolderetc

the scheme is content the host is comexampleproject the port is 200 and the path is

foldersubfolderetc The host and port together constitute the URI authority if a host is not

specified the port is ignored

Each of these attributes is optional but they are not independent of each other For an authority

to be meaningful a scheme must also be specified For a path to be meaningful both a scheme

and an authority must be specified

When the URI in an Intent object is compared to a URI specification in a filter its compared

only to the parts of the URI actually mentioned in the filter For example if a filter specifies only

a scheme all URIs with that scheme match the filter If a filter specifies a scheme and an

authority but no path all URIs with the same scheme and authority match regardless of their

paths If a filter specifies a scheme an authority and a path only URIs with the same scheme

authority and path match However a path specification in the filter can contain wildcards to

require only a partial match of the path

The type attribute of a ltdatagt element specifies the MIME type of the data Its more common in

filters than a URI Both the Intent object and the filter can use a wildcard for the subtype field

mdash for example text or audio mdash indicating any subtype matches

The data test compares both the URI and the data type in the Intent object to a URI and data

type specified in the filter The rules are as follows

a An Intent object that contains neither a URI nor a data type passes the test only if the filter

likewise does not specify any URIs or data types

b An Intent object that contains a URI but no data type (and a type cannot be inferred from the

URI) passes the test only if its URI matches a URI in the filter and the filter likewise does not

specify a type This will be the case only for URIs like mailto and tel that do not refer to actual

data

c An Intent object that contains a data type but not a URI passes the test only if the filter lists the

same data type and similarly does not specify a URI

d An Intent object that contains both a URI and a data type (or a data type can be inferred from

the URI) passes the data type part of the test only if its type matches a type listed in the filter It

passes the URI part of the test either if its URI matches a URI in the filter or if it has a content

or file URI and the filter does not specify a URI In other words a component is presumed to

support content and file data if its filter lists only a data type

If an intent can pass through the filters of more than one activity or service the user may be asked

which component to activate An exception is raised if no target can be found

Common cases

The last rule shown above for the data test rule (d) reflects the expectation that components are able

to get local data from a file or content provider Therefore their filters can list just a data type and do

not need to explicitly name the content and file schemes This is a typical case A ltdatagt element like

the following for example tells Android that the component can get image data from a content

provider and display it

ltdata androidmimeType=image gt

Since most available data is dispensed by content providers filters that specify a data type but not a

URI are perhaps the most common

Another common configuration is filters with a scheme and a data type For example a ltdatagt

element like the following tells Android that the component can get video data from the network and

display it

ltdata androidscheme=http androidtype=video gt

Consider for example what the browser application does when the user follows a link on a web page

It first tries to display the data (as it could if the link was to an HTML page) If it cant display the data it

puts together an implicit intent with the scheme and data type and tries to start an activity that can do

the job If there are no takers it asks the download manager to download the data That puts it under

the control of a content provider so a potentially larger pool of activities (those with filters that just

name a data type) can respond

Most applications also have a way to start fresh without a reference to any particular data Activities

that can initiate applications have filters with androidintentactionMAIN specified as the action If

they are to be represented in the application launcher they also specify the

androidintentcategoryLAUNCHER category

ltintent-filter gt ltaction androidname=code androidintentactionMAIN gt ltcategory androidname=code androidintentcategoryLAUNCHER gt ltintent-filtergt

Using intent matching

Intents are matched against intent filters not only to discover a target component to activate but also

to discover something about the set of components on the device For example the Android system

populates the application launcher the top-level screen that shows the applications that are available

for the user to launch by finding all the activities with intent filters that specify the

androidintentactionMAIN action and androidintentcategoryLAUNCHER category (as illustrated

in the previous section) It then displays the icons and labels of those activities in the launcher

Similarly it discovers the home screen by looking for the activity with androidintentcategoryHOME

in its filter

Your application can use intent matching is a similar way The PackageManager has a set of query()

methods that return all components that can accept a particular intent and a similar series of

resolve() methods that determine the best component to respond to an intent For example

queryIntentActivities() returns a list of all activities that can perform the intent passed as an argument

and queryIntentServices() returns a similar list of services Neither method activates the components

they just list the ones that can respond Theres a similar method queryBroadcastReceivers() for

broadcast receivers

Note Pad Example

The Note Pad sample application enables users to browse through a list of notes view details about

individual items in the list edit the items and add a new item to the list This section looks at the intent

filters declared in its manifest file (If youre working offline in the SDK you can find all the source files

for this sample application including its manifest file at ltsdkgtsamplesNotePadindexhtml If youre

viewing the documentation online the source files are in the Tutorials and Sample Code section here)

In its manifest file the Note Pad application declares three activities each with at least one intent filter

It also declares a content provider that manages the note data Here is the manifest file in its entirety

ltmanifest xmlnsandroid=httpschemasandroidcomapkresandroid package=comexampleandroidnotepadgt ltapplication androidicon=drawableapp_notes androidlabel=stringapp_name gt ltprovider androidname=NotePadProvider androidauthorities=comgoogleproviderNotePad gt ltactivity androidname=NotesList androidlabel=stringtitle_notes_listgt ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltactivity androidname=NoteEditor androidtheme=androidstyleThemeLight androidlabel=stringtitle_note gt ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltactivitygt

ltactivity androidname=TitleEditor androidlabel=stringtitle_edit_title androidtheme=androidstyleThemeDialoggt ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltapplicationgt ltmanifestgt

The first activity NotesList is distinguished from the other activities by the fact that it operates on a

directory of notes (the note list) rather than on a single note It would generally serve as the initial user

interface into the application It can do three things as described by its three intent filters

1 ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt

This filter declares the main entry point into the Note Pad application The standard MAIN action is an

entry point that does not require any other information in the Intent (no data specification for example)

and the LAUNCHER category says that this entry point should be listed in the application launcher

2 ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

This filter declares the things that the activity can do on a directory of notes It can allow the user to

view or edit the directory (via the VIEW and EDIT actions) or to pick a particular note from the

directory (via the PICK action)

The mimeType attribute of the ltdatagt element specifies the kind of data that these actions operate on

It indicates that the activity can get a Cursor over zero or more items (vndandroidcursordir) from a

content provider that holds Note Pad data (vndgooglenote) The Intent object that launches the

activity would include a content URI specifying the exact data of this type that the activity should open

Note also the DEFAULT category supplied in this filter Its there because the ContextstartActivity()

and ActivitystartActivityForResult() methods treat all intents as if they contained the DEFAULT

category mdash with just two exceptions

o Intents that explicitly name the target activity

o Intents consisting of the MAIN action and LAUNCHER category

Therefore the DEFAULT category is required for all filters mdash except for those with the MAIN action

and LAUNCHER category (Intent filters are not consulted for explicit intents)

3 ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

This filter describes the activitys ability to return a note selected by the user without requiring any

specification of the directory the user should choose from The GET_CONTENT action is similar to the

PICK action In both cases the activity returns the URI for a note selected by the user (In each case

its returned to the activity that called startActivityForResult() to start the NoteList activity) Here

however the caller specifies the type of data desired instead of the directory of data the user will be

picking from

The data type vndandroidcursoritemvndgooglenote indicates the type of data the activity can

return mdash a URI for a single note From the returned URI the caller can get a Cursor for exactly one

item (vndandroidcursoritem) from the content provider that holds Note Pad data (vndgooglenote)

In other words for the PICK action in the previous filter the data type indicates the type of data the

activity could display to the user For the GET_CONTENT filter it indicates the type of data the activity

can return to the caller

Given these capabilities the following intents will resolve to the NotesList activity

action androidintentactionMAIN

Launches the activity with no data specified

action androidintentactionMAIN

category androidintentcategoryLAUNCHER

Launches the activity with no data selected specified This is the actual intent used by the

Launcher to populate its top-level list All activities with filters that match this action and

category are added to the list

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of all the notes under

contentcomgoogleproviderNotePadnotes The user can then browse through the list and

get information about the items in it

action androidintentactionPICK

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of the notes under

contentcomgoogleproviderNotePadnotes The user can then pick a note from the list and

the activity will return the URI for that item back to the activity that started the NoteList activity

action androidintentactionGET_CONTENT

data type vndandroidcursoritemvndgooglenote

Asks the activity to supply a single item of Note Pad data

The second activity NoteEditor shows users a single note entry and allows them to edit it It can do

two things as described by its two intent filters

1 ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The first primary purpose of this activity is to enable the user to interact with a single note ampmdash to

either VIEW the note or EDIT it (The EDIT_NOTE category is a synonym for EDIT) The intent would

contain the URI for data matching the MIME type vndandroidcursoritemvndgooglenote mdash that is

the URI for a single specific note It would typically be a URI that was returned by the PICK or

GET_CONTENT actions of the NoteList activity

As before this filter lists the DEFAULT category so that the activity can be launched by intents that

dont explicitly specify the NoteEditor class

2 ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

The secondary purpose of this activity is to enable the user to create a new note which it will INSERT

into an existing directory of notes The intent would contain the URI for data matching the MIME type

vndandroidcursordirvndgooglenote mdash that is the URI for the directory where the note should be

placed

Given these capabilities the following intents will resolve to the NoteEditor activity

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID (For details on how content

URIs specify individual members of a group see Content Providers)

action androidintentactionEDIT

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID and to let the user edit it If

the user saves the changes the activity updates the data for the note in the content provider

action androidintentactionINSERT

data contentcomgoogleproviderNotePadnotes

Asks the activity to create a new empty note in the notes list at

contentcomgoogleproviderNotePadnotes and allow the user to edit it If the user saves the

note its URI is returned to the caller

The last activity TitleEditor enables the user to edit the title of a note This could be implemented by

directly invoking the activity (by explicitly setting its component name in the Intent) without using an

intent filter But here we take the opportunity to show how to publish alternative operations on existing

data

ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The single intent filter for this activity uses a custom action called

comandroidnotepadactionEDIT_TITLE It must be invoked on a specific note (data type

vndandroidcursoritemvndgooglenote) like the previous VIEW and EDIT actions However here the

activity displays the title contained in the note data not the content of the note itself

In addition to supporting the usual DEFAULT category the title editor also supports two other standard

categories ALTERNATIVE and SELECTED_ALTERNATIVE These categories identify activities that

can be presented to users in a menu of options (much as the LAUNCHER category identifies activities

that should be presented to user in the application launcher) Note that the filter also supplies an

explicit label (via androidlabel=stringresolve_title) to better control what users see when

presented with this activity as an alternative action to the data they are currently viewing (For more

information on these categories and building options menus see the

PackageManagerqueryIntentActivityOptions() and MenuaddIntentOptions() methods)

Given these capabilities the following intent will resolve to the TitleEditor activity

action comandroidnotepadactionEDIT_TITLE

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the title associated with note ID and allow the user to edit the title

Processes and Threads

When an application component starts and the application does not have any other components

running the Android system starts a new Linux process for the application with a single thread of

execution By default all components of the same application run in the same process and thread

(called the main thread) If an application component starts and there already exists a process for

that application (because another component from the application exists) then the component is

started within that process and uses the same thread of execution However you can arrange for

different components in your application to run in separate processes and you can create additional

threads for any process

This document discusses how processes and threads work in an Android application

Processes

By default all components of the same application run in the same process and most applications

should not change this However if you find that you need to control which process a certain

component belongs to you can do so in the manifest file

The manifest entry for each type of component elementmdashltactivitygt ltservicegt ltreceivergt and

ltprovidergtmdashsupports an androidprocess attribute that can specify a process in which that component

should run You can set this attribute so that each component runs in its own process or so that some

components share a process while others do not You can also set androidprocess so that

components of different applications run in the same processmdashprovided that the applications share the

same Linux user ID and are signed with the same certificates

The ltapplicationgt element also supports an androidprocess attribute to set a default value that

applies to all components

Android might 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 thats killed are consequently destroyed A process is started again for those components

when theres again work for them to do

When deciding which processes to kill the Android system weighs their relative importance to the

user For example it more readily shuts down a process hosting activities that are no longer visible on

screen compared to a process hosting visible activities The decision whether to terminate a process

therefore depends on the state of the components running in that process The rules used to decide

which processes to terminate is discussed below

Process lifecycle

The Android system tries to maintain an application process for as long as possible but eventually

needs to remove old processes to reclaim memory for new or more important processes To determine

which processes to keep and which to kill the system places each process into an importance

hierarchy based on the components running in the process and the state of those components

Processes with the lowest importance are eliminated first then those with the next lowest importance

and so on as necessary to recover system resources

There are five levels in the importance hierarchy The following list presents the different types of

processes in order of importance (the first process is most important and is killed last)

1 Foreground process

A process that is required for what the user is currently doing A process is considered to be in the

foreground if any of the following conditions are true

o It hosts an Activity that the user is interacting with (the Activitys onResume() method has been called)

o It hosts a Service thats bound to the activity that the user is interacting with

o It hosts a Service thats running in the foregroundmdashthe service has called startForeground()

o It hosts a Service thats executing one of its lifecycle callbacks (onCreate() onStart() or onDestroy())

o It hosts a BroadcastReceiver thats executing its onReceive() method

Generally only a few foreground processes exist at any given time They are killed only as a last

resortmdashif memory is so low that they cannot all continue to run Generally at that point the device has

reached a memory paging state so killing some foreground processes is required to keep the user

interface responsive

2 Visible process

A process that doesnt have any foreground components but still can affect what the user sees on

screen A process is considered to be visible if either of the following conditions are true

o It hosts an Activity that is not in the foreground but is still visible to the user (its onPause() method has

been called) This might occur for example if the foreground activity started a dialog which allows the

previous activity to be seen behind it

o It hosts a Service thats bound to a visible (or foreground) activity

A visible process is considered extremely important and will not be killed unless doing so is required to

keep all foreground processes running

3 Service process

A process that is running a service that has been started with the startService() method and does not

fall into either of the two higher categories Although service processes are not directly tied to anything

the user sees they are generally doing things that the user cares about (such as playing music in the

background or downloading data on the network) so the system keeps them running unless theres

not enough memory to retain them along with all foreground and visible processes

4 Background process

A process holding an activity thats not currently visible to the user (the activitys onStop() method has

been called) These processes have no direct impact on the user experience and the system can kill

them at any time to reclaim memory for a foreground visible or service process Usually there are

many background processes running so they are kept in an LRU (least recently used) list to ensure

that the process with the activity that was most recently seen by the user is the last to be killed If an

activity implements its lifecycle methods correctly and saves its current state killing its process will not

have a visible effect on the user experience because when the user navigates back to the activity the

activity restores all of its visible state See the Activities document for information about saving and

restoring state

5 Empty process

A process that doesnt hold any active application components The only reason to keep this kind of

process alive is for caching purposes to improve startup time the next time a component needs to run

in it The system often kills these processes in order to balance overall system resources between

process caches and the underlying kernel caches

Android ranks a process at the highest level it can based upon the importance of the components

currently active in the process For example if a process hosts a service and a visible activity the

process is ranked as a visible process not a service process

In addition a processs ranking might be increased because other processes are dependent on itmdasha

process that is serving another process can never be ranked lower than the process it is serving For

example if a content provider in process A is serving a client in process B or if a service in process A

is bound to a component in process B process A is always considered at least as important as

process B

Because a process running a service is ranked higher than a process with background activities an

activity that initiates a long-running operation might do well to start a service for that operation rather

than simply create a worker threadmdashparticularly if the operation will likely outlast the activity For

example an activity thats uploading a picture to a web site should start a service to perform the

upload so that the upload can continue in the background even if the user leaves the activity Using a

service guarantees that the operation will have at least service process priority regardless of what

happens to the activity This is the same reason that broadcast receivers should employ services

rather than simply put time-consuming operations in a thread

Threads

When an application is launched the system creates a thread of execution for the application called

main This thread is very important because it is in charge of dispatching events to the appropriate

user interface widgets including drawing events It is also the thread in which your application interacts

with components from the Android UI toolkit (components from the androidwidget and androidview

packages) As such the main thread is also sometimes called the UI thread

The system does not create a separate thread for each instance of a component All components that

run in the same process are instantiated in the UI thread and system calls to each component are

dispatched from that thread Consequently methods that respond to system callbacks (such as

onKeyDown() to report user actions or a lifecycle callback method) always run in the UI thread of the

process

For instance when the user touches a button on the screen your apps UI thread dispatches the touch

event to the widget which in turn sets its pressed state and posts an invalidate request to the event

queue The UI thread dequeues the request and notifies the widget that it should redraw itself

When your app performs intensive work in response to user interaction this single thread model can

yield poor performance unless you implement your application properly Specifically if everything is

happening in the UI thread performing long operations such as network access or database queries

will block the whole UI When the thread is blocked no events can be dispatched including drawing

events From the users perspective the application appears to hang Even worse if the UI thread is

blocked for more than a few seconds (about 5 seconds currently) the user is presented with the

infamous application not responding (ANR) dialog The user might then decide to quit your

application and uninstall it if they are unhappy

Additionally the Andoid UI toolkit is not thread-safe So you must not manipulate your UI from a

worker threadmdashyou must do all manipulation to your user interface from the UI thread Thus there are

simply two rules to Androids single thread model

1 Do not block the UI thread

2 Do not access the Android UI toolkit from outside the UI thread

Worker threads

Because of the single thread model described above its vital to the responsiveness of your

applications UI that you do not block the UI thread If you have operations to perform that are not

instantaneous you should make sure to do them in separate threads (background or worker

threads)

For example below is some code for a click listener that downloads an image from a separate thread

and displays it in an ImageView

public void onClick(View v) new Thread(new Runnable() public void run() Bitmap b = loadImageFromNetwork(httpexamplecomimagepng) mImageViewsetImageBitmap(b) )start()

At first this seems to work fine because it creates a new thread to handle the network operation

However it violates the second rule of the single-threaded model do not access the Android UI toolkit

from outside the UI threadmdashthis sample modifies the ImageView from the worker thread instead of the

UI thread This can result in undefined and unexpected behavior which can be difficult and time-

consuming to track down

To fix this problem Android offers several ways to access the UI thread from other threads Here is a

list of methods that can help

ActivityrunOnUiThread(Runnable)

Viewpost(Runnable)

ViewpostDelayed(Runnable long)

For example you can fix the above code by using the Viewpost(Runnable) method

public void onClick(View v) new Thread(new Runnable() public void run() final Bitmap bitmap = loadImageFromNetwork(httpexamplecomimagepng) mImageViewpost(new Runnable() public void run() mImageViewsetImageBitmap(bitmap) ) )start()

Now this implementation is thread-safe the network operation is done from a separate thread while

the ImageView is manipulated from the UI thread

However as the complexity of the operation grows this kind of code can get complicated and difficult

to maintain To handle more complex interactions with a worker thread you might consider using a

Handler in your worker thread to process messages delivered from the UI thread Perhaps the best

solution though is to extend the AsyncTask class which simplifies the execution of worker thread

tasks that need to interact with the UI

Using AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface It performs the blocking

operations in a worker thread and then publishes the results on the UI thread without requiring you to

handle threads andor handlers yourself

To use it you must subclass AsyncTask and implement the doInBackground() callback method which

runs in a pool of background threads To update your UI you should implement onPostExecute()

which delivers the result from doInBackground() and runs in the UI thread so you can safely update

your UI You can then run the task by calling execute() from the UI thread

For example you can implement the previous example using AsyncTask this way

public void onClick(View v) new DownloadImageTask()execute(httpexamplecomimagepng) private class DownloadImageTask extends AsyncTaskltString Void Bitmapgt The system calls this to perform work in a worker thread and delivers it the parameters given to AsyncTaskexecute() protected Bitmap doInBackground(String urls) return loadImageFromNetwork(urls[0])

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 17: 03 services

To use AIDL directly you must create an aidl file that defines the programming interface The

Android SDK tools use this file to generate an abstract class that implements the interface and

handles IPC which you can then extend within your service

Note Most applications should not use AIDL to create a bound service because it may require

multithreading capabilities and can result in a more complicated implementation As such AIDL is

not suitable for most applications and this document does not discuss how to use it for your

service If youre certain that you need to use AIDL directly see the AIDL document

Extending the Binder class

If your service is used only by the local application and does not need to work across processes then

you can implement your own Binder class that provides your client direct access to public methods in

the service

Note This works only if the client and service are in the same application and process which is

most common For example this would work well for a music application that needs to bind an

activity to its own service thats playing music in the background

Heres how to set it up

1 In your service create an instance of Binder that either

o contains public methods that the client can call

o returns the current Service instance which has public methods the client can call

o or returns an instance of another class hosted by the service with public methods the client can call

2 Return this instance of Binder from the onBind() callback method

3 In the client receive the Binder from the onServiceConnected() callback method and make calls to the

bound service using the methods provided

Note The reason the service and client must be in the same application is so the client can cast

the returned object and properly call its APIs The service and client must also be in the same

process because this technique does not perform any marshalling across processes

For example heres a service that provides clients access to methods in the service through a Binder

implementation

public class LocalService extends Service

Binder given to clients

private final IBinder mBinder = new LocalBinder()

Random number generator

private final Random mGenerator = new Random()

Class used for the client Binder Because we know this service always

runs in the same process as its clients we dont need to deal with IPC

public class LocalBinder extends Binder

LocalService getService()

Return this instance of LocalService so clients can call public methods

return LocalServicethis

Override

public IBinder onBind(Intent intent)

return mBinder

method for clients

public int getRandomNumber()

return mGeneratornextInt(100)

The LocalBinder provides the getService() method for clients to retrieve the current instance of

LocalService This allows clients to call public methods in the service For example clients can call

getRandomNumber() from the service

Heres an activity that binds to LocalService and calls getRandomNumber() when a button is clicked

public class BindingActivity extends Activity

LocalService mService

boolean mBound = false

Override

protected void onCreate(Bundle savedInstanceState)

superonCreate(savedInstanceState)

setContentView(Rlayoutmain)

Override

protected void onStart()

superonStart()

Bind to LocalService

Intent intent = new Intent(this LocalServiceclass)

bindService(intent mConnection ContextBIND_AUTO_CREATE)

Override

protected void onStop()

superonStop()

Unbind from the service

if (mBound)

unbindService(mConnection)

mBound = false

Called when a button is clicked (the button in the layout file attaches to

this method with the androidonClick attribute)

public void onButtonClick(View v)

if (mBound)

Call a method from the LocalService

However if this call were something that might hang then this request should

occur in a separate thread to avoid slowing down the activity performance

int num = mServicegetRandomNumber()

ToastmakeText(this number + num ToastLENGTH_SHORT)show()

Defines callbacks for service binding passed to bindService()

private ServiceConnection mConnection = new ServiceConnection()

Override

public void onServiceConnected(ComponentName className

IBinder service)

Weve bound to LocalService cast the IBinder and get LocalService instance

LocalBinder binder = (LocalBinder) service

mService = bindergetService()

mBound = true

Override

public void onServiceDisconnected(ComponentName arg0)

mBound = false

The above sample shows how the client binds to the service using an implementation of

ServiceConnection and the onServiceConnected() callback The next section provides more

information about this process of binding to the service

Note The example above doesnt explicitly unbind from the service but all clients should unbind

at an appropriate time (such as when the activity pauses)

For more sample code see the LocalServicejava class and the LocalServiceActivitiesjava class in

ApiDemos

Using a Messenger

Compared to AIDL

When you need to perform IPC using a Messenger for your interface is simpler than implementing it

with AIDL because Messenger queues all calls to the service whereas a pure AIDL interface sends

simultaneous requests to the service which must then handle multi-threading

For most applications the service doesnt need to perform multi-threading so using a Messenger

allows the service to handle one call at a time If its important that your service be multi-threaded then

you should use AIDL to define your interface

If you need your service to communicate with remote processes then you can use a Messenger to

provide the interface for your service This technique allows you to perform interprocess

communication (IPC) without the need to use AIDL

Heres a summary of how to use a Messenger

The service implements a Handler that receives a callback for each call from a client

The Handler is used to create a Messenger object (which is a reference to the Handler)

The Messenger creates an IBinder that the service returns to clients from onBind()

Clients use the IBinder to instantiate the Messenger (that references the services Handler) which the

client uses to send Message objects to the service

The service receives each Message in its Handlermdashspecifically in the handleMessage() method

In this way there are no methods for the client to call on the service Instead the client delivers

messages (Message objects) that the service receives in its Handler

Heres a simple example service that uses a Messenger interface

public class MessengerService extends Service Command to the service to display a message static final int MSG_SAY_HELLO = 1 Handler of incoming messages from clients class IncomingHandler extends Handler Override public void handleMessage(Message msg) switch (msgwhat) case MSG_SAY_HELLO ToastmakeText(getApplicationContext() hello ToastLENGTH_SHORT)show() break default superhandleMessage(msg) Target we publish for clients to send messages to IncomingHandler final Messenger mMessenger = new Messenger(new IncomingHandler()) When binding to the service we return an interface to our messenger for sending messages to the service Override public IBinder onBind(Intent intent) ToastmakeText(getApplicationContext() binding ToastLENGTH_SHORT)show() return mMessengergetBinder()

Notice that the handleMessage() method in the Handler is where the service receives the incoming

Message and decides what to do based on the what member

All that a client needs to do is create a Messenger based on the IBinder returned by the service and

send a message using send() For example heres a simple activity that binds to the service and

delivers the MSG_SAY_HELLO message to the service

public class ActivityMessenger extends Activity Messenger for communicating with the service Messenger mService = null Flag indicating whether we have called bind on the service boolean mBound Class for interacting with the main interface of the service private ServiceConnection mConnection = new ServiceConnection() public void onServiceConnected(ComponentName className IBinder service) This is called when the connection with the service has been established giving us the object we can use to interact with the service We are communicating with the service using a Messenger so here we get a client-side representation of that from the raw IBinder object mService = new Messenger(service) mBound = true public void onServiceDisconnected(ComponentName className) This is called when the connection with the service has been unexpectedly disconnected -- that is its process crashed mService = null mBound = false public void sayHello(View v) if (mBound) return Create and send a message to the service using a supported what value Message msg = Messageobtain(null MessengerServiceMSG_SAY_HELLO 0 0) try mServicesend(msg) catch (RemoteException e) eprintStackTrace() Override protected void onCreate(Bundle savedInstanceState) superonCreate(savedInstanceState) setContentView(Rlayoutmain)

Override protected void onStart() superonStart() Bind to the service bindService(new Intent(this MessengerServiceclass) mConnection ContextBIND_AUTO_CREATE) Override protected void onStop() superonStop() Unbind from the service if (mBound) unbindService(mConnection) mBound = false

Notice that this example does not show how the service can respond to the client If you want the

service to respond then you need to also create a Messenger in the client Then when the client

receives the onServiceConnected() callback it sends a Message to the service that includes the

clients Messenger in the replyTo parameter of the send() method

You can see an example of how to provide two-way messaging in the MessengerServicejava (service)

and MessengerServiceActivitiesjava (client) samples

Binding to a Service

Application components (clients) can bind to a service by calling bindService() The Android system

then calls the services onBind() method which returns an IBinder for interacting with the service

The binding is asynchronous bindService() returns immediately and does not return the IBinder to the

client To receive the IBinder the client must create an instance of ServiceConnection and pass it to

bindService() The ServiceConnection includes a callback method that the system calls to deliver the

IBinder

Note Only activities services and content providers can bind to a servicemdashyou cannot bind to a

service from a broadcast receiver

So to bind to a service from your client you must

1 Implement ServiceConnection

Your implementation must override two callback methods

onServiceConnected()

The system calls this to deliver the IBinder returned by the services onBind() method

onServiceDisconnected()

The Android system calls this when the connection to the service is unexpectedly lost such as

when the service has crashed or has been killed This is not called when the client unbinds

2 Call bindService() passing the ServiceConnection implementation

3 When the system calls your onServiceConnected() callback method you can begin making calls to the

service using the methods defined by the interface

4 To disconnect from the service call unbindService()

When your client is destroyed it will unbind from the service but you should always unbind when

youre done interacting with the service or when your activity pauses so that the service can shutdown

while its not being used (Appropriate times to bind and unbind is discussed more below)

For example the following snippet connects the client to the service created above by extending the

Binder class so all it must do is cast the returned IBinder to the LocalService class and request the

LocalService instance

LocalService mService private ServiceConnection mConnection = new ServiceConnection() Called when the connection with the service is established public void onServiceConnected(ComponentName className IBinder service) Because we have bound to an explicit service that is running in our own process we can cast its IBinder to a concrete class and directly access it LocalBinder binder = (LocalBinder) service mService = bindergetService() mBound = true Called when the connection with the service disconnects unexpectedly public void onServiceDisconnected(ComponentName className) Loge(TAG onServiceDisconnected) mBound = false

With this ServiceConnection the client can bind to a service by passing this it to bindService() For

example

Intent intent = new Intent(this LocalServiceclass) bindService(intent mConnection ContextBIND_AUTO_CREATE)

The first parameter of bindService() is an Intent that explicitly names the service to bind (thought the

intent could be implicit)

The second parameter is the ServiceConnection object

The third parameter is a flag indicating options for the binding It should usually be

BIND_AUTO_CREATE in order to create the service if its not already alive Other possible values are

BIND_DEBUG_UNBIND and BIND_NOT_FOREGROUND or 0 for none

Additional notes

Here are some important notes about binding to a service

You should always trap DeadObjectException exceptions which are thrown when the connection has

broken This is the only exception thrown by remote methods

Objects are reference counted across processes

You should usually pair the binding and unbinding during matching bring-up and tear-down moments

of the clients lifecycle For example

o If you only need to interact with the service while your activity is visible you should bind during

onStart() and unbind during onStop()

o If you want your activity to receive responses even while it is stopped in the background then you can

bind during onCreate() and unbind during onDestroy() Beware that this implies that your activity needs

to use the service the entire time its running (even in the background) so if the service is in another

process then you increase the weight of the process and it becomes more likely that the system will

kill it

Note You should usually not bind and unbind during your activitys onResume() and onPause()

because these callbacks occur at every lifecycle transition and you should keep the processing that

occurs at these transitions to a minimum Also if multiple activities in your application bind to the same

service and there is a transition between two of those activities the service may be destroyed and

recreated as the current activity unbinds (during pause) before the next one binds (during resume)

(This activity transition for how activities coordinate their lifecycles is described in the Activities

document)

For more sample code showing how to bind to a service see the RemoteServicejava class in

ApiDemos

Managing the Lifecycle of a Bound Service

Figure 1 The lifecycle for a service

that is started and also allows binding

When a service is unbound from all

clients the Android system destroys it

(unless it was also started with

onStartCommand()) As such you

dont have to manage the lifecycle of

your service if its purely a bound

servicemdashthe Android system manages

it for you based on whether it is bound

to any clients

However if you choose to implement

the onStartCommand() callback

method then you must explicitly stop

the service because the service is

now considered to be started In this

case the service runs until the service

stops itself with stopSelf() or another

component calls stopService()

regardless of whether it is bound to

any clients

Additionally if your service is started and accepts binding then when the system calls your onUnbind()

method you can optionally return true if you would like to receive a call to onRebind() the next time a

client binds to the service (instead of receiving a call to onBind()) onRebind() returns void but the

client still receives the IBinder in its onServiceConnected() callback Below figure 1 illustrates the logic

for this kind of lifecycle

For more information about the lifecycle of an started service see the Services document

Content Providers

Content providers store and retrieve data and make it accessible to all applications Theyre the only

way to share data across applications theres no common storage area that all Android packages can

access

Android ships with a number of content providers for common data types (audio video images

personal contact information and so on) You can see some of them listed in the androidprovider

package You can query these providers for the data they contain (although for some you must

acquire the proper permission to read the data)

If you want to make your own data public you have two options You can create your own content

provider (a ContentProvider subclass) or you can add the data to an existing provider mdash if theres one

that controls the same type of data and you have permission to write to it

This document is an introduction to using content providers After a brief discussion of the

fundamentals it explores how to query a content provider how to modify data controlled by a provider

and how to create a content provider of your own

Content Provider Basics

How a content provider actually stores its data under the covers is up to its designer But all content

providers implement a common interface for querying the provider and returning results mdash as well as

for adding altering and deleting data Its an interface that clients use indirectly most generally

through ContentResolver objects You get a ContentResolver by calling getContentResolver() from

within the implementation of an Activity or other application component

ContentResolver cr = getContentResolver()

You can then use the ContentResolvers methods to interact with whatever content providers youre

interested in When a query is initiated the Android system identifies the content provider thats the

target of the query and makes sure that it is up and running The system instantiates all

ContentProvider objects you never need to do it on your own In fact you never deal directly with

ContentProvider objects at all Typically theres just a single instance of each type of ContentProvider

But it can communicate with multiple ContentResolver objects in different applications and processes

The interaction between processes is handled by the ContentResolver and ContentProvider classes

The data model

Content providers expose their data as a simple table on a database model where each row is a

record and each column is data of a particular type and meaning For example information about

people and their phone numbers might be exposed as follows

_ID NUMBER NUMBER_KEY LABEL NAME TYPE

13 (425) 555 6677 425 555 6677 Kirkland office Bully Pulpit TYPE_WORK

44 (212) 555-1234 212 555 1234 NY apartment Alan Vain TYPE_HOME

45 (212) 555-6657 212 555 6657 Downtown office Alan Vain TYPE_MOBILE

53 2015554433 201 555 4433 Love Nest Rex Cars TYPE_HOME

Every record includes a numeric _ID field that uniquely identifies the record within the table IDs can be

used to match records in related tables mdash for example to find a persons phone number in one table

and pictures of that person in another

A query returns a Cursor object that can move from record to record and column to column to read the

contents of each field It has specialized methods for reading each type of data So to read a field you

must know what type of data the field contains (Theres more on query results and Cursor objects

later)

URIs

Each content provider exposes a public URI (wrapped as a Uri object) that uniquely identifies its data

set A content provider that controls multiple data sets (multiple tables) exposes a separate URI for

each one All URIs for providers begin with the string content The content scheme identifies the

data as being controlled by a content provider

If youre defining a content provider its a good idea to also define a constant for its URI to simplify

client code and make future updates cleaner Android defines CONTENT_URI constants for all the

providers that come with the platform For example the URI for the table that matches phone numbers

to people and the URI for the table that holds pictures of people (both controlled by the Contacts

content provider) are

androidproviderContactsPhonesCONTENT_URI

androidproviderContactsPhotosCONTENT_URI

The URI constant is used in all interactions with the content provider Every ContentResolver method

takes the URI as its first argument Its what identifies which provider the ContentResolver should talk

to and which table of the provider is being targeted

Querying a Content Provider

You need three pieces of information to query a content provider

The URI that identifies the provider

The names of the data fields you want to receive

The data types for those fields

If youre querying a particular record you also need the ID for that record

Making the query

To query a content provider you can use either the ContentResolverquery() method or the

ActivitymanagedQuery() method Both methods take the same set of arguments and both return a

Cursor object However managedQuery() causes the activity to manage the life cycle of the Cursor A

managed Cursor handles all of the niceties such as unloading itself when the activity pauses and

requerying itself when the activity restarts You can ask an Activity to begin managing an unmanaged

Cursor object for you by calling ActivitystartManagingCursor()

The first argument to either query() or managedQuery() is the provider URI mdash the CONTENT_URI

constant that identifies a particular ContentProvider and data set (see URIs earlier)

To restrict a query to just one record you can append the _ID value for that record to the URI mdash that

is place a string matching the ID as the last segment of the path part of the URI For example if the ID

is 23 the URI would be

content 23

There are some helper methods particularly ContentUriswithAppendedId() and

UriwithAppendedPath() that make it easy to append an ID to a URI Both are static methods that

return a Uri object with the ID added So for example if you were looking for record 23 in the database

of people contacts you might construct a query as follows

import androidproviderContactsPeople import androidcontentContentUris import androidnetUri import androiddatabaseCursor Use the ContentUris method to produce the base URI for the contact with _ID == 23 Uri myPerson = ContentUriswithAppendedId(PeopleCONTENT_URI 23) Alternatively use the Uri method to produce the base URI It takes a string rather than an integer Uri myPerson = UriwithAppendedPath(PeopleCONTENT_URI 23) Then query for this specific record Cursor cur = managedQuery(myPerson null null null null)

The other arguments to the query() and managedQuery() methods delimit the query in more detail

They are

The names of the data columns that should be returned A null value returns all columns Otherwise

only columns that are listed by name are returned All the content providers that come with the

platform define constants for their columns For example the androidproviderContactsPhones class

defines constants for the names of the columns in the phone table illustrated earlier ampmdash _ID

NUMBER NUMBER_KEY NAME and so on

A filter detailing which rows to return formatted as an SQL WHERE clause (excluding the WHERE

itself) A null value returns all rows (unless the URI limits the query to a single record)

Selection arguments

A sorting order for the rows that are returned formatted as an SQL ORDER BY clause (excluding the

ORDER BY itself) A null value returns the records in the default order for the table which may be

unordered

Lets look at an example query to retrieve a list of contact names and their primary phone numbers

import androidproviderContactsPeople import androiddatabaseCursor Form an array specifying which columns to return String[] projection = new String[] People_ID People_COUNT PeopleNAME PeopleNUMBER Get the base URI for the People table in the Contacts content provider Uri contacts = PeopleCONTENT_URI Make the query Cursor managedCursor = managedQuery(contacts projection Which columns to return null Which rows to return (all rows) null Selection arguments (none) Put the results in ascending order by name PeopleNAME + ASC)

This query retrieves data from the People table of the Contacts content provider It gets the name

primary phone number and unique record ID for each contact It also reports the number of records

that are returned as the _COUNT field of each record

The constants for the names of the columns are defined in various interfaces mdash _ID and _COUNT in

BaseColumns NAME in PeopleColumns and NUMBER in PhoneColumns The ContactsPeople

class implements each of these interfaces which is why the code example above could refer to them

using just the class name

What a query returns

A query returns a set of zero or more database records The names of the columns their default order

and their data types are specific to each content provider But every provider has an _ID column

which holds a unique numeric ID for each record Every provider can also report the number of records

returned as the _COUNT column its value is the same for all rows

Here is an example result set for the query in the previous section

_ID _COUNT NAME NUMBER

44 3 Alan Vain 212 555 1234

13 3 Bully Pulpit 425 555 6677

53 3 Rex Cars 201 555 4433

The retrieved data is exposed by a Cursor object that can be used to iterate backward or forward

through the result set You can use this object only to read the data To add modify or delete data

you must use a ContentResolver object

Reading retrieved data

The Cursor object returned by a query provides access to a recordset of results If you have queried

for a specific record by ID this set will contain only one value Otherwise it can contain multiple

values (If there are no matches it can also be empty) You can read data from specific fields in the

record but you must know the data type of the field because the Cursor object has a separate method

for reading each type of data mdash such as getString() getInt() and getFloat() (However for most types

if you call the method for reading strings the Cursor object will give you the String representation of

the data) The Cursor lets you request the column name from the index of the column or the index

number from the column name

The following snippet demonstrates reading names and phone numbers from the query illustrated

earlier

import androidproviderContactsPeople private void getColumnData(Cursor cur) if (curmoveToFirst()) String name String phoneNumber int nameColumn = curgetColumnIndex(PeopleNAME) int phoneColumn = curgetColumnIndex(PeopleNUMBER) String imagePath do Get the field values name = curgetString(nameColumn) phoneNumber = curgetString(phoneColumn) Do something with the values while (curmoveToNext())

If a query can return binary data such as an image or sound the data may be directly entered in the

table or the table entry for that data may be a string specifying a content URI that you can use to get

the data In general smaller amounts of data (say from 20 to 50K or less) are most often directly

entered in the table and can be read by calling CursorgetBlob() It returns a byte array

If the table entry is a content URI you should never try to open and read the file directly (for one thing

permissions problems can make this fail) Instead you should call ContentResolveropenInputStream()

to get an InputStream object that you can use to read the data

Modifying Data

Data kept by a content provider can be modified by

Adding new records

Adding new values to existing records

Batch updating existing records

Deleting records

All data modification is accomplished using ContentResolver methods Some content providers require

a more restrictive permission for writing data than they do for reading it If you dont have permission to

write to a content provider the ContentResolver methods will fail

Adding records

To add a new record to a content provider first set up a map of key-value pairs in a ContentValues

object where each key matches the name of a column in the content provider and the value is the

desired value for the new record in that column Then call ContentResolverinsert() and pass it the URI

of the provider and the ContentValues map This method returns the full URI of the new record mdash that

is the providers URI with the appended ID for the new record You can then use this URI to query and

get a Cursor over the new record and to further modify the record Heres an example

import androidproviderContactsPeople import androidcontentContentResolver import androidcontentContentValues ContentValues values = new ContentValues() Add Abraham Lincoln to contacts and make him a favorite valuesput(PeopleNAME Abraham Lincoln) 1 = the new contact is added to favorites 0 = the new contact is not added to favorites valuesput(PeopleSTARRED 1) Uri uri = getContentResolver()insert(PeopleCONTENT_URI values)

Adding new values

Once a record exists you can add new information to it or modify existing information For example

the next step in the example above would be to add contact information mdash like a phone number or an

IM or e-mail address mdash to the new entry

The best way to add to a record in the Contacts database is to append the name of the table where the

new data goes to the URI for the record then use the amended URI to add the new data values Each

Contacts table exposes a name for this purpose as a CONTENT_DIRECTORY constant The following

code continues the previous example by adding a phone number and e-mail address for the record

just created

Uri phoneUri = null Uri emailUri = null Add a phone number for Abraham Lincoln Begin with the URI for the new record just returned by insert() it ends with the _ID of the new record so we dont have to add the ID ourselves Then append the designation for the phone table to this URI and use the resulting URI to insert the phone number phoneUri = UriwithAppendedPath(uri PeoplePhonesCONTENT_DIRECTORY) valuesclear() valuesput(PeoplePhonesTYPE PeoplePhonesTYPE_MOBILE) valuesput(PeoplePhonesNUMBER 1233214567) getContentResolver()insert(phoneUri values) Now add an email address in the same way emailUri = UriwithAppendedPath(uri PeopleContactMethodsCONTENT_DIRECTORY) valuesclear() ContactMethodsKIND is used to distinguish different kinds of contact methods such as email IM etc valuesput(PeopleContactMethodsKIND ContactsKIND_EMAIL) valuesput(PeopleContactMethodsDATA testexamplecom) valuesput(PeopleContactMethodsTYPE PeopleContactMethodsTYPE_HOME) getContentResolver()insert(emailUri values)

You can place small amounts of binary data into a table by calling the version of ContentValuesput()

that takes a byte array That would work for a small icon-like image or a short audio clip for example

However if you have a large amount of binary data to add such as a photograph or a complete song

put a content URI for the data in the table and call ContentResolveropenOutputStream() with the files

URI (That causes the content provider to store the data in a file and record the file path in a hidden

field of the record)

In this regard the MediaStore content provider the main provider that dispenses image audio and

video data employs a special convention The same URI that is used with query() or managedQuery()

to get meta-information about the binary data (such as the caption of a photograph or the date it was

taken) is used with openInputStream() to get the data itself Similarly the same URI that is used with

insert() to put meta-information into a MediaStore record is used with openOutputStream() to place the

binary data there The following code snippet illustrates this convention

import androidproviderMediaStoreImagesMedia import androidcontentContentValues import javaioOutputStream Save the name and description of an image in a ContentValues map ContentValues values = new ContentValues(3) valuesput(MediaDISPLAY_NAME road_trip_1) valuesput(MediaDESCRIPTION Day 1 trip to Los Angeles) valuesput(MediaMIME_TYPE imagejpeg) Add a new record without the bitmap but with the values just set insert() returns the URI of the new record Uri uri = getContentResolver()insert(MediaEXTERNAL_CONTENT_URI values) Now get a handle to the file for that record and save the data into it Here sourceBitmap is a Bitmap object representing the file to save to the database try OutputStream outStream = getContentResolver()openOutputStream(uri) sourceBitmapcompress(BitmapCompressFormatJPEG 50 outStream) outStreamclose() catch (Exception e) Loge(TAG exception while writing image e)

Batch updating records

To batch update a group of records (for example to change NY to New York in all fields) call the

ContentResolverupdate() method with the columns and values to change

Deleting a record

To delete a single record call ContentResolverdelete() with the URI of a specific row

To delete multiple rows call ContentResolverdelete() with the URI of the type of record to delete (for

example androidproviderContactsPeopleCONTENT_URI) and an SQL WHERE clause defining

which rows to delete (Caution Be sure to include a valid WHERE clause if youre deleting a general

type or you risk deleting more records than you intended)

Creating a Content Provider

To create a content provider you must

Set up a system for storing the data Most content providers store their data using Androids file

storage methods or SQLite databases but you can store your data any way you want Android

provides the SQLiteOpenHelper class to help you create a database and SQLiteDatabase to manage

it

Extend the ContentProvider class to provide access to the data

Declare the content provider in the manifest file for your application (AndroidManifestxml)

The following sections have notes on the last two of these tasks

Extending the ContentProvider class

You define a ContentProvider subclass to expose your data to others using the conventions expected

by ContentResolver and Cursor objects Principally this means implementing six abstract methods

declared in the ContentProvider class

query()

insert()

update()

delete()

getType()

onCreate()

The query() method must return a Cursor object that can iterate over the requested data Cursor itself

is an interface but Android provides some ready-made Cursor objects that you can use For example

SQLiteCursor can iterate over data stored in an SQLite database You get the Cursor object by calling

any of the SQLiteDatabase classs query() methods There are other Cursor implementations mdash such

as MatrixCursor mdash for data not stored in a database

Because these ContentProvider methods can be called from various ContentResolver objects in

different processes and threads they must be implemented in a thread-safe manner

As a courtesy you might also want to call ContentResolvernotifyChange() to notify listeners when

there are modifications to the data

Beyond defining the subclass itself there are other steps you should take to simplify the work of clients

and make the class more accessible

Define a public static final Uri named CONTENT_URI This is the string that represents the full content

URI that your content provider handles You must define a unique string for this value The best

solution is to use the fully-qualified class name of the content provider (made lowercase) So for

example the URI for a TransportationProvider class could be defined as follows

public static final Uri CONTENT_URI = Uriparse(contentcomexamplecodelabtransportationprovider)

If the provider has subtables also define CONTENT_URI constants for each of the subtables These

URIs should all have the same authority (since that identifies the content provider) and be

distinguished only by their paths For example

contentcomexamplecodelabtransportationprovidertrain

contentcomexamplecodelabtransportationproviderairdomestic

contentcomexamplecodelabtransportationproviderairinternational

For an overview of content URIs see the Content URI Summary at the end of this document

Define the column names that the content provider will return to clients If you are using an underlying

database these column names are typically identical to the SQL database column names they

represent Also define public static String constants that clients can use to specify the columns in

queries and other instructions

Be sure to include an integer column named _id (with the constant _ID) for the IDs of the records

You should have this field whether or not you have another field (such as a URL) that is also unique

among all records If youre using the SQLite database the _ID field should be the following type

INTEGER PRIMARY KEY AUTOINCREMENT

The AUTOINCREMENT descriptor is optional But without it SQLite increments an ID counter field to

the next number above the largest existing number in the column If you delete the last row the next

row added will have the same ID as the deleted row AUTOINCREMENT avoids this by having SQLite

increment to the next largest value whether deleted or not

Carefully document the data type of each column Clients need this information to read the data

If you are handling a new data type you must define a new MIME type to return in your

implementation of ContentProvidergetType() The type depends in part on whether or not the content

URI submitted to getType() limits the request to a specific record Theres one form of the MIME type

for a single record and another for multiple records Use the Uri methods to help determine what is

being requested Here is the general format for each type

o For a single record vndandroidcursoritemvndyourcompanynamecontenttype

For example a request for train record 122 like this URI

contentcomexampletransportationprovidertrains122

might return this MIME type

vndandroidcursoritemvndexamplerail

o For multiple records vndandroidcursordirvndyourcompanynamecontenttype

For example a request for all train records like the following URI

contentcomexampletransportationprovidertrains

might return this MIME type

vndandroidcursordirvndexamplerail

If you are exposing byte data thats too big to put in the table itself mdash such as a large bitmap file mdash the

field that exposes the data to clients should actually contain a content URI string This is the field that

gives clients access to the data file The record should also have another field named _data that lists

the exact file path on the device for that file This field is not intended to be read by the client but by

the ContentResolver The client will call ContentResolveropenInputStream() on the user-facing field

holding the URI for the item The ContentResolver will request the _data field for that record and

because it has higher permissions than a client it should be able to access that file directly and return

a read wrapper for the file to the client

For an example of a private content provider implementation see the NodePadProvider class in the

Notepad sample application that ships with the SDK

Declaring the content provider

To let the Android system know about the content provider youve developed declare it with a

ltprovidergt element in the applications AndroidManifestxml file Content providers that are not

declared in the manifest are not visible to the Android system

The name attribute is the fully qualified name of the ContentProvider subclass The authorities attribute

is the authority part of the content URI that identifies the provider For example if the ContentProvider

subclass is AutoInfoProvider the ltprovidergt element might look like this

ltprovider androidname=comexampleautosAutoInfoProvider androidauthorities=comexampleautosautoinfoprovider gt ltprovidergt

Note that the authorities attribute omits the path part of a content URI For example if

AutoInfoProvider controlled subtables for different types of autos or different manufacturers

contentcomexampleautosautoinfoproviderhonda

contentcomexampleautosautoinfoprovidergmcompact

contentcomexampleautosautoinfoprovidergmsuv

those paths would not be declared in the manifest The authority is what identifies the provider not the

path your provider can interpret the path part of the URI in any way you choose

Other ltprovidergt attributes can set permissions to read and write data provide for an icon and text

that can be displayed to users enable and disable the provider and so on Set the multiprocess

attribute to true if data does not need to be synchronized between multiple running versions of the

content provider This permits an instance of the provider to be created in each client process

eliminating the need to perform IPC

Content URI Summary

Here is a recap of the important parts of a content URI

A Standard prefix indicating that the data is controlled by a content provider Its never modified

B The authority part of the URI it identifies the content provider For third-party applications this should

be a fully-qualified class name (reduced to lowercase) to ensure uniqueness The authority is declared

in the ltprovidergt elements authorities attribute

ltprovider androidname=TransportationProvider androidauthorities=comexampletransportationprovider gt

C The path that the content provider uses to determine what kind of data is being requested This can be

zero or more segments long If the content provider exposes only one type of data (only trains for

example) it can be absent If the provider exposes several types including subtypes it can be several

segments long mdash for example landbus landtrain seaship and seasubmarine to give four

possibilities

D The ID of the specific record being requested if any This is the _ID value of the requested record If

the request is not limited to a single record this segment and the trailing slash are omitted

contentcomexampletransportationprovidertrains

Intent and intent filters

Three of the core components of an application mdash activities services and broadcast receivers mdash 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 mdash 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 ContextstartActivity() or ActivitystartActivityForResult() to launch an

activity or get an existing activity to do something new (It can also be passed to ActivitysetResult() to

return information to the activity that called startActivityForResult())

An Intent object is passed to ContextstartService() to initiate a service or deliver new instructions to an

ongoing service Similarly an intent can be passed to ContextbindService() to establish a connection

between the calling component and a target service It can optionally initiate the service if its not

already running

Intent objects passed to any of the broadcast methods (such as ContextsendBroadcast()

ContextsendOrderedBroadcast() or ContextsendStickyBroadcast()) 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 mdash how it resolves which component should receive an intent message For

intents that dont explicitly name a target component this process involves testing the Intent object

against intent filters associated with potential targets

Intent Objects

An Intent object is a bundle of information It contains information of interest to the component that

receives the intent (such as the action to be taken and the data to act on) plus information of interest to

the Android system (such as the category of component that should handle the intent and instructions

on how to launch a target activity) Principally it can contain the following

Component name

The name of the component that should handle the intent This field is a ComponentName

object mdash a combination of the fully qualified class name of the target component (for example

comexampleprojectappFreneticActivity) and the package name set in the manifest file of the

application where the component resides (for example comexampleproject) The package

part of the component name and the package name set in the manifest do not necessarily have

to match

The component name is optional If it is set the Intent object is delivered to an instance of the

designated class If it is not set Android uses other information in the Intent object to locate a

suitable target mdash see Intent Resolution later in this document

The component name is set by setComponent() setClass() or setClassName() and read by

getComponent()

Action

A string naming the action to be performed mdash or in the case of broadcast intents the action

that took place and is being reported The Intent class defines a number of action constants

including these

Constant Target

component

Action

ACTION_CALL activity Initiate a phone call

ACTION_EDIT activity Display data for the user to edit

ACTION_MAIN activity Start up as the initial activity of a task

with no data input and no returned

output

ACTION_SYNC activity Synchronize data on a server with

data on the mobile device

ACTION_BATTERY_LOW broadcast

receiver

A warning that the battery is low

ACTION_HEADSET_PLUG broadcast

receiver

A headset has been plugged into the

device or unplugged from it

ACTION_SCREEN_ON broadcast

receiver

The screen has been turned on

ACTION_TIMEZONE_CHANGED broadcast

receiver

The setting for the time zone has

changed

See the Intent class description for a list of pre-defined constants for generic actions Other

actions are defined elsewhere in the Android API You can also define your own action strings

for activating the components in your application Those you invent should include the

application package as a prefix mdash for example comexampleprojectSHOW_COLOR

The action largely determines how the rest of the intent is structured mdash particularly the data and

extras fields mdash much as a method name determines a set of arguments and a return value For

this reason its a good idea to use action names that are as specific as possible and to couple

them tightly to the other fields of the intent In other words instead of defining an action in

isolation define an entire protocol for the Intent objects your components can handle

The action in an Intent object is set by the setAction() method and read by getAction()

Data

The URI of the data to be acted on and the MIME type of that data Different actions are paired

with different kinds of data specifications For example if the action field is ACTION_EDIT the

data field would contain the URI of the document to be displayed for editing If the action is

ACTION_CALL the data field would be a tel URI with the number to call Similarly if the action

is ACTION_VIEW and the data field is an http URI the receiving activity would be called upon

to download and display whatever data the URI refers to

When matching an intent to a component that is capable of handling the data its often

important to know the type of data (its MIME type) in addition to its URI For example a

component able to display image data should not be called upon to play an audio file

In many cases the data type can be inferred from the URI mdash particularly content URIs which

indicate that the data is located on the device and controlled by a content provider (see the

separate discussion on content providers) But the type can also be explicitly set in the Intent

object The setData() method specifies data only as a URI setType() specifies it only as a

MIME type and setDataAndType() specifies it as both a URI and a MIME type The URI is read

by getData() and the type by getType()

Category

A string containing additional information about the kind of component that should handle the

intent Any number of category descriptions can be placed in an Intent object As it does for

actions the Intent class defines several category constants including these

Constant Meaning

CATEGORY_BROWSABLE The target activity can be safely invoked by the browser to

display data referenced by a link mdash for example an image or

an e-mail message

CATEGORY_GADGET The activity can be embedded inside of another activity that

hosts gadgets

CATEGORY_HOME The activity displays the home screen the first screen the

user sees when the device is turned on or when the HOME

key is pressed

CATEGORY_LAUNCHER The activity can be the initial activity of a task and is listed in

the top-level application launcher

CATEGORY_PREFERENCE The target activity is a preference panel

See the Intent class description for the full list of categories

The addCategory() method places a category in an Intent object removeCategory() deletes a

category previously added and getCategories() gets the set of all categories currently in the

object

Extras

Key-value pairs for additional information that should be delivered to the component handling

the intent Just as some actions are paired with particular kinds of data URIs some are paired

with particular extras For example an ACTION_TIMEZONE_CHANGED intent has a time-

zone extra that identifies the new time zone and ACTION_HEADSET_PLUG has a state

extra indicating whether the headset is now plugged in or unplugged as well as a name extra

for the type of headset If you were to invent a SHOW_COLOR action the color value would be

set in an extra key-value pair

The Intent object has a series of put() methods for inserting various types of extra data and a

similar set of get() methods for reading the data These methods parallel those for Bundle

objects In fact the extras can be installed and read as a Bundle using the putExtras() and

getExtras() methods

Flags

Flags of various sorts Many instruct the Android system how to launch an activity (for example

which task the activity should belong to) and how to treat it after its launched (for example

whether it belongs in the list of recent activities) All these flags are defined in the Intent class

The Android system and the applications that come with the platform employ Intent objects both to

send out system-originated broadcasts and to activate system-defined components To see how to

structure an intent to activate a system component consult the list of intents in the reference

Intent Resolution

Intents can be divided into two groups

Explicit intents designate the target component by its name (the component name field mentioned

earlier has a value set) Since component names would generally not be known to developers of other

applications explicit intents are typically used for application-internal messages mdash such as an activity

starting a subordinate service or launching a sister activity

Implicit intents do not name a target (the field for the component name is blank) Implicit intents are

often used to activate components in other applications

Android delivers an explicit intent to an instance of the designated target class Nothing in the Intent

object other than the component name matters for determining which component should get the intent

A different strategy is needed for implicit intents In the absence of a designated target the Android

system must find the best component (or components) to handle the intent mdash a single activity or

service to perform the requested action or the set of broadcast receivers to respond to the broadcast

announcement It does so by comparing the contents of the Intent object to intent filters structures

associated with components that can potentially receive intents Filters advertise the capabilities of a

component and delimit the intents it can handle They open the component to the possibility of

receiving implicit intents of the advertised type If a component does not have any intent filters it can

receive only explicit intents A component with filters can receive both explicit and implicit intents

Only three aspects of an Intent object are consulted when the object is tested against an intent filter

action

data (both URI and data type)

category

The extras and flags play no part in resolving which component receives an intent

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 mdash but only unwanted implicit intents (those that dont 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

components 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 mdash 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 Pads filters are described in the Note Pad Example

section later)

Filters and security

An intent filter cannot be relied on for security While it opens a component to receiving only certain

kinds of implicit intents it does nothing to prevent explicit intents from targeting the component Even

though a filter restricts the intents a component will be asked to handle to certain actions and data

sources someone could always put together an explicit intent with a different action and data source

and name the component as the target

An intent filter is an instance of the IntentFilter class However since the Android system must know

about the capabilities of a component before it can launch that component intent filters are generally

not set up in Java code but in the applications manifest file (AndroidManifestxml) as ltintent-filtergt

elements (The one exception would be filters for broadcast receivers that are registered dynamically

by calling ContextregisterReceiver() they are directly created as IntentFilter objects)

A filter has fields that parallel the action data and category fields of an Intent object An implicit intent

is tested against the filter in all three areas To be delivered to the component that owns the filter it

must pass all three tests If it fails even one of them the Android system wont deliver it to the

component mdash at least not on the basis of that filter However since a component can have multiple

intent filters an intent that does not pass through one of a components filters might make it through on

another

Each of the three tests is described in detail below

Action test

An ltintent-filtergt element in the manifest file lists actions as ltactiongt subelements For

example

ltintent-filter gt ltaction androidname=comexampleprojectSHOW_CURRENT gt ltaction androidname=comexampleprojectSHOW_RECENT gt ltaction androidname=comexampleprojectSHOW_PENDING gt ltintent-filtergt

As the example shows while an Intent object names just a single action a filter may list more

than one The list cannot be empty a filter must contain at least one ltactiongt element or it will

block all intents

To pass this test the action specified in the Intent object must match one of the actions listed in

the filter If the object or the filter does not specify an action the results are as follows

If the filter fails to list any actions there is nothing for an intent to match so all intents fail the

test No intents can get through the filter

On the other hand an Intent object that doesnt specify an action automatically passes the test

mdash as long as the filter contains at least one action

Category test

An ltintent-filtergt element also lists categories as subelements For example

ltintent-filter gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryBROWSABLE gt ltintent-filtergt

Note that the constants described earlier for actions and categories are not used in the manifest

file The full string values are used instead For instance the

androidintentcategoryBROWSABLE string in the example above corresponds to the

CATEGORY_BROWSABLE constant mentioned earlier in this document Similarly the string

androidintentactionEDIT corresponds to the ACTION_EDIT constant

For an intent to pass the category test every category in the Intent object must match a

category in the filter The filter can list additional categories but it cannot omit any that are in the

intent

In principle therefore an Intent object with no categories should always pass this test

regardless of whats in the filter Thats mostly true However with one exception Android treats

all implicit intents passed to startActivity() as if they contained at least one category

androidintentcategoryDEFAULT (the CATEGORY_DEFAULT constant) Therefore activities

that are willing to receive implicit intents must include androidintentcategoryDEFAULT in

their intent filters (Filters with androidintentactionMAIN and

androidintentcategoryLAUNCHER settings are the exception They mark activities that begin

new tasks and that are represented on the launcher screen They can include

androidintentcategoryDEFAULT in the list of categories but dont need to) See Using intent

matching later for more on these filters)

Data test

Like the action and categories the data specification for an intent filter is contained in a

subelement And as in those cases the subelement can appear multiple times or not at all For

example

ltintent-filter gt ltdata androidmimeType=videompeg androidscheme=http gt ltdata androidmimeType=audiompeg androidscheme=http gt ltintent-filtergt

Each ltdatagt element can specify a URI and a data type (MIME media type) There are

separate attributes mdash scheme host port and path mdash for each part of the URI

schemehostportpath

For example in the following URI

contentcomexampleproject200foldersubfolderetc

the scheme is content the host is comexampleproject the port is 200 and the path is

foldersubfolderetc The host and port together constitute the URI authority if a host is not

specified the port is ignored

Each of these attributes is optional but they are not independent of each other For an authority

to be meaningful a scheme must also be specified For a path to be meaningful both a scheme

and an authority must be specified

When the URI in an Intent object is compared to a URI specification in a filter its compared

only to the parts of the URI actually mentioned in the filter For example if a filter specifies only

a scheme all URIs with that scheme match the filter If a filter specifies a scheme and an

authority but no path all URIs with the same scheme and authority match regardless of their

paths If a filter specifies a scheme an authority and a path only URIs with the same scheme

authority and path match However a path specification in the filter can contain wildcards to

require only a partial match of the path

The type attribute of a ltdatagt element specifies the MIME type of the data Its more common in

filters than a URI Both the Intent object and the filter can use a wildcard for the subtype field

mdash for example text or audio mdash indicating any subtype matches

The data test compares both the URI and the data type in the Intent object to a URI and data

type specified in the filter The rules are as follows

a An Intent object that contains neither a URI nor a data type passes the test only if the filter

likewise does not specify any URIs or data types

b An Intent object that contains a URI but no data type (and a type cannot be inferred from the

URI) passes the test only if its URI matches a URI in the filter and the filter likewise does not

specify a type This will be the case only for URIs like mailto and tel that do not refer to actual

data

c An Intent object that contains a data type but not a URI passes the test only if the filter lists the

same data type and similarly does not specify a URI

d An Intent object that contains both a URI and a data type (or a data type can be inferred from

the URI) passes the data type part of the test only if its type matches a type listed in the filter It

passes the URI part of the test either if its URI matches a URI in the filter or if it has a content

or file URI and the filter does not specify a URI In other words a component is presumed to

support content and file data if its filter lists only a data type

If an intent can pass through the filters of more than one activity or service the user may be asked

which component to activate An exception is raised if no target can be found

Common cases

The last rule shown above for the data test rule (d) reflects the expectation that components are able

to get local data from a file or content provider Therefore their filters can list just a data type and do

not need to explicitly name the content and file schemes This is a typical case A ltdatagt element like

the following for example tells Android that the component can get image data from a content

provider and display it

ltdata androidmimeType=image gt

Since most available data is dispensed by content providers filters that specify a data type but not a

URI are perhaps the most common

Another common configuration is filters with a scheme and a data type For example a ltdatagt

element like the following tells Android that the component can get video data from the network and

display it

ltdata androidscheme=http androidtype=video gt

Consider for example what the browser application does when the user follows a link on a web page

It first tries to display the data (as it could if the link was to an HTML page) If it cant display the data it

puts together an implicit intent with the scheme and data type and tries to start an activity that can do

the job If there are no takers it asks the download manager to download the data That puts it under

the control of a content provider so a potentially larger pool of activities (those with filters that just

name a data type) can respond

Most applications also have a way to start fresh without a reference to any particular data Activities

that can initiate applications have filters with androidintentactionMAIN specified as the action If

they are to be represented in the application launcher they also specify the

androidintentcategoryLAUNCHER category

ltintent-filter gt ltaction androidname=code androidintentactionMAIN gt ltcategory androidname=code androidintentcategoryLAUNCHER gt ltintent-filtergt

Using intent matching

Intents are matched against intent filters not only to discover a target component to activate but also

to discover something about the set of components on the device For example the Android system

populates the application launcher the top-level screen that shows the applications that are available

for the user to launch by finding all the activities with intent filters that specify the

androidintentactionMAIN action and androidintentcategoryLAUNCHER category (as illustrated

in the previous section) It then displays the icons and labels of those activities in the launcher

Similarly it discovers the home screen by looking for the activity with androidintentcategoryHOME

in its filter

Your application can use intent matching is a similar way The PackageManager has a set of query()

methods that return all components that can accept a particular intent and a similar series of

resolve() methods that determine the best component to respond to an intent For example

queryIntentActivities() returns a list of all activities that can perform the intent passed as an argument

and queryIntentServices() returns a similar list of services Neither method activates the components

they just list the ones that can respond Theres a similar method queryBroadcastReceivers() for

broadcast receivers

Note Pad Example

The Note Pad sample application enables users to browse through a list of notes view details about

individual items in the list edit the items and add a new item to the list This section looks at the intent

filters declared in its manifest file (If youre working offline in the SDK you can find all the source files

for this sample application including its manifest file at ltsdkgtsamplesNotePadindexhtml If youre

viewing the documentation online the source files are in the Tutorials and Sample Code section here)

In its manifest file the Note Pad application declares three activities each with at least one intent filter

It also declares a content provider that manages the note data Here is the manifest file in its entirety

ltmanifest xmlnsandroid=httpschemasandroidcomapkresandroid package=comexampleandroidnotepadgt ltapplication androidicon=drawableapp_notes androidlabel=stringapp_name gt ltprovider androidname=NotePadProvider androidauthorities=comgoogleproviderNotePad gt ltactivity androidname=NotesList androidlabel=stringtitle_notes_listgt ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltactivity androidname=NoteEditor androidtheme=androidstyleThemeLight androidlabel=stringtitle_note gt ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltactivitygt

ltactivity androidname=TitleEditor androidlabel=stringtitle_edit_title androidtheme=androidstyleThemeDialoggt ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltapplicationgt ltmanifestgt

The first activity NotesList is distinguished from the other activities by the fact that it operates on a

directory of notes (the note list) rather than on a single note It would generally serve as the initial user

interface into the application It can do three things as described by its three intent filters

1 ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt

This filter declares the main entry point into the Note Pad application The standard MAIN action is an

entry point that does not require any other information in the Intent (no data specification for example)

and the LAUNCHER category says that this entry point should be listed in the application launcher

2 ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

This filter declares the things that the activity can do on a directory of notes It can allow the user to

view or edit the directory (via the VIEW and EDIT actions) or to pick a particular note from the

directory (via the PICK action)

The mimeType attribute of the ltdatagt element specifies the kind of data that these actions operate on

It indicates that the activity can get a Cursor over zero or more items (vndandroidcursordir) from a

content provider that holds Note Pad data (vndgooglenote) The Intent object that launches the

activity would include a content URI specifying the exact data of this type that the activity should open

Note also the DEFAULT category supplied in this filter Its there because the ContextstartActivity()

and ActivitystartActivityForResult() methods treat all intents as if they contained the DEFAULT

category mdash with just two exceptions

o Intents that explicitly name the target activity

o Intents consisting of the MAIN action and LAUNCHER category

Therefore the DEFAULT category is required for all filters mdash except for those with the MAIN action

and LAUNCHER category (Intent filters are not consulted for explicit intents)

3 ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

This filter describes the activitys ability to return a note selected by the user without requiring any

specification of the directory the user should choose from The GET_CONTENT action is similar to the

PICK action In both cases the activity returns the URI for a note selected by the user (In each case

its returned to the activity that called startActivityForResult() to start the NoteList activity) Here

however the caller specifies the type of data desired instead of the directory of data the user will be

picking from

The data type vndandroidcursoritemvndgooglenote indicates the type of data the activity can

return mdash a URI for a single note From the returned URI the caller can get a Cursor for exactly one

item (vndandroidcursoritem) from the content provider that holds Note Pad data (vndgooglenote)

In other words for the PICK action in the previous filter the data type indicates the type of data the

activity could display to the user For the GET_CONTENT filter it indicates the type of data the activity

can return to the caller

Given these capabilities the following intents will resolve to the NotesList activity

action androidintentactionMAIN

Launches the activity with no data specified

action androidintentactionMAIN

category androidintentcategoryLAUNCHER

Launches the activity with no data selected specified This is the actual intent used by the

Launcher to populate its top-level list All activities with filters that match this action and

category are added to the list

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of all the notes under

contentcomgoogleproviderNotePadnotes The user can then browse through the list and

get information about the items in it

action androidintentactionPICK

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of the notes under

contentcomgoogleproviderNotePadnotes The user can then pick a note from the list and

the activity will return the URI for that item back to the activity that started the NoteList activity

action androidintentactionGET_CONTENT

data type vndandroidcursoritemvndgooglenote

Asks the activity to supply a single item of Note Pad data

The second activity NoteEditor shows users a single note entry and allows them to edit it It can do

two things as described by its two intent filters

1 ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The first primary purpose of this activity is to enable the user to interact with a single note ampmdash to

either VIEW the note or EDIT it (The EDIT_NOTE category is a synonym for EDIT) The intent would

contain the URI for data matching the MIME type vndandroidcursoritemvndgooglenote mdash that is

the URI for a single specific note It would typically be a URI that was returned by the PICK or

GET_CONTENT actions of the NoteList activity

As before this filter lists the DEFAULT category so that the activity can be launched by intents that

dont explicitly specify the NoteEditor class

2 ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

The secondary purpose of this activity is to enable the user to create a new note which it will INSERT

into an existing directory of notes The intent would contain the URI for data matching the MIME type

vndandroidcursordirvndgooglenote mdash that is the URI for the directory where the note should be

placed

Given these capabilities the following intents will resolve to the NoteEditor activity

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID (For details on how content

URIs specify individual members of a group see Content Providers)

action androidintentactionEDIT

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID and to let the user edit it If

the user saves the changes the activity updates the data for the note in the content provider

action androidintentactionINSERT

data contentcomgoogleproviderNotePadnotes

Asks the activity to create a new empty note in the notes list at

contentcomgoogleproviderNotePadnotes and allow the user to edit it If the user saves the

note its URI is returned to the caller

The last activity TitleEditor enables the user to edit the title of a note This could be implemented by

directly invoking the activity (by explicitly setting its component name in the Intent) without using an

intent filter But here we take the opportunity to show how to publish alternative operations on existing

data

ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The single intent filter for this activity uses a custom action called

comandroidnotepadactionEDIT_TITLE It must be invoked on a specific note (data type

vndandroidcursoritemvndgooglenote) like the previous VIEW and EDIT actions However here the

activity displays the title contained in the note data not the content of the note itself

In addition to supporting the usual DEFAULT category the title editor also supports two other standard

categories ALTERNATIVE and SELECTED_ALTERNATIVE These categories identify activities that

can be presented to users in a menu of options (much as the LAUNCHER category identifies activities

that should be presented to user in the application launcher) Note that the filter also supplies an

explicit label (via androidlabel=stringresolve_title) to better control what users see when

presented with this activity as an alternative action to the data they are currently viewing (For more

information on these categories and building options menus see the

PackageManagerqueryIntentActivityOptions() and MenuaddIntentOptions() methods)

Given these capabilities the following intent will resolve to the TitleEditor activity

action comandroidnotepadactionEDIT_TITLE

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the title associated with note ID and allow the user to edit the title

Processes and Threads

When an application component starts and the application does not have any other components

running the Android system starts a new Linux process for the application with a single thread of

execution By default all components of the same application run in the same process and thread

(called the main thread) If an application component starts and there already exists a process for

that application (because another component from the application exists) then the component is

started within that process and uses the same thread of execution However you can arrange for

different components in your application to run in separate processes and you can create additional

threads for any process

This document discusses how processes and threads work in an Android application

Processes

By default all components of the same application run in the same process and most applications

should not change this However if you find that you need to control which process a certain

component belongs to you can do so in the manifest file

The manifest entry for each type of component elementmdashltactivitygt ltservicegt ltreceivergt and

ltprovidergtmdashsupports an androidprocess attribute that can specify a process in which that component

should run You can set this attribute so that each component runs in its own process or so that some

components share a process while others do not You can also set androidprocess so that

components of different applications run in the same processmdashprovided that the applications share the

same Linux user ID and are signed with the same certificates

The ltapplicationgt element also supports an androidprocess attribute to set a default value that

applies to all components

Android might 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 thats killed are consequently destroyed A process is started again for those components

when theres again work for them to do

When deciding which processes to kill the Android system weighs their relative importance to the

user For example it more readily shuts down a process hosting activities that are no longer visible on

screen compared to a process hosting visible activities The decision whether to terminate a process

therefore depends on the state of the components running in that process The rules used to decide

which processes to terminate is discussed below

Process lifecycle

The Android system tries to maintain an application process for as long as possible but eventually

needs to remove old processes to reclaim memory for new or more important processes To determine

which processes to keep and which to kill the system places each process into an importance

hierarchy based on the components running in the process and the state of those components

Processes with the lowest importance are eliminated first then those with the next lowest importance

and so on as necessary to recover system resources

There are five levels in the importance hierarchy The following list presents the different types of

processes in order of importance (the first process is most important and is killed last)

1 Foreground process

A process that is required for what the user is currently doing A process is considered to be in the

foreground if any of the following conditions are true

o It hosts an Activity that the user is interacting with (the Activitys onResume() method has been called)

o It hosts a Service thats bound to the activity that the user is interacting with

o It hosts a Service thats running in the foregroundmdashthe service has called startForeground()

o It hosts a Service thats executing one of its lifecycle callbacks (onCreate() onStart() or onDestroy())

o It hosts a BroadcastReceiver thats executing its onReceive() method

Generally only a few foreground processes exist at any given time They are killed only as a last

resortmdashif memory is so low that they cannot all continue to run Generally at that point the device has

reached a memory paging state so killing some foreground processes is required to keep the user

interface responsive

2 Visible process

A process that doesnt have any foreground components but still can affect what the user sees on

screen A process is considered to be visible if either of the following conditions are true

o It hosts an Activity that is not in the foreground but is still visible to the user (its onPause() method has

been called) This might occur for example if the foreground activity started a dialog which allows the

previous activity to be seen behind it

o It hosts a Service thats bound to a visible (or foreground) activity

A visible process is considered extremely important and will not be killed unless doing so is required to

keep all foreground processes running

3 Service process

A process that is running a service that has been started with the startService() method and does not

fall into either of the two higher categories Although service processes are not directly tied to anything

the user sees they are generally doing things that the user cares about (such as playing music in the

background or downloading data on the network) so the system keeps them running unless theres

not enough memory to retain them along with all foreground and visible processes

4 Background process

A process holding an activity thats not currently visible to the user (the activitys onStop() method has

been called) These processes have no direct impact on the user experience and the system can kill

them at any time to reclaim memory for a foreground visible or service process Usually there are

many background processes running so they are kept in an LRU (least recently used) list to ensure

that the process with the activity that was most recently seen by the user is the last to be killed If an

activity implements its lifecycle methods correctly and saves its current state killing its process will not

have a visible effect on the user experience because when the user navigates back to the activity the

activity restores all of its visible state See the Activities document for information about saving and

restoring state

5 Empty process

A process that doesnt hold any active application components The only reason to keep this kind of

process alive is for caching purposes to improve startup time the next time a component needs to run

in it The system often kills these processes in order to balance overall system resources between

process caches and the underlying kernel caches

Android ranks a process at the highest level it can based upon the importance of the components

currently active in the process For example if a process hosts a service and a visible activity the

process is ranked as a visible process not a service process

In addition a processs ranking might be increased because other processes are dependent on itmdasha

process that is serving another process can never be ranked lower than the process it is serving For

example if a content provider in process A is serving a client in process B or if a service in process A

is bound to a component in process B process A is always considered at least as important as

process B

Because a process running a service is ranked higher than a process with background activities an

activity that initiates a long-running operation might do well to start a service for that operation rather

than simply create a worker threadmdashparticularly if the operation will likely outlast the activity For

example an activity thats uploading a picture to a web site should start a service to perform the

upload so that the upload can continue in the background even if the user leaves the activity Using a

service guarantees that the operation will have at least service process priority regardless of what

happens to the activity This is the same reason that broadcast receivers should employ services

rather than simply put time-consuming operations in a thread

Threads

When an application is launched the system creates a thread of execution for the application called

main This thread is very important because it is in charge of dispatching events to the appropriate

user interface widgets including drawing events It is also the thread in which your application interacts

with components from the Android UI toolkit (components from the androidwidget and androidview

packages) As such the main thread is also sometimes called the UI thread

The system does not create a separate thread for each instance of a component All components that

run in the same process are instantiated in the UI thread and system calls to each component are

dispatched from that thread Consequently methods that respond to system callbacks (such as

onKeyDown() to report user actions or a lifecycle callback method) always run in the UI thread of the

process

For instance when the user touches a button on the screen your apps UI thread dispatches the touch

event to the widget which in turn sets its pressed state and posts an invalidate request to the event

queue The UI thread dequeues the request and notifies the widget that it should redraw itself

When your app performs intensive work in response to user interaction this single thread model can

yield poor performance unless you implement your application properly Specifically if everything is

happening in the UI thread performing long operations such as network access or database queries

will block the whole UI When the thread is blocked no events can be dispatched including drawing

events From the users perspective the application appears to hang Even worse if the UI thread is

blocked for more than a few seconds (about 5 seconds currently) the user is presented with the

infamous application not responding (ANR) dialog The user might then decide to quit your

application and uninstall it if they are unhappy

Additionally the Andoid UI toolkit is not thread-safe So you must not manipulate your UI from a

worker threadmdashyou must do all manipulation to your user interface from the UI thread Thus there are

simply two rules to Androids single thread model

1 Do not block the UI thread

2 Do not access the Android UI toolkit from outside the UI thread

Worker threads

Because of the single thread model described above its vital to the responsiveness of your

applications UI that you do not block the UI thread If you have operations to perform that are not

instantaneous you should make sure to do them in separate threads (background or worker

threads)

For example below is some code for a click listener that downloads an image from a separate thread

and displays it in an ImageView

public void onClick(View v) new Thread(new Runnable() public void run() Bitmap b = loadImageFromNetwork(httpexamplecomimagepng) mImageViewsetImageBitmap(b) )start()

At first this seems to work fine because it creates a new thread to handle the network operation

However it violates the second rule of the single-threaded model do not access the Android UI toolkit

from outside the UI threadmdashthis sample modifies the ImageView from the worker thread instead of the

UI thread This can result in undefined and unexpected behavior which can be difficult and time-

consuming to track down

To fix this problem Android offers several ways to access the UI thread from other threads Here is a

list of methods that can help

ActivityrunOnUiThread(Runnable)

Viewpost(Runnable)

ViewpostDelayed(Runnable long)

For example you can fix the above code by using the Viewpost(Runnable) method

public void onClick(View v) new Thread(new Runnable() public void run() final Bitmap bitmap = loadImageFromNetwork(httpexamplecomimagepng) mImageViewpost(new Runnable() public void run() mImageViewsetImageBitmap(bitmap) ) )start()

Now this implementation is thread-safe the network operation is done from a separate thread while

the ImageView is manipulated from the UI thread

However as the complexity of the operation grows this kind of code can get complicated and difficult

to maintain To handle more complex interactions with a worker thread you might consider using a

Handler in your worker thread to process messages delivered from the UI thread Perhaps the best

solution though is to extend the AsyncTask class which simplifies the execution of worker thread

tasks that need to interact with the UI

Using AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface It performs the blocking

operations in a worker thread and then publishes the results on the UI thread without requiring you to

handle threads andor handlers yourself

To use it you must subclass AsyncTask and implement the doInBackground() callback method which

runs in a pool of background threads To update your UI you should implement onPostExecute()

which delivers the result from doInBackground() and runs in the UI thread so you can safely update

your UI You can then run the task by calling execute() from the UI thread

For example you can implement the previous example using AsyncTask this way

public void onClick(View v) new DownloadImageTask()execute(httpexamplecomimagepng) private class DownloadImageTask extends AsyncTaskltString Void Bitmapgt The system calls this to perform work in a worker thread and delivers it the parameters given to AsyncTaskexecute() protected Bitmap doInBackground(String urls) return loadImageFromNetwork(urls[0])

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 18: 03 services

return LocalServicethis

Override

public IBinder onBind(Intent intent)

return mBinder

method for clients

public int getRandomNumber()

return mGeneratornextInt(100)

The LocalBinder provides the getService() method for clients to retrieve the current instance of

LocalService This allows clients to call public methods in the service For example clients can call

getRandomNumber() from the service

Heres an activity that binds to LocalService and calls getRandomNumber() when a button is clicked

public class BindingActivity extends Activity

LocalService mService

boolean mBound = false

Override

protected void onCreate(Bundle savedInstanceState)

superonCreate(savedInstanceState)

setContentView(Rlayoutmain)

Override

protected void onStart()

superonStart()

Bind to LocalService

Intent intent = new Intent(this LocalServiceclass)

bindService(intent mConnection ContextBIND_AUTO_CREATE)

Override

protected void onStop()

superonStop()

Unbind from the service

if (mBound)

unbindService(mConnection)

mBound = false

Called when a button is clicked (the button in the layout file attaches to

this method with the androidonClick attribute)

public void onButtonClick(View v)

if (mBound)

Call a method from the LocalService

However if this call were something that might hang then this request should

occur in a separate thread to avoid slowing down the activity performance

int num = mServicegetRandomNumber()

ToastmakeText(this number + num ToastLENGTH_SHORT)show()

Defines callbacks for service binding passed to bindService()

private ServiceConnection mConnection = new ServiceConnection()

Override

public void onServiceConnected(ComponentName className

IBinder service)

Weve bound to LocalService cast the IBinder and get LocalService instance

LocalBinder binder = (LocalBinder) service

mService = bindergetService()

mBound = true

Override

public void onServiceDisconnected(ComponentName arg0)

mBound = false

The above sample shows how the client binds to the service using an implementation of

ServiceConnection and the onServiceConnected() callback The next section provides more

information about this process of binding to the service

Note The example above doesnt explicitly unbind from the service but all clients should unbind

at an appropriate time (such as when the activity pauses)

For more sample code see the LocalServicejava class and the LocalServiceActivitiesjava class in

ApiDemos

Using a Messenger

Compared to AIDL

When you need to perform IPC using a Messenger for your interface is simpler than implementing it

with AIDL because Messenger queues all calls to the service whereas a pure AIDL interface sends

simultaneous requests to the service which must then handle multi-threading

For most applications the service doesnt need to perform multi-threading so using a Messenger

allows the service to handle one call at a time If its important that your service be multi-threaded then

you should use AIDL to define your interface

If you need your service to communicate with remote processes then you can use a Messenger to

provide the interface for your service This technique allows you to perform interprocess

communication (IPC) without the need to use AIDL

Heres a summary of how to use a Messenger

The service implements a Handler that receives a callback for each call from a client

The Handler is used to create a Messenger object (which is a reference to the Handler)

The Messenger creates an IBinder that the service returns to clients from onBind()

Clients use the IBinder to instantiate the Messenger (that references the services Handler) which the

client uses to send Message objects to the service

The service receives each Message in its Handlermdashspecifically in the handleMessage() method

In this way there are no methods for the client to call on the service Instead the client delivers

messages (Message objects) that the service receives in its Handler

Heres a simple example service that uses a Messenger interface

public class MessengerService extends Service Command to the service to display a message static final int MSG_SAY_HELLO = 1 Handler of incoming messages from clients class IncomingHandler extends Handler Override public void handleMessage(Message msg) switch (msgwhat) case MSG_SAY_HELLO ToastmakeText(getApplicationContext() hello ToastLENGTH_SHORT)show() break default superhandleMessage(msg) Target we publish for clients to send messages to IncomingHandler final Messenger mMessenger = new Messenger(new IncomingHandler()) When binding to the service we return an interface to our messenger for sending messages to the service Override public IBinder onBind(Intent intent) ToastmakeText(getApplicationContext() binding ToastLENGTH_SHORT)show() return mMessengergetBinder()

Notice that the handleMessage() method in the Handler is where the service receives the incoming

Message and decides what to do based on the what member

All that a client needs to do is create a Messenger based on the IBinder returned by the service and

send a message using send() For example heres a simple activity that binds to the service and

delivers the MSG_SAY_HELLO message to the service

public class ActivityMessenger extends Activity Messenger for communicating with the service Messenger mService = null Flag indicating whether we have called bind on the service boolean mBound Class for interacting with the main interface of the service private ServiceConnection mConnection = new ServiceConnection() public void onServiceConnected(ComponentName className IBinder service) This is called when the connection with the service has been established giving us the object we can use to interact with the service We are communicating with the service using a Messenger so here we get a client-side representation of that from the raw IBinder object mService = new Messenger(service) mBound = true public void onServiceDisconnected(ComponentName className) This is called when the connection with the service has been unexpectedly disconnected -- that is its process crashed mService = null mBound = false public void sayHello(View v) if (mBound) return Create and send a message to the service using a supported what value Message msg = Messageobtain(null MessengerServiceMSG_SAY_HELLO 0 0) try mServicesend(msg) catch (RemoteException e) eprintStackTrace() Override protected void onCreate(Bundle savedInstanceState) superonCreate(savedInstanceState) setContentView(Rlayoutmain)

Override protected void onStart() superonStart() Bind to the service bindService(new Intent(this MessengerServiceclass) mConnection ContextBIND_AUTO_CREATE) Override protected void onStop() superonStop() Unbind from the service if (mBound) unbindService(mConnection) mBound = false

Notice that this example does not show how the service can respond to the client If you want the

service to respond then you need to also create a Messenger in the client Then when the client

receives the onServiceConnected() callback it sends a Message to the service that includes the

clients Messenger in the replyTo parameter of the send() method

You can see an example of how to provide two-way messaging in the MessengerServicejava (service)

and MessengerServiceActivitiesjava (client) samples

Binding to a Service

Application components (clients) can bind to a service by calling bindService() The Android system

then calls the services onBind() method which returns an IBinder for interacting with the service

The binding is asynchronous bindService() returns immediately and does not return the IBinder to the

client To receive the IBinder the client must create an instance of ServiceConnection and pass it to

bindService() The ServiceConnection includes a callback method that the system calls to deliver the

IBinder

Note Only activities services and content providers can bind to a servicemdashyou cannot bind to a

service from a broadcast receiver

So to bind to a service from your client you must

1 Implement ServiceConnection

Your implementation must override two callback methods

onServiceConnected()

The system calls this to deliver the IBinder returned by the services onBind() method

onServiceDisconnected()

The Android system calls this when the connection to the service is unexpectedly lost such as

when the service has crashed or has been killed This is not called when the client unbinds

2 Call bindService() passing the ServiceConnection implementation

3 When the system calls your onServiceConnected() callback method you can begin making calls to the

service using the methods defined by the interface

4 To disconnect from the service call unbindService()

When your client is destroyed it will unbind from the service but you should always unbind when

youre done interacting with the service or when your activity pauses so that the service can shutdown

while its not being used (Appropriate times to bind and unbind is discussed more below)

For example the following snippet connects the client to the service created above by extending the

Binder class so all it must do is cast the returned IBinder to the LocalService class and request the

LocalService instance

LocalService mService private ServiceConnection mConnection = new ServiceConnection() Called when the connection with the service is established public void onServiceConnected(ComponentName className IBinder service) Because we have bound to an explicit service that is running in our own process we can cast its IBinder to a concrete class and directly access it LocalBinder binder = (LocalBinder) service mService = bindergetService() mBound = true Called when the connection with the service disconnects unexpectedly public void onServiceDisconnected(ComponentName className) Loge(TAG onServiceDisconnected) mBound = false

With this ServiceConnection the client can bind to a service by passing this it to bindService() For

example

Intent intent = new Intent(this LocalServiceclass) bindService(intent mConnection ContextBIND_AUTO_CREATE)

The first parameter of bindService() is an Intent that explicitly names the service to bind (thought the

intent could be implicit)

The second parameter is the ServiceConnection object

The third parameter is a flag indicating options for the binding It should usually be

BIND_AUTO_CREATE in order to create the service if its not already alive Other possible values are

BIND_DEBUG_UNBIND and BIND_NOT_FOREGROUND or 0 for none

Additional notes

Here are some important notes about binding to a service

You should always trap DeadObjectException exceptions which are thrown when the connection has

broken This is the only exception thrown by remote methods

Objects are reference counted across processes

You should usually pair the binding and unbinding during matching bring-up and tear-down moments

of the clients lifecycle For example

o If you only need to interact with the service while your activity is visible you should bind during

onStart() and unbind during onStop()

o If you want your activity to receive responses even while it is stopped in the background then you can

bind during onCreate() and unbind during onDestroy() Beware that this implies that your activity needs

to use the service the entire time its running (even in the background) so if the service is in another

process then you increase the weight of the process and it becomes more likely that the system will

kill it

Note You should usually not bind and unbind during your activitys onResume() and onPause()

because these callbacks occur at every lifecycle transition and you should keep the processing that

occurs at these transitions to a minimum Also if multiple activities in your application bind to the same

service and there is a transition between two of those activities the service may be destroyed and

recreated as the current activity unbinds (during pause) before the next one binds (during resume)

(This activity transition for how activities coordinate their lifecycles is described in the Activities

document)

For more sample code showing how to bind to a service see the RemoteServicejava class in

ApiDemos

Managing the Lifecycle of a Bound Service

Figure 1 The lifecycle for a service

that is started and also allows binding

When a service is unbound from all

clients the Android system destroys it

(unless it was also started with

onStartCommand()) As such you

dont have to manage the lifecycle of

your service if its purely a bound

servicemdashthe Android system manages

it for you based on whether it is bound

to any clients

However if you choose to implement

the onStartCommand() callback

method then you must explicitly stop

the service because the service is

now considered to be started In this

case the service runs until the service

stops itself with stopSelf() or another

component calls stopService()

regardless of whether it is bound to

any clients

Additionally if your service is started and accepts binding then when the system calls your onUnbind()

method you can optionally return true if you would like to receive a call to onRebind() the next time a

client binds to the service (instead of receiving a call to onBind()) onRebind() returns void but the

client still receives the IBinder in its onServiceConnected() callback Below figure 1 illustrates the logic

for this kind of lifecycle

For more information about the lifecycle of an started service see the Services document

Content Providers

Content providers store and retrieve data and make it accessible to all applications Theyre the only

way to share data across applications theres no common storage area that all Android packages can

access

Android ships with a number of content providers for common data types (audio video images

personal contact information and so on) You can see some of them listed in the androidprovider

package You can query these providers for the data they contain (although for some you must

acquire the proper permission to read the data)

If you want to make your own data public you have two options You can create your own content

provider (a ContentProvider subclass) or you can add the data to an existing provider mdash if theres one

that controls the same type of data and you have permission to write to it

This document is an introduction to using content providers After a brief discussion of the

fundamentals it explores how to query a content provider how to modify data controlled by a provider

and how to create a content provider of your own

Content Provider Basics

How a content provider actually stores its data under the covers is up to its designer But all content

providers implement a common interface for querying the provider and returning results mdash as well as

for adding altering and deleting data Its an interface that clients use indirectly most generally

through ContentResolver objects You get a ContentResolver by calling getContentResolver() from

within the implementation of an Activity or other application component

ContentResolver cr = getContentResolver()

You can then use the ContentResolvers methods to interact with whatever content providers youre

interested in When a query is initiated the Android system identifies the content provider thats the

target of the query and makes sure that it is up and running The system instantiates all

ContentProvider objects you never need to do it on your own In fact you never deal directly with

ContentProvider objects at all Typically theres just a single instance of each type of ContentProvider

But it can communicate with multiple ContentResolver objects in different applications and processes

The interaction between processes is handled by the ContentResolver and ContentProvider classes

The data model

Content providers expose their data as a simple table on a database model where each row is a

record and each column is data of a particular type and meaning For example information about

people and their phone numbers might be exposed as follows

_ID NUMBER NUMBER_KEY LABEL NAME TYPE

13 (425) 555 6677 425 555 6677 Kirkland office Bully Pulpit TYPE_WORK

44 (212) 555-1234 212 555 1234 NY apartment Alan Vain TYPE_HOME

45 (212) 555-6657 212 555 6657 Downtown office Alan Vain TYPE_MOBILE

53 2015554433 201 555 4433 Love Nest Rex Cars TYPE_HOME

Every record includes a numeric _ID field that uniquely identifies the record within the table IDs can be

used to match records in related tables mdash for example to find a persons phone number in one table

and pictures of that person in another

A query returns a Cursor object that can move from record to record and column to column to read the

contents of each field It has specialized methods for reading each type of data So to read a field you

must know what type of data the field contains (Theres more on query results and Cursor objects

later)

URIs

Each content provider exposes a public URI (wrapped as a Uri object) that uniquely identifies its data

set A content provider that controls multiple data sets (multiple tables) exposes a separate URI for

each one All URIs for providers begin with the string content The content scheme identifies the

data as being controlled by a content provider

If youre defining a content provider its a good idea to also define a constant for its URI to simplify

client code and make future updates cleaner Android defines CONTENT_URI constants for all the

providers that come with the platform For example the URI for the table that matches phone numbers

to people and the URI for the table that holds pictures of people (both controlled by the Contacts

content provider) are

androidproviderContactsPhonesCONTENT_URI

androidproviderContactsPhotosCONTENT_URI

The URI constant is used in all interactions with the content provider Every ContentResolver method

takes the URI as its first argument Its what identifies which provider the ContentResolver should talk

to and which table of the provider is being targeted

Querying a Content Provider

You need three pieces of information to query a content provider

The URI that identifies the provider

The names of the data fields you want to receive

The data types for those fields

If youre querying a particular record you also need the ID for that record

Making the query

To query a content provider you can use either the ContentResolverquery() method or the

ActivitymanagedQuery() method Both methods take the same set of arguments and both return a

Cursor object However managedQuery() causes the activity to manage the life cycle of the Cursor A

managed Cursor handles all of the niceties such as unloading itself when the activity pauses and

requerying itself when the activity restarts You can ask an Activity to begin managing an unmanaged

Cursor object for you by calling ActivitystartManagingCursor()

The first argument to either query() or managedQuery() is the provider URI mdash the CONTENT_URI

constant that identifies a particular ContentProvider and data set (see URIs earlier)

To restrict a query to just one record you can append the _ID value for that record to the URI mdash that

is place a string matching the ID as the last segment of the path part of the URI For example if the ID

is 23 the URI would be

content 23

There are some helper methods particularly ContentUriswithAppendedId() and

UriwithAppendedPath() that make it easy to append an ID to a URI Both are static methods that

return a Uri object with the ID added So for example if you were looking for record 23 in the database

of people contacts you might construct a query as follows

import androidproviderContactsPeople import androidcontentContentUris import androidnetUri import androiddatabaseCursor Use the ContentUris method to produce the base URI for the contact with _ID == 23 Uri myPerson = ContentUriswithAppendedId(PeopleCONTENT_URI 23) Alternatively use the Uri method to produce the base URI It takes a string rather than an integer Uri myPerson = UriwithAppendedPath(PeopleCONTENT_URI 23) Then query for this specific record Cursor cur = managedQuery(myPerson null null null null)

The other arguments to the query() and managedQuery() methods delimit the query in more detail

They are

The names of the data columns that should be returned A null value returns all columns Otherwise

only columns that are listed by name are returned All the content providers that come with the

platform define constants for their columns For example the androidproviderContactsPhones class

defines constants for the names of the columns in the phone table illustrated earlier ampmdash _ID

NUMBER NUMBER_KEY NAME and so on

A filter detailing which rows to return formatted as an SQL WHERE clause (excluding the WHERE

itself) A null value returns all rows (unless the URI limits the query to a single record)

Selection arguments

A sorting order for the rows that are returned formatted as an SQL ORDER BY clause (excluding the

ORDER BY itself) A null value returns the records in the default order for the table which may be

unordered

Lets look at an example query to retrieve a list of contact names and their primary phone numbers

import androidproviderContactsPeople import androiddatabaseCursor Form an array specifying which columns to return String[] projection = new String[] People_ID People_COUNT PeopleNAME PeopleNUMBER Get the base URI for the People table in the Contacts content provider Uri contacts = PeopleCONTENT_URI Make the query Cursor managedCursor = managedQuery(contacts projection Which columns to return null Which rows to return (all rows) null Selection arguments (none) Put the results in ascending order by name PeopleNAME + ASC)

This query retrieves data from the People table of the Contacts content provider It gets the name

primary phone number and unique record ID for each contact It also reports the number of records

that are returned as the _COUNT field of each record

The constants for the names of the columns are defined in various interfaces mdash _ID and _COUNT in

BaseColumns NAME in PeopleColumns and NUMBER in PhoneColumns The ContactsPeople

class implements each of these interfaces which is why the code example above could refer to them

using just the class name

What a query returns

A query returns a set of zero or more database records The names of the columns their default order

and their data types are specific to each content provider But every provider has an _ID column

which holds a unique numeric ID for each record Every provider can also report the number of records

returned as the _COUNT column its value is the same for all rows

Here is an example result set for the query in the previous section

_ID _COUNT NAME NUMBER

44 3 Alan Vain 212 555 1234

13 3 Bully Pulpit 425 555 6677

53 3 Rex Cars 201 555 4433

The retrieved data is exposed by a Cursor object that can be used to iterate backward or forward

through the result set You can use this object only to read the data To add modify or delete data

you must use a ContentResolver object

Reading retrieved data

The Cursor object returned by a query provides access to a recordset of results If you have queried

for a specific record by ID this set will contain only one value Otherwise it can contain multiple

values (If there are no matches it can also be empty) You can read data from specific fields in the

record but you must know the data type of the field because the Cursor object has a separate method

for reading each type of data mdash such as getString() getInt() and getFloat() (However for most types

if you call the method for reading strings the Cursor object will give you the String representation of

the data) The Cursor lets you request the column name from the index of the column or the index

number from the column name

The following snippet demonstrates reading names and phone numbers from the query illustrated

earlier

import androidproviderContactsPeople private void getColumnData(Cursor cur) if (curmoveToFirst()) String name String phoneNumber int nameColumn = curgetColumnIndex(PeopleNAME) int phoneColumn = curgetColumnIndex(PeopleNUMBER) String imagePath do Get the field values name = curgetString(nameColumn) phoneNumber = curgetString(phoneColumn) Do something with the values while (curmoveToNext())

If a query can return binary data such as an image or sound the data may be directly entered in the

table or the table entry for that data may be a string specifying a content URI that you can use to get

the data In general smaller amounts of data (say from 20 to 50K or less) are most often directly

entered in the table and can be read by calling CursorgetBlob() It returns a byte array

If the table entry is a content URI you should never try to open and read the file directly (for one thing

permissions problems can make this fail) Instead you should call ContentResolveropenInputStream()

to get an InputStream object that you can use to read the data

Modifying Data

Data kept by a content provider can be modified by

Adding new records

Adding new values to existing records

Batch updating existing records

Deleting records

All data modification is accomplished using ContentResolver methods Some content providers require

a more restrictive permission for writing data than they do for reading it If you dont have permission to

write to a content provider the ContentResolver methods will fail

Adding records

To add a new record to a content provider first set up a map of key-value pairs in a ContentValues

object where each key matches the name of a column in the content provider and the value is the

desired value for the new record in that column Then call ContentResolverinsert() and pass it the URI

of the provider and the ContentValues map This method returns the full URI of the new record mdash that

is the providers URI with the appended ID for the new record You can then use this URI to query and

get a Cursor over the new record and to further modify the record Heres an example

import androidproviderContactsPeople import androidcontentContentResolver import androidcontentContentValues ContentValues values = new ContentValues() Add Abraham Lincoln to contacts and make him a favorite valuesput(PeopleNAME Abraham Lincoln) 1 = the new contact is added to favorites 0 = the new contact is not added to favorites valuesput(PeopleSTARRED 1) Uri uri = getContentResolver()insert(PeopleCONTENT_URI values)

Adding new values

Once a record exists you can add new information to it or modify existing information For example

the next step in the example above would be to add contact information mdash like a phone number or an

IM or e-mail address mdash to the new entry

The best way to add to a record in the Contacts database is to append the name of the table where the

new data goes to the URI for the record then use the amended URI to add the new data values Each

Contacts table exposes a name for this purpose as a CONTENT_DIRECTORY constant The following

code continues the previous example by adding a phone number and e-mail address for the record

just created

Uri phoneUri = null Uri emailUri = null Add a phone number for Abraham Lincoln Begin with the URI for the new record just returned by insert() it ends with the _ID of the new record so we dont have to add the ID ourselves Then append the designation for the phone table to this URI and use the resulting URI to insert the phone number phoneUri = UriwithAppendedPath(uri PeoplePhonesCONTENT_DIRECTORY) valuesclear() valuesput(PeoplePhonesTYPE PeoplePhonesTYPE_MOBILE) valuesput(PeoplePhonesNUMBER 1233214567) getContentResolver()insert(phoneUri values) Now add an email address in the same way emailUri = UriwithAppendedPath(uri PeopleContactMethodsCONTENT_DIRECTORY) valuesclear() ContactMethodsKIND is used to distinguish different kinds of contact methods such as email IM etc valuesput(PeopleContactMethodsKIND ContactsKIND_EMAIL) valuesput(PeopleContactMethodsDATA testexamplecom) valuesput(PeopleContactMethodsTYPE PeopleContactMethodsTYPE_HOME) getContentResolver()insert(emailUri values)

You can place small amounts of binary data into a table by calling the version of ContentValuesput()

that takes a byte array That would work for a small icon-like image or a short audio clip for example

However if you have a large amount of binary data to add such as a photograph or a complete song

put a content URI for the data in the table and call ContentResolveropenOutputStream() with the files

URI (That causes the content provider to store the data in a file and record the file path in a hidden

field of the record)

In this regard the MediaStore content provider the main provider that dispenses image audio and

video data employs a special convention The same URI that is used with query() or managedQuery()

to get meta-information about the binary data (such as the caption of a photograph or the date it was

taken) is used with openInputStream() to get the data itself Similarly the same URI that is used with

insert() to put meta-information into a MediaStore record is used with openOutputStream() to place the

binary data there The following code snippet illustrates this convention

import androidproviderMediaStoreImagesMedia import androidcontentContentValues import javaioOutputStream Save the name and description of an image in a ContentValues map ContentValues values = new ContentValues(3) valuesput(MediaDISPLAY_NAME road_trip_1) valuesput(MediaDESCRIPTION Day 1 trip to Los Angeles) valuesput(MediaMIME_TYPE imagejpeg) Add a new record without the bitmap but with the values just set insert() returns the URI of the new record Uri uri = getContentResolver()insert(MediaEXTERNAL_CONTENT_URI values) Now get a handle to the file for that record and save the data into it Here sourceBitmap is a Bitmap object representing the file to save to the database try OutputStream outStream = getContentResolver()openOutputStream(uri) sourceBitmapcompress(BitmapCompressFormatJPEG 50 outStream) outStreamclose() catch (Exception e) Loge(TAG exception while writing image e)

Batch updating records

To batch update a group of records (for example to change NY to New York in all fields) call the

ContentResolverupdate() method with the columns and values to change

Deleting a record

To delete a single record call ContentResolverdelete() with the URI of a specific row

To delete multiple rows call ContentResolverdelete() with the URI of the type of record to delete (for

example androidproviderContactsPeopleCONTENT_URI) and an SQL WHERE clause defining

which rows to delete (Caution Be sure to include a valid WHERE clause if youre deleting a general

type or you risk deleting more records than you intended)

Creating a Content Provider

To create a content provider you must

Set up a system for storing the data Most content providers store their data using Androids file

storage methods or SQLite databases but you can store your data any way you want Android

provides the SQLiteOpenHelper class to help you create a database and SQLiteDatabase to manage

it

Extend the ContentProvider class to provide access to the data

Declare the content provider in the manifest file for your application (AndroidManifestxml)

The following sections have notes on the last two of these tasks

Extending the ContentProvider class

You define a ContentProvider subclass to expose your data to others using the conventions expected

by ContentResolver and Cursor objects Principally this means implementing six abstract methods

declared in the ContentProvider class

query()

insert()

update()

delete()

getType()

onCreate()

The query() method must return a Cursor object that can iterate over the requested data Cursor itself

is an interface but Android provides some ready-made Cursor objects that you can use For example

SQLiteCursor can iterate over data stored in an SQLite database You get the Cursor object by calling

any of the SQLiteDatabase classs query() methods There are other Cursor implementations mdash such

as MatrixCursor mdash for data not stored in a database

Because these ContentProvider methods can be called from various ContentResolver objects in

different processes and threads they must be implemented in a thread-safe manner

As a courtesy you might also want to call ContentResolvernotifyChange() to notify listeners when

there are modifications to the data

Beyond defining the subclass itself there are other steps you should take to simplify the work of clients

and make the class more accessible

Define a public static final Uri named CONTENT_URI This is the string that represents the full content

URI that your content provider handles You must define a unique string for this value The best

solution is to use the fully-qualified class name of the content provider (made lowercase) So for

example the URI for a TransportationProvider class could be defined as follows

public static final Uri CONTENT_URI = Uriparse(contentcomexamplecodelabtransportationprovider)

If the provider has subtables also define CONTENT_URI constants for each of the subtables These

URIs should all have the same authority (since that identifies the content provider) and be

distinguished only by their paths For example

contentcomexamplecodelabtransportationprovidertrain

contentcomexamplecodelabtransportationproviderairdomestic

contentcomexamplecodelabtransportationproviderairinternational

For an overview of content URIs see the Content URI Summary at the end of this document

Define the column names that the content provider will return to clients If you are using an underlying

database these column names are typically identical to the SQL database column names they

represent Also define public static String constants that clients can use to specify the columns in

queries and other instructions

Be sure to include an integer column named _id (with the constant _ID) for the IDs of the records

You should have this field whether or not you have another field (such as a URL) that is also unique

among all records If youre using the SQLite database the _ID field should be the following type

INTEGER PRIMARY KEY AUTOINCREMENT

The AUTOINCREMENT descriptor is optional But without it SQLite increments an ID counter field to

the next number above the largest existing number in the column If you delete the last row the next

row added will have the same ID as the deleted row AUTOINCREMENT avoids this by having SQLite

increment to the next largest value whether deleted or not

Carefully document the data type of each column Clients need this information to read the data

If you are handling a new data type you must define a new MIME type to return in your

implementation of ContentProvidergetType() The type depends in part on whether or not the content

URI submitted to getType() limits the request to a specific record Theres one form of the MIME type

for a single record and another for multiple records Use the Uri methods to help determine what is

being requested Here is the general format for each type

o For a single record vndandroidcursoritemvndyourcompanynamecontenttype

For example a request for train record 122 like this URI

contentcomexampletransportationprovidertrains122

might return this MIME type

vndandroidcursoritemvndexamplerail

o For multiple records vndandroidcursordirvndyourcompanynamecontenttype

For example a request for all train records like the following URI

contentcomexampletransportationprovidertrains

might return this MIME type

vndandroidcursordirvndexamplerail

If you are exposing byte data thats too big to put in the table itself mdash such as a large bitmap file mdash the

field that exposes the data to clients should actually contain a content URI string This is the field that

gives clients access to the data file The record should also have another field named _data that lists

the exact file path on the device for that file This field is not intended to be read by the client but by

the ContentResolver The client will call ContentResolveropenInputStream() on the user-facing field

holding the URI for the item The ContentResolver will request the _data field for that record and

because it has higher permissions than a client it should be able to access that file directly and return

a read wrapper for the file to the client

For an example of a private content provider implementation see the NodePadProvider class in the

Notepad sample application that ships with the SDK

Declaring the content provider

To let the Android system know about the content provider youve developed declare it with a

ltprovidergt element in the applications AndroidManifestxml file Content providers that are not

declared in the manifest are not visible to the Android system

The name attribute is the fully qualified name of the ContentProvider subclass The authorities attribute

is the authority part of the content URI that identifies the provider For example if the ContentProvider

subclass is AutoInfoProvider the ltprovidergt element might look like this

ltprovider androidname=comexampleautosAutoInfoProvider androidauthorities=comexampleautosautoinfoprovider gt ltprovidergt

Note that the authorities attribute omits the path part of a content URI For example if

AutoInfoProvider controlled subtables for different types of autos or different manufacturers

contentcomexampleautosautoinfoproviderhonda

contentcomexampleautosautoinfoprovidergmcompact

contentcomexampleautosautoinfoprovidergmsuv

those paths would not be declared in the manifest The authority is what identifies the provider not the

path your provider can interpret the path part of the URI in any way you choose

Other ltprovidergt attributes can set permissions to read and write data provide for an icon and text

that can be displayed to users enable and disable the provider and so on Set the multiprocess

attribute to true if data does not need to be synchronized between multiple running versions of the

content provider This permits an instance of the provider to be created in each client process

eliminating the need to perform IPC

Content URI Summary

Here is a recap of the important parts of a content URI

A Standard prefix indicating that the data is controlled by a content provider Its never modified

B The authority part of the URI it identifies the content provider For third-party applications this should

be a fully-qualified class name (reduced to lowercase) to ensure uniqueness The authority is declared

in the ltprovidergt elements authorities attribute

ltprovider androidname=TransportationProvider androidauthorities=comexampletransportationprovider gt

C The path that the content provider uses to determine what kind of data is being requested This can be

zero or more segments long If the content provider exposes only one type of data (only trains for

example) it can be absent If the provider exposes several types including subtypes it can be several

segments long mdash for example landbus landtrain seaship and seasubmarine to give four

possibilities

D The ID of the specific record being requested if any This is the _ID value of the requested record If

the request is not limited to a single record this segment and the trailing slash are omitted

contentcomexampletransportationprovidertrains

Intent and intent filters

Three of the core components of an application mdash activities services and broadcast receivers mdash 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 mdash 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 ContextstartActivity() or ActivitystartActivityForResult() to launch an

activity or get an existing activity to do something new (It can also be passed to ActivitysetResult() to

return information to the activity that called startActivityForResult())

An Intent object is passed to ContextstartService() to initiate a service or deliver new instructions to an

ongoing service Similarly an intent can be passed to ContextbindService() to establish a connection

between the calling component and a target service It can optionally initiate the service if its not

already running

Intent objects passed to any of the broadcast methods (such as ContextsendBroadcast()

ContextsendOrderedBroadcast() or ContextsendStickyBroadcast()) 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 mdash how it resolves which component should receive an intent message For

intents that dont explicitly name a target component this process involves testing the Intent object

against intent filters associated with potential targets

Intent Objects

An Intent object is a bundle of information It contains information of interest to the component that

receives the intent (such as the action to be taken and the data to act on) plus information of interest to

the Android system (such as the category of component that should handle the intent and instructions

on how to launch a target activity) Principally it can contain the following

Component name

The name of the component that should handle the intent This field is a ComponentName

object mdash a combination of the fully qualified class name of the target component (for example

comexampleprojectappFreneticActivity) and the package name set in the manifest file of the

application where the component resides (for example comexampleproject) The package

part of the component name and the package name set in the manifest do not necessarily have

to match

The component name is optional If it is set the Intent object is delivered to an instance of the

designated class If it is not set Android uses other information in the Intent object to locate a

suitable target mdash see Intent Resolution later in this document

The component name is set by setComponent() setClass() or setClassName() and read by

getComponent()

Action

A string naming the action to be performed mdash or in the case of broadcast intents the action

that took place and is being reported The Intent class defines a number of action constants

including these

Constant Target

component

Action

ACTION_CALL activity Initiate a phone call

ACTION_EDIT activity Display data for the user to edit

ACTION_MAIN activity Start up as the initial activity of a task

with no data input and no returned

output

ACTION_SYNC activity Synchronize data on a server with

data on the mobile device

ACTION_BATTERY_LOW broadcast

receiver

A warning that the battery is low

ACTION_HEADSET_PLUG broadcast

receiver

A headset has been plugged into the

device or unplugged from it

ACTION_SCREEN_ON broadcast

receiver

The screen has been turned on

ACTION_TIMEZONE_CHANGED broadcast

receiver

The setting for the time zone has

changed

See the Intent class description for a list of pre-defined constants for generic actions Other

actions are defined elsewhere in the Android API You can also define your own action strings

for activating the components in your application Those you invent should include the

application package as a prefix mdash for example comexampleprojectSHOW_COLOR

The action largely determines how the rest of the intent is structured mdash particularly the data and

extras fields mdash much as a method name determines a set of arguments and a return value For

this reason its a good idea to use action names that are as specific as possible and to couple

them tightly to the other fields of the intent In other words instead of defining an action in

isolation define an entire protocol for the Intent objects your components can handle

The action in an Intent object is set by the setAction() method and read by getAction()

Data

The URI of the data to be acted on and the MIME type of that data Different actions are paired

with different kinds of data specifications For example if the action field is ACTION_EDIT the

data field would contain the URI of the document to be displayed for editing If the action is

ACTION_CALL the data field would be a tel URI with the number to call Similarly if the action

is ACTION_VIEW and the data field is an http URI the receiving activity would be called upon

to download and display whatever data the URI refers to

When matching an intent to a component that is capable of handling the data its often

important to know the type of data (its MIME type) in addition to its URI For example a

component able to display image data should not be called upon to play an audio file

In many cases the data type can be inferred from the URI mdash particularly content URIs which

indicate that the data is located on the device and controlled by a content provider (see the

separate discussion on content providers) But the type can also be explicitly set in the Intent

object The setData() method specifies data only as a URI setType() specifies it only as a

MIME type and setDataAndType() specifies it as both a URI and a MIME type The URI is read

by getData() and the type by getType()

Category

A string containing additional information about the kind of component that should handle the

intent Any number of category descriptions can be placed in an Intent object As it does for

actions the Intent class defines several category constants including these

Constant Meaning

CATEGORY_BROWSABLE The target activity can be safely invoked by the browser to

display data referenced by a link mdash for example an image or

an e-mail message

CATEGORY_GADGET The activity can be embedded inside of another activity that

hosts gadgets

CATEGORY_HOME The activity displays the home screen the first screen the

user sees when the device is turned on or when the HOME

key is pressed

CATEGORY_LAUNCHER The activity can be the initial activity of a task and is listed in

the top-level application launcher

CATEGORY_PREFERENCE The target activity is a preference panel

See the Intent class description for the full list of categories

The addCategory() method places a category in an Intent object removeCategory() deletes a

category previously added and getCategories() gets the set of all categories currently in the

object

Extras

Key-value pairs for additional information that should be delivered to the component handling

the intent Just as some actions are paired with particular kinds of data URIs some are paired

with particular extras For example an ACTION_TIMEZONE_CHANGED intent has a time-

zone extra that identifies the new time zone and ACTION_HEADSET_PLUG has a state

extra indicating whether the headset is now plugged in or unplugged as well as a name extra

for the type of headset If you were to invent a SHOW_COLOR action the color value would be

set in an extra key-value pair

The Intent object has a series of put() methods for inserting various types of extra data and a

similar set of get() methods for reading the data These methods parallel those for Bundle

objects In fact the extras can be installed and read as a Bundle using the putExtras() and

getExtras() methods

Flags

Flags of various sorts Many instruct the Android system how to launch an activity (for example

which task the activity should belong to) and how to treat it after its launched (for example

whether it belongs in the list of recent activities) All these flags are defined in the Intent class

The Android system and the applications that come with the platform employ Intent objects both to

send out system-originated broadcasts and to activate system-defined components To see how to

structure an intent to activate a system component consult the list of intents in the reference

Intent Resolution

Intents can be divided into two groups

Explicit intents designate the target component by its name (the component name field mentioned

earlier has a value set) Since component names would generally not be known to developers of other

applications explicit intents are typically used for application-internal messages mdash such as an activity

starting a subordinate service or launching a sister activity

Implicit intents do not name a target (the field for the component name is blank) Implicit intents are

often used to activate components in other applications

Android delivers an explicit intent to an instance of the designated target class Nothing in the Intent

object other than the component name matters for determining which component should get the intent

A different strategy is needed for implicit intents In the absence of a designated target the Android

system must find the best component (or components) to handle the intent mdash a single activity or

service to perform the requested action or the set of broadcast receivers to respond to the broadcast

announcement It does so by comparing the contents of the Intent object to intent filters structures

associated with components that can potentially receive intents Filters advertise the capabilities of a

component and delimit the intents it can handle They open the component to the possibility of

receiving implicit intents of the advertised type If a component does not have any intent filters it can

receive only explicit intents A component with filters can receive both explicit and implicit intents

Only three aspects of an Intent object are consulted when the object is tested against an intent filter

action

data (both URI and data type)

category

The extras and flags play no part in resolving which component receives an intent

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 mdash but only unwanted implicit intents (those that dont 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

components 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 mdash 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 Pads filters are described in the Note Pad Example

section later)

Filters and security

An intent filter cannot be relied on for security While it opens a component to receiving only certain

kinds of implicit intents it does nothing to prevent explicit intents from targeting the component Even

though a filter restricts the intents a component will be asked to handle to certain actions and data

sources someone could always put together an explicit intent with a different action and data source

and name the component as the target

An intent filter is an instance of the IntentFilter class However since the Android system must know

about the capabilities of a component before it can launch that component intent filters are generally

not set up in Java code but in the applications manifest file (AndroidManifestxml) as ltintent-filtergt

elements (The one exception would be filters for broadcast receivers that are registered dynamically

by calling ContextregisterReceiver() they are directly created as IntentFilter objects)

A filter has fields that parallel the action data and category fields of an Intent object An implicit intent

is tested against the filter in all three areas To be delivered to the component that owns the filter it

must pass all three tests If it fails even one of them the Android system wont deliver it to the

component mdash at least not on the basis of that filter However since a component can have multiple

intent filters an intent that does not pass through one of a components filters might make it through on

another

Each of the three tests is described in detail below

Action test

An ltintent-filtergt element in the manifest file lists actions as ltactiongt subelements For

example

ltintent-filter gt ltaction androidname=comexampleprojectSHOW_CURRENT gt ltaction androidname=comexampleprojectSHOW_RECENT gt ltaction androidname=comexampleprojectSHOW_PENDING gt ltintent-filtergt

As the example shows while an Intent object names just a single action a filter may list more

than one The list cannot be empty a filter must contain at least one ltactiongt element or it will

block all intents

To pass this test the action specified in the Intent object must match one of the actions listed in

the filter If the object or the filter does not specify an action the results are as follows

If the filter fails to list any actions there is nothing for an intent to match so all intents fail the

test No intents can get through the filter

On the other hand an Intent object that doesnt specify an action automatically passes the test

mdash as long as the filter contains at least one action

Category test

An ltintent-filtergt element also lists categories as subelements For example

ltintent-filter gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryBROWSABLE gt ltintent-filtergt

Note that the constants described earlier for actions and categories are not used in the manifest

file The full string values are used instead For instance the

androidintentcategoryBROWSABLE string in the example above corresponds to the

CATEGORY_BROWSABLE constant mentioned earlier in this document Similarly the string

androidintentactionEDIT corresponds to the ACTION_EDIT constant

For an intent to pass the category test every category in the Intent object must match a

category in the filter The filter can list additional categories but it cannot omit any that are in the

intent

In principle therefore an Intent object with no categories should always pass this test

regardless of whats in the filter Thats mostly true However with one exception Android treats

all implicit intents passed to startActivity() as if they contained at least one category

androidintentcategoryDEFAULT (the CATEGORY_DEFAULT constant) Therefore activities

that are willing to receive implicit intents must include androidintentcategoryDEFAULT in

their intent filters (Filters with androidintentactionMAIN and

androidintentcategoryLAUNCHER settings are the exception They mark activities that begin

new tasks and that are represented on the launcher screen They can include

androidintentcategoryDEFAULT in the list of categories but dont need to) See Using intent

matching later for more on these filters)

Data test

Like the action and categories the data specification for an intent filter is contained in a

subelement And as in those cases the subelement can appear multiple times or not at all For

example

ltintent-filter gt ltdata androidmimeType=videompeg androidscheme=http gt ltdata androidmimeType=audiompeg androidscheme=http gt ltintent-filtergt

Each ltdatagt element can specify a URI and a data type (MIME media type) There are

separate attributes mdash scheme host port and path mdash for each part of the URI

schemehostportpath

For example in the following URI

contentcomexampleproject200foldersubfolderetc

the scheme is content the host is comexampleproject the port is 200 and the path is

foldersubfolderetc The host and port together constitute the URI authority if a host is not

specified the port is ignored

Each of these attributes is optional but they are not independent of each other For an authority

to be meaningful a scheme must also be specified For a path to be meaningful both a scheme

and an authority must be specified

When the URI in an Intent object is compared to a URI specification in a filter its compared

only to the parts of the URI actually mentioned in the filter For example if a filter specifies only

a scheme all URIs with that scheme match the filter If a filter specifies a scheme and an

authority but no path all URIs with the same scheme and authority match regardless of their

paths If a filter specifies a scheme an authority and a path only URIs with the same scheme

authority and path match However a path specification in the filter can contain wildcards to

require only a partial match of the path

The type attribute of a ltdatagt element specifies the MIME type of the data Its more common in

filters than a URI Both the Intent object and the filter can use a wildcard for the subtype field

mdash for example text or audio mdash indicating any subtype matches

The data test compares both the URI and the data type in the Intent object to a URI and data

type specified in the filter The rules are as follows

a An Intent object that contains neither a URI nor a data type passes the test only if the filter

likewise does not specify any URIs or data types

b An Intent object that contains a URI but no data type (and a type cannot be inferred from the

URI) passes the test only if its URI matches a URI in the filter and the filter likewise does not

specify a type This will be the case only for URIs like mailto and tel that do not refer to actual

data

c An Intent object that contains a data type but not a URI passes the test only if the filter lists the

same data type and similarly does not specify a URI

d An Intent object that contains both a URI and a data type (or a data type can be inferred from

the URI) passes the data type part of the test only if its type matches a type listed in the filter It

passes the URI part of the test either if its URI matches a URI in the filter or if it has a content

or file URI and the filter does not specify a URI In other words a component is presumed to

support content and file data if its filter lists only a data type

If an intent can pass through the filters of more than one activity or service the user may be asked

which component to activate An exception is raised if no target can be found

Common cases

The last rule shown above for the data test rule (d) reflects the expectation that components are able

to get local data from a file or content provider Therefore their filters can list just a data type and do

not need to explicitly name the content and file schemes This is a typical case A ltdatagt element like

the following for example tells Android that the component can get image data from a content

provider and display it

ltdata androidmimeType=image gt

Since most available data is dispensed by content providers filters that specify a data type but not a

URI are perhaps the most common

Another common configuration is filters with a scheme and a data type For example a ltdatagt

element like the following tells Android that the component can get video data from the network and

display it

ltdata androidscheme=http androidtype=video gt

Consider for example what the browser application does when the user follows a link on a web page

It first tries to display the data (as it could if the link was to an HTML page) If it cant display the data it

puts together an implicit intent with the scheme and data type and tries to start an activity that can do

the job If there are no takers it asks the download manager to download the data That puts it under

the control of a content provider so a potentially larger pool of activities (those with filters that just

name a data type) can respond

Most applications also have a way to start fresh without a reference to any particular data Activities

that can initiate applications have filters with androidintentactionMAIN specified as the action If

they are to be represented in the application launcher they also specify the

androidintentcategoryLAUNCHER category

ltintent-filter gt ltaction androidname=code androidintentactionMAIN gt ltcategory androidname=code androidintentcategoryLAUNCHER gt ltintent-filtergt

Using intent matching

Intents are matched against intent filters not only to discover a target component to activate but also

to discover something about the set of components on the device For example the Android system

populates the application launcher the top-level screen that shows the applications that are available

for the user to launch by finding all the activities with intent filters that specify the

androidintentactionMAIN action and androidintentcategoryLAUNCHER category (as illustrated

in the previous section) It then displays the icons and labels of those activities in the launcher

Similarly it discovers the home screen by looking for the activity with androidintentcategoryHOME

in its filter

Your application can use intent matching is a similar way The PackageManager has a set of query()

methods that return all components that can accept a particular intent and a similar series of

resolve() methods that determine the best component to respond to an intent For example

queryIntentActivities() returns a list of all activities that can perform the intent passed as an argument

and queryIntentServices() returns a similar list of services Neither method activates the components

they just list the ones that can respond Theres a similar method queryBroadcastReceivers() for

broadcast receivers

Note Pad Example

The Note Pad sample application enables users to browse through a list of notes view details about

individual items in the list edit the items and add a new item to the list This section looks at the intent

filters declared in its manifest file (If youre working offline in the SDK you can find all the source files

for this sample application including its manifest file at ltsdkgtsamplesNotePadindexhtml If youre

viewing the documentation online the source files are in the Tutorials and Sample Code section here)

In its manifest file the Note Pad application declares three activities each with at least one intent filter

It also declares a content provider that manages the note data Here is the manifest file in its entirety

ltmanifest xmlnsandroid=httpschemasandroidcomapkresandroid package=comexampleandroidnotepadgt ltapplication androidicon=drawableapp_notes androidlabel=stringapp_name gt ltprovider androidname=NotePadProvider androidauthorities=comgoogleproviderNotePad gt ltactivity androidname=NotesList androidlabel=stringtitle_notes_listgt ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltactivity androidname=NoteEditor androidtheme=androidstyleThemeLight androidlabel=stringtitle_note gt ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltactivitygt

ltactivity androidname=TitleEditor androidlabel=stringtitle_edit_title androidtheme=androidstyleThemeDialoggt ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltapplicationgt ltmanifestgt

The first activity NotesList is distinguished from the other activities by the fact that it operates on a

directory of notes (the note list) rather than on a single note It would generally serve as the initial user

interface into the application It can do three things as described by its three intent filters

1 ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt

This filter declares the main entry point into the Note Pad application The standard MAIN action is an

entry point that does not require any other information in the Intent (no data specification for example)

and the LAUNCHER category says that this entry point should be listed in the application launcher

2 ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

This filter declares the things that the activity can do on a directory of notes It can allow the user to

view or edit the directory (via the VIEW and EDIT actions) or to pick a particular note from the

directory (via the PICK action)

The mimeType attribute of the ltdatagt element specifies the kind of data that these actions operate on

It indicates that the activity can get a Cursor over zero or more items (vndandroidcursordir) from a

content provider that holds Note Pad data (vndgooglenote) The Intent object that launches the

activity would include a content URI specifying the exact data of this type that the activity should open

Note also the DEFAULT category supplied in this filter Its there because the ContextstartActivity()

and ActivitystartActivityForResult() methods treat all intents as if they contained the DEFAULT

category mdash with just two exceptions

o Intents that explicitly name the target activity

o Intents consisting of the MAIN action and LAUNCHER category

Therefore the DEFAULT category is required for all filters mdash except for those with the MAIN action

and LAUNCHER category (Intent filters are not consulted for explicit intents)

3 ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

This filter describes the activitys ability to return a note selected by the user without requiring any

specification of the directory the user should choose from The GET_CONTENT action is similar to the

PICK action In both cases the activity returns the URI for a note selected by the user (In each case

its returned to the activity that called startActivityForResult() to start the NoteList activity) Here

however the caller specifies the type of data desired instead of the directory of data the user will be

picking from

The data type vndandroidcursoritemvndgooglenote indicates the type of data the activity can

return mdash a URI for a single note From the returned URI the caller can get a Cursor for exactly one

item (vndandroidcursoritem) from the content provider that holds Note Pad data (vndgooglenote)

In other words for the PICK action in the previous filter the data type indicates the type of data the

activity could display to the user For the GET_CONTENT filter it indicates the type of data the activity

can return to the caller

Given these capabilities the following intents will resolve to the NotesList activity

action androidintentactionMAIN

Launches the activity with no data specified

action androidintentactionMAIN

category androidintentcategoryLAUNCHER

Launches the activity with no data selected specified This is the actual intent used by the

Launcher to populate its top-level list All activities with filters that match this action and

category are added to the list

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of all the notes under

contentcomgoogleproviderNotePadnotes The user can then browse through the list and

get information about the items in it

action androidintentactionPICK

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of the notes under

contentcomgoogleproviderNotePadnotes The user can then pick a note from the list and

the activity will return the URI for that item back to the activity that started the NoteList activity

action androidintentactionGET_CONTENT

data type vndandroidcursoritemvndgooglenote

Asks the activity to supply a single item of Note Pad data

The second activity NoteEditor shows users a single note entry and allows them to edit it It can do

two things as described by its two intent filters

1 ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The first primary purpose of this activity is to enable the user to interact with a single note ampmdash to

either VIEW the note or EDIT it (The EDIT_NOTE category is a synonym for EDIT) The intent would

contain the URI for data matching the MIME type vndandroidcursoritemvndgooglenote mdash that is

the URI for a single specific note It would typically be a URI that was returned by the PICK or

GET_CONTENT actions of the NoteList activity

As before this filter lists the DEFAULT category so that the activity can be launched by intents that

dont explicitly specify the NoteEditor class

2 ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

The secondary purpose of this activity is to enable the user to create a new note which it will INSERT

into an existing directory of notes The intent would contain the URI for data matching the MIME type

vndandroidcursordirvndgooglenote mdash that is the URI for the directory where the note should be

placed

Given these capabilities the following intents will resolve to the NoteEditor activity

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID (For details on how content

URIs specify individual members of a group see Content Providers)

action androidintentactionEDIT

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID and to let the user edit it If

the user saves the changes the activity updates the data for the note in the content provider

action androidintentactionINSERT

data contentcomgoogleproviderNotePadnotes

Asks the activity to create a new empty note in the notes list at

contentcomgoogleproviderNotePadnotes and allow the user to edit it If the user saves the

note its URI is returned to the caller

The last activity TitleEditor enables the user to edit the title of a note This could be implemented by

directly invoking the activity (by explicitly setting its component name in the Intent) without using an

intent filter But here we take the opportunity to show how to publish alternative operations on existing

data

ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The single intent filter for this activity uses a custom action called

comandroidnotepadactionEDIT_TITLE It must be invoked on a specific note (data type

vndandroidcursoritemvndgooglenote) like the previous VIEW and EDIT actions However here the

activity displays the title contained in the note data not the content of the note itself

In addition to supporting the usual DEFAULT category the title editor also supports two other standard

categories ALTERNATIVE and SELECTED_ALTERNATIVE These categories identify activities that

can be presented to users in a menu of options (much as the LAUNCHER category identifies activities

that should be presented to user in the application launcher) Note that the filter also supplies an

explicit label (via androidlabel=stringresolve_title) to better control what users see when

presented with this activity as an alternative action to the data they are currently viewing (For more

information on these categories and building options menus see the

PackageManagerqueryIntentActivityOptions() and MenuaddIntentOptions() methods)

Given these capabilities the following intent will resolve to the TitleEditor activity

action comandroidnotepadactionEDIT_TITLE

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the title associated with note ID and allow the user to edit the title

Processes and Threads

When an application component starts and the application does not have any other components

running the Android system starts a new Linux process for the application with a single thread of

execution By default all components of the same application run in the same process and thread

(called the main thread) If an application component starts and there already exists a process for

that application (because another component from the application exists) then the component is

started within that process and uses the same thread of execution However you can arrange for

different components in your application to run in separate processes and you can create additional

threads for any process

This document discusses how processes and threads work in an Android application

Processes

By default all components of the same application run in the same process and most applications

should not change this However if you find that you need to control which process a certain

component belongs to you can do so in the manifest file

The manifest entry for each type of component elementmdashltactivitygt ltservicegt ltreceivergt and

ltprovidergtmdashsupports an androidprocess attribute that can specify a process in which that component

should run You can set this attribute so that each component runs in its own process or so that some

components share a process while others do not You can also set androidprocess so that

components of different applications run in the same processmdashprovided that the applications share the

same Linux user ID and are signed with the same certificates

The ltapplicationgt element also supports an androidprocess attribute to set a default value that

applies to all components

Android might 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 thats killed are consequently destroyed A process is started again for those components

when theres again work for them to do

When deciding which processes to kill the Android system weighs their relative importance to the

user For example it more readily shuts down a process hosting activities that are no longer visible on

screen compared to a process hosting visible activities The decision whether to terminate a process

therefore depends on the state of the components running in that process The rules used to decide

which processes to terminate is discussed below

Process lifecycle

The Android system tries to maintain an application process for as long as possible but eventually

needs to remove old processes to reclaim memory for new or more important processes To determine

which processes to keep and which to kill the system places each process into an importance

hierarchy based on the components running in the process and the state of those components

Processes with the lowest importance are eliminated first then those with the next lowest importance

and so on as necessary to recover system resources

There are five levels in the importance hierarchy The following list presents the different types of

processes in order of importance (the first process is most important and is killed last)

1 Foreground process

A process that is required for what the user is currently doing A process is considered to be in the

foreground if any of the following conditions are true

o It hosts an Activity that the user is interacting with (the Activitys onResume() method has been called)

o It hosts a Service thats bound to the activity that the user is interacting with

o It hosts a Service thats running in the foregroundmdashthe service has called startForeground()

o It hosts a Service thats executing one of its lifecycle callbacks (onCreate() onStart() or onDestroy())

o It hosts a BroadcastReceiver thats executing its onReceive() method

Generally only a few foreground processes exist at any given time They are killed only as a last

resortmdashif memory is so low that they cannot all continue to run Generally at that point the device has

reached a memory paging state so killing some foreground processes is required to keep the user

interface responsive

2 Visible process

A process that doesnt have any foreground components but still can affect what the user sees on

screen A process is considered to be visible if either of the following conditions are true

o It hosts an Activity that is not in the foreground but is still visible to the user (its onPause() method has

been called) This might occur for example if the foreground activity started a dialog which allows the

previous activity to be seen behind it

o It hosts a Service thats bound to a visible (or foreground) activity

A visible process is considered extremely important and will not be killed unless doing so is required to

keep all foreground processes running

3 Service process

A process that is running a service that has been started with the startService() method and does not

fall into either of the two higher categories Although service processes are not directly tied to anything

the user sees they are generally doing things that the user cares about (such as playing music in the

background or downloading data on the network) so the system keeps them running unless theres

not enough memory to retain them along with all foreground and visible processes

4 Background process

A process holding an activity thats not currently visible to the user (the activitys onStop() method has

been called) These processes have no direct impact on the user experience and the system can kill

them at any time to reclaim memory for a foreground visible or service process Usually there are

many background processes running so they are kept in an LRU (least recently used) list to ensure

that the process with the activity that was most recently seen by the user is the last to be killed If an

activity implements its lifecycle methods correctly and saves its current state killing its process will not

have a visible effect on the user experience because when the user navigates back to the activity the

activity restores all of its visible state See the Activities document for information about saving and

restoring state

5 Empty process

A process that doesnt hold any active application components The only reason to keep this kind of

process alive is for caching purposes to improve startup time the next time a component needs to run

in it The system often kills these processes in order to balance overall system resources between

process caches and the underlying kernel caches

Android ranks a process at the highest level it can based upon the importance of the components

currently active in the process For example if a process hosts a service and a visible activity the

process is ranked as a visible process not a service process

In addition a processs ranking might be increased because other processes are dependent on itmdasha

process that is serving another process can never be ranked lower than the process it is serving For

example if a content provider in process A is serving a client in process B or if a service in process A

is bound to a component in process B process A is always considered at least as important as

process B

Because a process running a service is ranked higher than a process with background activities an

activity that initiates a long-running operation might do well to start a service for that operation rather

than simply create a worker threadmdashparticularly if the operation will likely outlast the activity For

example an activity thats uploading a picture to a web site should start a service to perform the

upload so that the upload can continue in the background even if the user leaves the activity Using a

service guarantees that the operation will have at least service process priority regardless of what

happens to the activity This is the same reason that broadcast receivers should employ services

rather than simply put time-consuming operations in a thread

Threads

When an application is launched the system creates a thread of execution for the application called

main This thread is very important because it is in charge of dispatching events to the appropriate

user interface widgets including drawing events It is also the thread in which your application interacts

with components from the Android UI toolkit (components from the androidwidget and androidview

packages) As such the main thread is also sometimes called the UI thread

The system does not create a separate thread for each instance of a component All components that

run in the same process are instantiated in the UI thread and system calls to each component are

dispatched from that thread Consequently methods that respond to system callbacks (such as

onKeyDown() to report user actions or a lifecycle callback method) always run in the UI thread of the

process

For instance when the user touches a button on the screen your apps UI thread dispatches the touch

event to the widget which in turn sets its pressed state and posts an invalidate request to the event

queue The UI thread dequeues the request and notifies the widget that it should redraw itself

When your app performs intensive work in response to user interaction this single thread model can

yield poor performance unless you implement your application properly Specifically if everything is

happening in the UI thread performing long operations such as network access or database queries

will block the whole UI When the thread is blocked no events can be dispatched including drawing

events From the users perspective the application appears to hang Even worse if the UI thread is

blocked for more than a few seconds (about 5 seconds currently) the user is presented with the

infamous application not responding (ANR) dialog The user might then decide to quit your

application and uninstall it if they are unhappy

Additionally the Andoid UI toolkit is not thread-safe So you must not manipulate your UI from a

worker threadmdashyou must do all manipulation to your user interface from the UI thread Thus there are

simply two rules to Androids single thread model

1 Do not block the UI thread

2 Do not access the Android UI toolkit from outside the UI thread

Worker threads

Because of the single thread model described above its vital to the responsiveness of your

applications UI that you do not block the UI thread If you have operations to perform that are not

instantaneous you should make sure to do them in separate threads (background or worker

threads)

For example below is some code for a click listener that downloads an image from a separate thread

and displays it in an ImageView

public void onClick(View v) new Thread(new Runnable() public void run() Bitmap b = loadImageFromNetwork(httpexamplecomimagepng) mImageViewsetImageBitmap(b) )start()

At first this seems to work fine because it creates a new thread to handle the network operation

However it violates the second rule of the single-threaded model do not access the Android UI toolkit

from outside the UI threadmdashthis sample modifies the ImageView from the worker thread instead of the

UI thread This can result in undefined and unexpected behavior which can be difficult and time-

consuming to track down

To fix this problem Android offers several ways to access the UI thread from other threads Here is a

list of methods that can help

ActivityrunOnUiThread(Runnable)

Viewpost(Runnable)

ViewpostDelayed(Runnable long)

For example you can fix the above code by using the Viewpost(Runnable) method

public void onClick(View v) new Thread(new Runnable() public void run() final Bitmap bitmap = loadImageFromNetwork(httpexamplecomimagepng) mImageViewpost(new Runnable() public void run() mImageViewsetImageBitmap(bitmap) ) )start()

Now this implementation is thread-safe the network operation is done from a separate thread while

the ImageView is manipulated from the UI thread

However as the complexity of the operation grows this kind of code can get complicated and difficult

to maintain To handle more complex interactions with a worker thread you might consider using a

Handler in your worker thread to process messages delivered from the UI thread Perhaps the best

solution though is to extend the AsyncTask class which simplifies the execution of worker thread

tasks that need to interact with the UI

Using AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface It performs the blocking

operations in a worker thread and then publishes the results on the UI thread without requiring you to

handle threads andor handlers yourself

To use it you must subclass AsyncTask and implement the doInBackground() callback method which

runs in a pool of background threads To update your UI you should implement onPostExecute()

which delivers the result from doInBackground() and runs in the UI thread so you can safely update

your UI You can then run the task by calling execute() from the UI thread

For example you can implement the previous example using AsyncTask this way

public void onClick(View v) new DownloadImageTask()execute(httpexamplecomimagepng) private class DownloadImageTask extends AsyncTaskltString Void Bitmapgt The system calls this to perform work in a worker thread and delivers it the parameters given to AsyncTaskexecute() protected Bitmap doInBackground(String urls) return loadImageFromNetwork(urls[0])

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 19: 03 services

int num = mServicegetRandomNumber()

ToastmakeText(this number + num ToastLENGTH_SHORT)show()

Defines callbacks for service binding passed to bindService()

private ServiceConnection mConnection = new ServiceConnection()

Override

public void onServiceConnected(ComponentName className

IBinder service)

Weve bound to LocalService cast the IBinder and get LocalService instance

LocalBinder binder = (LocalBinder) service

mService = bindergetService()

mBound = true

Override

public void onServiceDisconnected(ComponentName arg0)

mBound = false

The above sample shows how the client binds to the service using an implementation of

ServiceConnection and the onServiceConnected() callback The next section provides more

information about this process of binding to the service

Note The example above doesnt explicitly unbind from the service but all clients should unbind

at an appropriate time (such as when the activity pauses)

For more sample code see the LocalServicejava class and the LocalServiceActivitiesjava class in

ApiDemos

Using a Messenger

Compared to AIDL

When you need to perform IPC using a Messenger for your interface is simpler than implementing it

with AIDL because Messenger queues all calls to the service whereas a pure AIDL interface sends

simultaneous requests to the service which must then handle multi-threading

For most applications the service doesnt need to perform multi-threading so using a Messenger

allows the service to handle one call at a time If its important that your service be multi-threaded then

you should use AIDL to define your interface

If you need your service to communicate with remote processes then you can use a Messenger to

provide the interface for your service This technique allows you to perform interprocess

communication (IPC) without the need to use AIDL

Heres a summary of how to use a Messenger

The service implements a Handler that receives a callback for each call from a client

The Handler is used to create a Messenger object (which is a reference to the Handler)

The Messenger creates an IBinder that the service returns to clients from onBind()

Clients use the IBinder to instantiate the Messenger (that references the services Handler) which the

client uses to send Message objects to the service

The service receives each Message in its Handlermdashspecifically in the handleMessage() method

In this way there are no methods for the client to call on the service Instead the client delivers

messages (Message objects) that the service receives in its Handler

Heres a simple example service that uses a Messenger interface

public class MessengerService extends Service Command to the service to display a message static final int MSG_SAY_HELLO = 1 Handler of incoming messages from clients class IncomingHandler extends Handler Override public void handleMessage(Message msg) switch (msgwhat) case MSG_SAY_HELLO ToastmakeText(getApplicationContext() hello ToastLENGTH_SHORT)show() break default superhandleMessage(msg) Target we publish for clients to send messages to IncomingHandler final Messenger mMessenger = new Messenger(new IncomingHandler()) When binding to the service we return an interface to our messenger for sending messages to the service Override public IBinder onBind(Intent intent) ToastmakeText(getApplicationContext() binding ToastLENGTH_SHORT)show() return mMessengergetBinder()

Notice that the handleMessage() method in the Handler is where the service receives the incoming

Message and decides what to do based on the what member

All that a client needs to do is create a Messenger based on the IBinder returned by the service and

send a message using send() For example heres a simple activity that binds to the service and

delivers the MSG_SAY_HELLO message to the service

public class ActivityMessenger extends Activity Messenger for communicating with the service Messenger mService = null Flag indicating whether we have called bind on the service boolean mBound Class for interacting with the main interface of the service private ServiceConnection mConnection = new ServiceConnection() public void onServiceConnected(ComponentName className IBinder service) This is called when the connection with the service has been established giving us the object we can use to interact with the service We are communicating with the service using a Messenger so here we get a client-side representation of that from the raw IBinder object mService = new Messenger(service) mBound = true public void onServiceDisconnected(ComponentName className) This is called when the connection with the service has been unexpectedly disconnected -- that is its process crashed mService = null mBound = false public void sayHello(View v) if (mBound) return Create and send a message to the service using a supported what value Message msg = Messageobtain(null MessengerServiceMSG_SAY_HELLO 0 0) try mServicesend(msg) catch (RemoteException e) eprintStackTrace() Override protected void onCreate(Bundle savedInstanceState) superonCreate(savedInstanceState) setContentView(Rlayoutmain)

Override protected void onStart() superonStart() Bind to the service bindService(new Intent(this MessengerServiceclass) mConnection ContextBIND_AUTO_CREATE) Override protected void onStop() superonStop() Unbind from the service if (mBound) unbindService(mConnection) mBound = false

Notice that this example does not show how the service can respond to the client If you want the

service to respond then you need to also create a Messenger in the client Then when the client

receives the onServiceConnected() callback it sends a Message to the service that includes the

clients Messenger in the replyTo parameter of the send() method

You can see an example of how to provide two-way messaging in the MessengerServicejava (service)

and MessengerServiceActivitiesjava (client) samples

Binding to a Service

Application components (clients) can bind to a service by calling bindService() The Android system

then calls the services onBind() method which returns an IBinder for interacting with the service

The binding is asynchronous bindService() returns immediately and does not return the IBinder to the

client To receive the IBinder the client must create an instance of ServiceConnection and pass it to

bindService() The ServiceConnection includes a callback method that the system calls to deliver the

IBinder

Note Only activities services and content providers can bind to a servicemdashyou cannot bind to a

service from a broadcast receiver

So to bind to a service from your client you must

1 Implement ServiceConnection

Your implementation must override two callback methods

onServiceConnected()

The system calls this to deliver the IBinder returned by the services onBind() method

onServiceDisconnected()

The Android system calls this when the connection to the service is unexpectedly lost such as

when the service has crashed or has been killed This is not called when the client unbinds

2 Call bindService() passing the ServiceConnection implementation

3 When the system calls your onServiceConnected() callback method you can begin making calls to the

service using the methods defined by the interface

4 To disconnect from the service call unbindService()

When your client is destroyed it will unbind from the service but you should always unbind when

youre done interacting with the service or when your activity pauses so that the service can shutdown

while its not being used (Appropriate times to bind and unbind is discussed more below)

For example the following snippet connects the client to the service created above by extending the

Binder class so all it must do is cast the returned IBinder to the LocalService class and request the

LocalService instance

LocalService mService private ServiceConnection mConnection = new ServiceConnection() Called when the connection with the service is established public void onServiceConnected(ComponentName className IBinder service) Because we have bound to an explicit service that is running in our own process we can cast its IBinder to a concrete class and directly access it LocalBinder binder = (LocalBinder) service mService = bindergetService() mBound = true Called when the connection with the service disconnects unexpectedly public void onServiceDisconnected(ComponentName className) Loge(TAG onServiceDisconnected) mBound = false

With this ServiceConnection the client can bind to a service by passing this it to bindService() For

example

Intent intent = new Intent(this LocalServiceclass) bindService(intent mConnection ContextBIND_AUTO_CREATE)

The first parameter of bindService() is an Intent that explicitly names the service to bind (thought the

intent could be implicit)

The second parameter is the ServiceConnection object

The third parameter is a flag indicating options for the binding It should usually be

BIND_AUTO_CREATE in order to create the service if its not already alive Other possible values are

BIND_DEBUG_UNBIND and BIND_NOT_FOREGROUND or 0 for none

Additional notes

Here are some important notes about binding to a service

You should always trap DeadObjectException exceptions which are thrown when the connection has

broken This is the only exception thrown by remote methods

Objects are reference counted across processes

You should usually pair the binding and unbinding during matching bring-up and tear-down moments

of the clients lifecycle For example

o If you only need to interact with the service while your activity is visible you should bind during

onStart() and unbind during onStop()

o If you want your activity to receive responses even while it is stopped in the background then you can

bind during onCreate() and unbind during onDestroy() Beware that this implies that your activity needs

to use the service the entire time its running (even in the background) so if the service is in another

process then you increase the weight of the process and it becomes more likely that the system will

kill it

Note You should usually not bind and unbind during your activitys onResume() and onPause()

because these callbacks occur at every lifecycle transition and you should keep the processing that

occurs at these transitions to a minimum Also if multiple activities in your application bind to the same

service and there is a transition between two of those activities the service may be destroyed and

recreated as the current activity unbinds (during pause) before the next one binds (during resume)

(This activity transition for how activities coordinate their lifecycles is described in the Activities

document)

For more sample code showing how to bind to a service see the RemoteServicejava class in

ApiDemos

Managing the Lifecycle of a Bound Service

Figure 1 The lifecycle for a service

that is started and also allows binding

When a service is unbound from all

clients the Android system destroys it

(unless it was also started with

onStartCommand()) As such you

dont have to manage the lifecycle of

your service if its purely a bound

servicemdashthe Android system manages

it for you based on whether it is bound

to any clients

However if you choose to implement

the onStartCommand() callback

method then you must explicitly stop

the service because the service is

now considered to be started In this

case the service runs until the service

stops itself with stopSelf() or another

component calls stopService()

regardless of whether it is bound to

any clients

Additionally if your service is started and accepts binding then when the system calls your onUnbind()

method you can optionally return true if you would like to receive a call to onRebind() the next time a

client binds to the service (instead of receiving a call to onBind()) onRebind() returns void but the

client still receives the IBinder in its onServiceConnected() callback Below figure 1 illustrates the logic

for this kind of lifecycle

For more information about the lifecycle of an started service see the Services document

Content Providers

Content providers store and retrieve data and make it accessible to all applications Theyre the only

way to share data across applications theres no common storage area that all Android packages can

access

Android ships with a number of content providers for common data types (audio video images

personal contact information and so on) You can see some of them listed in the androidprovider

package You can query these providers for the data they contain (although for some you must

acquire the proper permission to read the data)

If you want to make your own data public you have two options You can create your own content

provider (a ContentProvider subclass) or you can add the data to an existing provider mdash if theres one

that controls the same type of data and you have permission to write to it

This document is an introduction to using content providers After a brief discussion of the

fundamentals it explores how to query a content provider how to modify data controlled by a provider

and how to create a content provider of your own

Content Provider Basics

How a content provider actually stores its data under the covers is up to its designer But all content

providers implement a common interface for querying the provider and returning results mdash as well as

for adding altering and deleting data Its an interface that clients use indirectly most generally

through ContentResolver objects You get a ContentResolver by calling getContentResolver() from

within the implementation of an Activity or other application component

ContentResolver cr = getContentResolver()

You can then use the ContentResolvers methods to interact with whatever content providers youre

interested in When a query is initiated the Android system identifies the content provider thats the

target of the query and makes sure that it is up and running The system instantiates all

ContentProvider objects you never need to do it on your own In fact you never deal directly with

ContentProvider objects at all Typically theres just a single instance of each type of ContentProvider

But it can communicate with multiple ContentResolver objects in different applications and processes

The interaction between processes is handled by the ContentResolver and ContentProvider classes

The data model

Content providers expose their data as a simple table on a database model where each row is a

record and each column is data of a particular type and meaning For example information about

people and their phone numbers might be exposed as follows

_ID NUMBER NUMBER_KEY LABEL NAME TYPE

13 (425) 555 6677 425 555 6677 Kirkland office Bully Pulpit TYPE_WORK

44 (212) 555-1234 212 555 1234 NY apartment Alan Vain TYPE_HOME

45 (212) 555-6657 212 555 6657 Downtown office Alan Vain TYPE_MOBILE

53 2015554433 201 555 4433 Love Nest Rex Cars TYPE_HOME

Every record includes a numeric _ID field that uniquely identifies the record within the table IDs can be

used to match records in related tables mdash for example to find a persons phone number in one table

and pictures of that person in another

A query returns a Cursor object that can move from record to record and column to column to read the

contents of each field It has specialized methods for reading each type of data So to read a field you

must know what type of data the field contains (Theres more on query results and Cursor objects

later)

URIs

Each content provider exposes a public URI (wrapped as a Uri object) that uniquely identifies its data

set A content provider that controls multiple data sets (multiple tables) exposes a separate URI for

each one All URIs for providers begin with the string content The content scheme identifies the

data as being controlled by a content provider

If youre defining a content provider its a good idea to also define a constant for its URI to simplify

client code and make future updates cleaner Android defines CONTENT_URI constants for all the

providers that come with the platform For example the URI for the table that matches phone numbers

to people and the URI for the table that holds pictures of people (both controlled by the Contacts

content provider) are

androidproviderContactsPhonesCONTENT_URI

androidproviderContactsPhotosCONTENT_URI

The URI constant is used in all interactions with the content provider Every ContentResolver method

takes the URI as its first argument Its what identifies which provider the ContentResolver should talk

to and which table of the provider is being targeted

Querying a Content Provider

You need three pieces of information to query a content provider

The URI that identifies the provider

The names of the data fields you want to receive

The data types for those fields

If youre querying a particular record you also need the ID for that record

Making the query

To query a content provider you can use either the ContentResolverquery() method or the

ActivitymanagedQuery() method Both methods take the same set of arguments and both return a

Cursor object However managedQuery() causes the activity to manage the life cycle of the Cursor A

managed Cursor handles all of the niceties such as unloading itself when the activity pauses and

requerying itself when the activity restarts You can ask an Activity to begin managing an unmanaged

Cursor object for you by calling ActivitystartManagingCursor()

The first argument to either query() or managedQuery() is the provider URI mdash the CONTENT_URI

constant that identifies a particular ContentProvider and data set (see URIs earlier)

To restrict a query to just one record you can append the _ID value for that record to the URI mdash that

is place a string matching the ID as the last segment of the path part of the URI For example if the ID

is 23 the URI would be

content 23

There are some helper methods particularly ContentUriswithAppendedId() and

UriwithAppendedPath() that make it easy to append an ID to a URI Both are static methods that

return a Uri object with the ID added So for example if you were looking for record 23 in the database

of people contacts you might construct a query as follows

import androidproviderContactsPeople import androidcontentContentUris import androidnetUri import androiddatabaseCursor Use the ContentUris method to produce the base URI for the contact with _ID == 23 Uri myPerson = ContentUriswithAppendedId(PeopleCONTENT_URI 23) Alternatively use the Uri method to produce the base URI It takes a string rather than an integer Uri myPerson = UriwithAppendedPath(PeopleCONTENT_URI 23) Then query for this specific record Cursor cur = managedQuery(myPerson null null null null)

The other arguments to the query() and managedQuery() methods delimit the query in more detail

They are

The names of the data columns that should be returned A null value returns all columns Otherwise

only columns that are listed by name are returned All the content providers that come with the

platform define constants for their columns For example the androidproviderContactsPhones class

defines constants for the names of the columns in the phone table illustrated earlier ampmdash _ID

NUMBER NUMBER_KEY NAME and so on

A filter detailing which rows to return formatted as an SQL WHERE clause (excluding the WHERE

itself) A null value returns all rows (unless the URI limits the query to a single record)

Selection arguments

A sorting order for the rows that are returned formatted as an SQL ORDER BY clause (excluding the

ORDER BY itself) A null value returns the records in the default order for the table which may be

unordered

Lets look at an example query to retrieve a list of contact names and their primary phone numbers

import androidproviderContactsPeople import androiddatabaseCursor Form an array specifying which columns to return String[] projection = new String[] People_ID People_COUNT PeopleNAME PeopleNUMBER Get the base URI for the People table in the Contacts content provider Uri contacts = PeopleCONTENT_URI Make the query Cursor managedCursor = managedQuery(contacts projection Which columns to return null Which rows to return (all rows) null Selection arguments (none) Put the results in ascending order by name PeopleNAME + ASC)

This query retrieves data from the People table of the Contacts content provider It gets the name

primary phone number and unique record ID for each contact It also reports the number of records

that are returned as the _COUNT field of each record

The constants for the names of the columns are defined in various interfaces mdash _ID and _COUNT in

BaseColumns NAME in PeopleColumns and NUMBER in PhoneColumns The ContactsPeople

class implements each of these interfaces which is why the code example above could refer to them

using just the class name

What a query returns

A query returns a set of zero or more database records The names of the columns their default order

and their data types are specific to each content provider But every provider has an _ID column

which holds a unique numeric ID for each record Every provider can also report the number of records

returned as the _COUNT column its value is the same for all rows

Here is an example result set for the query in the previous section

_ID _COUNT NAME NUMBER

44 3 Alan Vain 212 555 1234

13 3 Bully Pulpit 425 555 6677

53 3 Rex Cars 201 555 4433

The retrieved data is exposed by a Cursor object that can be used to iterate backward or forward

through the result set You can use this object only to read the data To add modify or delete data

you must use a ContentResolver object

Reading retrieved data

The Cursor object returned by a query provides access to a recordset of results If you have queried

for a specific record by ID this set will contain only one value Otherwise it can contain multiple

values (If there are no matches it can also be empty) You can read data from specific fields in the

record but you must know the data type of the field because the Cursor object has a separate method

for reading each type of data mdash such as getString() getInt() and getFloat() (However for most types

if you call the method for reading strings the Cursor object will give you the String representation of

the data) The Cursor lets you request the column name from the index of the column or the index

number from the column name

The following snippet demonstrates reading names and phone numbers from the query illustrated

earlier

import androidproviderContactsPeople private void getColumnData(Cursor cur) if (curmoveToFirst()) String name String phoneNumber int nameColumn = curgetColumnIndex(PeopleNAME) int phoneColumn = curgetColumnIndex(PeopleNUMBER) String imagePath do Get the field values name = curgetString(nameColumn) phoneNumber = curgetString(phoneColumn) Do something with the values while (curmoveToNext())

If a query can return binary data such as an image or sound the data may be directly entered in the

table or the table entry for that data may be a string specifying a content URI that you can use to get

the data In general smaller amounts of data (say from 20 to 50K or less) are most often directly

entered in the table and can be read by calling CursorgetBlob() It returns a byte array

If the table entry is a content URI you should never try to open and read the file directly (for one thing

permissions problems can make this fail) Instead you should call ContentResolveropenInputStream()

to get an InputStream object that you can use to read the data

Modifying Data

Data kept by a content provider can be modified by

Adding new records

Adding new values to existing records

Batch updating existing records

Deleting records

All data modification is accomplished using ContentResolver methods Some content providers require

a more restrictive permission for writing data than they do for reading it If you dont have permission to

write to a content provider the ContentResolver methods will fail

Adding records

To add a new record to a content provider first set up a map of key-value pairs in a ContentValues

object where each key matches the name of a column in the content provider and the value is the

desired value for the new record in that column Then call ContentResolverinsert() and pass it the URI

of the provider and the ContentValues map This method returns the full URI of the new record mdash that

is the providers URI with the appended ID for the new record You can then use this URI to query and

get a Cursor over the new record and to further modify the record Heres an example

import androidproviderContactsPeople import androidcontentContentResolver import androidcontentContentValues ContentValues values = new ContentValues() Add Abraham Lincoln to contacts and make him a favorite valuesput(PeopleNAME Abraham Lincoln) 1 = the new contact is added to favorites 0 = the new contact is not added to favorites valuesput(PeopleSTARRED 1) Uri uri = getContentResolver()insert(PeopleCONTENT_URI values)

Adding new values

Once a record exists you can add new information to it or modify existing information For example

the next step in the example above would be to add contact information mdash like a phone number or an

IM or e-mail address mdash to the new entry

The best way to add to a record in the Contacts database is to append the name of the table where the

new data goes to the URI for the record then use the amended URI to add the new data values Each

Contacts table exposes a name for this purpose as a CONTENT_DIRECTORY constant The following

code continues the previous example by adding a phone number and e-mail address for the record

just created

Uri phoneUri = null Uri emailUri = null Add a phone number for Abraham Lincoln Begin with the URI for the new record just returned by insert() it ends with the _ID of the new record so we dont have to add the ID ourselves Then append the designation for the phone table to this URI and use the resulting URI to insert the phone number phoneUri = UriwithAppendedPath(uri PeoplePhonesCONTENT_DIRECTORY) valuesclear() valuesput(PeoplePhonesTYPE PeoplePhonesTYPE_MOBILE) valuesput(PeoplePhonesNUMBER 1233214567) getContentResolver()insert(phoneUri values) Now add an email address in the same way emailUri = UriwithAppendedPath(uri PeopleContactMethodsCONTENT_DIRECTORY) valuesclear() ContactMethodsKIND is used to distinguish different kinds of contact methods such as email IM etc valuesput(PeopleContactMethodsKIND ContactsKIND_EMAIL) valuesput(PeopleContactMethodsDATA testexamplecom) valuesput(PeopleContactMethodsTYPE PeopleContactMethodsTYPE_HOME) getContentResolver()insert(emailUri values)

You can place small amounts of binary data into a table by calling the version of ContentValuesput()

that takes a byte array That would work for a small icon-like image or a short audio clip for example

However if you have a large amount of binary data to add such as a photograph or a complete song

put a content URI for the data in the table and call ContentResolveropenOutputStream() with the files

URI (That causes the content provider to store the data in a file and record the file path in a hidden

field of the record)

In this regard the MediaStore content provider the main provider that dispenses image audio and

video data employs a special convention The same URI that is used with query() or managedQuery()

to get meta-information about the binary data (such as the caption of a photograph or the date it was

taken) is used with openInputStream() to get the data itself Similarly the same URI that is used with

insert() to put meta-information into a MediaStore record is used with openOutputStream() to place the

binary data there The following code snippet illustrates this convention

import androidproviderMediaStoreImagesMedia import androidcontentContentValues import javaioOutputStream Save the name and description of an image in a ContentValues map ContentValues values = new ContentValues(3) valuesput(MediaDISPLAY_NAME road_trip_1) valuesput(MediaDESCRIPTION Day 1 trip to Los Angeles) valuesput(MediaMIME_TYPE imagejpeg) Add a new record without the bitmap but with the values just set insert() returns the URI of the new record Uri uri = getContentResolver()insert(MediaEXTERNAL_CONTENT_URI values) Now get a handle to the file for that record and save the data into it Here sourceBitmap is a Bitmap object representing the file to save to the database try OutputStream outStream = getContentResolver()openOutputStream(uri) sourceBitmapcompress(BitmapCompressFormatJPEG 50 outStream) outStreamclose() catch (Exception e) Loge(TAG exception while writing image e)

Batch updating records

To batch update a group of records (for example to change NY to New York in all fields) call the

ContentResolverupdate() method with the columns and values to change

Deleting a record

To delete a single record call ContentResolverdelete() with the URI of a specific row

To delete multiple rows call ContentResolverdelete() with the URI of the type of record to delete (for

example androidproviderContactsPeopleCONTENT_URI) and an SQL WHERE clause defining

which rows to delete (Caution Be sure to include a valid WHERE clause if youre deleting a general

type or you risk deleting more records than you intended)

Creating a Content Provider

To create a content provider you must

Set up a system for storing the data Most content providers store their data using Androids file

storage methods or SQLite databases but you can store your data any way you want Android

provides the SQLiteOpenHelper class to help you create a database and SQLiteDatabase to manage

it

Extend the ContentProvider class to provide access to the data

Declare the content provider in the manifest file for your application (AndroidManifestxml)

The following sections have notes on the last two of these tasks

Extending the ContentProvider class

You define a ContentProvider subclass to expose your data to others using the conventions expected

by ContentResolver and Cursor objects Principally this means implementing six abstract methods

declared in the ContentProvider class

query()

insert()

update()

delete()

getType()

onCreate()

The query() method must return a Cursor object that can iterate over the requested data Cursor itself

is an interface but Android provides some ready-made Cursor objects that you can use For example

SQLiteCursor can iterate over data stored in an SQLite database You get the Cursor object by calling

any of the SQLiteDatabase classs query() methods There are other Cursor implementations mdash such

as MatrixCursor mdash for data not stored in a database

Because these ContentProvider methods can be called from various ContentResolver objects in

different processes and threads they must be implemented in a thread-safe manner

As a courtesy you might also want to call ContentResolvernotifyChange() to notify listeners when

there are modifications to the data

Beyond defining the subclass itself there are other steps you should take to simplify the work of clients

and make the class more accessible

Define a public static final Uri named CONTENT_URI This is the string that represents the full content

URI that your content provider handles You must define a unique string for this value The best

solution is to use the fully-qualified class name of the content provider (made lowercase) So for

example the URI for a TransportationProvider class could be defined as follows

public static final Uri CONTENT_URI = Uriparse(contentcomexamplecodelabtransportationprovider)

If the provider has subtables also define CONTENT_URI constants for each of the subtables These

URIs should all have the same authority (since that identifies the content provider) and be

distinguished only by their paths For example

contentcomexamplecodelabtransportationprovidertrain

contentcomexamplecodelabtransportationproviderairdomestic

contentcomexamplecodelabtransportationproviderairinternational

For an overview of content URIs see the Content URI Summary at the end of this document

Define the column names that the content provider will return to clients If you are using an underlying

database these column names are typically identical to the SQL database column names they

represent Also define public static String constants that clients can use to specify the columns in

queries and other instructions

Be sure to include an integer column named _id (with the constant _ID) for the IDs of the records

You should have this field whether or not you have another field (such as a URL) that is also unique

among all records If youre using the SQLite database the _ID field should be the following type

INTEGER PRIMARY KEY AUTOINCREMENT

The AUTOINCREMENT descriptor is optional But without it SQLite increments an ID counter field to

the next number above the largest existing number in the column If you delete the last row the next

row added will have the same ID as the deleted row AUTOINCREMENT avoids this by having SQLite

increment to the next largest value whether deleted or not

Carefully document the data type of each column Clients need this information to read the data

If you are handling a new data type you must define a new MIME type to return in your

implementation of ContentProvidergetType() The type depends in part on whether or not the content

URI submitted to getType() limits the request to a specific record Theres one form of the MIME type

for a single record and another for multiple records Use the Uri methods to help determine what is

being requested Here is the general format for each type

o For a single record vndandroidcursoritemvndyourcompanynamecontenttype

For example a request for train record 122 like this URI

contentcomexampletransportationprovidertrains122

might return this MIME type

vndandroidcursoritemvndexamplerail

o For multiple records vndandroidcursordirvndyourcompanynamecontenttype

For example a request for all train records like the following URI

contentcomexampletransportationprovidertrains

might return this MIME type

vndandroidcursordirvndexamplerail

If you are exposing byte data thats too big to put in the table itself mdash such as a large bitmap file mdash the

field that exposes the data to clients should actually contain a content URI string This is the field that

gives clients access to the data file The record should also have another field named _data that lists

the exact file path on the device for that file This field is not intended to be read by the client but by

the ContentResolver The client will call ContentResolveropenInputStream() on the user-facing field

holding the URI for the item The ContentResolver will request the _data field for that record and

because it has higher permissions than a client it should be able to access that file directly and return

a read wrapper for the file to the client

For an example of a private content provider implementation see the NodePadProvider class in the

Notepad sample application that ships with the SDK

Declaring the content provider

To let the Android system know about the content provider youve developed declare it with a

ltprovidergt element in the applications AndroidManifestxml file Content providers that are not

declared in the manifest are not visible to the Android system

The name attribute is the fully qualified name of the ContentProvider subclass The authorities attribute

is the authority part of the content URI that identifies the provider For example if the ContentProvider

subclass is AutoInfoProvider the ltprovidergt element might look like this

ltprovider androidname=comexampleautosAutoInfoProvider androidauthorities=comexampleautosautoinfoprovider gt ltprovidergt

Note that the authorities attribute omits the path part of a content URI For example if

AutoInfoProvider controlled subtables for different types of autos or different manufacturers

contentcomexampleautosautoinfoproviderhonda

contentcomexampleautosautoinfoprovidergmcompact

contentcomexampleautosautoinfoprovidergmsuv

those paths would not be declared in the manifest The authority is what identifies the provider not the

path your provider can interpret the path part of the URI in any way you choose

Other ltprovidergt attributes can set permissions to read and write data provide for an icon and text

that can be displayed to users enable and disable the provider and so on Set the multiprocess

attribute to true if data does not need to be synchronized between multiple running versions of the

content provider This permits an instance of the provider to be created in each client process

eliminating the need to perform IPC

Content URI Summary

Here is a recap of the important parts of a content URI

A Standard prefix indicating that the data is controlled by a content provider Its never modified

B The authority part of the URI it identifies the content provider For third-party applications this should

be a fully-qualified class name (reduced to lowercase) to ensure uniqueness The authority is declared

in the ltprovidergt elements authorities attribute

ltprovider androidname=TransportationProvider androidauthorities=comexampletransportationprovider gt

C The path that the content provider uses to determine what kind of data is being requested This can be

zero or more segments long If the content provider exposes only one type of data (only trains for

example) it can be absent If the provider exposes several types including subtypes it can be several

segments long mdash for example landbus landtrain seaship and seasubmarine to give four

possibilities

D The ID of the specific record being requested if any This is the _ID value of the requested record If

the request is not limited to a single record this segment and the trailing slash are omitted

contentcomexampletransportationprovidertrains

Intent and intent filters

Three of the core components of an application mdash activities services and broadcast receivers mdash 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 mdash 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 ContextstartActivity() or ActivitystartActivityForResult() to launch an

activity or get an existing activity to do something new (It can also be passed to ActivitysetResult() to

return information to the activity that called startActivityForResult())

An Intent object is passed to ContextstartService() to initiate a service or deliver new instructions to an

ongoing service Similarly an intent can be passed to ContextbindService() to establish a connection

between the calling component and a target service It can optionally initiate the service if its not

already running

Intent objects passed to any of the broadcast methods (such as ContextsendBroadcast()

ContextsendOrderedBroadcast() or ContextsendStickyBroadcast()) 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 mdash how it resolves which component should receive an intent message For

intents that dont explicitly name a target component this process involves testing the Intent object

against intent filters associated with potential targets

Intent Objects

An Intent object is a bundle of information It contains information of interest to the component that

receives the intent (such as the action to be taken and the data to act on) plus information of interest to

the Android system (such as the category of component that should handle the intent and instructions

on how to launch a target activity) Principally it can contain the following

Component name

The name of the component that should handle the intent This field is a ComponentName

object mdash a combination of the fully qualified class name of the target component (for example

comexampleprojectappFreneticActivity) and the package name set in the manifest file of the

application where the component resides (for example comexampleproject) The package

part of the component name and the package name set in the manifest do not necessarily have

to match

The component name is optional If it is set the Intent object is delivered to an instance of the

designated class If it is not set Android uses other information in the Intent object to locate a

suitable target mdash see Intent Resolution later in this document

The component name is set by setComponent() setClass() or setClassName() and read by

getComponent()

Action

A string naming the action to be performed mdash or in the case of broadcast intents the action

that took place and is being reported The Intent class defines a number of action constants

including these

Constant Target

component

Action

ACTION_CALL activity Initiate a phone call

ACTION_EDIT activity Display data for the user to edit

ACTION_MAIN activity Start up as the initial activity of a task

with no data input and no returned

output

ACTION_SYNC activity Synchronize data on a server with

data on the mobile device

ACTION_BATTERY_LOW broadcast

receiver

A warning that the battery is low

ACTION_HEADSET_PLUG broadcast

receiver

A headset has been plugged into the

device or unplugged from it

ACTION_SCREEN_ON broadcast

receiver

The screen has been turned on

ACTION_TIMEZONE_CHANGED broadcast

receiver

The setting for the time zone has

changed

See the Intent class description for a list of pre-defined constants for generic actions Other

actions are defined elsewhere in the Android API You can also define your own action strings

for activating the components in your application Those you invent should include the

application package as a prefix mdash for example comexampleprojectSHOW_COLOR

The action largely determines how the rest of the intent is structured mdash particularly the data and

extras fields mdash much as a method name determines a set of arguments and a return value For

this reason its a good idea to use action names that are as specific as possible and to couple

them tightly to the other fields of the intent In other words instead of defining an action in

isolation define an entire protocol for the Intent objects your components can handle

The action in an Intent object is set by the setAction() method and read by getAction()

Data

The URI of the data to be acted on and the MIME type of that data Different actions are paired

with different kinds of data specifications For example if the action field is ACTION_EDIT the

data field would contain the URI of the document to be displayed for editing If the action is

ACTION_CALL the data field would be a tel URI with the number to call Similarly if the action

is ACTION_VIEW and the data field is an http URI the receiving activity would be called upon

to download and display whatever data the URI refers to

When matching an intent to a component that is capable of handling the data its often

important to know the type of data (its MIME type) in addition to its URI For example a

component able to display image data should not be called upon to play an audio file

In many cases the data type can be inferred from the URI mdash particularly content URIs which

indicate that the data is located on the device and controlled by a content provider (see the

separate discussion on content providers) But the type can also be explicitly set in the Intent

object The setData() method specifies data only as a URI setType() specifies it only as a

MIME type and setDataAndType() specifies it as both a URI and a MIME type The URI is read

by getData() and the type by getType()

Category

A string containing additional information about the kind of component that should handle the

intent Any number of category descriptions can be placed in an Intent object As it does for

actions the Intent class defines several category constants including these

Constant Meaning

CATEGORY_BROWSABLE The target activity can be safely invoked by the browser to

display data referenced by a link mdash for example an image or

an e-mail message

CATEGORY_GADGET The activity can be embedded inside of another activity that

hosts gadgets

CATEGORY_HOME The activity displays the home screen the first screen the

user sees when the device is turned on or when the HOME

key is pressed

CATEGORY_LAUNCHER The activity can be the initial activity of a task and is listed in

the top-level application launcher

CATEGORY_PREFERENCE The target activity is a preference panel

See the Intent class description for the full list of categories

The addCategory() method places a category in an Intent object removeCategory() deletes a

category previously added and getCategories() gets the set of all categories currently in the

object

Extras

Key-value pairs for additional information that should be delivered to the component handling

the intent Just as some actions are paired with particular kinds of data URIs some are paired

with particular extras For example an ACTION_TIMEZONE_CHANGED intent has a time-

zone extra that identifies the new time zone and ACTION_HEADSET_PLUG has a state

extra indicating whether the headset is now plugged in or unplugged as well as a name extra

for the type of headset If you were to invent a SHOW_COLOR action the color value would be

set in an extra key-value pair

The Intent object has a series of put() methods for inserting various types of extra data and a

similar set of get() methods for reading the data These methods parallel those for Bundle

objects In fact the extras can be installed and read as a Bundle using the putExtras() and

getExtras() methods

Flags

Flags of various sorts Many instruct the Android system how to launch an activity (for example

which task the activity should belong to) and how to treat it after its launched (for example

whether it belongs in the list of recent activities) All these flags are defined in the Intent class

The Android system and the applications that come with the platform employ Intent objects both to

send out system-originated broadcasts and to activate system-defined components To see how to

structure an intent to activate a system component consult the list of intents in the reference

Intent Resolution

Intents can be divided into two groups

Explicit intents designate the target component by its name (the component name field mentioned

earlier has a value set) Since component names would generally not be known to developers of other

applications explicit intents are typically used for application-internal messages mdash such as an activity

starting a subordinate service or launching a sister activity

Implicit intents do not name a target (the field for the component name is blank) Implicit intents are

often used to activate components in other applications

Android delivers an explicit intent to an instance of the designated target class Nothing in the Intent

object other than the component name matters for determining which component should get the intent

A different strategy is needed for implicit intents In the absence of a designated target the Android

system must find the best component (or components) to handle the intent mdash a single activity or

service to perform the requested action or the set of broadcast receivers to respond to the broadcast

announcement It does so by comparing the contents of the Intent object to intent filters structures

associated with components that can potentially receive intents Filters advertise the capabilities of a

component and delimit the intents it can handle They open the component to the possibility of

receiving implicit intents of the advertised type If a component does not have any intent filters it can

receive only explicit intents A component with filters can receive both explicit and implicit intents

Only three aspects of an Intent object are consulted when the object is tested against an intent filter

action

data (both URI and data type)

category

The extras and flags play no part in resolving which component receives an intent

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 mdash but only unwanted implicit intents (those that dont 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

components 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 mdash 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 Pads filters are described in the Note Pad Example

section later)

Filters and security

An intent filter cannot be relied on for security While it opens a component to receiving only certain

kinds of implicit intents it does nothing to prevent explicit intents from targeting the component Even

though a filter restricts the intents a component will be asked to handle to certain actions and data

sources someone could always put together an explicit intent with a different action and data source

and name the component as the target

An intent filter is an instance of the IntentFilter class However since the Android system must know

about the capabilities of a component before it can launch that component intent filters are generally

not set up in Java code but in the applications manifest file (AndroidManifestxml) as ltintent-filtergt

elements (The one exception would be filters for broadcast receivers that are registered dynamically

by calling ContextregisterReceiver() they are directly created as IntentFilter objects)

A filter has fields that parallel the action data and category fields of an Intent object An implicit intent

is tested against the filter in all three areas To be delivered to the component that owns the filter it

must pass all three tests If it fails even one of them the Android system wont deliver it to the

component mdash at least not on the basis of that filter However since a component can have multiple

intent filters an intent that does not pass through one of a components filters might make it through on

another

Each of the three tests is described in detail below

Action test

An ltintent-filtergt element in the manifest file lists actions as ltactiongt subelements For

example

ltintent-filter gt ltaction androidname=comexampleprojectSHOW_CURRENT gt ltaction androidname=comexampleprojectSHOW_RECENT gt ltaction androidname=comexampleprojectSHOW_PENDING gt ltintent-filtergt

As the example shows while an Intent object names just a single action a filter may list more

than one The list cannot be empty a filter must contain at least one ltactiongt element or it will

block all intents

To pass this test the action specified in the Intent object must match one of the actions listed in

the filter If the object or the filter does not specify an action the results are as follows

If the filter fails to list any actions there is nothing for an intent to match so all intents fail the

test No intents can get through the filter

On the other hand an Intent object that doesnt specify an action automatically passes the test

mdash as long as the filter contains at least one action

Category test

An ltintent-filtergt element also lists categories as subelements For example

ltintent-filter gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryBROWSABLE gt ltintent-filtergt

Note that the constants described earlier for actions and categories are not used in the manifest

file The full string values are used instead For instance the

androidintentcategoryBROWSABLE string in the example above corresponds to the

CATEGORY_BROWSABLE constant mentioned earlier in this document Similarly the string

androidintentactionEDIT corresponds to the ACTION_EDIT constant

For an intent to pass the category test every category in the Intent object must match a

category in the filter The filter can list additional categories but it cannot omit any that are in the

intent

In principle therefore an Intent object with no categories should always pass this test

regardless of whats in the filter Thats mostly true However with one exception Android treats

all implicit intents passed to startActivity() as if they contained at least one category

androidintentcategoryDEFAULT (the CATEGORY_DEFAULT constant) Therefore activities

that are willing to receive implicit intents must include androidintentcategoryDEFAULT in

their intent filters (Filters with androidintentactionMAIN and

androidintentcategoryLAUNCHER settings are the exception They mark activities that begin

new tasks and that are represented on the launcher screen They can include

androidintentcategoryDEFAULT in the list of categories but dont need to) See Using intent

matching later for more on these filters)

Data test

Like the action and categories the data specification for an intent filter is contained in a

subelement And as in those cases the subelement can appear multiple times or not at all For

example

ltintent-filter gt ltdata androidmimeType=videompeg androidscheme=http gt ltdata androidmimeType=audiompeg androidscheme=http gt ltintent-filtergt

Each ltdatagt element can specify a URI and a data type (MIME media type) There are

separate attributes mdash scheme host port and path mdash for each part of the URI

schemehostportpath

For example in the following URI

contentcomexampleproject200foldersubfolderetc

the scheme is content the host is comexampleproject the port is 200 and the path is

foldersubfolderetc The host and port together constitute the URI authority if a host is not

specified the port is ignored

Each of these attributes is optional but they are not independent of each other For an authority

to be meaningful a scheme must also be specified For a path to be meaningful both a scheme

and an authority must be specified

When the URI in an Intent object is compared to a URI specification in a filter its compared

only to the parts of the URI actually mentioned in the filter For example if a filter specifies only

a scheme all URIs with that scheme match the filter If a filter specifies a scheme and an

authority but no path all URIs with the same scheme and authority match regardless of their

paths If a filter specifies a scheme an authority and a path only URIs with the same scheme

authority and path match However a path specification in the filter can contain wildcards to

require only a partial match of the path

The type attribute of a ltdatagt element specifies the MIME type of the data Its more common in

filters than a URI Both the Intent object and the filter can use a wildcard for the subtype field

mdash for example text or audio mdash indicating any subtype matches

The data test compares both the URI and the data type in the Intent object to a URI and data

type specified in the filter The rules are as follows

a An Intent object that contains neither a URI nor a data type passes the test only if the filter

likewise does not specify any URIs or data types

b An Intent object that contains a URI but no data type (and a type cannot be inferred from the

URI) passes the test only if its URI matches a URI in the filter and the filter likewise does not

specify a type This will be the case only for URIs like mailto and tel that do not refer to actual

data

c An Intent object that contains a data type but not a URI passes the test only if the filter lists the

same data type and similarly does not specify a URI

d An Intent object that contains both a URI and a data type (or a data type can be inferred from

the URI) passes the data type part of the test only if its type matches a type listed in the filter It

passes the URI part of the test either if its URI matches a URI in the filter or if it has a content

or file URI and the filter does not specify a URI In other words a component is presumed to

support content and file data if its filter lists only a data type

If an intent can pass through the filters of more than one activity or service the user may be asked

which component to activate An exception is raised if no target can be found

Common cases

The last rule shown above for the data test rule (d) reflects the expectation that components are able

to get local data from a file or content provider Therefore their filters can list just a data type and do

not need to explicitly name the content and file schemes This is a typical case A ltdatagt element like

the following for example tells Android that the component can get image data from a content

provider and display it

ltdata androidmimeType=image gt

Since most available data is dispensed by content providers filters that specify a data type but not a

URI are perhaps the most common

Another common configuration is filters with a scheme and a data type For example a ltdatagt

element like the following tells Android that the component can get video data from the network and

display it

ltdata androidscheme=http androidtype=video gt

Consider for example what the browser application does when the user follows a link on a web page

It first tries to display the data (as it could if the link was to an HTML page) If it cant display the data it

puts together an implicit intent with the scheme and data type and tries to start an activity that can do

the job If there are no takers it asks the download manager to download the data That puts it under

the control of a content provider so a potentially larger pool of activities (those with filters that just

name a data type) can respond

Most applications also have a way to start fresh without a reference to any particular data Activities

that can initiate applications have filters with androidintentactionMAIN specified as the action If

they are to be represented in the application launcher they also specify the

androidintentcategoryLAUNCHER category

ltintent-filter gt ltaction androidname=code androidintentactionMAIN gt ltcategory androidname=code androidintentcategoryLAUNCHER gt ltintent-filtergt

Using intent matching

Intents are matched against intent filters not only to discover a target component to activate but also

to discover something about the set of components on the device For example the Android system

populates the application launcher the top-level screen that shows the applications that are available

for the user to launch by finding all the activities with intent filters that specify the

androidintentactionMAIN action and androidintentcategoryLAUNCHER category (as illustrated

in the previous section) It then displays the icons and labels of those activities in the launcher

Similarly it discovers the home screen by looking for the activity with androidintentcategoryHOME

in its filter

Your application can use intent matching is a similar way The PackageManager has a set of query()

methods that return all components that can accept a particular intent and a similar series of

resolve() methods that determine the best component to respond to an intent For example

queryIntentActivities() returns a list of all activities that can perform the intent passed as an argument

and queryIntentServices() returns a similar list of services Neither method activates the components

they just list the ones that can respond Theres a similar method queryBroadcastReceivers() for

broadcast receivers

Note Pad Example

The Note Pad sample application enables users to browse through a list of notes view details about

individual items in the list edit the items and add a new item to the list This section looks at the intent

filters declared in its manifest file (If youre working offline in the SDK you can find all the source files

for this sample application including its manifest file at ltsdkgtsamplesNotePadindexhtml If youre

viewing the documentation online the source files are in the Tutorials and Sample Code section here)

In its manifest file the Note Pad application declares three activities each with at least one intent filter

It also declares a content provider that manages the note data Here is the manifest file in its entirety

ltmanifest xmlnsandroid=httpschemasandroidcomapkresandroid package=comexampleandroidnotepadgt ltapplication androidicon=drawableapp_notes androidlabel=stringapp_name gt ltprovider androidname=NotePadProvider androidauthorities=comgoogleproviderNotePad gt ltactivity androidname=NotesList androidlabel=stringtitle_notes_listgt ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltactivity androidname=NoteEditor androidtheme=androidstyleThemeLight androidlabel=stringtitle_note gt ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltactivitygt

ltactivity androidname=TitleEditor androidlabel=stringtitle_edit_title androidtheme=androidstyleThemeDialoggt ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltapplicationgt ltmanifestgt

The first activity NotesList is distinguished from the other activities by the fact that it operates on a

directory of notes (the note list) rather than on a single note It would generally serve as the initial user

interface into the application It can do three things as described by its three intent filters

1 ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt

This filter declares the main entry point into the Note Pad application The standard MAIN action is an

entry point that does not require any other information in the Intent (no data specification for example)

and the LAUNCHER category says that this entry point should be listed in the application launcher

2 ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

This filter declares the things that the activity can do on a directory of notes It can allow the user to

view or edit the directory (via the VIEW and EDIT actions) or to pick a particular note from the

directory (via the PICK action)

The mimeType attribute of the ltdatagt element specifies the kind of data that these actions operate on

It indicates that the activity can get a Cursor over zero or more items (vndandroidcursordir) from a

content provider that holds Note Pad data (vndgooglenote) The Intent object that launches the

activity would include a content URI specifying the exact data of this type that the activity should open

Note also the DEFAULT category supplied in this filter Its there because the ContextstartActivity()

and ActivitystartActivityForResult() methods treat all intents as if they contained the DEFAULT

category mdash with just two exceptions

o Intents that explicitly name the target activity

o Intents consisting of the MAIN action and LAUNCHER category

Therefore the DEFAULT category is required for all filters mdash except for those with the MAIN action

and LAUNCHER category (Intent filters are not consulted for explicit intents)

3 ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

This filter describes the activitys ability to return a note selected by the user without requiring any

specification of the directory the user should choose from The GET_CONTENT action is similar to the

PICK action In both cases the activity returns the URI for a note selected by the user (In each case

its returned to the activity that called startActivityForResult() to start the NoteList activity) Here

however the caller specifies the type of data desired instead of the directory of data the user will be

picking from

The data type vndandroidcursoritemvndgooglenote indicates the type of data the activity can

return mdash a URI for a single note From the returned URI the caller can get a Cursor for exactly one

item (vndandroidcursoritem) from the content provider that holds Note Pad data (vndgooglenote)

In other words for the PICK action in the previous filter the data type indicates the type of data the

activity could display to the user For the GET_CONTENT filter it indicates the type of data the activity

can return to the caller

Given these capabilities the following intents will resolve to the NotesList activity

action androidintentactionMAIN

Launches the activity with no data specified

action androidintentactionMAIN

category androidintentcategoryLAUNCHER

Launches the activity with no data selected specified This is the actual intent used by the

Launcher to populate its top-level list All activities with filters that match this action and

category are added to the list

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of all the notes under

contentcomgoogleproviderNotePadnotes The user can then browse through the list and

get information about the items in it

action androidintentactionPICK

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of the notes under

contentcomgoogleproviderNotePadnotes The user can then pick a note from the list and

the activity will return the URI for that item back to the activity that started the NoteList activity

action androidintentactionGET_CONTENT

data type vndandroidcursoritemvndgooglenote

Asks the activity to supply a single item of Note Pad data

The second activity NoteEditor shows users a single note entry and allows them to edit it It can do

two things as described by its two intent filters

1 ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The first primary purpose of this activity is to enable the user to interact with a single note ampmdash to

either VIEW the note or EDIT it (The EDIT_NOTE category is a synonym for EDIT) The intent would

contain the URI for data matching the MIME type vndandroidcursoritemvndgooglenote mdash that is

the URI for a single specific note It would typically be a URI that was returned by the PICK or

GET_CONTENT actions of the NoteList activity

As before this filter lists the DEFAULT category so that the activity can be launched by intents that

dont explicitly specify the NoteEditor class

2 ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

The secondary purpose of this activity is to enable the user to create a new note which it will INSERT

into an existing directory of notes The intent would contain the URI for data matching the MIME type

vndandroidcursordirvndgooglenote mdash that is the URI for the directory where the note should be

placed

Given these capabilities the following intents will resolve to the NoteEditor activity

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID (For details on how content

URIs specify individual members of a group see Content Providers)

action androidintentactionEDIT

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID and to let the user edit it If

the user saves the changes the activity updates the data for the note in the content provider

action androidintentactionINSERT

data contentcomgoogleproviderNotePadnotes

Asks the activity to create a new empty note in the notes list at

contentcomgoogleproviderNotePadnotes and allow the user to edit it If the user saves the

note its URI is returned to the caller

The last activity TitleEditor enables the user to edit the title of a note This could be implemented by

directly invoking the activity (by explicitly setting its component name in the Intent) without using an

intent filter But here we take the opportunity to show how to publish alternative operations on existing

data

ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The single intent filter for this activity uses a custom action called

comandroidnotepadactionEDIT_TITLE It must be invoked on a specific note (data type

vndandroidcursoritemvndgooglenote) like the previous VIEW and EDIT actions However here the

activity displays the title contained in the note data not the content of the note itself

In addition to supporting the usual DEFAULT category the title editor also supports two other standard

categories ALTERNATIVE and SELECTED_ALTERNATIVE These categories identify activities that

can be presented to users in a menu of options (much as the LAUNCHER category identifies activities

that should be presented to user in the application launcher) Note that the filter also supplies an

explicit label (via androidlabel=stringresolve_title) to better control what users see when

presented with this activity as an alternative action to the data they are currently viewing (For more

information on these categories and building options menus see the

PackageManagerqueryIntentActivityOptions() and MenuaddIntentOptions() methods)

Given these capabilities the following intent will resolve to the TitleEditor activity

action comandroidnotepadactionEDIT_TITLE

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the title associated with note ID and allow the user to edit the title

Processes and Threads

When an application component starts and the application does not have any other components

running the Android system starts a new Linux process for the application with a single thread of

execution By default all components of the same application run in the same process and thread

(called the main thread) If an application component starts and there already exists a process for

that application (because another component from the application exists) then the component is

started within that process and uses the same thread of execution However you can arrange for

different components in your application to run in separate processes and you can create additional

threads for any process

This document discusses how processes and threads work in an Android application

Processes

By default all components of the same application run in the same process and most applications

should not change this However if you find that you need to control which process a certain

component belongs to you can do so in the manifest file

The manifest entry for each type of component elementmdashltactivitygt ltservicegt ltreceivergt and

ltprovidergtmdashsupports an androidprocess attribute that can specify a process in which that component

should run You can set this attribute so that each component runs in its own process or so that some

components share a process while others do not You can also set androidprocess so that

components of different applications run in the same processmdashprovided that the applications share the

same Linux user ID and are signed with the same certificates

The ltapplicationgt element also supports an androidprocess attribute to set a default value that

applies to all components

Android might 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 thats killed are consequently destroyed A process is started again for those components

when theres again work for them to do

When deciding which processes to kill the Android system weighs their relative importance to the

user For example it more readily shuts down a process hosting activities that are no longer visible on

screen compared to a process hosting visible activities The decision whether to terminate a process

therefore depends on the state of the components running in that process The rules used to decide

which processes to terminate is discussed below

Process lifecycle

The Android system tries to maintain an application process for as long as possible but eventually

needs to remove old processes to reclaim memory for new or more important processes To determine

which processes to keep and which to kill the system places each process into an importance

hierarchy based on the components running in the process and the state of those components

Processes with the lowest importance are eliminated first then those with the next lowest importance

and so on as necessary to recover system resources

There are five levels in the importance hierarchy The following list presents the different types of

processes in order of importance (the first process is most important and is killed last)

1 Foreground process

A process that is required for what the user is currently doing A process is considered to be in the

foreground if any of the following conditions are true

o It hosts an Activity that the user is interacting with (the Activitys onResume() method has been called)

o It hosts a Service thats bound to the activity that the user is interacting with

o It hosts a Service thats running in the foregroundmdashthe service has called startForeground()

o It hosts a Service thats executing one of its lifecycle callbacks (onCreate() onStart() or onDestroy())

o It hosts a BroadcastReceiver thats executing its onReceive() method

Generally only a few foreground processes exist at any given time They are killed only as a last

resortmdashif memory is so low that they cannot all continue to run Generally at that point the device has

reached a memory paging state so killing some foreground processes is required to keep the user

interface responsive

2 Visible process

A process that doesnt have any foreground components but still can affect what the user sees on

screen A process is considered to be visible if either of the following conditions are true

o It hosts an Activity that is not in the foreground but is still visible to the user (its onPause() method has

been called) This might occur for example if the foreground activity started a dialog which allows the

previous activity to be seen behind it

o It hosts a Service thats bound to a visible (or foreground) activity

A visible process is considered extremely important and will not be killed unless doing so is required to

keep all foreground processes running

3 Service process

A process that is running a service that has been started with the startService() method and does not

fall into either of the two higher categories Although service processes are not directly tied to anything

the user sees they are generally doing things that the user cares about (such as playing music in the

background or downloading data on the network) so the system keeps them running unless theres

not enough memory to retain them along with all foreground and visible processes

4 Background process

A process holding an activity thats not currently visible to the user (the activitys onStop() method has

been called) These processes have no direct impact on the user experience and the system can kill

them at any time to reclaim memory for a foreground visible or service process Usually there are

many background processes running so they are kept in an LRU (least recently used) list to ensure

that the process with the activity that was most recently seen by the user is the last to be killed If an

activity implements its lifecycle methods correctly and saves its current state killing its process will not

have a visible effect on the user experience because when the user navigates back to the activity the

activity restores all of its visible state See the Activities document for information about saving and

restoring state

5 Empty process

A process that doesnt hold any active application components The only reason to keep this kind of

process alive is for caching purposes to improve startup time the next time a component needs to run

in it The system often kills these processes in order to balance overall system resources between

process caches and the underlying kernel caches

Android ranks a process at the highest level it can based upon the importance of the components

currently active in the process For example if a process hosts a service and a visible activity the

process is ranked as a visible process not a service process

In addition a processs ranking might be increased because other processes are dependent on itmdasha

process that is serving another process can never be ranked lower than the process it is serving For

example if a content provider in process A is serving a client in process B or if a service in process A

is bound to a component in process B process A is always considered at least as important as

process B

Because a process running a service is ranked higher than a process with background activities an

activity that initiates a long-running operation might do well to start a service for that operation rather

than simply create a worker threadmdashparticularly if the operation will likely outlast the activity For

example an activity thats uploading a picture to a web site should start a service to perform the

upload so that the upload can continue in the background even if the user leaves the activity Using a

service guarantees that the operation will have at least service process priority regardless of what

happens to the activity This is the same reason that broadcast receivers should employ services

rather than simply put time-consuming operations in a thread

Threads

When an application is launched the system creates a thread of execution for the application called

main This thread is very important because it is in charge of dispatching events to the appropriate

user interface widgets including drawing events It is also the thread in which your application interacts

with components from the Android UI toolkit (components from the androidwidget and androidview

packages) As such the main thread is also sometimes called the UI thread

The system does not create a separate thread for each instance of a component All components that

run in the same process are instantiated in the UI thread and system calls to each component are

dispatched from that thread Consequently methods that respond to system callbacks (such as

onKeyDown() to report user actions or a lifecycle callback method) always run in the UI thread of the

process

For instance when the user touches a button on the screen your apps UI thread dispatches the touch

event to the widget which in turn sets its pressed state and posts an invalidate request to the event

queue The UI thread dequeues the request and notifies the widget that it should redraw itself

When your app performs intensive work in response to user interaction this single thread model can

yield poor performance unless you implement your application properly Specifically if everything is

happening in the UI thread performing long operations such as network access or database queries

will block the whole UI When the thread is blocked no events can be dispatched including drawing

events From the users perspective the application appears to hang Even worse if the UI thread is

blocked for more than a few seconds (about 5 seconds currently) the user is presented with the

infamous application not responding (ANR) dialog The user might then decide to quit your

application and uninstall it if they are unhappy

Additionally the Andoid UI toolkit is not thread-safe So you must not manipulate your UI from a

worker threadmdashyou must do all manipulation to your user interface from the UI thread Thus there are

simply two rules to Androids single thread model

1 Do not block the UI thread

2 Do not access the Android UI toolkit from outside the UI thread

Worker threads

Because of the single thread model described above its vital to the responsiveness of your

applications UI that you do not block the UI thread If you have operations to perform that are not

instantaneous you should make sure to do them in separate threads (background or worker

threads)

For example below is some code for a click listener that downloads an image from a separate thread

and displays it in an ImageView

public void onClick(View v) new Thread(new Runnable() public void run() Bitmap b = loadImageFromNetwork(httpexamplecomimagepng) mImageViewsetImageBitmap(b) )start()

At first this seems to work fine because it creates a new thread to handle the network operation

However it violates the second rule of the single-threaded model do not access the Android UI toolkit

from outside the UI threadmdashthis sample modifies the ImageView from the worker thread instead of the

UI thread This can result in undefined and unexpected behavior which can be difficult and time-

consuming to track down

To fix this problem Android offers several ways to access the UI thread from other threads Here is a

list of methods that can help

ActivityrunOnUiThread(Runnable)

Viewpost(Runnable)

ViewpostDelayed(Runnable long)

For example you can fix the above code by using the Viewpost(Runnable) method

public void onClick(View v) new Thread(new Runnable() public void run() final Bitmap bitmap = loadImageFromNetwork(httpexamplecomimagepng) mImageViewpost(new Runnable() public void run() mImageViewsetImageBitmap(bitmap) ) )start()

Now this implementation is thread-safe the network operation is done from a separate thread while

the ImageView is manipulated from the UI thread

However as the complexity of the operation grows this kind of code can get complicated and difficult

to maintain To handle more complex interactions with a worker thread you might consider using a

Handler in your worker thread to process messages delivered from the UI thread Perhaps the best

solution though is to extend the AsyncTask class which simplifies the execution of worker thread

tasks that need to interact with the UI

Using AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface It performs the blocking

operations in a worker thread and then publishes the results on the UI thread without requiring you to

handle threads andor handlers yourself

To use it you must subclass AsyncTask and implement the doInBackground() callback method which

runs in a pool of background threads To update your UI you should implement onPostExecute()

which delivers the result from doInBackground() and runs in the UI thread so you can safely update

your UI You can then run the task by calling execute() from the UI thread

For example you can implement the previous example using AsyncTask this way

public void onClick(View v) new DownloadImageTask()execute(httpexamplecomimagepng) private class DownloadImageTask extends AsyncTaskltString Void Bitmapgt The system calls this to perform work in a worker thread and delivers it the parameters given to AsyncTaskexecute() protected Bitmap doInBackground(String urls) return loadImageFromNetwork(urls[0])

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 20: 03 services

The Handler is used to create a Messenger object (which is a reference to the Handler)

The Messenger creates an IBinder that the service returns to clients from onBind()

Clients use the IBinder to instantiate the Messenger (that references the services Handler) which the

client uses to send Message objects to the service

The service receives each Message in its Handlermdashspecifically in the handleMessage() method

In this way there are no methods for the client to call on the service Instead the client delivers

messages (Message objects) that the service receives in its Handler

Heres a simple example service that uses a Messenger interface

public class MessengerService extends Service Command to the service to display a message static final int MSG_SAY_HELLO = 1 Handler of incoming messages from clients class IncomingHandler extends Handler Override public void handleMessage(Message msg) switch (msgwhat) case MSG_SAY_HELLO ToastmakeText(getApplicationContext() hello ToastLENGTH_SHORT)show() break default superhandleMessage(msg) Target we publish for clients to send messages to IncomingHandler final Messenger mMessenger = new Messenger(new IncomingHandler()) When binding to the service we return an interface to our messenger for sending messages to the service Override public IBinder onBind(Intent intent) ToastmakeText(getApplicationContext() binding ToastLENGTH_SHORT)show() return mMessengergetBinder()

Notice that the handleMessage() method in the Handler is where the service receives the incoming

Message and decides what to do based on the what member

All that a client needs to do is create a Messenger based on the IBinder returned by the service and

send a message using send() For example heres a simple activity that binds to the service and

delivers the MSG_SAY_HELLO message to the service

public class ActivityMessenger extends Activity Messenger for communicating with the service Messenger mService = null Flag indicating whether we have called bind on the service boolean mBound Class for interacting with the main interface of the service private ServiceConnection mConnection = new ServiceConnection() public void onServiceConnected(ComponentName className IBinder service) This is called when the connection with the service has been established giving us the object we can use to interact with the service We are communicating with the service using a Messenger so here we get a client-side representation of that from the raw IBinder object mService = new Messenger(service) mBound = true public void onServiceDisconnected(ComponentName className) This is called when the connection with the service has been unexpectedly disconnected -- that is its process crashed mService = null mBound = false public void sayHello(View v) if (mBound) return Create and send a message to the service using a supported what value Message msg = Messageobtain(null MessengerServiceMSG_SAY_HELLO 0 0) try mServicesend(msg) catch (RemoteException e) eprintStackTrace() Override protected void onCreate(Bundle savedInstanceState) superonCreate(savedInstanceState) setContentView(Rlayoutmain)

Override protected void onStart() superonStart() Bind to the service bindService(new Intent(this MessengerServiceclass) mConnection ContextBIND_AUTO_CREATE) Override protected void onStop() superonStop() Unbind from the service if (mBound) unbindService(mConnection) mBound = false

Notice that this example does not show how the service can respond to the client If you want the

service to respond then you need to also create a Messenger in the client Then when the client

receives the onServiceConnected() callback it sends a Message to the service that includes the

clients Messenger in the replyTo parameter of the send() method

You can see an example of how to provide two-way messaging in the MessengerServicejava (service)

and MessengerServiceActivitiesjava (client) samples

Binding to a Service

Application components (clients) can bind to a service by calling bindService() The Android system

then calls the services onBind() method which returns an IBinder for interacting with the service

The binding is asynchronous bindService() returns immediately and does not return the IBinder to the

client To receive the IBinder the client must create an instance of ServiceConnection and pass it to

bindService() The ServiceConnection includes a callback method that the system calls to deliver the

IBinder

Note Only activities services and content providers can bind to a servicemdashyou cannot bind to a

service from a broadcast receiver

So to bind to a service from your client you must

1 Implement ServiceConnection

Your implementation must override two callback methods

onServiceConnected()

The system calls this to deliver the IBinder returned by the services onBind() method

onServiceDisconnected()

The Android system calls this when the connection to the service is unexpectedly lost such as

when the service has crashed or has been killed This is not called when the client unbinds

2 Call bindService() passing the ServiceConnection implementation

3 When the system calls your onServiceConnected() callback method you can begin making calls to the

service using the methods defined by the interface

4 To disconnect from the service call unbindService()

When your client is destroyed it will unbind from the service but you should always unbind when

youre done interacting with the service or when your activity pauses so that the service can shutdown

while its not being used (Appropriate times to bind and unbind is discussed more below)

For example the following snippet connects the client to the service created above by extending the

Binder class so all it must do is cast the returned IBinder to the LocalService class and request the

LocalService instance

LocalService mService private ServiceConnection mConnection = new ServiceConnection() Called when the connection with the service is established public void onServiceConnected(ComponentName className IBinder service) Because we have bound to an explicit service that is running in our own process we can cast its IBinder to a concrete class and directly access it LocalBinder binder = (LocalBinder) service mService = bindergetService() mBound = true Called when the connection with the service disconnects unexpectedly public void onServiceDisconnected(ComponentName className) Loge(TAG onServiceDisconnected) mBound = false

With this ServiceConnection the client can bind to a service by passing this it to bindService() For

example

Intent intent = new Intent(this LocalServiceclass) bindService(intent mConnection ContextBIND_AUTO_CREATE)

The first parameter of bindService() is an Intent that explicitly names the service to bind (thought the

intent could be implicit)

The second parameter is the ServiceConnection object

The third parameter is a flag indicating options for the binding It should usually be

BIND_AUTO_CREATE in order to create the service if its not already alive Other possible values are

BIND_DEBUG_UNBIND and BIND_NOT_FOREGROUND or 0 for none

Additional notes

Here are some important notes about binding to a service

You should always trap DeadObjectException exceptions which are thrown when the connection has

broken This is the only exception thrown by remote methods

Objects are reference counted across processes

You should usually pair the binding and unbinding during matching bring-up and tear-down moments

of the clients lifecycle For example

o If you only need to interact with the service while your activity is visible you should bind during

onStart() and unbind during onStop()

o If you want your activity to receive responses even while it is stopped in the background then you can

bind during onCreate() and unbind during onDestroy() Beware that this implies that your activity needs

to use the service the entire time its running (even in the background) so if the service is in another

process then you increase the weight of the process and it becomes more likely that the system will

kill it

Note You should usually not bind and unbind during your activitys onResume() and onPause()

because these callbacks occur at every lifecycle transition and you should keep the processing that

occurs at these transitions to a minimum Also if multiple activities in your application bind to the same

service and there is a transition between two of those activities the service may be destroyed and

recreated as the current activity unbinds (during pause) before the next one binds (during resume)

(This activity transition for how activities coordinate their lifecycles is described in the Activities

document)

For more sample code showing how to bind to a service see the RemoteServicejava class in

ApiDemos

Managing the Lifecycle of a Bound Service

Figure 1 The lifecycle for a service

that is started and also allows binding

When a service is unbound from all

clients the Android system destroys it

(unless it was also started with

onStartCommand()) As such you

dont have to manage the lifecycle of

your service if its purely a bound

servicemdashthe Android system manages

it for you based on whether it is bound

to any clients

However if you choose to implement

the onStartCommand() callback

method then you must explicitly stop

the service because the service is

now considered to be started In this

case the service runs until the service

stops itself with stopSelf() or another

component calls stopService()

regardless of whether it is bound to

any clients

Additionally if your service is started and accepts binding then when the system calls your onUnbind()

method you can optionally return true if you would like to receive a call to onRebind() the next time a

client binds to the service (instead of receiving a call to onBind()) onRebind() returns void but the

client still receives the IBinder in its onServiceConnected() callback Below figure 1 illustrates the logic

for this kind of lifecycle

For more information about the lifecycle of an started service see the Services document

Content Providers

Content providers store and retrieve data and make it accessible to all applications Theyre the only

way to share data across applications theres no common storage area that all Android packages can

access

Android ships with a number of content providers for common data types (audio video images

personal contact information and so on) You can see some of them listed in the androidprovider

package You can query these providers for the data they contain (although for some you must

acquire the proper permission to read the data)

If you want to make your own data public you have two options You can create your own content

provider (a ContentProvider subclass) or you can add the data to an existing provider mdash if theres one

that controls the same type of data and you have permission to write to it

This document is an introduction to using content providers After a brief discussion of the

fundamentals it explores how to query a content provider how to modify data controlled by a provider

and how to create a content provider of your own

Content Provider Basics

How a content provider actually stores its data under the covers is up to its designer But all content

providers implement a common interface for querying the provider and returning results mdash as well as

for adding altering and deleting data Its an interface that clients use indirectly most generally

through ContentResolver objects You get a ContentResolver by calling getContentResolver() from

within the implementation of an Activity or other application component

ContentResolver cr = getContentResolver()

You can then use the ContentResolvers methods to interact with whatever content providers youre

interested in When a query is initiated the Android system identifies the content provider thats the

target of the query and makes sure that it is up and running The system instantiates all

ContentProvider objects you never need to do it on your own In fact you never deal directly with

ContentProvider objects at all Typically theres just a single instance of each type of ContentProvider

But it can communicate with multiple ContentResolver objects in different applications and processes

The interaction between processes is handled by the ContentResolver and ContentProvider classes

The data model

Content providers expose their data as a simple table on a database model where each row is a

record and each column is data of a particular type and meaning For example information about

people and their phone numbers might be exposed as follows

_ID NUMBER NUMBER_KEY LABEL NAME TYPE

13 (425) 555 6677 425 555 6677 Kirkland office Bully Pulpit TYPE_WORK

44 (212) 555-1234 212 555 1234 NY apartment Alan Vain TYPE_HOME

45 (212) 555-6657 212 555 6657 Downtown office Alan Vain TYPE_MOBILE

53 2015554433 201 555 4433 Love Nest Rex Cars TYPE_HOME

Every record includes a numeric _ID field that uniquely identifies the record within the table IDs can be

used to match records in related tables mdash for example to find a persons phone number in one table

and pictures of that person in another

A query returns a Cursor object that can move from record to record and column to column to read the

contents of each field It has specialized methods for reading each type of data So to read a field you

must know what type of data the field contains (Theres more on query results and Cursor objects

later)

URIs

Each content provider exposes a public URI (wrapped as a Uri object) that uniquely identifies its data

set A content provider that controls multiple data sets (multiple tables) exposes a separate URI for

each one All URIs for providers begin with the string content The content scheme identifies the

data as being controlled by a content provider

If youre defining a content provider its a good idea to also define a constant for its URI to simplify

client code and make future updates cleaner Android defines CONTENT_URI constants for all the

providers that come with the platform For example the URI for the table that matches phone numbers

to people and the URI for the table that holds pictures of people (both controlled by the Contacts

content provider) are

androidproviderContactsPhonesCONTENT_URI

androidproviderContactsPhotosCONTENT_URI

The URI constant is used in all interactions with the content provider Every ContentResolver method

takes the URI as its first argument Its what identifies which provider the ContentResolver should talk

to and which table of the provider is being targeted

Querying a Content Provider

You need three pieces of information to query a content provider

The URI that identifies the provider

The names of the data fields you want to receive

The data types for those fields

If youre querying a particular record you also need the ID for that record

Making the query

To query a content provider you can use either the ContentResolverquery() method or the

ActivitymanagedQuery() method Both methods take the same set of arguments and both return a

Cursor object However managedQuery() causes the activity to manage the life cycle of the Cursor A

managed Cursor handles all of the niceties such as unloading itself when the activity pauses and

requerying itself when the activity restarts You can ask an Activity to begin managing an unmanaged

Cursor object for you by calling ActivitystartManagingCursor()

The first argument to either query() or managedQuery() is the provider URI mdash the CONTENT_URI

constant that identifies a particular ContentProvider and data set (see URIs earlier)

To restrict a query to just one record you can append the _ID value for that record to the URI mdash that

is place a string matching the ID as the last segment of the path part of the URI For example if the ID

is 23 the URI would be

content 23

There are some helper methods particularly ContentUriswithAppendedId() and

UriwithAppendedPath() that make it easy to append an ID to a URI Both are static methods that

return a Uri object with the ID added So for example if you were looking for record 23 in the database

of people contacts you might construct a query as follows

import androidproviderContactsPeople import androidcontentContentUris import androidnetUri import androiddatabaseCursor Use the ContentUris method to produce the base URI for the contact with _ID == 23 Uri myPerson = ContentUriswithAppendedId(PeopleCONTENT_URI 23) Alternatively use the Uri method to produce the base URI It takes a string rather than an integer Uri myPerson = UriwithAppendedPath(PeopleCONTENT_URI 23) Then query for this specific record Cursor cur = managedQuery(myPerson null null null null)

The other arguments to the query() and managedQuery() methods delimit the query in more detail

They are

The names of the data columns that should be returned A null value returns all columns Otherwise

only columns that are listed by name are returned All the content providers that come with the

platform define constants for their columns For example the androidproviderContactsPhones class

defines constants for the names of the columns in the phone table illustrated earlier ampmdash _ID

NUMBER NUMBER_KEY NAME and so on

A filter detailing which rows to return formatted as an SQL WHERE clause (excluding the WHERE

itself) A null value returns all rows (unless the URI limits the query to a single record)

Selection arguments

A sorting order for the rows that are returned formatted as an SQL ORDER BY clause (excluding the

ORDER BY itself) A null value returns the records in the default order for the table which may be

unordered

Lets look at an example query to retrieve a list of contact names and their primary phone numbers

import androidproviderContactsPeople import androiddatabaseCursor Form an array specifying which columns to return String[] projection = new String[] People_ID People_COUNT PeopleNAME PeopleNUMBER Get the base URI for the People table in the Contacts content provider Uri contacts = PeopleCONTENT_URI Make the query Cursor managedCursor = managedQuery(contacts projection Which columns to return null Which rows to return (all rows) null Selection arguments (none) Put the results in ascending order by name PeopleNAME + ASC)

This query retrieves data from the People table of the Contacts content provider It gets the name

primary phone number and unique record ID for each contact It also reports the number of records

that are returned as the _COUNT field of each record

The constants for the names of the columns are defined in various interfaces mdash _ID and _COUNT in

BaseColumns NAME in PeopleColumns and NUMBER in PhoneColumns The ContactsPeople

class implements each of these interfaces which is why the code example above could refer to them

using just the class name

What a query returns

A query returns a set of zero or more database records The names of the columns their default order

and their data types are specific to each content provider But every provider has an _ID column

which holds a unique numeric ID for each record Every provider can also report the number of records

returned as the _COUNT column its value is the same for all rows

Here is an example result set for the query in the previous section

_ID _COUNT NAME NUMBER

44 3 Alan Vain 212 555 1234

13 3 Bully Pulpit 425 555 6677

53 3 Rex Cars 201 555 4433

The retrieved data is exposed by a Cursor object that can be used to iterate backward or forward

through the result set You can use this object only to read the data To add modify or delete data

you must use a ContentResolver object

Reading retrieved data

The Cursor object returned by a query provides access to a recordset of results If you have queried

for a specific record by ID this set will contain only one value Otherwise it can contain multiple

values (If there are no matches it can also be empty) You can read data from specific fields in the

record but you must know the data type of the field because the Cursor object has a separate method

for reading each type of data mdash such as getString() getInt() and getFloat() (However for most types

if you call the method for reading strings the Cursor object will give you the String representation of

the data) The Cursor lets you request the column name from the index of the column or the index

number from the column name

The following snippet demonstrates reading names and phone numbers from the query illustrated

earlier

import androidproviderContactsPeople private void getColumnData(Cursor cur) if (curmoveToFirst()) String name String phoneNumber int nameColumn = curgetColumnIndex(PeopleNAME) int phoneColumn = curgetColumnIndex(PeopleNUMBER) String imagePath do Get the field values name = curgetString(nameColumn) phoneNumber = curgetString(phoneColumn) Do something with the values while (curmoveToNext())

If a query can return binary data such as an image or sound the data may be directly entered in the

table or the table entry for that data may be a string specifying a content URI that you can use to get

the data In general smaller amounts of data (say from 20 to 50K or less) are most often directly

entered in the table and can be read by calling CursorgetBlob() It returns a byte array

If the table entry is a content URI you should never try to open and read the file directly (for one thing

permissions problems can make this fail) Instead you should call ContentResolveropenInputStream()

to get an InputStream object that you can use to read the data

Modifying Data

Data kept by a content provider can be modified by

Adding new records

Adding new values to existing records

Batch updating existing records

Deleting records

All data modification is accomplished using ContentResolver methods Some content providers require

a more restrictive permission for writing data than they do for reading it If you dont have permission to

write to a content provider the ContentResolver methods will fail

Adding records

To add a new record to a content provider first set up a map of key-value pairs in a ContentValues

object where each key matches the name of a column in the content provider and the value is the

desired value for the new record in that column Then call ContentResolverinsert() and pass it the URI

of the provider and the ContentValues map This method returns the full URI of the new record mdash that

is the providers URI with the appended ID for the new record You can then use this URI to query and

get a Cursor over the new record and to further modify the record Heres an example

import androidproviderContactsPeople import androidcontentContentResolver import androidcontentContentValues ContentValues values = new ContentValues() Add Abraham Lincoln to contacts and make him a favorite valuesput(PeopleNAME Abraham Lincoln) 1 = the new contact is added to favorites 0 = the new contact is not added to favorites valuesput(PeopleSTARRED 1) Uri uri = getContentResolver()insert(PeopleCONTENT_URI values)

Adding new values

Once a record exists you can add new information to it or modify existing information For example

the next step in the example above would be to add contact information mdash like a phone number or an

IM or e-mail address mdash to the new entry

The best way to add to a record in the Contacts database is to append the name of the table where the

new data goes to the URI for the record then use the amended URI to add the new data values Each

Contacts table exposes a name for this purpose as a CONTENT_DIRECTORY constant The following

code continues the previous example by adding a phone number and e-mail address for the record

just created

Uri phoneUri = null Uri emailUri = null Add a phone number for Abraham Lincoln Begin with the URI for the new record just returned by insert() it ends with the _ID of the new record so we dont have to add the ID ourselves Then append the designation for the phone table to this URI and use the resulting URI to insert the phone number phoneUri = UriwithAppendedPath(uri PeoplePhonesCONTENT_DIRECTORY) valuesclear() valuesput(PeoplePhonesTYPE PeoplePhonesTYPE_MOBILE) valuesput(PeoplePhonesNUMBER 1233214567) getContentResolver()insert(phoneUri values) Now add an email address in the same way emailUri = UriwithAppendedPath(uri PeopleContactMethodsCONTENT_DIRECTORY) valuesclear() ContactMethodsKIND is used to distinguish different kinds of contact methods such as email IM etc valuesput(PeopleContactMethodsKIND ContactsKIND_EMAIL) valuesput(PeopleContactMethodsDATA testexamplecom) valuesput(PeopleContactMethodsTYPE PeopleContactMethodsTYPE_HOME) getContentResolver()insert(emailUri values)

You can place small amounts of binary data into a table by calling the version of ContentValuesput()

that takes a byte array That would work for a small icon-like image or a short audio clip for example

However if you have a large amount of binary data to add such as a photograph or a complete song

put a content URI for the data in the table and call ContentResolveropenOutputStream() with the files

URI (That causes the content provider to store the data in a file and record the file path in a hidden

field of the record)

In this regard the MediaStore content provider the main provider that dispenses image audio and

video data employs a special convention The same URI that is used with query() or managedQuery()

to get meta-information about the binary data (such as the caption of a photograph or the date it was

taken) is used with openInputStream() to get the data itself Similarly the same URI that is used with

insert() to put meta-information into a MediaStore record is used with openOutputStream() to place the

binary data there The following code snippet illustrates this convention

import androidproviderMediaStoreImagesMedia import androidcontentContentValues import javaioOutputStream Save the name and description of an image in a ContentValues map ContentValues values = new ContentValues(3) valuesput(MediaDISPLAY_NAME road_trip_1) valuesput(MediaDESCRIPTION Day 1 trip to Los Angeles) valuesput(MediaMIME_TYPE imagejpeg) Add a new record without the bitmap but with the values just set insert() returns the URI of the new record Uri uri = getContentResolver()insert(MediaEXTERNAL_CONTENT_URI values) Now get a handle to the file for that record and save the data into it Here sourceBitmap is a Bitmap object representing the file to save to the database try OutputStream outStream = getContentResolver()openOutputStream(uri) sourceBitmapcompress(BitmapCompressFormatJPEG 50 outStream) outStreamclose() catch (Exception e) Loge(TAG exception while writing image e)

Batch updating records

To batch update a group of records (for example to change NY to New York in all fields) call the

ContentResolverupdate() method with the columns and values to change

Deleting a record

To delete a single record call ContentResolverdelete() with the URI of a specific row

To delete multiple rows call ContentResolverdelete() with the URI of the type of record to delete (for

example androidproviderContactsPeopleCONTENT_URI) and an SQL WHERE clause defining

which rows to delete (Caution Be sure to include a valid WHERE clause if youre deleting a general

type or you risk deleting more records than you intended)

Creating a Content Provider

To create a content provider you must

Set up a system for storing the data Most content providers store their data using Androids file

storage methods or SQLite databases but you can store your data any way you want Android

provides the SQLiteOpenHelper class to help you create a database and SQLiteDatabase to manage

it

Extend the ContentProvider class to provide access to the data

Declare the content provider in the manifest file for your application (AndroidManifestxml)

The following sections have notes on the last two of these tasks

Extending the ContentProvider class

You define a ContentProvider subclass to expose your data to others using the conventions expected

by ContentResolver and Cursor objects Principally this means implementing six abstract methods

declared in the ContentProvider class

query()

insert()

update()

delete()

getType()

onCreate()

The query() method must return a Cursor object that can iterate over the requested data Cursor itself

is an interface but Android provides some ready-made Cursor objects that you can use For example

SQLiteCursor can iterate over data stored in an SQLite database You get the Cursor object by calling

any of the SQLiteDatabase classs query() methods There are other Cursor implementations mdash such

as MatrixCursor mdash for data not stored in a database

Because these ContentProvider methods can be called from various ContentResolver objects in

different processes and threads they must be implemented in a thread-safe manner

As a courtesy you might also want to call ContentResolvernotifyChange() to notify listeners when

there are modifications to the data

Beyond defining the subclass itself there are other steps you should take to simplify the work of clients

and make the class more accessible

Define a public static final Uri named CONTENT_URI This is the string that represents the full content

URI that your content provider handles You must define a unique string for this value The best

solution is to use the fully-qualified class name of the content provider (made lowercase) So for

example the URI for a TransportationProvider class could be defined as follows

public static final Uri CONTENT_URI = Uriparse(contentcomexamplecodelabtransportationprovider)

If the provider has subtables also define CONTENT_URI constants for each of the subtables These

URIs should all have the same authority (since that identifies the content provider) and be

distinguished only by their paths For example

contentcomexamplecodelabtransportationprovidertrain

contentcomexamplecodelabtransportationproviderairdomestic

contentcomexamplecodelabtransportationproviderairinternational

For an overview of content URIs see the Content URI Summary at the end of this document

Define the column names that the content provider will return to clients If you are using an underlying

database these column names are typically identical to the SQL database column names they

represent Also define public static String constants that clients can use to specify the columns in

queries and other instructions

Be sure to include an integer column named _id (with the constant _ID) for the IDs of the records

You should have this field whether or not you have another field (such as a URL) that is also unique

among all records If youre using the SQLite database the _ID field should be the following type

INTEGER PRIMARY KEY AUTOINCREMENT

The AUTOINCREMENT descriptor is optional But without it SQLite increments an ID counter field to

the next number above the largest existing number in the column If you delete the last row the next

row added will have the same ID as the deleted row AUTOINCREMENT avoids this by having SQLite

increment to the next largest value whether deleted or not

Carefully document the data type of each column Clients need this information to read the data

If you are handling a new data type you must define a new MIME type to return in your

implementation of ContentProvidergetType() The type depends in part on whether or not the content

URI submitted to getType() limits the request to a specific record Theres one form of the MIME type

for a single record and another for multiple records Use the Uri methods to help determine what is

being requested Here is the general format for each type

o For a single record vndandroidcursoritemvndyourcompanynamecontenttype

For example a request for train record 122 like this URI

contentcomexampletransportationprovidertrains122

might return this MIME type

vndandroidcursoritemvndexamplerail

o For multiple records vndandroidcursordirvndyourcompanynamecontenttype

For example a request for all train records like the following URI

contentcomexampletransportationprovidertrains

might return this MIME type

vndandroidcursordirvndexamplerail

If you are exposing byte data thats too big to put in the table itself mdash such as a large bitmap file mdash the

field that exposes the data to clients should actually contain a content URI string This is the field that

gives clients access to the data file The record should also have another field named _data that lists

the exact file path on the device for that file This field is not intended to be read by the client but by

the ContentResolver The client will call ContentResolveropenInputStream() on the user-facing field

holding the URI for the item The ContentResolver will request the _data field for that record and

because it has higher permissions than a client it should be able to access that file directly and return

a read wrapper for the file to the client

For an example of a private content provider implementation see the NodePadProvider class in the

Notepad sample application that ships with the SDK

Declaring the content provider

To let the Android system know about the content provider youve developed declare it with a

ltprovidergt element in the applications AndroidManifestxml file Content providers that are not

declared in the manifest are not visible to the Android system

The name attribute is the fully qualified name of the ContentProvider subclass The authorities attribute

is the authority part of the content URI that identifies the provider For example if the ContentProvider

subclass is AutoInfoProvider the ltprovidergt element might look like this

ltprovider androidname=comexampleautosAutoInfoProvider androidauthorities=comexampleautosautoinfoprovider gt ltprovidergt

Note that the authorities attribute omits the path part of a content URI For example if

AutoInfoProvider controlled subtables for different types of autos or different manufacturers

contentcomexampleautosautoinfoproviderhonda

contentcomexampleautosautoinfoprovidergmcompact

contentcomexampleautosautoinfoprovidergmsuv

those paths would not be declared in the manifest The authority is what identifies the provider not the

path your provider can interpret the path part of the URI in any way you choose

Other ltprovidergt attributes can set permissions to read and write data provide for an icon and text

that can be displayed to users enable and disable the provider and so on Set the multiprocess

attribute to true if data does not need to be synchronized between multiple running versions of the

content provider This permits an instance of the provider to be created in each client process

eliminating the need to perform IPC

Content URI Summary

Here is a recap of the important parts of a content URI

A Standard prefix indicating that the data is controlled by a content provider Its never modified

B The authority part of the URI it identifies the content provider For third-party applications this should

be a fully-qualified class name (reduced to lowercase) to ensure uniqueness The authority is declared

in the ltprovidergt elements authorities attribute

ltprovider androidname=TransportationProvider androidauthorities=comexampletransportationprovider gt

C The path that the content provider uses to determine what kind of data is being requested This can be

zero or more segments long If the content provider exposes only one type of data (only trains for

example) it can be absent If the provider exposes several types including subtypes it can be several

segments long mdash for example landbus landtrain seaship and seasubmarine to give four

possibilities

D The ID of the specific record being requested if any This is the _ID value of the requested record If

the request is not limited to a single record this segment and the trailing slash are omitted

contentcomexampletransportationprovidertrains

Intent and intent filters

Three of the core components of an application mdash activities services and broadcast receivers mdash 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 mdash 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 ContextstartActivity() or ActivitystartActivityForResult() to launch an

activity or get an existing activity to do something new (It can also be passed to ActivitysetResult() to

return information to the activity that called startActivityForResult())

An Intent object is passed to ContextstartService() to initiate a service or deliver new instructions to an

ongoing service Similarly an intent can be passed to ContextbindService() to establish a connection

between the calling component and a target service It can optionally initiate the service if its not

already running

Intent objects passed to any of the broadcast methods (such as ContextsendBroadcast()

ContextsendOrderedBroadcast() or ContextsendStickyBroadcast()) 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 mdash how it resolves which component should receive an intent message For

intents that dont explicitly name a target component this process involves testing the Intent object

against intent filters associated with potential targets

Intent Objects

An Intent object is a bundle of information It contains information of interest to the component that

receives the intent (such as the action to be taken and the data to act on) plus information of interest to

the Android system (such as the category of component that should handle the intent and instructions

on how to launch a target activity) Principally it can contain the following

Component name

The name of the component that should handle the intent This field is a ComponentName

object mdash a combination of the fully qualified class name of the target component (for example

comexampleprojectappFreneticActivity) and the package name set in the manifest file of the

application where the component resides (for example comexampleproject) The package

part of the component name and the package name set in the manifest do not necessarily have

to match

The component name is optional If it is set the Intent object is delivered to an instance of the

designated class If it is not set Android uses other information in the Intent object to locate a

suitable target mdash see Intent Resolution later in this document

The component name is set by setComponent() setClass() or setClassName() and read by

getComponent()

Action

A string naming the action to be performed mdash or in the case of broadcast intents the action

that took place and is being reported The Intent class defines a number of action constants

including these

Constant Target

component

Action

ACTION_CALL activity Initiate a phone call

ACTION_EDIT activity Display data for the user to edit

ACTION_MAIN activity Start up as the initial activity of a task

with no data input and no returned

output

ACTION_SYNC activity Synchronize data on a server with

data on the mobile device

ACTION_BATTERY_LOW broadcast

receiver

A warning that the battery is low

ACTION_HEADSET_PLUG broadcast

receiver

A headset has been plugged into the

device or unplugged from it

ACTION_SCREEN_ON broadcast

receiver

The screen has been turned on

ACTION_TIMEZONE_CHANGED broadcast

receiver

The setting for the time zone has

changed

See the Intent class description for a list of pre-defined constants for generic actions Other

actions are defined elsewhere in the Android API You can also define your own action strings

for activating the components in your application Those you invent should include the

application package as a prefix mdash for example comexampleprojectSHOW_COLOR

The action largely determines how the rest of the intent is structured mdash particularly the data and

extras fields mdash much as a method name determines a set of arguments and a return value For

this reason its a good idea to use action names that are as specific as possible and to couple

them tightly to the other fields of the intent In other words instead of defining an action in

isolation define an entire protocol for the Intent objects your components can handle

The action in an Intent object is set by the setAction() method and read by getAction()

Data

The URI of the data to be acted on and the MIME type of that data Different actions are paired

with different kinds of data specifications For example if the action field is ACTION_EDIT the

data field would contain the URI of the document to be displayed for editing If the action is

ACTION_CALL the data field would be a tel URI with the number to call Similarly if the action

is ACTION_VIEW and the data field is an http URI the receiving activity would be called upon

to download and display whatever data the URI refers to

When matching an intent to a component that is capable of handling the data its often

important to know the type of data (its MIME type) in addition to its URI For example a

component able to display image data should not be called upon to play an audio file

In many cases the data type can be inferred from the URI mdash particularly content URIs which

indicate that the data is located on the device and controlled by a content provider (see the

separate discussion on content providers) But the type can also be explicitly set in the Intent

object The setData() method specifies data only as a URI setType() specifies it only as a

MIME type and setDataAndType() specifies it as both a URI and a MIME type The URI is read

by getData() and the type by getType()

Category

A string containing additional information about the kind of component that should handle the

intent Any number of category descriptions can be placed in an Intent object As it does for

actions the Intent class defines several category constants including these

Constant Meaning

CATEGORY_BROWSABLE The target activity can be safely invoked by the browser to

display data referenced by a link mdash for example an image or

an e-mail message

CATEGORY_GADGET The activity can be embedded inside of another activity that

hosts gadgets

CATEGORY_HOME The activity displays the home screen the first screen the

user sees when the device is turned on or when the HOME

key is pressed

CATEGORY_LAUNCHER The activity can be the initial activity of a task and is listed in

the top-level application launcher

CATEGORY_PREFERENCE The target activity is a preference panel

See the Intent class description for the full list of categories

The addCategory() method places a category in an Intent object removeCategory() deletes a

category previously added and getCategories() gets the set of all categories currently in the

object

Extras

Key-value pairs for additional information that should be delivered to the component handling

the intent Just as some actions are paired with particular kinds of data URIs some are paired

with particular extras For example an ACTION_TIMEZONE_CHANGED intent has a time-

zone extra that identifies the new time zone and ACTION_HEADSET_PLUG has a state

extra indicating whether the headset is now plugged in or unplugged as well as a name extra

for the type of headset If you were to invent a SHOW_COLOR action the color value would be

set in an extra key-value pair

The Intent object has a series of put() methods for inserting various types of extra data and a

similar set of get() methods for reading the data These methods parallel those for Bundle

objects In fact the extras can be installed and read as a Bundle using the putExtras() and

getExtras() methods

Flags

Flags of various sorts Many instruct the Android system how to launch an activity (for example

which task the activity should belong to) and how to treat it after its launched (for example

whether it belongs in the list of recent activities) All these flags are defined in the Intent class

The Android system and the applications that come with the platform employ Intent objects both to

send out system-originated broadcasts and to activate system-defined components To see how to

structure an intent to activate a system component consult the list of intents in the reference

Intent Resolution

Intents can be divided into two groups

Explicit intents designate the target component by its name (the component name field mentioned

earlier has a value set) Since component names would generally not be known to developers of other

applications explicit intents are typically used for application-internal messages mdash such as an activity

starting a subordinate service or launching a sister activity

Implicit intents do not name a target (the field for the component name is blank) Implicit intents are

often used to activate components in other applications

Android delivers an explicit intent to an instance of the designated target class Nothing in the Intent

object other than the component name matters for determining which component should get the intent

A different strategy is needed for implicit intents In the absence of a designated target the Android

system must find the best component (or components) to handle the intent mdash a single activity or

service to perform the requested action or the set of broadcast receivers to respond to the broadcast

announcement It does so by comparing the contents of the Intent object to intent filters structures

associated with components that can potentially receive intents Filters advertise the capabilities of a

component and delimit the intents it can handle They open the component to the possibility of

receiving implicit intents of the advertised type If a component does not have any intent filters it can

receive only explicit intents A component with filters can receive both explicit and implicit intents

Only three aspects of an Intent object are consulted when the object is tested against an intent filter

action

data (both URI and data type)

category

The extras and flags play no part in resolving which component receives an intent

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 mdash but only unwanted implicit intents (those that dont 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

components 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 mdash 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 Pads filters are described in the Note Pad Example

section later)

Filters and security

An intent filter cannot be relied on for security While it opens a component to receiving only certain

kinds of implicit intents it does nothing to prevent explicit intents from targeting the component Even

though a filter restricts the intents a component will be asked to handle to certain actions and data

sources someone could always put together an explicit intent with a different action and data source

and name the component as the target

An intent filter is an instance of the IntentFilter class However since the Android system must know

about the capabilities of a component before it can launch that component intent filters are generally

not set up in Java code but in the applications manifest file (AndroidManifestxml) as ltintent-filtergt

elements (The one exception would be filters for broadcast receivers that are registered dynamically

by calling ContextregisterReceiver() they are directly created as IntentFilter objects)

A filter has fields that parallel the action data and category fields of an Intent object An implicit intent

is tested against the filter in all three areas To be delivered to the component that owns the filter it

must pass all three tests If it fails even one of them the Android system wont deliver it to the

component mdash at least not on the basis of that filter However since a component can have multiple

intent filters an intent that does not pass through one of a components filters might make it through on

another

Each of the three tests is described in detail below

Action test

An ltintent-filtergt element in the manifest file lists actions as ltactiongt subelements For

example

ltintent-filter gt ltaction androidname=comexampleprojectSHOW_CURRENT gt ltaction androidname=comexampleprojectSHOW_RECENT gt ltaction androidname=comexampleprojectSHOW_PENDING gt ltintent-filtergt

As the example shows while an Intent object names just a single action a filter may list more

than one The list cannot be empty a filter must contain at least one ltactiongt element or it will

block all intents

To pass this test the action specified in the Intent object must match one of the actions listed in

the filter If the object or the filter does not specify an action the results are as follows

If the filter fails to list any actions there is nothing for an intent to match so all intents fail the

test No intents can get through the filter

On the other hand an Intent object that doesnt specify an action automatically passes the test

mdash as long as the filter contains at least one action

Category test

An ltintent-filtergt element also lists categories as subelements For example

ltintent-filter gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryBROWSABLE gt ltintent-filtergt

Note that the constants described earlier for actions and categories are not used in the manifest

file The full string values are used instead For instance the

androidintentcategoryBROWSABLE string in the example above corresponds to the

CATEGORY_BROWSABLE constant mentioned earlier in this document Similarly the string

androidintentactionEDIT corresponds to the ACTION_EDIT constant

For an intent to pass the category test every category in the Intent object must match a

category in the filter The filter can list additional categories but it cannot omit any that are in the

intent

In principle therefore an Intent object with no categories should always pass this test

regardless of whats in the filter Thats mostly true However with one exception Android treats

all implicit intents passed to startActivity() as if they contained at least one category

androidintentcategoryDEFAULT (the CATEGORY_DEFAULT constant) Therefore activities

that are willing to receive implicit intents must include androidintentcategoryDEFAULT in

their intent filters (Filters with androidintentactionMAIN and

androidintentcategoryLAUNCHER settings are the exception They mark activities that begin

new tasks and that are represented on the launcher screen They can include

androidintentcategoryDEFAULT in the list of categories but dont need to) See Using intent

matching later for more on these filters)

Data test

Like the action and categories the data specification for an intent filter is contained in a

subelement And as in those cases the subelement can appear multiple times or not at all For

example

ltintent-filter gt ltdata androidmimeType=videompeg androidscheme=http gt ltdata androidmimeType=audiompeg androidscheme=http gt ltintent-filtergt

Each ltdatagt element can specify a URI and a data type (MIME media type) There are

separate attributes mdash scheme host port and path mdash for each part of the URI

schemehostportpath

For example in the following URI

contentcomexampleproject200foldersubfolderetc

the scheme is content the host is comexampleproject the port is 200 and the path is

foldersubfolderetc The host and port together constitute the URI authority if a host is not

specified the port is ignored

Each of these attributes is optional but they are not independent of each other For an authority

to be meaningful a scheme must also be specified For a path to be meaningful both a scheme

and an authority must be specified

When the URI in an Intent object is compared to a URI specification in a filter its compared

only to the parts of the URI actually mentioned in the filter For example if a filter specifies only

a scheme all URIs with that scheme match the filter If a filter specifies a scheme and an

authority but no path all URIs with the same scheme and authority match regardless of their

paths If a filter specifies a scheme an authority and a path only URIs with the same scheme

authority and path match However a path specification in the filter can contain wildcards to

require only a partial match of the path

The type attribute of a ltdatagt element specifies the MIME type of the data Its more common in

filters than a URI Both the Intent object and the filter can use a wildcard for the subtype field

mdash for example text or audio mdash indicating any subtype matches

The data test compares both the URI and the data type in the Intent object to a URI and data

type specified in the filter The rules are as follows

a An Intent object that contains neither a URI nor a data type passes the test only if the filter

likewise does not specify any URIs or data types

b An Intent object that contains a URI but no data type (and a type cannot be inferred from the

URI) passes the test only if its URI matches a URI in the filter and the filter likewise does not

specify a type This will be the case only for URIs like mailto and tel that do not refer to actual

data

c An Intent object that contains a data type but not a URI passes the test only if the filter lists the

same data type and similarly does not specify a URI

d An Intent object that contains both a URI and a data type (or a data type can be inferred from

the URI) passes the data type part of the test only if its type matches a type listed in the filter It

passes the URI part of the test either if its URI matches a URI in the filter or if it has a content

or file URI and the filter does not specify a URI In other words a component is presumed to

support content and file data if its filter lists only a data type

If an intent can pass through the filters of more than one activity or service the user may be asked

which component to activate An exception is raised if no target can be found

Common cases

The last rule shown above for the data test rule (d) reflects the expectation that components are able

to get local data from a file or content provider Therefore their filters can list just a data type and do

not need to explicitly name the content and file schemes This is a typical case A ltdatagt element like

the following for example tells Android that the component can get image data from a content

provider and display it

ltdata androidmimeType=image gt

Since most available data is dispensed by content providers filters that specify a data type but not a

URI are perhaps the most common

Another common configuration is filters with a scheme and a data type For example a ltdatagt

element like the following tells Android that the component can get video data from the network and

display it

ltdata androidscheme=http androidtype=video gt

Consider for example what the browser application does when the user follows a link on a web page

It first tries to display the data (as it could if the link was to an HTML page) If it cant display the data it

puts together an implicit intent with the scheme and data type and tries to start an activity that can do

the job If there are no takers it asks the download manager to download the data That puts it under

the control of a content provider so a potentially larger pool of activities (those with filters that just

name a data type) can respond

Most applications also have a way to start fresh without a reference to any particular data Activities

that can initiate applications have filters with androidintentactionMAIN specified as the action If

they are to be represented in the application launcher they also specify the

androidintentcategoryLAUNCHER category

ltintent-filter gt ltaction androidname=code androidintentactionMAIN gt ltcategory androidname=code androidintentcategoryLAUNCHER gt ltintent-filtergt

Using intent matching

Intents are matched against intent filters not only to discover a target component to activate but also

to discover something about the set of components on the device For example the Android system

populates the application launcher the top-level screen that shows the applications that are available

for the user to launch by finding all the activities with intent filters that specify the

androidintentactionMAIN action and androidintentcategoryLAUNCHER category (as illustrated

in the previous section) It then displays the icons and labels of those activities in the launcher

Similarly it discovers the home screen by looking for the activity with androidintentcategoryHOME

in its filter

Your application can use intent matching is a similar way The PackageManager has a set of query()

methods that return all components that can accept a particular intent and a similar series of

resolve() methods that determine the best component to respond to an intent For example

queryIntentActivities() returns a list of all activities that can perform the intent passed as an argument

and queryIntentServices() returns a similar list of services Neither method activates the components

they just list the ones that can respond Theres a similar method queryBroadcastReceivers() for

broadcast receivers

Note Pad Example

The Note Pad sample application enables users to browse through a list of notes view details about

individual items in the list edit the items and add a new item to the list This section looks at the intent

filters declared in its manifest file (If youre working offline in the SDK you can find all the source files

for this sample application including its manifest file at ltsdkgtsamplesNotePadindexhtml If youre

viewing the documentation online the source files are in the Tutorials and Sample Code section here)

In its manifest file the Note Pad application declares three activities each with at least one intent filter

It also declares a content provider that manages the note data Here is the manifest file in its entirety

ltmanifest xmlnsandroid=httpschemasandroidcomapkresandroid package=comexampleandroidnotepadgt ltapplication androidicon=drawableapp_notes androidlabel=stringapp_name gt ltprovider androidname=NotePadProvider androidauthorities=comgoogleproviderNotePad gt ltactivity androidname=NotesList androidlabel=stringtitle_notes_listgt ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltactivity androidname=NoteEditor androidtheme=androidstyleThemeLight androidlabel=stringtitle_note gt ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltactivitygt

ltactivity androidname=TitleEditor androidlabel=stringtitle_edit_title androidtheme=androidstyleThemeDialoggt ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltapplicationgt ltmanifestgt

The first activity NotesList is distinguished from the other activities by the fact that it operates on a

directory of notes (the note list) rather than on a single note It would generally serve as the initial user

interface into the application It can do three things as described by its three intent filters

1 ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt

This filter declares the main entry point into the Note Pad application The standard MAIN action is an

entry point that does not require any other information in the Intent (no data specification for example)

and the LAUNCHER category says that this entry point should be listed in the application launcher

2 ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

This filter declares the things that the activity can do on a directory of notes It can allow the user to

view or edit the directory (via the VIEW and EDIT actions) or to pick a particular note from the

directory (via the PICK action)

The mimeType attribute of the ltdatagt element specifies the kind of data that these actions operate on

It indicates that the activity can get a Cursor over zero or more items (vndandroidcursordir) from a

content provider that holds Note Pad data (vndgooglenote) The Intent object that launches the

activity would include a content URI specifying the exact data of this type that the activity should open

Note also the DEFAULT category supplied in this filter Its there because the ContextstartActivity()

and ActivitystartActivityForResult() methods treat all intents as if they contained the DEFAULT

category mdash with just two exceptions

o Intents that explicitly name the target activity

o Intents consisting of the MAIN action and LAUNCHER category

Therefore the DEFAULT category is required for all filters mdash except for those with the MAIN action

and LAUNCHER category (Intent filters are not consulted for explicit intents)

3 ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

This filter describes the activitys ability to return a note selected by the user without requiring any

specification of the directory the user should choose from The GET_CONTENT action is similar to the

PICK action In both cases the activity returns the URI for a note selected by the user (In each case

its returned to the activity that called startActivityForResult() to start the NoteList activity) Here

however the caller specifies the type of data desired instead of the directory of data the user will be

picking from

The data type vndandroidcursoritemvndgooglenote indicates the type of data the activity can

return mdash a URI for a single note From the returned URI the caller can get a Cursor for exactly one

item (vndandroidcursoritem) from the content provider that holds Note Pad data (vndgooglenote)

In other words for the PICK action in the previous filter the data type indicates the type of data the

activity could display to the user For the GET_CONTENT filter it indicates the type of data the activity

can return to the caller

Given these capabilities the following intents will resolve to the NotesList activity

action androidintentactionMAIN

Launches the activity with no data specified

action androidintentactionMAIN

category androidintentcategoryLAUNCHER

Launches the activity with no data selected specified This is the actual intent used by the

Launcher to populate its top-level list All activities with filters that match this action and

category are added to the list

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of all the notes under

contentcomgoogleproviderNotePadnotes The user can then browse through the list and

get information about the items in it

action androidintentactionPICK

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of the notes under

contentcomgoogleproviderNotePadnotes The user can then pick a note from the list and

the activity will return the URI for that item back to the activity that started the NoteList activity

action androidintentactionGET_CONTENT

data type vndandroidcursoritemvndgooglenote

Asks the activity to supply a single item of Note Pad data

The second activity NoteEditor shows users a single note entry and allows them to edit it It can do

two things as described by its two intent filters

1 ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The first primary purpose of this activity is to enable the user to interact with a single note ampmdash to

either VIEW the note or EDIT it (The EDIT_NOTE category is a synonym for EDIT) The intent would

contain the URI for data matching the MIME type vndandroidcursoritemvndgooglenote mdash that is

the URI for a single specific note It would typically be a URI that was returned by the PICK or

GET_CONTENT actions of the NoteList activity

As before this filter lists the DEFAULT category so that the activity can be launched by intents that

dont explicitly specify the NoteEditor class

2 ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

The secondary purpose of this activity is to enable the user to create a new note which it will INSERT

into an existing directory of notes The intent would contain the URI for data matching the MIME type

vndandroidcursordirvndgooglenote mdash that is the URI for the directory where the note should be

placed

Given these capabilities the following intents will resolve to the NoteEditor activity

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID (For details on how content

URIs specify individual members of a group see Content Providers)

action androidintentactionEDIT

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID and to let the user edit it If

the user saves the changes the activity updates the data for the note in the content provider

action androidintentactionINSERT

data contentcomgoogleproviderNotePadnotes

Asks the activity to create a new empty note in the notes list at

contentcomgoogleproviderNotePadnotes and allow the user to edit it If the user saves the

note its URI is returned to the caller

The last activity TitleEditor enables the user to edit the title of a note This could be implemented by

directly invoking the activity (by explicitly setting its component name in the Intent) without using an

intent filter But here we take the opportunity to show how to publish alternative operations on existing

data

ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The single intent filter for this activity uses a custom action called

comandroidnotepadactionEDIT_TITLE It must be invoked on a specific note (data type

vndandroidcursoritemvndgooglenote) like the previous VIEW and EDIT actions However here the

activity displays the title contained in the note data not the content of the note itself

In addition to supporting the usual DEFAULT category the title editor also supports two other standard

categories ALTERNATIVE and SELECTED_ALTERNATIVE These categories identify activities that

can be presented to users in a menu of options (much as the LAUNCHER category identifies activities

that should be presented to user in the application launcher) Note that the filter also supplies an

explicit label (via androidlabel=stringresolve_title) to better control what users see when

presented with this activity as an alternative action to the data they are currently viewing (For more

information on these categories and building options menus see the

PackageManagerqueryIntentActivityOptions() and MenuaddIntentOptions() methods)

Given these capabilities the following intent will resolve to the TitleEditor activity

action comandroidnotepadactionEDIT_TITLE

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the title associated with note ID and allow the user to edit the title

Processes and Threads

When an application component starts and the application does not have any other components

running the Android system starts a new Linux process for the application with a single thread of

execution By default all components of the same application run in the same process and thread

(called the main thread) If an application component starts and there already exists a process for

that application (because another component from the application exists) then the component is

started within that process and uses the same thread of execution However you can arrange for

different components in your application to run in separate processes and you can create additional

threads for any process

This document discusses how processes and threads work in an Android application

Processes

By default all components of the same application run in the same process and most applications

should not change this However if you find that you need to control which process a certain

component belongs to you can do so in the manifest file

The manifest entry for each type of component elementmdashltactivitygt ltservicegt ltreceivergt and

ltprovidergtmdashsupports an androidprocess attribute that can specify a process in which that component

should run You can set this attribute so that each component runs in its own process or so that some

components share a process while others do not You can also set androidprocess so that

components of different applications run in the same processmdashprovided that the applications share the

same Linux user ID and are signed with the same certificates

The ltapplicationgt element also supports an androidprocess attribute to set a default value that

applies to all components

Android might 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 thats killed are consequently destroyed A process is started again for those components

when theres again work for them to do

When deciding which processes to kill the Android system weighs their relative importance to the

user For example it more readily shuts down a process hosting activities that are no longer visible on

screen compared to a process hosting visible activities The decision whether to terminate a process

therefore depends on the state of the components running in that process The rules used to decide

which processes to terminate is discussed below

Process lifecycle

The Android system tries to maintain an application process for as long as possible but eventually

needs to remove old processes to reclaim memory for new or more important processes To determine

which processes to keep and which to kill the system places each process into an importance

hierarchy based on the components running in the process and the state of those components

Processes with the lowest importance are eliminated first then those with the next lowest importance

and so on as necessary to recover system resources

There are five levels in the importance hierarchy The following list presents the different types of

processes in order of importance (the first process is most important and is killed last)

1 Foreground process

A process that is required for what the user is currently doing A process is considered to be in the

foreground if any of the following conditions are true

o It hosts an Activity that the user is interacting with (the Activitys onResume() method has been called)

o It hosts a Service thats bound to the activity that the user is interacting with

o It hosts a Service thats running in the foregroundmdashthe service has called startForeground()

o It hosts a Service thats executing one of its lifecycle callbacks (onCreate() onStart() or onDestroy())

o It hosts a BroadcastReceiver thats executing its onReceive() method

Generally only a few foreground processes exist at any given time They are killed only as a last

resortmdashif memory is so low that they cannot all continue to run Generally at that point the device has

reached a memory paging state so killing some foreground processes is required to keep the user

interface responsive

2 Visible process

A process that doesnt have any foreground components but still can affect what the user sees on

screen A process is considered to be visible if either of the following conditions are true

o It hosts an Activity that is not in the foreground but is still visible to the user (its onPause() method has

been called) This might occur for example if the foreground activity started a dialog which allows the

previous activity to be seen behind it

o It hosts a Service thats bound to a visible (or foreground) activity

A visible process is considered extremely important and will not be killed unless doing so is required to

keep all foreground processes running

3 Service process

A process that is running a service that has been started with the startService() method and does not

fall into either of the two higher categories Although service processes are not directly tied to anything

the user sees they are generally doing things that the user cares about (such as playing music in the

background or downloading data on the network) so the system keeps them running unless theres

not enough memory to retain them along with all foreground and visible processes

4 Background process

A process holding an activity thats not currently visible to the user (the activitys onStop() method has

been called) These processes have no direct impact on the user experience and the system can kill

them at any time to reclaim memory for a foreground visible or service process Usually there are

many background processes running so they are kept in an LRU (least recently used) list to ensure

that the process with the activity that was most recently seen by the user is the last to be killed If an

activity implements its lifecycle methods correctly and saves its current state killing its process will not

have a visible effect on the user experience because when the user navigates back to the activity the

activity restores all of its visible state See the Activities document for information about saving and

restoring state

5 Empty process

A process that doesnt hold any active application components The only reason to keep this kind of

process alive is for caching purposes to improve startup time the next time a component needs to run

in it The system often kills these processes in order to balance overall system resources between

process caches and the underlying kernel caches

Android ranks a process at the highest level it can based upon the importance of the components

currently active in the process For example if a process hosts a service and a visible activity the

process is ranked as a visible process not a service process

In addition a processs ranking might be increased because other processes are dependent on itmdasha

process that is serving another process can never be ranked lower than the process it is serving For

example if a content provider in process A is serving a client in process B or if a service in process A

is bound to a component in process B process A is always considered at least as important as

process B

Because a process running a service is ranked higher than a process with background activities an

activity that initiates a long-running operation might do well to start a service for that operation rather

than simply create a worker threadmdashparticularly if the operation will likely outlast the activity For

example an activity thats uploading a picture to a web site should start a service to perform the

upload so that the upload can continue in the background even if the user leaves the activity Using a

service guarantees that the operation will have at least service process priority regardless of what

happens to the activity This is the same reason that broadcast receivers should employ services

rather than simply put time-consuming operations in a thread

Threads

When an application is launched the system creates a thread of execution for the application called

main This thread is very important because it is in charge of dispatching events to the appropriate

user interface widgets including drawing events It is also the thread in which your application interacts

with components from the Android UI toolkit (components from the androidwidget and androidview

packages) As such the main thread is also sometimes called the UI thread

The system does not create a separate thread for each instance of a component All components that

run in the same process are instantiated in the UI thread and system calls to each component are

dispatched from that thread Consequently methods that respond to system callbacks (such as

onKeyDown() to report user actions or a lifecycle callback method) always run in the UI thread of the

process

For instance when the user touches a button on the screen your apps UI thread dispatches the touch

event to the widget which in turn sets its pressed state and posts an invalidate request to the event

queue The UI thread dequeues the request and notifies the widget that it should redraw itself

When your app performs intensive work in response to user interaction this single thread model can

yield poor performance unless you implement your application properly Specifically if everything is

happening in the UI thread performing long operations such as network access or database queries

will block the whole UI When the thread is blocked no events can be dispatched including drawing

events From the users perspective the application appears to hang Even worse if the UI thread is

blocked for more than a few seconds (about 5 seconds currently) the user is presented with the

infamous application not responding (ANR) dialog The user might then decide to quit your

application and uninstall it if they are unhappy

Additionally the Andoid UI toolkit is not thread-safe So you must not manipulate your UI from a

worker threadmdashyou must do all manipulation to your user interface from the UI thread Thus there are

simply two rules to Androids single thread model

1 Do not block the UI thread

2 Do not access the Android UI toolkit from outside the UI thread

Worker threads

Because of the single thread model described above its vital to the responsiveness of your

applications UI that you do not block the UI thread If you have operations to perform that are not

instantaneous you should make sure to do them in separate threads (background or worker

threads)

For example below is some code for a click listener that downloads an image from a separate thread

and displays it in an ImageView

public void onClick(View v) new Thread(new Runnable() public void run() Bitmap b = loadImageFromNetwork(httpexamplecomimagepng) mImageViewsetImageBitmap(b) )start()

At first this seems to work fine because it creates a new thread to handle the network operation

However it violates the second rule of the single-threaded model do not access the Android UI toolkit

from outside the UI threadmdashthis sample modifies the ImageView from the worker thread instead of the

UI thread This can result in undefined and unexpected behavior which can be difficult and time-

consuming to track down

To fix this problem Android offers several ways to access the UI thread from other threads Here is a

list of methods that can help

ActivityrunOnUiThread(Runnable)

Viewpost(Runnable)

ViewpostDelayed(Runnable long)

For example you can fix the above code by using the Viewpost(Runnable) method

public void onClick(View v) new Thread(new Runnable() public void run() final Bitmap bitmap = loadImageFromNetwork(httpexamplecomimagepng) mImageViewpost(new Runnable() public void run() mImageViewsetImageBitmap(bitmap) ) )start()

Now this implementation is thread-safe the network operation is done from a separate thread while

the ImageView is manipulated from the UI thread

However as the complexity of the operation grows this kind of code can get complicated and difficult

to maintain To handle more complex interactions with a worker thread you might consider using a

Handler in your worker thread to process messages delivered from the UI thread Perhaps the best

solution though is to extend the AsyncTask class which simplifies the execution of worker thread

tasks that need to interact with the UI

Using AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface It performs the blocking

operations in a worker thread and then publishes the results on the UI thread without requiring you to

handle threads andor handlers yourself

To use it you must subclass AsyncTask and implement the doInBackground() callback method which

runs in a pool of background threads To update your UI you should implement onPostExecute()

which delivers the result from doInBackground() and runs in the UI thread so you can safely update

your UI You can then run the task by calling execute() from the UI thread

For example you can implement the previous example using AsyncTask this way

public void onClick(View v) new DownloadImageTask()execute(httpexamplecomimagepng) private class DownloadImageTask extends AsyncTaskltString Void Bitmapgt The system calls this to perform work in a worker thread and delivers it the parameters given to AsyncTaskexecute() protected Bitmap doInBackground(String urls) return loadImageFromNetwork(urls[0])

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 21: 03 services

All that a client needs to do is create a Messenger based on the IBinder returned by the service and

send a message using send() For example heres a simple activity that binds to the service and

delivers the MSG_SAY_HELLO message to the service

public class ActivityMessenger extends Activity Messenger for communicating with the service Messenger mService = null Flag indicating whether we have called bind on the service boolean mBound Class for interacting with the main interface of the service private ServiceConnection mConnection = new ServiceConnection() public void onServiceConnected(ComponentName className IBinder service) This is called when the connection with the service has been established giving us the object we can use to interact with the service We are communicating with the service using a Messenger so here we get a client-side representation of that from the raw IBinder object mService = new Messenger(service) mBound = true public void onServiceDisconnected(ComponentName className) This is called when the connection with the service has been unexpectedly disconnected -- that is its process crashed mService = null mBound = false public void sayHello(View v) if (mBound) return Create and send a message to the service using a supported what value Message msg = Messageobtain(null MessengerServiceMSG_SAY_HELLO 0 0) try mServicesend(msg) catch (RemoteException e) eprintStackTrace() Override protected void onCreate(Bundle savedInstanceState) superonCreate(savedInstanceState) setContentView(Rlayoutmain)

Override protected void onStart() superonStart() Bind to the service bindService(new Intent(this MessengerServiceclass) mConnection ContextBIND_AUTO_CREATE) Override protected void onStop() superonStop() Unbind from the service if (mBound) unbindService(mConnection) mBound = false

Notice that this example does not show how the service can respond to the client If you want the

service to respond then you need to also create a Messenger in the client Then when the client

receives the onServiceConnected() callback it sends a Message to the service that includes the

clients Messenger in the replyTo parameter of the send() method

You can see an example of how to provide two-way messaging in the MessengerServicejava (service)

and MessengerServiceActivitiesjava (client) samples

Binding to a Service

Application components (clients) can bind to a service by calling bindService() The Android system

then calls the services onBind() method which returns an IBinder for interacting with the service

The binding is asynchronous bindService() returns immediately and does not return the IBinder to the

client To receive the IBinder the client must create an instance of ServiceConnection and pass it to

bindService() The ServiceConnection includes a callback method that the system calls to deliver the

IBinder

Note Only activities services and content providers can bind to a servicemdashyou cannot bind to a

service from a broadcast receiver

So to bind to a service from your client you must

1 Implement ServiceConnection

Your implementation must override two callback methods

onServiceConnected()

The system calls this to deliver the IBinder returned by the services onBind() method

onServiceDisconnected()

The Android system calls this when the connection to the service is unexpectedly lost such as

when the service has crashed or has been killed This is not called when the client unbinds

2 Call bindService() passing the ServiceConnection implementation

3 When the system calls your onServiceConnected() callback method you can begin making calls to the

service using the methods defined by the interface

4 To disconnect from the service call unbindService()

When your client is destroyed it will unbind from the service but you should always unbind when

youre done interacting with the service or when your activity pauses so that the service can shutdown

while its not being used (Appropriate times to bind and unbind is discussed more below)

For example the following snippet connects the client to the service created above by extending the

Binder class so all it must do is cast the returned IBinder to the LocalService class and request the

LocalService instance

LocalService mService private ServiceConnection mConnection = new ServiceConnection() Called when the connection with the service is established public void onServiceConnected(ComponentName className IBinder service) Because we have bound to an explicit service that is running in our own process we can cast its IBinder to a concrete class and directly access it LocalBinder binder = (LocalBinder) service mService = bindergetService() mBound = true Called when the connection with the service disconnects unexpectedly public void onServiceDisconnected(ComponentName className) Loge(TAG onServiceDisconnected) mBound = false

With this ServiceConnection the client can bind to a service by passing this it to bindService() For

example

Intent intent = new Intent(this LocalServiceclass) bindService(intent mConnection ContextBIND_AUTO_CREATE)

The first parameter of bindService() is an Intent that explicitly names the service to bind (thought the

intent could be implicit)

The second parameter is the ServiceConnection object

The third parameter is a flag indicating options for the binding It should usually be

BIND_AUTO_CREATE in order to create the service if its not already alive Other possible values are

BIND_DEBUG_UNBIND and BIND_NOT_FOREGROUND or 0 for none

Additional notes

Here are some important notes about binding to a service

You should always trap DeadObjectException exceptions which are thrown when the connection has

broken This is the only exception thrown by remote methods

Objects are reference counted across processes

You should usually pair the binding and unbinding during matching bring-up and tear-down moments

of the clients lifecycle For example

o If you only need to interact with the service while your activity is visible you should bind during

onStart() and unbind during onStop()

o If you want your activity to receive responses even while it is stopped in the background then you can

bind during onCreate() and unbind during onDestroy() Beware that this implies that your activity needs

to use the service the entire time its running (even in the background) so if the service is in another

process then you increase the weight of the process and it becomes more likely that the system will

kill it

Note You should usually not bind and unbind during your activitys onResume() and onPause()

because these callbacks occur at every lifecycle transition and you should keep the processing that

occurs at these transitions to a minimum Also if multiple activities in your application bind to the same

service and there is a transition between two of those activities the service may be destroyed and

recreated as the current activity unbinds (during pause) before the next one binds (during resume)

(This activity transition for how activities coordinate their lifecycles is described in the Activities

document)

For more sample code showing how to bind to a service see the RemoteServicejava class in

ApiDemos

Managing the Lifecycle of a Bound Service

Figure 1 The lifecycle for a service

that is started and also allows binding

When a service is unbound from all

clients the Android system destroys it

(unless it was also started with

onStartCommand()) As such you

dont have to manage the lifecycle of

your service if its purely a bound

servicemdashthe Android system manages

it for you based on whether it is bound

to any clients

However if you choose to implement

the onStartCommand() callback

method then you must explicitly stop

the service because the service is

now considered to be started In this

case the service runs until the service

stops itself with stopSelf() or another

component calls stopService()

regardless of whether it is bound to

any clients

Additionally if your service is started and accepts binding then when the system calls your onUnbind()

method you can optionally return true if you would like to receive a call to onRebind() the next time a

client binds to the service (instead of receiving a call to onBind()) onRebind() returns void but the

client still receives the IBinder in its onServiceConnected() callback Below figure 1 illustrates the logic

for this kind of lifecycle

For more information about the lifecycle of an started service see the Services document

Content Providers

Content providers store and retrieve data and make it accessible to all applications Theyre the only

way to share data across applications theres no common storage area that all Android packages can

access

Android ships with a number of content providers for common data types (audio video images

personal contact information and so on) You can see some of them listed in the androidprovider

package You can query these providers for the data they contain (although for some you must

acquire the proper permission to read the data)

If you want to make your own data public you have two options You can create your own content

provider (a ContentProvider subclass) or you can add the data to an existing provider mdash if theres one

that controls the same type of data and you have permission to write to it

This document is an introduction to using content providers After a brief discussion of the

fundamentals it explores how to query a content provider how to modify data controlled by a provider

and how to create a content provider of your own

Content Provider Basics

How a content provider actually stores its data under the covers is up to its designer But all content

providers implement a common interface for querying the provider and returning results mdash as well as

for adding altering and deleting data Its an interface that clients use indirectly most generally

through ContentResolver objects You get a ContentResolver by calling getContentResolver() from

within the implementation of an Activity or other application component

ContentResolver cr = getContentResolver()

You can then use the ContentResolvers methods to interact with whatever content providers youre

interested in When a query is initiated the Android system identifies the content provider thats the

target of the query and makes sure that it is up and running The system instantiates all

ContentProvider objects you never need to do it on your own In fact you never deal directly with

ContentProvider objects at all Typically theres just a single instance of each type of ContentProvider

But it can communicate with multiple ContentResolver objects in different applications and processes

The interaction between processes is handled by the ContentResolver and ContentProvider classes

The data model

Content providers expose their data as a simple table on a database model where each row is a

record and each column is data of a particular type and meaning For example information about

people and their phone numbers might be exposed as follows

_ID NUMBER NUMBER_KEY LABEL NAME TYPE

13 (425) 555 6677 425 555 6677 Kirkland office Bully Pulpit TYPE_WORK

44 (212) 555-1234 212 555 1234 NY apartment Alan Vain TYPE_HOME

45 (212) 555-6657 212 555 6657 Downtown office Alan Vain TYPE_MOBILE

53 2015554433 201 555 4433 Love Nest Rex Cars TYPE_HOME

Every record includes a numeric _ID field that uniquely identifies the record within the table IDs can be

used to match records in related tables mdash for example to find a persons phone number in one table

and pictures of that person in another

A query returns a Cursor object that can move from record to record and column to column to read the

contents of each field It has specialized methods for reading each type of data So to read a field you

must know what type of data the field contains (Theres more on query results and Cursor objects

later)

URIs

Each content provider exposes a public URI (wrapped as a Uri object) that uniquely identifies its data

set A content provider that controls multiple data sets (multiple tables) exposes a separate URI for

each one All URIs for providers begin with the string content The content scheme identifies the

data as being controlled by a content provider

If youre defining a content provider its a good idea to also define a constant for its URI to simplify

client code and make future updates cleaner Android defines CONTENT_URI constants for all the

providers that come with the platform For example the URI for the table that matches phone numbers

to people and the URI for the table that holds pictures of people (both controlled by the Contacts

content provider) are

androidproviderContactsPhonesCONTENT_URI

androidproviderContactsPhotosCONTENT_URI

The URI constant is used in all interactions with the content provider Every ContentResolver method

takes the URI as its first argument Its what identifies which provider the ContentResolver should talk

to and which table of the provider is being targeted

Querying a Content Provider

You need three pieces of information to query a content provider

The URI that identifies the provider

The names of the data fields you want to receive

The data types for those fields

If youre querying a particular record you also need the ID for that record

Making the query

To query a content provider you can use either the ContentResolverquery() method or the

ActivitymanagedQuery() method Both methods take the same set of arguments and both return a

Cursor object However managedQuery() causes the activity to manage the life cycle of the Cursor A

managed Cursor handles all of the niceties such as unloading itself when the activity pauses and

requerying itself when the activity restarts You can ask an Activity to begin managing an unmanaged

Cursor object for you by calling ActivitystartManagingCursor()

The first argument to either query() or managedQuery() is the provider URI mdash the CONTENT_URI

constant that identifies a particular ContentProvider and data set (see URIs earlier)

To restrict a query to just one record you can append the _ID value for that record to the URI mdash that

is place a string matching the ID as the last segment of the path part of the URI For example if the ID

is 23 the URI would be

content 23

There are some helper methods particularly ContentUriswithAppendedId() and

UriwithAppendedPath() that make it easy to append an ID to a URI Both are static methods that

return a Uri object with the ID added So for example if you were looking for record 23 in the database

of people contacts you might construct a query as follows

import androidproviderContactsPeople import androidcontentContentUris import androidnetUri import androiddatabaseCursor Use the ContentUris method to produce the base URI for the contact with _ID == 23 Uri myPerson = ContentUriswithAppendedId(PeopleCONTENT_URI 23) Alternatively use the Uri method to produce the base URI It takes a string rather than an integer Uri myPerson = UriwithAppendedPath(PeopleCONTENT_URI 23) Then query for this specific record Cursor cur = managedQuery(myPerson null null null null)

The other arguments to the query() and managedQuery() methods delimit the query in more detail

They are

The names of the data columns that should be returned A null value returns all columns Otherwise

only columns that are listed by name are returned All the content providers that come with the

platform define constants for their columns For example the androidproviderContactsPhones class

defines constants for the names of the columns in the phone table illustrated earlier ampmdash _ID

NUMBER NUMBER_KEY NAME and so on

A filter detailing which rows to return formatted as an SQL WHERE clause (excluding the WHERE

itself) A null value returns all rows (unless the URI limits the query to a single record)

Selection arguments

A sorting order for the rows that are returned formatted as an SQL ORDER BY clause (excluding the

ORDER BY itself) A null value returns the records in the default order for the table which may be

unordered

Lets look at an example query to retrieve a list of contact names and their primary phone numbers

import androidproviderContactsPeople import androiddatabaseCursor Form an array specifying which columns to return String[] projection = new String[] People_ID People_COUNT PeopleNAME PeopleNUMBER Get the base URI for the People table in the Contacts content provider Uri contacts = PeopleCONTENT_URI Make the query Cursor managedCursor = managedQuery(contacts projection Which columns to return null Which rows to return (all rows) null Selection arguments (none) Put the results in ascending order by name PeopleNAME + ASC)

This query retrieves data from the People table of the Contacts content provider It gets the name

primary phone number and unique record ID for each contact It also reports the number of records

that are returned as the _COUNT field of each record

The constants for the names of the columns are defined in various interfaces mdash _ID and _COUNT in

BaseColumns NAME in PeopleColumns and NUMBER in PhoneColumns The ContactsPeople

class implements each of these interfaces which is why the code example above could refer to them

using just the class name

What a query returns

A query returns a set of zero or more database records The names of the columns their default order

and their data types are specific to each content provider But every provider has an _ID column

which holds a unique numeric ID for each record Every provider can also report the number of records

returned as the _COUNT column its value is the same for all rows

Here is an example result set for the query in the previous section

_ID _COUNT NAME NUMBER

44 3 Alan Vain 212 555 1234

13 3 Bully Pulpit 425 555 6677

53 3 Rex Cars 201 555 4433

The retrieved data is exposed by a Cursor object that can be used to iterate backward or forward

through the result set You can use this object only to read the data To add modify or delete data

you must use a ContentResolver object

Reading retrieved data

The Cursor object returned by a query provides access to a recordset of results If you have queried

for a specific record by ID this set will contain only one value Otherwise it can contain multiple

values (If there are no matches it can also be empty) You can read data from specific fields in the

record but you must know the data type of the field because the Cursor object has a separate method

for reading each type of data mdash such as getString() getInt() and getFloat() (However for most types

if you call the method for reading strings the Cursor object will give you the String representation of

the data) The Cursor lets you request the column name from the index of the column or the index

number from the column name

The following snippet demonstrates reading names and phone numbers from the query illustrated

earlier

import androidproviderContactsPeople private void getColumnData(Cursor cur) if (curmoveToFirst()) String name String phoneNumber int nameColumn = curgetColumnIndex(PeopleNAME) int phoneColumn = curgetColumnIndex(PeopleNUMBER) String imagePath do Get the field values name = curgetString(nameColumn) phoneNumber = curgetString(phoneColumn) Do something with the values while (curmoveToNext())

If a query can return binary data such as an image or sound the data may be directly entered in the

table or the table entry for that data may be a string specifying a content URI that you can use to get

the data In general smaller amounts of data (say from 20 to 50K or less) are most often directly

entered in the table and can be read by calling CursorgetBlob() It returns a byte array

If the table entry is a content URI you should never try to open and read the file directly (for one thing

permissions problems can make this fail) Instead you should call ContentResolveropenInputStream()

to get an InputStream object that you can use to read the data

Modifying Data

Data kept by a content provider can be modified by

Adding new records

Adding new values to existing records

Batch updating existing records

Deleting records

All data modification is accomplished using ContentResolver methods Some content providers require

a more restrictive permission for writing data than they do for reading it If you dont have permission to

write to a content provider the ContentResolver methods will fail

Adding records

To add a new record to a content provider first set up a map of key-value pairs in a ContentValues

object where each key matches the name of a column in the content provider and the value is the

desired value for the new record in that column Then call ContentResolverinsert() and pass it the URI

of the provider and the ContentValues map This method returns the full URI of the new record mdash that

is the providers URI with the appended ID for the new record You can then use this URI to query and

get a Cursor over the new record and to further modify the record Heres an example

import androidproviderContactsPeople import androidcontentContentResolver import androidcontentContentValues ContentValues values = new ContentValues() Add Abraham Lincoln to contacts and make him a favorite valuesput(PeopleNAME Abraham Lincoln) 1 = the new contact is added to favorites 0 = the new contact is not added to favorites valuesput(PeopleSTARRED 1) Uri uri = getContentResolver()insert(PeopleCONTENT_URI values)

Adding new values

Once a record exists you can add new information to it or modify existing information For example

the next step in the example above would be to add contact information mdash like a phone number or an

IM or e-mail address mdash to the new entry

The best way to add to a record in the Contacts database is to append the name of the table where the

new data goes to the URI for the record then use the amended URI to add the new data values Each

Contacts table exposes a name for this purpose as a CONTENT_DIRECTORY constant The following

code continues the previous example by adding a phone number and e-mail address for the record

just created

Uri phoneUri = null Uri emailUri = null Add a phone number for Abraham Lincoln Begin with the URI for the new record just returned by insert() it ends with the _ID of the new record so we dont have to add the ID ourselves Then append the designation for the phone table to this URI and use the resulting URI to insert the phone number phoneUri = UriwithAppendedPath(uri PeoplePhonesCONTENT_DIRECTORY) valuesclear() valuesput(PeoplePhonesTYPE PeoplePhonesTYPE_MOBILE) valuesput(PeoplePhonesNUMBER 1233214567) getContentResolver()insert(phoneUri values) Now add an email address in the same way emailUri = UriwithAppendedPath(uri PeopleContactMethodsCONTENT_DIRECTORY) valuesclear() ContactMethodsKIND is used to distinguish different kinds of contact methods such as email IM etc valuesput(PeopleContactMethodsKIND ContactsKIND_EMAIL) valuesput(PeopleContactMethodsDATA testexamplecom) valuesput(PeopleContactMethodsTYPE PeopleContactMethodsTYPE_HOME) getContentResolver()insert(emailUri values)

You can place small amounts of binary data into a table by calling the version of ContentValuesput()

that takes a byte array That would work for a small icon-like image or a short audio clip for example

However if you have a large amount of binary data to add such as a photograph or a complete song

put a content URI for the data in the table and call ContentResolveropenOutputStream() with the files

URI (That causes the content provider to store the data in a file and record the file path in a hidden

field of the record)

In this regard the MediaStore content provider the main provider that dispenses image audio and

video data employs a special convention The same URI that is used with query() or managedQuery()

to get meta-information about the binary data (such as the caption of a photograph or the date it was

taken) is used with openInputStream() to get the data itself Similarly the same URI that is used with

insert() to put meta-information into a MediaStore record is used with openOutputStream() to place the

binary data there The following code snippet illustrates this convention

import androidproviderMediaStoreImagesMedia import androidcontentContentValues import javaioOutputStream Save the name and description of an image in a ContentValues map ContentValues values = new ContentValues(3) valuesput(MediaDISPLAY_NAME road_trip_1) valuesput(MediaDESCRIPTION Day 1 trip to Los Angeles) valuesput(MediaMIME_TYPE imagejpeg) Add a new record without the bitmap but with the values just set insert() returns the URI of the new record Uri uri = getContentResolver()insert(MediaEXTERNAL_CONTENT_URI values) Now get a handle to the file for that record and save the data into it Here sourceBitmap is a Bitmap object representing the file to save to the database try OutputStream outStream = getContentResolver()openOutputStream(uri) sourceBitmapcompress(BitmapCompressFormatJPEG 50 outStream) outStreamclose() catch (Exception e) Loge(TAG exception while writing image e)

Batch updating records

To batch update a group of records (for example to change NY to New York in all fields) call the

ContentResolverupdate() method with the columns and values to change

Deleting a record

To delete a single record call ContentResolverdelete() with the URI of a specific row

To delete multiple rows call ContentResolverdelete() with the URI of the type of record to delete (for

example androidproviderContactsPeopleCONTENT_URI) and an SQL WHERE clause defining

which rows to delete (Caution Be sure to include a valid WHERE clause if youre deleting a general

type or you risk deleting more records than you intended)

Creating a Content Provider

To create a content provider you must

Set up a system for storing the data Most content providers store their data using Androids file

storage methods or SQLite databases but you can store your data any way you want Android

provides the SQLiteOpenHelper class to help you create a database and SQLiteDatabase to manage

it

Extend the ContentProvider class to provide access to the data

Declare the content provider in the manifest file for your application (AndroidManifestxml)

The following sections have notes on the last two of these tasks

Extending the ContentProvider class

You define a ContentProvider subclass to expose your data to others using the conventions expected

by ContentResolver and Cursor objects Principally this means implementing six abstract methods

declared in the ContentProvider class

query()

insert()

update()

delete()

getType()

onCreate()

The query() method must return a Cursor object that can iterate over the requested data Cursor itself

is an interface but Android provides some ready-made Cursor objects that you can use For example

SQLiteCursor can iterate over data stored in an SQLite database You get the Cursor object by calling

any of the SQLiteDatabase classs query() methods There are other Cursor implementations mdash such

as MatrixCursor mdash for data not stored in a database

Because these ContentProvider methods can be called from various ContentResolver objects in

different processes and threads they must be implemented in a thread-safe manner

As a courtesy you might also want to call ContentResolvernotifyChange() to notify listeners when

there are modifications to the data

Beyond defining the subclass itself there are other steps you should take to simplify the work of clients

and make the class more accessible

Define a public static final Uri named CONTENT_URI This is the string that represents the full content

URI that your content provider handles You must define a unique string for this value The best

solution is to use the fully-qualified class name of the content provider (made lowercase) So for

example the URI for a TransportationProvider class could be defined as follows

public static final Uri CONTENT_URI = Uriparse(contentcomexamplecodelabtransportationprovider)

If the provider has subtables also define CONTENT_URI constants for each of the subtables These

URIs should all have the same authority (since that identifies the content provider) and be

distinguished only by their paths For example

contentcomexamplecodelabtransportationprovidertrain

contentcomexamplecodelabtransportationproviderairdomestic

contentcomexamplecodelabtransportationproviderairinternational

For an overview of content URIs see the Content URI Summary at the end of this document

Define the column names that the content provider will return to clients If you are using an underlying

database these column names are typically identical to the SQL database column names they

represent Also define public static String constants that clients can use to specify the columns in

queries and other instructions

Be sure to include an integer column named _id (with the constant _ID) for the IDs of the records

You should have this field whether or not you have another field (such as a URL) that is also unique

among all records If youre using the SQLite database the _ID field should be the following type

INTEGER PRIMARY KEY AUTOINCREMENT

The AUTOINCREMENT descriptor is optional But without it SQLite increments an ID counter field to

the next number above the largest existing number in the column If you delete the last row the next

row added will have the same ID as the deleted row AUTOINCREMENT avoids this by having SQLite

increment to the next largest value whether deleted or not

Carefully document the data type of each column Clients need this information to read the data

If you are handling a new data type you must define a new MIME type to return in your

implementation of ContentProvidergetType() The type depends in part on whether or not the content

URI submitted to getType() limits the request to a specific record Theres one form of the MIME type

for a single record and another for multiple records Use the Uri methods to help determine what is

being requested Here is the general format for each type

o For a single record vndandroidcursoritemvndyourcompanynamecontenttype

For example a request for train record 122 like this URI

contentcomexampletransportationprovidertrains122

might return this MIME type

vndandroidcursoritemvndexamplerail

o For multiple records vndandroidcursordirvndyourcompanynamecontenttype

For example a request for all train records like the following URI

contentcomexampletransportationprovidertrains

might return this MIME type

vndandroidcursordirvndexamplerail

If you are exposing byte data thats too big to put in the table itself mdash such as a large bitmap file mdash the

field that exposes the data to clients should actually contain a content URI string This is the field that

gives clients access to the data file The record should also have another field named _data that lists

the exact file path on the device for that file This field is not intended to be read by the client but by

the ContentResolver The client will call ContentResolveropenInputStream() on the user-facing field

holding the URI for the item The ContentResolver will request the _data field for that record and

because it has higher permissions than a client it should be able to access that file directly and return

a read wrapper for the file to the client

For an example of a private content provider implementation see the NodePadProvider class in the

Notepad sample application that ships with the SDK

Declaring the content provider

To let the Android system know about the content provider youve developed declare it with a

ltprovidergt element in the applications AndroidManifestxml file Content providers that are not

declared in the manifest are not visible to the Android system

The name attribute is the fully qualified name of the ContentProvider subclass The authorities attribute

is the authority part of the content URI that identifies the provider For example if the ContentProvider

subclass is AutoInfoProvider the ltprovidergt element might look like this

ltprovider androidname=comexampleautosAutoInfoProvider androidauthorities=comexampleautosautoinfoprovider gt ltprovidergt

Note that the authorities attribute omits the path part of a content URI For example if

AutoInfoProvider controlled subtables for different types of autos or different manufacturers

contentcomexampleautosautoinfoproviderhonda

contentcomexampleautosautoinfoprovidergmcompact

contentcomexampleautosautoinfoprovidergmsuv

those paths would not be declared in the manifest The authority is what identifies the provider not the

path your provider can interpret the path part of the URI in any way you choose

Other ltprovidergt attributes can set permissions to read and write data provide for an icon and text

that can be displayed to users enable and disable the provider and so on Set the multiprocess

attribute to true if data does not need to be synchronized between multiple running versions of the

content provider This permits an instance of the provider to be created in each client process

eliminating the need to perform IPC

Content URI Summary

Here is a recap of the important parts of a content URI

A Standard prefix indicating that the data is controlled by a content provider Its never modified

B The authority part of the URI it identifies the content provider For third-party applications this should

be a fully-qualified class name (reduced to lowercase) to ensure uniqueness The authority is declared

in the ltprovidergt elements authorities attribute

ltprovider androidname=TransportationProvider androidauthorities=comexampletransportationprovider gt

C The path that the content provider uses to determine what kind of data is being requested This can be

zero or more segments long If the content provider exposes only one type of data (only trains for

example) it can be absent If the provider exposes several types including subtypes it can be several

segments long mdash for example landbus landtrain seaship and seasubmarine to give four

possibilities

D The ID of the specific record being requested if any This is the _ID value of the requested record If

the request is not limited to a single record this segment and the trailing slash are omitted

contentcomexampletransportationprovidertrains

Intent and intent filters

Three of the core components of an application mdash activities services and broadcast receivers mdash 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 mdash 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 ContextstartActivity() or ActivitystartActivityForResult() to launch an

activity or get an existing activity to do something new (It can also be passed to ActivitysetResult() to

return information to the activity that called startActivityForResult())

An Intent object is passed to ContextstartService() to initiate a service or deliver new instructions to an

ongoing service Similarly an intent can be passed to ContextbindService() to establish a connection

between the calling component and a target service It can optionally initiate the service if its not

already running

Intent objects passed to any of the broadcast methods (such as ContextsendBroadcast()

ContextsendOrderedBroadcast() or ContextsendStickyBroadcast()) 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 mdash how it resolves which component should receive an intent message For

intents that dont explicitly name a target component this process involves testing the Intent object

against intent filters associated with potential targets

Intent Objects

An Intent object is a bundle of information It contains information of interest to the component that

receives the intent (such as the action to be taken and the data to act on) plus information of interest to

the Android system (such as the category of component that should handle the intent and instructions

on how to launch a target activity) Principally it can contain the following

Component name

The name of the component that should handle the intent This field is a ComponentName

object mdash a combination of the fully qualified class name of the target component (for example

comexampleprojectappFreneticActivity) and the package name set in the manifest file of the

application where the component resides (for example comexampleproject) The package

part of the component name and the package name set in the manifest do not necessarily have

to match

The component name is optional If it is set the Intent object is delivered to an instance of the

designated class If it is not set Android uses other information in the Intent object to locate a

suitable target mdash see Intent Resolution later in this document

The component name is set by setComponent() setClass() or setClassName() and read by

getComponent()

Action

A string naming the action to be performed mdash or in the case of broadcast intents the action

that took place and is being reported The Intent class defines a number of action constants

including these

Constant Target

component

Action

ACTION_CALL activity Initiate a phone call

ACTION_EDIT activity Display data for the user to edit

ACTION_MAIN activity Start up as the initial activity of a task

with no data input and no returned

output

ACTION_SYNC activity Synchronize data on a server with

data on the mobile device

ACTION_BATTERY_LOW broadcast

receiver

A warning that the battery is low

ACTION_HEADSET_PLUG broadcast

receiver

A headset has been plugged into the

device or unplugged from it

ACTION_SCREEN_ON broadcast

receiver

The screen has been turned on

ACTION_TIMEZONE_CHANGED broadcast

receiver

The setting for the time zone has

changed

See the Intent class description for a list of pre-defined constants for generic actions Other

actions are defined elsewhere in the Android API You can also define your own action strings

for activating the components in your application Those you invent should include the

application package as a prefix mdash for example comexampleprojectSHOW_COLOR

The action largely determines how the rest of the intent is structured mdash particularly the data and

extras fields mdash much as a method name determines a set of arguments and a return value For

this reason its a good idea to use action names that are as specific as possible and to couple

them tightly to the other fields of the intent In other words instead of defining an action in

isolation define an entire protocol for the Intent objects your components can handle

The action in an Intent object is set by the setAction() method and read by getAction()

Data

The URI of the data to be acted on and the MIME type of that data Different actions are paired

with different kinds of data specifications For example if the action field is ACTION_EDIT the

data field would contain the URI of the document to be displayed for editing If the action is

ACTION_CALL the data field would be a tel URI with the number to call Similarly if the action

is ACTION_VIEW and the data field is an http URI the receiving activity would be called upon

to download and display whatever data the URI refers to

When matching an intent to a component that is capable of handling the data its often

important to know the type of data (its MIME type) in addition to its URI For example a

component able to display image data should not be called upon to play an audio file

In many cases the data type can be inferred from the URI mdash particularly content URIs which

indicate that the data is located on the device and controlled by a content provider (see the

separate discussion on content providers) But the type can also be explicitly set in the Intent

object The setData() method specifies data only as a URI setType() specifies it only as a

MIME type and setDataAndType() specifies it as both a URI and a MIME type The URI is read

by getData() and the type by getType()

Category

A string containing additional information about the kind of component that should handle the

intent Any number of category descriptions can be placed in an Intent object As it does for

actions the Intent class defines several category constants including these

Constant Meaning

CATEGORY_BROWSABLE The target activity can be safely invoked by the browser to

display data referenced by a link mdash for example an image or

an e-mail message

CATEGORY_GADGET The activity can be embedded inside of another activity that

hosts gadgets

CATEGORY_HOME The activity displays the home screen the first screen the

user sees when the device is turned on or when the HOME

key is pressed

CATEGORY_LAUNCHER The activity can be the initial activity of a task and is listed in

the top-level application launcher

CATEGORY_PREFERENCE The target activity is a preference panel

See the Intent class description for the full list of categories

The addCategory() method places a category in an Intent object removeCategory() deletes a

category previously added and getCategories() gets the set of all categories currently in the

object

Extras

Key-value pairs for additional information that should be delivered to the component handling

the intent Just as some actions are paired with particular kinds of data URIs some are paired

with particular extras For example an ACTION_TIMEZONE_CHANGED intent has a time-

zone extra that identifies the new time zone and ACTION_HEADSET_PLUG has a state

extra indicating whether the headset is now plugged in or unplugged as well as a name extra

for the type of headset If you were to invent a SHOW_COLOR action the color value would be

set in an extra key-value pair

The Intent object has a series of put() methods for inserting various types of extra data and a

similar set of get() methods for reading the data These methods parallel those for Bundle

objects In fact the extras can be installed and read as a Bundle using the putExtras() and

getExtras() methods

Flags

Flags of various sorts Many instruct the Android system how to launch an activity (for example

which task the activity should belong to) and how to treat it after its launched (for example

whether it belongs in the list of recent activities) All these flags are defined in the Intent class

The Android system and the applications that come with the platform employ Intent objects both to

send out system-originated broadcasts and to activate system-defined components To see how to

structure an intent to activate a system component consult the list of intents in the reference

Intent Resolution

Intents can be divided into two groups

Explicit intents designate the target component by its name (the component name field mentioned

earlier has a value set) Since component names would generally not be known to developers of other

applications explicit intents are typically used for application-internal messages mdash such as an activity

starting a subordinate service or launching a sister activity

Implicit intents do not name a target (the field for the component name is blank) Implicit intents are

often used to activate components in other applications

Android delivers an explicit intent to an instance of the designated target class Nothing in the Intent

object other than the component name matters for determining which component should get the intent

A different strategy is needed for implicit intents In the absence of a designated target the Android

system must find the best component (or components) to handle the intent mdash a single activity or

service to perform the requested action or the set of broadcast receivers to respond to the broadcast

announcement It does so by comparing the contents of the Intent object to intent filters structures

associated with components that can potentially receive intents Filters advertise the capabilities of a

component and delimit the intents it can handle They open the component to the possibility of

receiving implicit intents of the advertised type If a component does not have any intent filters it can

receive only explicit intents A component with filters can receive both explicit and implicit intents

Only three aspects of an Intent object are consulted when the object is tested against an intent filter

action

data (both URI and data type)

category

The extras and flags play no part in resolving which component receives an intent

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 mdash but only unwanted implicit intents (those that dont 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

components 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 mdash 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 Pads filters are described in the Note Pad Example

section later)

Filters and security

An intent filter cannot be relied on for security While it opens a component to receiving only certain

kinds of implicit intents it does nothing to prevent explicit intents from targeting the component Even

though a filter restricts the intents a component will be asked to handle to certain actions and data

sources someone could always put together an explicit intent with a different action and data source

and name the component as the target

An intent filter is an instance of the IntentFilter class However since the Android system must know

about the capabilities of a component before it can launch that component intent filters are generally

not set up in Java code but in the applications manifest file (AndroidManifestxml) as ltintent-filtergt

elements (The one exception would be filters for broadcast receivers that are registered dynamically

by calling ContextregisterReceiver() they are directly created as IntentFilter objects)

A filter has fields that parallel the action data and category fields of an Intent object An implicit intent

is tested against the filter in all three areas To be delivered to the component that owns the filter it

must pass all three tests If it fails even one of them the Android system wont deliver it to the

component mdash at least not on the basis of that filter However since a component can have multiple

intent filters an intent that does not pass through one of a components filters might make it through on

another

Each of the three tests is described in detail below

Action test

An ltintent-filtergt element in the manifest file lists actions as ltactiongt subelements For

example

ltintent-filter gt ltaction androidname=comexampleprojectSHOW_CURRENT gt ltaction androidname=comexampleprojectSHOW_RECENT gt ltaction androidname=comexampleprojectSHOW_PENDING gt ltintent-filtergt

As the example shows while an Intent object names just a single action a filter may list more

than one The list cannot be empty a filter must contain at least one ltactiongt element or it will

block all intents

To pass this test the action specified in the Intent object must match one of the actions listed in

the filter If the object or the filter does not specify an action the results are as follows

If the filter fails to list any actions there is nothing for an intent to match so all intents fail the

test No intents can get through the filter

On the other hand an Intent object that doesnt specify an action automatically passes the test

mdash as long as the filter contains at least one action

Category test

An ltintent-filtergt element also lists categories as subelements For example

ltintent-filter gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryBROWSABLE gt ltintent-filtergt

Note that the constants described earlier for actions and categories are not used in the manifest

file The full string values are used instead For instance the

androidintentcategoryBROWSABLE string in the example above corresponds to the

CATEGORY_BROWSABLE constant mentioned earlier in this document Similarly the string

androidintentactionEDIT corresponds to the ACTION_EDIT constant

For an intent to pass the category test every category in the Intent object must match a

category in the filter The filter can list additional categories but it cannot omit any that are in the

intent

In principle therefore an Intent object with no categories should always pass this test

regardless of whats in the filter Thats mostly true However with one exception Android treats

all implicit intents passed to startActivity() as if they contained at least one category

androidintentcategoryDEFAULT (the CATEGORY_DEFAULT constant) Therefore activities

that are willing to receive implicit intents must include androidintentcategoryDEFAULT in

their intent filters (Filters with androidintentactionMAIN and

androidintentcategoryLAUNCHER settings are the exception They mark activities that begin

new tasks and that are represented on the launcher screen They can include

androidintentcategoryDEFAULT in the list of categories but dont need to) See Using intent

matching later for more on these filters)

Data test

Like the action and categories the data specification for an intent filter is contained in a

subelement And as in those cases the subelement can appear multiple times or not at all For

example

ltintent-filter gt ltdata androidmimeType=videompeg androidscheme=http gt ltdata androidmimeType=audiompeg androidscheme=http gt ltintent-filtergt

Each ltdatagt element can specify a URI and a data type (MIME media type) There are

separate attributes mdash scheme host port and path mdash for each part of the URI

schemehostportpath

For example in the following URI

contentcomexampleproject200foldersubfolderetc

the scheme is content the host is comexampleproject the port is 200 and the path is

foldersubfolderetc The host and port together constitute the URI authority if a host is not

specified the port is ignored

Each of these attributes is optional but they are not independent of each other For an authority

to be meaningful a scheme must also be specified For a path to be meaningful both a scheme

and an authority must be specified

When the URI in an Intent object is compared to a URI specification in a filter its compared

only to the parts of the URI actually mentioned in the filter For example if a filter specifies only

a scheme all URIs with that scheme match the filter If a filter specifies a scheme and an

authority but no path all URIs with the same scheme and authority match regardless of their

paths If a filter specifies a scheme an authority and a path only URIs with the same scheme

authority and path match However a path specification in the filter can contain wildcards to

require only a partial match of the path

The type attribute of a ltdatagt element specifies the MIME type of the data Its more common in

filters than a URI Both the Intent object and the filter can use a wildcard for the subtype field

mdash for example text or audio mdash indicating any subtype matches

The data test compares both the URI and the data type in the Intent object to a URI and data

type specified in the filter The rules are as follows

a An Intent object that contains neither a URI nor a data type passes the test only if the filter

likewise does not specify any URIs or data types

b An Intent object that contains a URI but no data type (and a type cannot be inferred from the

URI) passes the test only if its URI matches a URI in the filter and the filter likewise does not

specify a type This will be the case only for URIs like mailto and tel that do not refer to actual

data

c An Intent object that contains a data type but not a URI passes the test only if the filter lists the

same data type and similarly does not specify a URI

d An Intent object that contains both a URI and a data type (or a data type can be inferred from

the URI) passes the data type part of the test only if its type matches a type listed in the filter It

passes the URI part of the test either if its URI matches a URI in the filter or if it has a content

or file URI and the filter does not specify a URI In other words a component is presumed to

support content and file data if its filter lists only a data type

If an intent can pass through the filters of more than one activity or service the user may be asked

which component to activate An exception is raised if no target can be found

Common cases

The last rule shown above for the data test rule (d) reflects the expectation that components are able

to get local data from a file or content provider Therefore their filters can list just a data type and do

not need to explicitly name the content and file schemes This is a typical case A ltdatagt element like

the following for example tells Android that the component can get image data from a content

provider and display it

ltdata androidmimeType=image gt

Since most available data is dispensed by content providers filters that specify a data type but not a

URI are perhaps the most common

Another common configuration is filters with a scheme and a data type For example a ltdatagt

element like the following tells Android that the component can get video data from the network and

display it

ltdata androidscheme=http androidtype=video gt

Consider for example what the browser application does when the user follows a link on a web page

It first tries to display the data (as it could if the link was to an HTML page) If it cant display the data it

puts together an implicit intent with the scheme and data type and tries to start an activity that can do

the job If there are no takers it asks the download manager to download the data That puts it under

the control of a content provider so a potentially larger pool of activities (those with filters that just

name a data type) can respond

Most applications also have a way to start fresh without a reference to any particular data Activities

that can initiate applications have filters with androidintentactionMAIN specified as the action If

they are to be represented in the application launcher they also specify the

androidintentcategoryLAUNCHER category

ltintent-filter gt ltaction androidname=code androidintentactionMAIN gt ltcategory androidname=code androidintentcategoryLAUNCHER gt ltintent-filtergt

Using intent matching

Intents are matched against intent filters not only to discover a target component to activate but also

to discover something about the set of components on the device For example the Android system

populates the application launcher the top-level screen that shows the applications that are available

for the user to launch by finding all the activities with intent filters that specify the

androidintentactionMAIN action and androidintentcategoryLAUNCHER category (as illustrated

in the previous section) It then displays the icons and labels of those activities in the launcher

Similarly it discovers the home screen by looking for the activity with androidintentcategoryHOME

in its filter

Your application can use intent matching is a similar way The PackageManager has a set of query()

methods that return all components that can accept a particular intent and a similar series of

resolve() methods that determine the best component to respond to an intent For example

queryIntentActivities() returns a list of all activities that can perform the intent passed as an argument

and queryIntentServices() returns a similar list of services Neither method activates the components

they just list the ones that can respond Theres a similar method queryBroadcastReceivers() for

broadcast receivers

Note Pad Example

The Note Pad sample application enables users to browse through a list of notes view details about

individual items in the list edit the items and add a new item to the list This section looks at the intent

filters declared in its manifest file (If youre working offline in the SDK you can find all the source files

for this sample application including its manifest file at ltsdkgtsamplesNotePadindexhtml If youre

viewing the documentation online the source files are in the Tutorials and Sample Code section here)

In its manifest file the Note Pad application declares three activities each with at least one intent filter

It also declares a content provider that manages the note data Here is the manifest file in its entirety

ltmanifest xmlnsandroid=httpschemasandroidcomapkresandroid package=comexampleandroidnotepadgt ltapplication androidicon=drawableapp_notes androidlabel=stringapp_name gt ltprovider androidname=NotePadProvider androidauthorities=comgoogleproviderNotePad gt ltactivity androidname=NotesList androidlabel=stringtitle_notes_listgt ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltactivity androidname=NoteEditor androidtheme=androidstyleThemeLight androidlabel=stringtitle_note gt ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltactivitygt

ltactivity androidname=TitleEditor androidlabel=stringtitle_edit_title androidtheme=androidstyleThemeDialoggt ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltapplicationgt ltmanifestgt

The first activity NotesList is distinguished from the other activities by the fact that it operates on a

directory of notes (the note list) rather than on a single note It would generally serve as the initial user

interface into the application It can do three things as described by its three intent filters

1 ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt

This filter declares the main entry point into the Note Pad application The standard MAIN action is an

entry point that does not require any other information in the Intent (no data specification for example)

and the LAUNCHER category says that this entry point should be listed in the application launcher

2 ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

This filter declares the things that the activity can do on a directory of notes It can allow the user to

view or edit the directory (via the VIEW and EDIT actions) or to pick a particular note from the

directory (via the PICK action)

The mimeType attribute of the ltdatagt element specifies the kind of data that these actions operate on

It indicates that the activity can get a Cursor over zero or more items (vndandroidcursordir) from a

content provider that holds Note Pad data (vndgooglenote) The Intent object that launches the

activity would include a content URI specifying the exact data of this type that the activity should open

Note also the DEFAULT category supplied in this filter Its there because the ContextstartActivity()

and ActivitystartActivityForResult() methods treat all intents as if they contained the DEFAULT

category mdash with just two exceptions

o Intents that explicitly name the target activity

o Intents consisting of the MAIN action and LAUNCHER category

Therefore the DEFAULT category is required for all filters mdash except for those with the MAIN action

and LAUNCHER category (Intent filters are not consulted for explicit intents)

3 ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

This filter describes the activitys ability to return a note selected by the user without requiring any

specification of the directory the user should choose from The GET_CONTENT action is similar to the

PICK action In both cases the activity returns the URI for a note selected by the user (In each case

its returned to the activity that called startActivityForResult() to start the NoteList activity) Here

however the caller specifies the type of data desired instead of the directory of data the user will be

picking from

The data type vndandroidcursoritemvndgooglenote indicates the type of data the activity can

return mdash a URI for a single note From the returned URI the caller can get a Cursor for exactly one

item (vndandroidcursoritem) from the content provider that holds Note Pad data (vndgooglenote)

In other words for the PICK action in the previous filter the data type indicates the type of data the

activity could display to the user For the GET_CONTENT filter it indicates the type of data the activity

can return to the caller

Given these capabilities the following intents will resolve to the NotesList activity

action androidintentactionMAIN

Launches the activity with no data specified

action androidintentactionMAIN

category androidintentcategoryLAUNCHER

Launches the activity with no data selected specified This is the actual intent used by the

Launcher to populate its top-level list All activities with filters that match this action and

category are added to the list

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of all the notes under

contentcomgoogleproviderNotePadnotes The user can then browse through the list and

get information about the items in it

action androidintentactionPICK

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of the notes under

contentcomgoogleproviderNotePadnotes The user can then pick a note from the list and

the activity will return the URI for that item back to the activity that started the NoteList activity

action androidintentactionGET_CONTENT

data type vndandroidcursoritemvndgooglenote

Asks the activity to supply a single item of Note Pad data

The second activity NoteEditor shows users a single note entry and allows them to edit it It can do

two things as described by its two intent filters

1 ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The first primary purpose of this activity is to enable the user to interact with a single note ampmdash to

either VIEW the note or EDIT it (The EDIT_NOTE category is a synonym for EDIT) The intent would

contain the URI for data matching the MIME type vndandroidcursoritemvndgooglenote mdash that is

the URI for a single specific note It would typically be a URI that was returned by the PICK or

GET_CONTENT actions of the NoteList activity

As before this filter lists the DEFAULT category so that the activity can be launched by intents that

dont explicitly specify the NoteEditor class

2 ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

The secondary purpose of this activity is to enable the user to create a new note which it will INSERT

into an existing directory of notes The intent would contain the URI for data matching the MIME type

vndandroidcursordirvndgooglenote mdash that is the URI for the directory where the note should be

placed

Given these capabilities the following intents will resolve to the NoteEditor activity

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID (For details on how content

URIs specify individual members of a group see Content Providers)

action androidintentactionEDIT

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID and to let the user edit it If

the user saves the changes the activity updates the data for the note in the content provider

action androidintentactionINSERT

data contentcomgoogleproviderNotePadnotes

Asks the activity to create a new empty note in the notes list at

contentcomgoogleproviderNotePadnotes and allow the user to edit it If the user saves the

note its URI is returned to the caller

The last activity TitleEditor enables the user to edit the title of a note This could be implemented by

directly invoking the activity (by explicitly setting its component name in the Intent) without using an

intent filter But here we take the opportunity to show how to publish alternative operations on existing

data

ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The single intent filter for this activity uses a custom action called

comandroidnotepadactionEDIT_TITLE It must be invoked on a specific note (data type

vndandroidcursoritemvndgooglenote) like the previous VIEW and EDIT actions However here the

activity displays the title contained in the note data not the content of the note itself

In addition to supporting the usual DEFAULT category the title editor also supports two other standard

categories ALTERNATIVE and SELECTED_ALTERNATIVE These categories identify activities that

can be presented to users in a menu of options (much as the LAUNCHER category identifies activities

that should be presented to user in the application launcher) Note that the filter also supplies an

explicit label (via androidlabel=stringresolve_title) to better control what users see when

presented with this activity as an alternative action to the data they are currently viewing (For more

information on these categories and building options menus see the

PackageManagerqueryIntentActivityOptions() and MenuaddIntentOptions() methods)

Given these capabilities the following intent will resolve to the TitleEditor activity

action comandroidnotepadactionEDIT_TITLE

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the title associated with note ID and allow the user to edit the title

Processes and Threads

When an application component starts and the application does not have any other components

running the Android system starts a new Linux process for the application with a single thread of

execution By default all components of the same application run in the same process and thread

(called the main thread) If an application component starts and there already exists a process for

that application (because another component from the application exists) then the component is

started within that process and uses the same thread of execution However you can arrange for

different components in your application to run in separate processes and you can create additional

threads for any process

This document discusses how processes and threads work in an Android application

Processes

By default all components of the same application run in the same process and most applications

should not change this However if you find that you need to control which process a certain

component belongs to you can do so in the manifest file

The manifest entry for each type of component elementmdashltactivitygt ltservicegt ltreceivergt and

ltprovidergtmdashsupports an androidprocess attribute that can specify a process in which that component

should run You can set this attribute so that each component runs in its own process or so that some

components share a process while others do not You can also set androidprocess so that

components of different applications run in the same processmdashprovided that the applications share the

same Linux user ID and are signed with the same certificates

The ltapplicationgt element also supports an androidprocess attribute to set a default value that

applies to all components

Android might 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 thats killed are consequently destroyed A process is started again for those components

when theres again work for them to do

When deciding which processes to kill the Android system weighs their relative importance to the

user For example it more readily shuts down a process hosting activities that are no longer visible on

screen compared to a process hosting visible activities The decision whether to terminate a process

therefore depends on the state of the components running in that process The rules used to decide

which processes to terminate is discussed below

Process lifecycle

The Android system tries to maintain an application process for as long as possible but eventually

needs to remove old processes to reclaim memory for new or more important processes To determine

which processes to keep and which to kill the system places each process into an importance

hierarchy based on the components running in the process and the state of those components

Processes with the lowest importance are eliminated first then those with the next lowest importance

and so on as necessary to recover system resources

There are five levels in the importance hierarchy The following list presents the different types of

processes in order of importance (the first process is most important and is killed last)

1 Foreground process

A process that is required for what the user is currently doing A process is considered to be in the

foreground if any of the following conditions are true

o It hosts an Activity that the user is interacting with (the Activitys onResume() method has been called)

o It hosts a Service thats bound to the activity that the user is interacting with

o It hosts a Service thats running in the foregroundmdashthe service has called startForeground()

o It hosts a Service thats executing one of its lifecycle callbacks (onCreate() onStart() or onDestroy())

o It hosts a BroadcastReceiver thats executing its onReceive() method

Generally only a few foreground processes exist at any given time They are killed only as a last

resortmdashif memory is so low that they cannot all continue to run Generally at that point the device has

reached a memory paging state so killing some foreground processes is required to keep the user

interface responsive

2 Visible process

A process that doesnt have any foreground components but still can affect what the user sees on

screen A process is considered to be visible if either of the following conditions are true

o It hosts an Activity that is not in the foreground but is still visible to the user (its onPause() method has

been called) This might occur for example if the foreground activity started a dialog which allows the

previous activity to be seen behind it

o It hosts a Service thats bound to a visible (or foreground) activity

A visible process is considered extremely important and will not be killed unless doing so is required to

keep all foreground processes running

3 Service process

A process that is running a service that has been started with the startService() method and does not

fall into either of the two higher categories Although service processes are not directly tied to anything

the user sees they are generally doing things that the user cares about (such as playing music in the

background or downloading data on the network) so the system keeps them running unless theres

not enough memory to retain them along with all foreground and visible processes

4 Background process

A process holding an activity thats not currently visible to the user (the activitys onStop() method has

been called) These processes have no direct impact on the user experience and the system can kill

them at any time to reclaim memory for a foreground visible or service process Usually there are

many background processes running so they are kept in an LRU (least recently used) list to ensure

that the process with the activity that was most recently seen by the user is the last to be killed If an

activity implements its lifecycle methods correctly and saves its current state killing its process will not

have a visible effect on the user experience because when the user navigates back to the activity the

activity restores all of its visible state See the Activities document for information about saving and

restoring state

5 Empty process

A process that doesnt hold any active application components The only reason to keep this kind of

process alive is for caching purposes to improve startup time the next time a component needs to run

in it The system often kills these processes in order to balance overall system resources between

process caches and the underlying kernel caches

Android ranks a process at the highest level it can based upon the importance of the components

currently active in the process For example if a process hosts a service and a visible activity the

process is ranked as a visible process not a service process

In addition a processs ranking might be increased because other processes are dependent on itmdasha

process that is serving another process can never be ranked lower than the process it is serving For

example if a content provider in process A is serving a client in process B or if a service in process A

is bound to a component in process B process A is always considered at least as important as

process B

Because a process running a service is ranked higher than a process with background activities an

activity that initiates a long-running operation might do well to start a service for that operation rather

than simply create a worker threadmdashparticularly if the operation will likely outlast the activity For

example an activity thats uploading a picture to a web site should start a service to perform the

upload so that the upload can continue in the background even if the user leaves the activity Using a

service guarantees that the operation will have at least service process priority regardless of what

happens to the activity This is the same reason that broadcast receivers should employ services

rather than simply put time-consuming operations in a thread

Threads

When an application is launched the system creates a thread of execution for the application called

main This thread is very important because it is in charge of dispatching events to the appropriate

user interface widgets including drawing events It is also the thread in which your application interacts

with components from the Android UI toolkit (components from the androidwidget and androidview

packages) As such the main thread is also sometimes called the UI thread

The system does not create a separate thread for each instance of a component All components that

run in the same process are instantiated in the UI thread and system calls to each component are

dispatched from that thread Consequently methods that respond to system callbacks (such as

onKeyDown() to report user actions or a lifecycle callback method) always run in the UI thread of the

process

For instance when the user touches a button on the screen your apps UI thread dispatches the touch

event to the widget which in turn sets its pressed state and posts an invalidate request to the event

queue The UI thread dequeues the request and notifies the widget that it should redraw itself

When your app performs intensive work in response to user interaction this single thread model can

yield poor performance unless you implement your application properly Specifically if everything is

happening in the UI thread performing long operations such as network access or database queries

will block the whole UI When the thread is blocked no events can be dispatched including drawing

events From the users perspective the application appears to hang Even worse if the UI thread is

blocked for more than a few seconds (about 5 seconds currently) the user is presented with the

infamous application not responding (ANR) dialog The user might then decide to quit your

application and uninstall it if they are unhappy

Additionally the Andoid UI toolkit is not thread-safe So you must not manipulate your UI from a

worker threadmdashyou must do all manipulation to your user interface from the UI thread Thus there are

simply two rules to Androids single thread model

1 Do not block the UI thread

2 Do not access the Android UI toolkit from outside the UI thread

Worker threads

Because of the single thread model described above its vital to the responsiveness of your

applications UI that you do not block the UI thread If you have operations to perform that are not

instantaneous you should make sure to do them in separate threads (background or worker

threads)

For example below is some code for a click listener that downloads an image from a separate thread

and displays it in an ImageView

public void onClick(View v) new Thread(new Runnable() public void run() Bitmap b = loadImageFromNetwork(httpexamplecomimagepng) mImageViewsetImageBitmap(b) )start()

At first this seems to work fine because it creates a new thread to handle the network operation

However it violates the second rule of the single-threaded model do not access the Android UI toolkit

from outside the UI threadmdashthis sample modifies the ImageView from the worker thread instead of the

UI thread This can result in undefined and unexpected behavior which can be difficult and time-

consuming to track down

To fix this problem Android offers several ways to access the UI thread from other threads Here is a

list of methods that can help

ActivityrunOnUiThread(Runnable)

Viewpost(Runnable)

ViewpostDelayed(Runnable long)

For example you can fix the above code by using the Viewpost(Runnable) method

public void onClick(View v) new Thread(new Runnable() public void run() final Bitmap bitmap = loadImageFromNetwork(httpexamplecomimagepng) mImageViewpost(new Runnable() public void run() mImageViewsetImageBitmap(bitmap) ) )start()

Now this implementation is thread-safe the network operation is done from a separate thread while

the ImageView is manipulated from the UI thread

However as the complexity of the operation grows this kind of code can get complicated and difficult

to maintain To handle more complex interactions with a worker thread you might consider using a

Handler in your worker thread to process messages delivered from the UI thread Perhaps the best

solution though is to extend the AsyncTask class which simplifies the execution of worker thread

tasks that need to interact with the UI

Using AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface It performs the blocking

operations in a worker thread and then publishes the results on the UI thread without requiring you to

handle threads andor handlers yourself

To use it you must subclass AsyncTask and implement the doInBackground() callback method which

runs in a pool of background threads To update your UI you should implement onPostExecute()

which delivers the result from doInBackground() and runs in the UI thread so you can safely update

your UI You can then run the task by calling execute() from the UI thread

For example you can implement the previous example using AsyncTask this way

public void onClick(View v) new DownloadImageTask()execute(httpexamplecomimagepng) private class DownloadImageTask extends AsyncTaskltString Void Bitmapgt The system calls this to perform work in a worker thread and delivers it the parameters given to AsyncTaskexecute() protected Bitmap doInBackground(String urls) return loadImageFromNetwork(urls[0])

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 22: 03 services

Override protected void onStart() superonStart() Bind to the service bindService(new Intent(this MessengerServiceclass) mConnection ContextBIND_AUTO_CREATE) Override protected void onStop() superonStop() Unbind from the service if (mBound) unbindService(mConnection) mBound = false

Notice that this example does not show how the service can respond to the client If you want the

service to respond then you need to also create a Messenger in the client Then when the client

receives the onServiceConnected() callback it sends a Message to the service that includes the

clients Messenger in the replyTo parameter of the send() method

You can see an example of how to provide two-way messaging in the MessengerServicejava (service)

and MessengerServiceActivitiesjava (client) samples

Binding to a Service

Application components (clients) can bind to a service by calling bindService() The Android system

then calls the services onBind() method which returns an IBinder for interacting with the service

The binding is asynchronous bindService() returns immediately and does not return the IBinder to the

client To receive the IBinder the client must create an instance of ServiceConnection and pass it to

bindService() The ServiceConnection includes a callback method that the system calls to deliver the

IBinder

Note Only activities services and content providers can bind to a servicemdashyou cannot bind to a

service from a broadcast receiver

So to bind to a service from your client you must

1 Implement ServiceConnection

Your implementation must override two callback methods

onServiceConnected()

The system calls this to deliver the IBinder returned by the services onBind() method

onServiceDisconnected()

The Android system calls this when the connection to the service is unexpectedly lost such as

when the service has crashed or has been killed This is not called when the client unbinds

2 Call bindService() passing the ServiceConnection implementation

3 When the system calls your onServiceConnected() callback method you can begin making calls to the

service using the methods defined by the interface

4 To disconnect from the service call unbindService()

When your client is destroyed it will unbind from the service but you should always unbind when

youre done interacting with the service or when your activity pauses so that the service can shutdown

while its not being used (Appropriate times to bind and unbind is discussed more below)

For example the following snippet connects the client to the service created above by extending the

Binder class so all it must do is cast the returned IBinder to the LocalService class and request the

LocalService instance

LocalService mService private ServiceConnection mConnection = new ServiceConnection() Called when the connection with the service is established public void onServiceConnected(ComponentName className IBinder service) Because we have bound to an explicit service that is running in our own process we can cast its IBinder to a concrete class and directly access it LocalBinder binder = (LocalBinder) service mService = bindergetService() mBound = true Called when the connection with the service disconnects unexpectedly public void onServiceDisconnected(ComponentName className) Loge(TAG onServiceDisconnected) mBound = false

With this ServiceConnection the client can bind to a service by passing this it to bindService() For

example

Intent intent = new Intent(this LocalServiceclass) bindService(intent mConnection ContextBIND_AUTO_CREATE)

The first parameter of bindService() is an Intent that explicitly names the service to bind (thought the

intent could be implicit)

The second parameter is the ServiceConnection object

The third parameter is a flag indicating options for the binding It should usually be

BIND_AUTO_CREATE in order to create the service if its not already alive Other possible values are

BIND_DEBUG_UNBIND and BIND_NOT_FOREGROUND or 0 for none

Additional notes

Here are some important notes about binding to a service

You should always trap DeadObjectException exceptions which are thrown when the connection has

broken This is the only exception thrown by remote methods

Objects are reference counted across processes

You should usually pair the binding and unbinding during matching bring-up and tear-down moments

of the clients lifecycle For example

o If you only need to interact with the service while your activity is visible you should bind during

onStart() and unbind during onStop()

o If you want your activity to receive responses even while it is stopped in the background then you can

bind during onCreate() and unbind during onDestroy() Beware that this implies that your activity needs

to use the service the entire time its running (even in the background) so if the service is in another

process then you increase the weight of the process and it becomes more likely that the system will

kill it

Note You should usually not bind and unbind during your activitys onResume() and onPause()

because these callbacks occur at every lifecycle transition and you should keep the processing that

occurs at these transitions to a minimum Also if multiple activities in your application bind to the same

service and there is a transition between two of those activities the service may be destroyed and

recreated as the current activity unbinds (during pause) before the next one binds (during resume)

(This activity transition for how activities coordinate their lifecycles is described in the Activities

document)

For more sample code showing how to bind to a service see the RemoteServicejava class in

ApiDemos

Managing the Lifecycle of a Bound Service

Figure 1 The lifecycle for a service

that is started and also allows binding

When a service is unbound from all

clients the Android system destroys it

(unless it was also started with

onStartCommand()) As such you

dont have to manage the lifecycle of

your service if its purely a bound

servicemdashthe Android system manages

it for you based on whether it is bound

to any clients

However if you choose to implement

the onStartCommand() callback

method then you must explicitly stop

the service because the service is

now considered to be started In this

case the service runs until the service

stops itself with stopSelf() or another

component calls stopService()

regardless of whether it is bound to

any clients

Additionally if your service is started and accepts binding then when the system calls your onUnbind()

method you can optionally return true if you would like to receive a call to onRebind() the next time a

client binds to the service (instead of receiving a call to onBind()) onRebind() returns void but the

client still receives the IBinder in its onServiceConnected() callback Below figure 1 illustrates the logic

for this kind of lifecycle

For more information about the lifecycle of an started service see the Services document

Content Providers

Content providers store and retrieve data and make it accessible to all applications Theyre the only

way to share data across applications theres no common storage area that all Android packages can

access

Android ships with a number of content providers for common data types (audio video images

personal contact information and so on) You can see some of them listed in the androidprovider

package You can query these providers for the data they contain (although for some you must

acquire the proper permission to read the data)

If you want to make your own data public you have two options You can create your own content

provider (a ContentProvider subclass) or you can add the data to an existing provider mdash if theres one

that controls the same type of data and you have permission to write to it

This document is an introduction to using content providers After a brief discussion of the

fundamentals it explores how to query a content provider how to modify data controlled by a provider

and how to create a content provider of your own

Content Provider Basics

How a content provider actually stores its data under the covers is up to its designer But all content

providers implement a common interface for querying the provider and returning results mdash as well as

for adding altering and deleting data Its an interface that clients use indirectly most generally

through ContentResolver objects You get a ContentResolver by calling getContentResolver() from

within the implementation of an Activity or other application component

ContentResolver cr = getContentResolver()

You can then use the ContentResolvers methods to interact with whatever content providers youre

interested in When a query is initiated the Android system identifies the content provider thats the

target of the query and makes sure that it is up and running The system instantiates all

ContentProvider objects you never need to do it on your own In fact you never deal directly with

ContentProvider objects at all Typically theres just a single instance of each type of ContentProvider

But it can communicate with multiple ContentResolver objects in different applications and processes

The interaction between processes is handled by the ContentResolver and ContentProvider classes

The data model

Content providers expose their data as a simple table on a database model where each row is a

record and each column is data of a particular type and meaning For example information about

people and their phone numbers might be exposed as follows

_ID NUMBER NUMBER_KEY LABEL NAME TYPE

13 (425) 555 6677 425 555 6677 Kirkland office Bully Pulpit TYPE_WORK

44 (212) 555-1234 212 555 1234 NY apartment Alan Vain TYPE_HOME

45 (212) 555-6657 212 555 6657 Downtown office Alan Vain TYPE_MOBILE

53 2015554433 201 555 4433 Love Nest Rex Cars TYPE_HOME

Every record includes a numeric _ID field that uniquely identifies the record within the table IDs can be

used to match records in related tables mdash for example to find a persons phone number in one table

and pictures of that person in another

A query returns a Cursor object that can move from record to record and column to column to read the

contents of each field It has specialized methods for reading each type of data So to read a field you

must know what type of data the field contains (Theres more on query results and Cursor objects

later)

URIs

Each content provider exposes a public URI (wrapped as a Uri object) that uniquely identifies its data

set A content provider that controls multiple data sets (multiple tables) exposes a separate URI for

each one All URIs for providers begin with the string content The content scheme identifies the

data as being controlled by a content provider

If youre defining a content provider its a good idea to also define a constant for its URI to simplify

client code and make future updates cleaner Android defines CONTENT_URI constants for all the

providers that come with the platform For example the URI for the table that matches phone numbers

to people and the URI for the table that holds pictures of people (both controlled by the Contacts

content provider) are

androidproviderContactsPhonesCONTENT_URI

androidproviderContactsPhotosCONTENT_URI

The URI constant is used in all interactions with the content provider Every ContentResolver method

takes the URI as its first argument Its what identifies which provider the ContentResolver should talk

to and which table of the provider is being targeted

Querying a Content Provider

You need three pieces of information to query a content provider

The URI that identifies the provider

The names of the data fields you want to receive

The data types for those fields

If youre querying a particular record you also need the ID for that record

Making the query

To query a content provider you can use either the ContentResolverquery() method or the

ActivitymanagedQuery() method Both methods take the same set of arguments and both return a

Cursor object However managedQuery() causes the activity to manage the life cycle of the Cursor A

managed Cursor handles all of the niceties such as unloading itself when the activity pauses and

requerying itself when the activity restarts You can ask an Activity to begin managing an unmanaged

Cursor object for you by calling ActivitystartManagingCursor()

The first argument to either query() or managedQuery() is the provider URI mdash the CONTENT_URI

constant that identifies a particular ContentProvider and data set (see URIs earlier)

To restrict a query to just one record you can append the _ID value for that record to the URI mdash that

is place a string matching the ID as the last segment of the path part of the URI For example if the ID

is 23 the URI would be

content 23

There are some helper methods particularly ContentUriswithAppendedId() and

UriwithAppendedPath() that make it easy to append an ID to a URI Both are static methods that

return a Uri object with the ID added So for example if you were looking for record 23 in the database

of people contacts you might construct a query as follows

import androidproviderContactsPeople import androidcontentContentUris import androidnetUri import androiddatabaseCursor Use the ContentUris method to produce the base URI for the contact with _ID == 23 Uri myPerson = ContentUriswithAppendedId(PeopleCONTENT_URI 23) Alternatively use the Uri method to produce the base URI It takes a string rather than an integer Uri myPerson = UriwithAppendedPath(PeopleCONTENT_URI 23) Then query for this specific record Cursor cur = managedQuery(myPerson null null null null)

The other arguments to the query() and managedQuery() methods delimit the query in more detail

They are

The names of the data columns that should be returned A null value returns all columns Otherwise

only columns that are listed by name are returned All the content providers that come with the

platform define constants for their columns For example the androidproviderContactsPhones class

defines constants for the names of the columns in the phone table illustrated earlier ampmdash _ID

NUMBER NUMBER_KEY NAME and so on

A filter detailing which rows to return formatted as an SQL WHERE clause (excluding the WHERE

itself) A null value returns all rows (unless the URI limits the query to a single record)

Selection arguments

A sorting order for the rows that are returned formatted as an SQL ORDER BY clause (excluding the

ORDER BY itself) A null value returns the records in the default order for the table which may be

unordered

Lets look at an example query to retrieve a list of contact names and their primary phone numbers

import androidproviderContactsPeople import androiddatabaseCursor Form an array specifying which columns to return String[] projection = new String[] People_ID People_COUNT PeopleNAME PeopleNUMBER Get the base URI for the People table in the Contacts content provider Uri contacts = PeopleCONTENT_URI Make the query Cursor managedCursor = managedQuery(contacts projection Which columns to return null Which rows to return (all rows) null Selection arguments (none) Put the results in ascending order by name PeopleNAME + ASC)

This query retrieves data from the People table of the Contacts content provider It gets the name

primary phone number and unique record ID for each contact It also reports the number of records

that are returned as the _COUNT field of each record

The constants for the names of the columns are defined in various interfaces mdash _ID and _COUNT in

BaseColumns NAME in PeopleColumns and NUMBER in PhoneColumns The ContactsPeople

class implements each of these interfaces which is why the code example above could refer to them

using just the class name

What a query returns

A query returns a set of zero or more database records The names of the columns their default order

and their data types are specific to each content provider But every provider has an _ID column

which holds a unique numeric ID for each record Every provider can also report the number of records

returned as the _COUNT column its value is the same for all rows

Here is an example result set for the query in the previous section

_ID _COUNT NAME NUMBER

44 3 Alan Vain 212 555 1234

13 3 Bully Pulpit 425 555 6677

53 3 Rex Cars 201 555 4433

The retrieved data is exposed by a Cursor object that can be used to iterate backward or forward

through the result set You can use this object only to read the data To add modify or delete data

you must use a ContentResolver object

Reading retrieved data

The Cursor object returned by a query provides access to a recordset of results If you have queried

for a specific record by ID this set will contain only one value Otherwise it can contain multiple

values (If there are no matches it can also be empty) You can read data from specific fields in the

record but you must know the data type of the field because the Cursor object has a separate method

for reading each type of data mdash such as getString() getInt() and getFloat() (However for most types

if you call the method for reading strings the Cursor object will give you the String representation of

the data) The Cursor lets you request the column name from the index of the column or the index

number from the column name

The following snippet demonstrates reading names and phone numbers from the query illustrated

earlier

import androidproviderContactsPeople private void getColumnData(Cursor cur) if (curmoveToFirst()) String name String phoneNumber int nameColumn = curgetColumnIndex(PeopleNAME) int phoneColumn = curgetColumnIndex(PeopleNUMBER) String imagePath do Get the field values name = curgetString(nameColumn) phoneNumber = curgetString(phoneColumn) Do something with the values while (curmoveToNext())

If a query can return binary data such as an image or sound the data may be directly entered in the

table or the table entry for that data may be a string specifying a content URI that you can use to get

the data In general smaller amounts of data (say from 20 to 50K or less) are most often directly

entered in the table and can be read by calling CursorgetBlob() It returns a byte array

If the table entry is a content URI you should never try to open and read the file directly (for one thing

permissions problems can make this fail) Instead you should call ContentResolveropenInputStream()

to get an InputStream object that you can use to read the data

Modifying Data

Data kept by a content provider can be modified by

Adding new records

Adding new values to existing records

Batch updating existing records

Deleting records

All data modification is accomplished using ContentResolver methods Some content providers require

a more restrictive permission for writing data than they do for reading it If you dont have permission to

write to a content provider the ContentResolver methods will fail

Adding records

To add a new record to a content provider first set up a map of key-value pairs in a ContentValues

object where each key matches the name of a column in the content provider and the value is the

desired value for the new record in that column Then call ContentResolverinsert() and pass it the URI

of the provider and the ContentValues map This method returns the full URI of the new record mdash that

is the providers URI with the appended ID for the new record You can then use this URI to query and

get a Cursor over the new record and to further modify the record Heres an example

import androidproviderContactsPeople import androidcontentContentResolver import androidcontentContentValues ContentValues values = new ContentValues() Add Abraham Lincoln to contacts and make him a favorite valuesput(PeopleNAME Abraham Lincoln) 1 = the new contact is added to favorites 0 = the new contact is not added to favorites valuesput(PeopleSTARRED 1) Uri uri = getContentResolver()insert(PeopleCONTENT_URI values)

Adding new values

Once a record exists you can add new information to it or modify existing information For example

the next step in the example above would be to add contact information mdash like a phone number or an

IM or e-mail address mdash to the new entry

The best way to add to a record in the Contacts database is to append the name of the table where the

new data goes to the URI for the record then use the amended URI to add the new data values Each

Contacts table exposes a name for this purpose as a CONTENT_DIRECTORY constant The following

code continues the previous example by adding a phone number and e-mail address for the record

just created

Uri phoneUri = null Uri emailUri = null Add a phone number for Abraham Lincoln Begin with the URI for the new record just returned by insert() it ends with the _ID of the new record so we dont have to add the ID ourselves Then append the designation for the phone table to this URI and use the resulting URI to insert the phone number phoneUri = UriwithAppendedPath(uri PeoplePhonesCONTENT_DIRECTORY) valuesclear() valuesput(PeoplePhonesTYPE PeoplePhonesTYPE_MOBILE) valuesput(PeoplePhonesNUMBER 1233214567) getContentResolver()insert(phoneUri values) Now add an email address in the same way emailUri = UriwithAppendedPath(uri PeopleContactMethodsCONTENT_DIRECTORY) valuesclear() ContactMethodsKIND is used to distinguish different kinds of contact methods such as email IM etc valuesput(PeopleContactMethodsKIND ContactsKIND_EMAIL) valuesput(PeopleContactMethodsDATA testexamplecom) valuesput(PeopleContactMethodsTYPE PeopleContactMethodsTYPE_HOME) getContentResolver()insert(emailUri values)

You can place small amounts of binary data into a table by calling the version of ContentValuesput()

that takes a byte array That would work for a small icon-like image or a short audio clip for example

However if you have a large amount of binary data to add such as a photograph or a complete song

put a content URI for the data in the table and call ContentResolveropenOutputStream() with the files

URI (That causes the content provider to store the data in a file and record the file path in a hidden

field of the record)

In this regard the MediaStore content provider the main provider that dispenses image audio and

video data employs a special convention The same URI that is used with query() or managedQuery()

to get meta-information about the binary data (such as the caption of a photograph or the date it was

taken) is used with openInputStream() to get the data itself Similarly the same URI that is used with

insert() to put meta-information into a MediaStore record is used with openOutputStream() to place the

binary data there The following code snippet illustrates this convention

import androidproviderMediaStoreImagesMedia import androidcontentContentValues import javaioOutputStream Save the name and description of an image in a ContentValues map ContentValues values = new ContentValues(3) valuesput(MediaDISPLAY_NAME road_trip_1) valuesput(MediaDESCRIPTION Day 1 trip to Los Angeles) valuesput(MediaMIME_TYPE imagejpeg) Add a new record without the bitmap but with the values just set insert() returns the URI of the new record Uri uri = getContentResolver()insert(MediaEXTERNAL_CONTENT_URI values) Now get a handle to the file for that record and save the data into it Here sourceBitmap is a Bitmap object representing the file to save to the database try OutputStream outStream = getContentResolver()openOutputStream(uri) sourceBitmapcompress(BitmapCompressFormatJPEG 50 outStream) outStreamclose() catch (Exception e) Loge(TAG exception while writing image e)

Batch updating records

To batch update a group of records (for example to change NY to New York in all fields) call the

ContentResolverupdate() method with the columns and values to change

Deleting a record

To delete a single record call ContentResolverdelete() with the URI of a specific row

To delete multiple rows call ContentResolverdelete() with the URI of the type of record to delete (for

example androidproviderContactsPeopleCONTENT_URI) and an SQL WHERE clause defining

which rows to delete (Caution Be sure to include a valid WHERE clause if youre deleting a general

type or you risk deleting more records than you intended)

Creating a Content Provider

To create a content provider you must

Set up a system for storing the data Most content providers store their data using Androids file

storage methods or SQLite databases but you can store your data any way you want Android

provides the SQLiteOpenHelper class to help you create a database and SQLiteDatabase to manage

it

Extend the ContentProvider class to provide access to the data

Declare the content provider in the manifest file for your application (AndroidManifestxml)

The following sections have notes on the last two of these tasks

Extending the ContentProvider class

You define a ContentProvider subclass to expose your data to others using the conventions expected

by ContentResolver and Cursor objects Principally this means implementing six abstract methods

declared in the ContentProvider class

query()

insert()

update()

delete()

getType()

onCreate()

The query() method must return a Cursor object that can iterate over the requested data Cursor itself

is an interface but Android provides some ready-made Cursor objects that you can use For example

SQLiteCursor can iterate over data stored in an SQLite database You get the Cursor object by calling

any of the SQLiteDatabase classs query() methods There are other Cursor implementations mdash such

as MatrixCursor mdash for data not stored in a database

Because these ContentProvider methods can be called from various ContentResolver objects in

different processes and threads they must be implemented in a thread-safe manner

As a courtesy you might also want to call ContentResolvernotifyChange() to notify listeners when

there are modifications to the data

Beyond defining the subclass itself there are other steps you should take to simplify the work of clients

and make the class more accessible

Define a public static final Uri named CONTENT_URI This is the string that represents the full content

URI that your content provider handles You must define a unique string for this value The best

solution is to use the fully-qualified class name of the content provider (made lowercase) So for

example the URI for a TransportationProvider class could be defined as follows

public static final Uri CONTENT_URI = Uriparse(contentcomexamplecodelabtransportationprovider)

If the provider has subtables also define CONTENT_URI constants for each of the subtables These

URIs should all have the same authority (since that identifies the content provider) and be

distinguished only by their paths For example

contentcomexamplecodelabtransportationprovidertrain

contentcomexamplecodelabtransportationproviderairdomestic

contentcomexamplecodelabtransportationproviderairinternational

For an overview of content URIs see the Content URI Summary at the end of this document

Define the column names that the content provider will return to clients If you are using an underlying

database these column names are typically identical to the SQL database column names they

represent Also define public static String constants that clients can use to specify the columns in

queries and other instructions

Be sure to include an integer column named _id (with the constant _ID) for the IDs of the records

You should have this field whether or not you have another field (such as a URL) that is also unique

among all records If youre using the SQLite database the _ID field should be the following type

INTEGER PRIMARY KEY AUTOINCREMENT

The AUTOINCREMENT descriptor is optional But without it SQLite increments an ID counter field to

the next number above the largest existing number in the column If you delete the last row the next

row added will have the same ID as the deleted row AUTOINCREMENT avoids this by having SQLite

increment to the next largest value whether deleted or not

Carefully document the data type of each column Clients need this information to read the data

If you are handling a new data type you must define a new MIME type to return in your

implementation of ContentProvidergetType() The type depends in part on whether or not the content

URI submitted to getType() limits the request to a specific record Theres one form of the MIME type

for a single record and another for multiple records Use the Uri methods to help determine what is

being requested Here is the general format for each type

o For a single record vndandroidcursoritemvndyourcompanynamecontenttype

For example a request for train record 122 like this URI

contentcomexampletransportationprovidertrains122

might return this MIME type

vndandroidcursoritemvndexamplerail

o For multiple records vndandroidcursordirvndyourcompanynamecontenttype

For example a request for all train records like the following URI

contentcomexampletransportationprovidertrains

might return this MIME type

vndandroidcursordirvndexamplerail

If you are exposing byte data thats too big to put in the table itself mdash such as a large bitmap file mdash the

field that exposes the data to clients should actually contain a content URI string This is the field that

gives clients access to the data file The record should also have another field named _data that lists

the exact file path on the device for that file This field is not intended to be read by the client but by

the ContentResolver The client will call ContentResolveropenInputStream() on the user-facing field

holding the URI for the item The ContentResolver will request the _data field for that record and

because it has higher permissions than a client it should be able to access that file directly and return

a read wrapper for the file to the client

For an example of a private content provider implementation see the NodePadProvider class in the

Notepad sample application that ships with the SDK

Declaring the content provider

To let the Android system know about the content provider youve developed declare it with a

ltprovidergt element in the applications AndroidManifestxml file Content providers that are not

declared in the manifest are not visible to the Android system

The name attribute is the fully qualified name of the ContentProvider subclass The authorities attribute

is the authority part of the content URI that identifies the provider For example if the ContentProvider

subclass is AutoInfoProvider the ltprovidergt element might look like this

ltprovider androidname=comexampleautosAutoInfoProvider androidauthorities=comexampleautosautoinfoprovider gt ltprovidergt

Note that the authorities attribute omits the path part of a content URI For example if

AutoInfoProvider controlled subtables for different types of autos or different manufacturers

contentcomexampleautosautoinfoproviderhonda

contentcomexampleautosautoinfoprovidergmcompact

contentcomexampleautosautoinfoprovidergmsuv

those paths would not be declared in the manifest The authority is what identifies the provider not the

path your provider can interpret the path part of the URI in any way you choose

Other ltprovidergt attributes can set permissions to read and write data provide for an icon and text

that can be displayed to users enable and disable the provider and so on Set the multiprocess

attribute to true if data does not need to be synchronized between multiple running versions of the

content provider This permits an instance of the provider to be created in each client process

eliminating the need to perform IPC

Content URI Summary

Here is a recap of the important parts of a content URI

A Standard prefix indicating that the data is controlled by a content provider Its never modified

B The authority part of the URI it identifies the content provider For third-party applications this should

be a fully-qualified class name (reduced to lowercase) to ensure uniqueness The authority is declared

in the ltprovidergt elements authorities attribute

ltprovider androidname=TransportationProvider androidauthorities=comexampletransportationprovider gt

C The path that the content provider uses to determine what kind of data is being requested This can be

zero or more segments long If the content provider exposes only one type of data (only trains for

example) it can be absent If the provider exposes several types including subtypes it can be several

segments long mdash for example landbus landtrain seaship and seasubmarine to give four

possibilities

D The ID of the specific record being requested if any This is the _ID value of the requested record If

the request is not limited to a single record this segment and the trailing slash are omitted

contentcomexampletransportationprovidertrains

Intent and intent filters

Three of the core components of an application mdash activities services and broadcast receivers mdash 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 mdash 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 ContextstartActivity() or ActivitystartActivityForResult() to launch an

activity or get an existing activity to do something new (It can also be passed to ActivitysetResult() to

return information to the activity that called startActivityForResult())

An Intent object is passed to ContextstartService() to initiate a service or deliver new instructions to an

ongoing service Similarly an intent can be passed to ContextbindService() to establish a connection

between the calling component and a target service It can optionally initiate the service if its not

already running

Intent objects passed to any of the broadcast methods (such as ContextsendBroadcast()

ContextsendOrderedBroadcast() or ContextsendStickyBroadcast()) 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 mdash how it resolves which component should receive an intent message For

intents that dont explicitly name a target component this process involves testing the Intent object

against intent filters associated with potential targets

Intent Objects

An Intent object is a bundle of information It contains information of interest to the component that

receives the intent (such as the action to be taken and the data to act on) plus information of interest to

the Android system (such as the category of component that should handle the intent and instructions

on how to launch a target activity) Principally it can contain the following

Component name

The name of the component that should handle the intent This field is a ComponentName

object mdash a combination of the fully qualified class name of the target component (for example

comexampleprojectappFreneticActivity) and the package name set in the manifest file of the

application where the component resides (for example comexampleproject) The package

part of the component name and the package name set in the manifest do not necessarily have

to match

The component name is optional If it is set the Intent object is delivered to an instance of the

designated class If it is not set Android uses other information in the Intent object to locate a

suitable target mdash see Intent Resolution later in this document

The component name is set by setComponent() setClass() or setClassName() and read by

getComponent()

Action

A string naming the action to be performed mdash or in the case of broadcast intents the action

that took place and is being reported The Intent class defines a number of action constants

including these

Constant Target

component

Action

ACTION_CALL activity Initiate a phone call

ACTION_EDIT activity Display data for the user to edit

ACTION_MAIN activity Start up as the initial activity of a task

with no data input and no returned

output

ACTION_SYNC activity Synchronize data on a server with

data on the mobile device

ACTION_BATTERY_LOW broadcast

receiver

A warning that the battery is low

ACTION_HEADSET_PLUG broadcast

receiver

A headset has been plugged into the

device or unplugged from it

ACTION_SCREEN_ON broadcast

receiver

The screen has been turned on

ACTION_TIMEZONE_CHANGED broadcast

receiver

The setting for the time zone has

changed

See the Intent class description for a list of pre-defined constants for generic actions Other

actions are defined elsewhere in the Android API You can also define your own action strings

for activating the components in your application Those you invent should include the

application package as a prefix mdash for example comexampleprojectSHOW_COLOR

The action largely determines how the rest of the intent is structured mdash particularly the data and

extras fields mdash much as a method name determines a set of arguments and a return value For

this reason its a good idea to use action names that are as specific as possible and to couple

them tightly to the other fields of the intent In other words instead of defining an action in

isolation define an entire protocol for the Intent objects your components can handle

The action in an Intent object is set by the setAction() method and read by getAction()

Data

The URI of the data to be acted on and the MIME type of that data Different actions are paired

with different kinds of data specifications For example if the action field is ACTION_EDIT the

data field would contain the URI of the document to be displayed for editing If the action is

ACTION_CALL the data field would be a tel URI with the number to call Similarly if the action

is ACTION_VIEW and the data field is an http URI the receiving activity would be called upon

to download and display whatever data the URI refers to

When matching an intent to a component that is capable of handling the data its often

important to know the type of data (its MIME type) in addition to its URI For example a

component able to display image data should not be called upon to play an audio file

In many cases the data type can be inferred from the URI mdash particularly content URIs which

indicate that the data is located on the device and controlled by a content provider (see the

separate discussion on content providers) But the type can also be explicitly set in the Intent

object The setData() method specifies data only as a URI setType() specifies it only as a

MIME type and setDataAndType() specifies it as both a URI and a MIME type The URI is read

by getData() and the type by getType()

Category

A string containing additional information about the kind of component that should handle the

intent Any number of category descriptions can be placed in an Intent object As it does for

actions the Intent class defines several category constants including these

Constant Meaning

CATEGORY_BROWSABLE The target activity can be safely invoked by the browser to

display data referenced by a link mdash for example an image or

an e-mail message

CATEGORY_GADGET The activity can be embedded inside of another activity that

hosts gadgets

CATEGORY_HOME The activity displays the home screen the first screen the

user sees when the device is turned on or when the HOME

key is pressed

CATEGORY_LAUNCHER The activity can be the initial activity of a task and is listed in

the top-level application launcher

CATEGORY_PREFERENCE The target activity is a preference panel

See the Intent class description for the full list of categories

The addCategory() method places a category in an Intent object removeCategory() deletes a

category previously added and getCategories() gets the set of all categories currently in the

object

Extras

Key-value pairs for additional information that should be delivered to the component handling

the intent Just as some actions are paired with particular kinds of data URIs some are paired

with particular extras For example an ACTION_TIMEZONE_CHANGED intent has a time-

zone extra that identifies the new time zone and ACTION_HEADSET_PLUG has a state

extra indicating whether the headset is now plugged in or unplugged as well as a name extra

for the type of headset If you were to invent a SHOW_COLOR action the color value would be

set in an extra key-value pair

The Intent object has a series of put() methods for inserting various types of extra data and a

similar set of get() methods for reading the data These methods parallel those for Bundle

objects In fact the extras can be installed and read as a Bundle using the putExtras() and

getExtras() methods

Flags

Flags of various sorts Many instruct the Android system how to launch an activity (for example

which task the activity should belong to) and how to treat it after its launched (for example

whether it belongs in the list of recent activities) All these flags are defined in the Intent class

The Android system and the applications that come with the platform employ Intent objects both to

send out system-originated broadcasts and to activate system-defined components To see how to

structure an intent to activate a system component consult the list of intents in the reference

Intent Resolution

Intents can be divided into two groups

Explicit intents designate the target component by its name (the component name field mentioned

earlier has a value set) Since component names would generally not be known to developers of other

applications explicit intents are typically used for application-internal messages mdash such as an activity

starting a subordinate service or launching a sister activity

Implicit intents do not name a target (the field for the component name is blank) Implicit intents are

often used to activate components in other applications

Android delivers an explicit intent to an instance of the designated target class Nothing in the Intent

object other than the component name matters for determining which component should get the intent

A different strategy is needed for implicit intents In the absence of a designated target the Android

system must find the best component (or components) to handle the intent mdash a single activity or

service to perform the requested action or the set of broadcast receivers to respond to the broadcast

announcement It does so by comparing the contents of the Intent object to intent filters structures

associated with components that can potentially receive intents Filters advertise the capabilities of a

component and delimit the intents it can handle They open the component to the possibility of

receiving implicit intents of the advertised type If a component does not have any intent filters it can

receive only explicit intents A component with filters can receive both explicit and implicit intents

Only three aspects of an Intent object are consulted when the object is tested against an intent filter

action

data (both URI and data type)

category

The extras and flags play no part in resolving which component receives an intent

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 mdash but only unwanted implicit intents (those that dont 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

components 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 mdash 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 Pads filters are described in the Note Pad Example

section later)

Filters and security

An intent filter cannot be relied on for security While it opens a component to receiving only certain

kinds of implicit intents it does nothing to prevent explicit intents from targeting the component Even

though a filter restricts the intents a component will be asked to handle to certain actions and data

sources someone could always put together an explicit intent with a different action and data source

and name the component as the target

An intent filter is an instance of the IntentFilter class However since the Android system must know

about the capabilities of a component before it can launch that component intent filters are generally

not set up in Java code but in the applications manifest file (AndroidManifestxml) as ltintent-filtergt

elements (The one exception would be filters for broadcast receivers that are registered dynamically

by calling ContextregisterReceiver() they are directly created as IntentFilter objects)

A filter has fields that parallel the action data and category fields of an Intent object An implicit intent

is tested against the filter in all three areas To be delivered to the component that owns the filter it

must pass all three tests If it fails even one of them the Android system wont deliver it to the

component mdash at least not on the basis of that filter However since a component can have multiple

intent filters an intent that does not pass through one of a components filters might make it through on

another

Each of the three tests is described in detail below

Action test

An ltintent-filtergt element in the manifest file lists actions as ltactiongt subelements For

example

ltintent-filter gt ltaction androidname=comexampleprojectSHOW_CURRENT gt ltaction androidname=comexampleprojectSHOW_RECENT gt ltaction androidname=comexampleprojectSHOW_PENDING gt ltintent-filtergt

As the example shows while an Intent object names just a single action a filter may list more

than one The list cannot be empty a filter must contain at least one ltactiongt element or it will

block all intents

To pass this test the action specified in the Intent object must match one of the actions listed in

the filter If the object or the filter does not specify an action the results are as follows

If the filter fails to list any actions there is nothing for an intent to match so all intents fail the

test No intents can get through the filter

On the other hand an Intent object that doesnt specify an action automatically passes the test

mdash as long as the filter contains at least one action

Category test

An ltintent-filtergt element also lists categories as subelements For example

ltintent-filter gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryBROWSABLE gt ltintent-filtergt

Note that the constants described earlier for actions and categories are not used in the manifest

file The full string values are used instead For instance the

androidintentcategoryBROWSABLE string in the example above corresponds to the

CATEGORY_BROWSABLE constant mentioned earlier in this document Similarly the string

androidintentactionEDIT corresponds to the ACTION_EDIT constant

For an intent to pass the category test every category in the Intent object must match a

category in the filter The filter can list additional categories but it cannot omit any that are in the

intent

In principle therefore an Intent object with no categories should always pass this test

regardless of whats in the filter Thats mostly true However with one exception Android treats

all implicit intents passed to startActivity() as if they contained at least one category

androidintentcategoryDEFAULT (the CATEGORY_DEFAULT constant) Therefore activities

that are willing to receive implicit intents must include androidintentcategoryDEFAULT in

their intent filters (Filters with androidintentactionMAIN and

androidintentcategoryLAUNCHER settings are the exception They mark activities that begin

new tasks and that are represented on the launcher screen They can include

androidintentcategoryDEFAULT in the list of categories but dont need to) See Using intent

matching later for more on these filters)

Data test

Like the action and categories the data specification for an intent filter is contained in a

subelement And as in those cases the subelement can appear multiple times or not at all For

example

ltintent-filter gt ltdata androidmimeType=videompeg androidscheme=http gt ltdata androidmimeType=audiompeg androidscheme=http gt ltintent-filtergt

Each ltdatagt element can specify a URI and a data type (MIME media type) There are

separate attributes mdash scheme host port and path mdash for each part of the URI

schemehostportpath

For example in the following URI

contentcomexampleproject200foldersubfolderetc

the scheme is content the host is comexampleproject the port is 200 and the path is

foldersubfolderetc The host and port together constitute the URI authority if a host is not

specified the port is ignored

Each of these attributes is optional but they are not independent of each other For an authority

to be meaningful a scheme must also be specified For a path to be meaningful both a scheme

and an authority must be specified

When the URI in an Intent object is compared to a URI specification in a filter its compared

only to the parts of the URI actually mentioned in the filter For example if a filter specifies only

a scheme all URIs with that scheme match the filter If a filter specifies a scheme and an

authority but no path all URIs with the same scheme and authority match regardless of their

paths If a filter specifies a scheme an authority and a path only URIs with the same scheme

authority and path match However a path specification in the filter can contain wildcards to

require only a partial match of the path

The type attribute of a ltdatagt element specifies the MIME type of the data Its more common in

filters than a URI Both the Intent object and the filter can use a wildcard for the subtype field

mdash for example text or audio mdash indicating any subtype matches

The data test compares both the URI and the data type in the Intent object to a URI and data

type specified in the filter The rules are as follows

a An Intent object that contains neither a URI nor a data type passes the test only if the filter

likewise does not specify any URIs or data types

b An Intent object that contains a URI but no data type (and a type cannot be inferred from the

URI) passes the test only if its URI matches a URI in the filter and the filter likewise does not

specify a type This will be the case only for URIs like mailto and tel that do not refer to actual

data

c An Intent object that contains a data type but not a URI passes the test only if the filter lists the

same data type and similarly does not specify a URI

d An Intent object that contains both a URI and a data type (or a data type can be inferred from

the URI) passes the data type part of the test only if its type matches a type listed in the filter It

passes the URI part of the test either if its URI matches a URI in the filter or if it has a content

or file URI and the filter does not specify a URI In other words a component is presumed to

support content and file data if its filter lists only a data type

If an intent can pass through the filters of more than one activity or service the user may be asked

which component to activate An exception is raised if no target can be found

Common cases

The last rule shown above for the data test rule (d) reflects the expectation that components are able

to get local data from a file or content provider Therefore their filters can list just a data type and do

not need to explicitly name the content and file schemes This is a typical case A ltdatagt element like

the following for example tells Android that the component can get image data from a content

provider and display it

ltdata androidmimeType=image gt

Since most available data is dispensed by content providers filters that specify a data type but not a

URI are perhaps the most common

Another common configuration is filters with a scheme and a data type For example a ltdatagt

element like the following tells Android that the component can get video data from the network and

display it

ltdata androidscheme=http androidtype=video gt

Consider for example what the browser application does when the user follows a link on a web page

It first tries to display the data (as it could if the link was to an HTML page) If it cant display the data it

puts together an implicit intent with the scheme and data type and tries to start an activity that can do

the job If there are no takers it asks the download manager to download the data That puts it under

the control of a content provider so a potentially larger pool of activities (those with filters that just

name a data type) can respond

Most applications also have a way to start fresh without a reference to any particular data Activities

that can initiate applications have filters with androidintentactionMAIN specified as the action If

they are to be represented in the application launcher they also specify the

androidintentcategoryLAUNCHER category

ltintent-filter gt ltaction androidname=code androidintentactionMAIN gt ltcategory androidname=code androidintentcategoryLAUNCHER gt ltintent-filtergt

Using intent matching

Intents are matched against intent filters not only to discover a target component to activate but also

to discover something about the set of components on the device For example the Android system

populates the application launcher the top-level screen that shows the applications that are available

for the user to launch by finding all the activities with intent filters that specify the

androidintentactionMAIN action and androidintentcategoryLAUNCHER category (as illustrated

in the previous section) It then displays the icons and labels of those activities in the launcher

Similarly it discovers the home screen by looking for the activity with androidintentcategoryHOME

in its filter

Your application can use intent matching is a similar way The PackageManager has a set of query()

methods that return all components that can accept a particular intent and a similar series of

resolve() methods that determine the best component to respond to an intent For example

queryIntentActivities() returns a list of all activities that can perform the intent passed as an argument

and queryIntentServices() returns a similar list of services Neither method activates the components

they just list the ones that can respond Theres a similar method queryBroadcastReceivers() for

broadcast receivers

Note Pad Example

The Note Pad sample application enables users to browse through a list of notes view details about

individual items in the list edit the items and add a new item to the list This section looks at the intent

filters declared in its manifest file (If youre working offline in the SDK you can find all the source files

for this sample application including its manifest file at ltsdkgtsamplesNotePadindexhtml If youre

viewing the documentation online the source files are in the Tutorials and Sample Code section here)

In its manifest file the Note Pad application declares three activities each with at least one intent filter

It also declares a content provider that manages the note data Here is the manifest file in its entirety

ltmanifest xmlnsandroid=httpschemasandroidcomapkresandroid package=comexampleandroidnotepadgt ltapplication androidicon=drawableapp_notes androidlabel=stringapp_name gt ltprovider androidname=NotePadProvider androidauthorities=comgoogleproviderNotePad gt ltactivity androidname=NotesList androidlabel=stringtitle_notes_listgt ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltactivity androidname=NoteEditor androidtheme=androidstyleThemeLight androidlabel=stringtitle_note gt ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltactivitygt

ltactivity androidname=TitleEditor androidlabel=stringtitle_edit_title androidtheme=androidstyleThemeDialoggt ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltapplicationgt ltmanifestgt

The first activity NotesList is distinguished from the other activities by the fact that it operates on a

directory of notes (the note list) rather than on a single note It would generally serve as the initial user

interface into the application It can do three things as described by its three intent filters

1 ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt

This filter declares the main entry point into the Note Pad application The standard MAIN action is an

entry point that does not require any other information in the Intent (no data specification for example)

and the LAUNCHER category says that this entry point should be listed in the application launcher

2 ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

This filter declares the things that the activity can do on a directory of notes It can allow the user to

view or edit the directory (via the VIEW and EDIT actions) or to pick a particular note from the

directory (via the PICK action)

The mimeType attribute of the ltdatagt element specifies the kind of data that these actions operate on

It indicates that the activity can get a Cursor over zero or more items (vndandroidcursordir) from a

content provider that holds Note Pad data (vndgooglenote) The Intent object that launches the

activity would include a content URI specifying the exact data of this type that the activity should open

Note also the DEFAULT category supplied in this filter Its there because the ContextstartActivity()

and ActivitystartActivityForResult() methods treat all intents as if they contained the DEFAULT

category mdash with just two exceptions

o Intents that explicitly name the target activity

o Intents consisting of the MAIN action and LAUNCHER category

Therefore the DEFAULT category is required for all filters mdash except for those with the MAIN action

and LAUNCHER category (Intent filters are not consulted for explicit intents)

3 ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

This filter describes the activitys ability to return a note selected by the user without requiring any

specification of the directory the user should choose from The GET_CONTENT action is similar to the

PICK action In both cases the activity returns the URI for a note selected by the user (In each case

its returned to the activity that called startActivityForResult() to start the NoteList activity) Here

however the caller specifies the type of data desired instead of the directory of data the user will be

picking from

The data type vndandroidcursoritemvndgooglenote indicates the type of data the activity can

return mdash a URI for a single note From the returned URI the caller can get a Cursor for exactly one

item (vndandroidcursoritem) from the content provider that holds Note Pad data (vndgooglenote)

In other words for the PICK action in the previous filter the data type indicates the type of data the

activity could display to the user For the GET_CONTENT filter it indicates the type of data the activity

can return to the caller

Given these capabilities the following intents will resolve to the NotesList activity

action androidintentactionMAIN

Launches the activity with no data specified

action androidintentactionMAIN

category androidintentcategoryLAUNCHER

Launches the activity with no data selected specified This is the actual intent used by the

Launcher to populate its top-level list All activities with filters that match this action and

category are added to the list

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of all the notes under

contentcomgoogleproviderNotePadnotes The user can then browse through the list and

get information about the items in it

action androidintentactionPICK

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of the notes under

contentcomgoogleproviderNotePadnotes The user can then pick a note from the list and

the activity will return the URI for that item back to the activity that started the NoteList activity

action androidintentactionGET_CONTENT

data type vndandroidcursoritemvndgooglenote

Asks the activity to supply a single item of Note Pad data

The second activity NoteEditor shows users a single note entry and allows them to edit it It can do

two things as described by its two intent filters

1 ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The first primary purpose of this activity is to enable the user to interact with a single note ampmdash to

either VIEW the note or EDIT it (The EDIT_NOTE category is a synonym for EDIT) The intent would

contain the URI for data matching the MIME type vndandroidcursoritemvndgooglenote mdash that is

the URI for a single specific note It would typically be a URI that was returned by the PICK or

GET_CONTENT actions of the NoteList activity

As before this filter lists the DEFAULT category so that the activity can be launched by intents that

dont explicitly specify the NoteEditor class

2 ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

The secondary purpose of this activity is to enable the user to create a new note which it will INSERT

into an existing directory of notes The intent would contain the URI for data matching the MIME type

vndandroidcursordirvndgooglenote mdash that is the URI for the directory where the note should be

placed

Given these capabilities the following intents will resolve to the NoteEditor activity

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID (For details on how content

URIs specify individual members of a group see Content Providers)

action androidintentactionEDIT

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID and to let the user edit it If

the user saves the changes the activity updates the data for the note in the content provider

action androidintentactionINSERT

data contentcomgoogleproviderNotePadnotes

Asks the activity to create a new empty note in the notes list at

contentcomgoogleproviderNotePadnotes and allow the user to edit it If the user saves the

note its URI is returned to the caller

The last activity TitleEditor enables the user to edit the title of a note This could be implemented by

directly invoking the activity (by explicitly setting its component name in the Intent) without using an

intent filter But here we take the opportunity to show how to publish alternative operations on existing

data

ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The single intent filter for this activity uses a custom action called

comandroidnotepadactionEDIT_TITLE It must be invoked on a specific note (data type

vndandroidcursoritemvndgooglenote) like the previous VIEW and EDIT actions However here the

activity displays the title contained in the note data not the content of the note itself

In addition to supporting the usual DEFAULT category the title editor also supports two other standard

categories ALTERNATIVE and SELECTED_ALTERNATIVE These categories identify activities that

can be presented to users in a menu of options (much as the LAUNCHER category identifies activities

that should be presented to user in the application launcher) Note that the filter also supplies an

explicit label (via androidlabel=stringresolve_title) to better control what users see when

presented with this activity as an alternative action to the data they are currently viewing (For more

information on these categories and building options menus see the

PackageManagerqueryIntentActivityOptions() and MenuaddIntentOptions() methods)

Given these capabilities the following intent will resolve to the TitleEditor activity

action comandroidnotepadactionEDIT_TITLE

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the title associated with note ID and allow the user to edit the title

Processes and Threads

When an application component starts and the application does not have any other components

running the Android system starts a new Linux process for the application with a single thread of

execution By default all components of the same application run in the same process and thread

(called the main thread) If an application component starts and there already exists a process for

that application (because another component from the application exists) then the component is

started within that process and uses the same thread of execution However you can arrange for

different components in your application to run in separate processes and you can create additional

threads for any process

This document discusses how processes and threads work in an Android application

Processes

By default all components of the same application run in the same process and most applications

should not change this However if you find that you need to control which process a certain

component belongs to you can do so in the manifest file

The manifest entry for each type of component elementmdashltactivitygt ltservicegt ltreceivergt and

ltprovidergtmdashsupports an androidprocess attribute that can specify a process in which that component

should run You can set this attribute so that each component runs in its own process or so that some

components share a process while others do not You can also set androidprocess so that

components of different applications run in the same processmdashprovided that the applications share the

same Linux user ID and are signed with the same certificates

The ltapplicationgt element also supports an androidprocess attribute to set a default value that

applies to all components

Android might 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 thats killed are consequently destroyed A process is started again for those components

when theres again work for them to do

When deciding which processes to kill the Android system weighs their relative importance to the

user For example it more readily shuts down a process hosting activities that are no longer visible on

screen compared to a process hosting visible activities The decision whether to terminate a process

therefore depends on the state of the components running in that process The rules used to decide

which processes to terminate is discussed below

Process lifecycle

The Android system tries to maintain an application process for as long as possible but eventually

needs to remove old processes to reclaim memory for new or more important processes To determine

which processes to keep and which to kill the system places each process into an importance

hierarchy based on the components running in the process and the state of those components

Processes with the lowest importance are eliminated first then those with the next lowest importance

and so on as necessary to recover system resources

There are five levels in the importance hierarchy The following list presents the different types of

processes in order of importance (the first process is most important and is killed last)

1 Foreground process

A process that is required for what the user is currently doing A process is considered to be in the

foreground if any of the following conditions are true

o It hosts an Activity that the user is interacting with (the Activitys onResume() method has been called)

o It hosts a Service thats bound to the activity that the user is interacting with

o It hosts a Service thats running in the foregroundmdashthe service has called startForeground()

o It hosts a Service thats executing one of its lifecycle callbacks (onCreate() onStart() or onDestroy())

o It hosts a BroadcastReceiver thats executing its onReceive() method

Generally only a few foreground processes exist at any given time They are killed only as a last

resortmdashif memory is so low that they cannot all continue to run Generally at that point the device has

reached a memory paging state so killing some foreground processes is required to keep the user

interface responsive

2 Visible process

A process that doesnt have any foreground components but still can affect what the user sees on

screen A process is considered to be visible if either of the following conditions are true

o It hosts an Activity that is not in the foreground but is still visible to the user (its onPause() method has

been called) This might occur for example if the foreground activity started a dialog which allows the

previous activity to be seen behind it

o It hosts a Service thats bound to a visible (or foreground) activity

A visible process is considered extremely important and will not be killed unless doing so is required to

keep all foreground processes running

3 Service process

A process that is running a service that has been started with the startService() method and does not

fall into either of the two higher categories Although service processes are not directly tied to anything

the user sees they are generally doing things that the user cares about (such as playing music in the

background or downloading data on the network) so the system keeps them running unless theres

not enough memory to retain them along with all foreground and visible processes

4 Background process

A process holding an activity thats not currently visible to the user (the activitys onStop() method has

been called) These processes have no direct impact on the user experience and the system can kill

them at any time to reclaim memory for a foreground visible or service process Usually there are

many background processes running so they are kept in an LRU (least recently used) list to ensure

that the process with the activity that was most recently seen by the user is the last to be killed If an

activity implements its lifecycle methods correctly and saves its current state killing its process will not

have a visible effect on the user experience because when the user navigates back to the activity the

activity restores all of its visible state See the Activities document for information about saving and

restoring state

5 Empty process

A process that doesnt hold any active application components The only reason to keep this kind of

process alive is for caching purposes to improve startup time the next time a component needs to run

in it The system often kills these processes in order to balance overall system resources between

process caches and the underlying kernel caches

Android ranks a process at the highest level it can based upon the importance of the components

currently active in the process For example if a process hosts a service and a visible activity the

process is ranked as a visible process not a service process

In addition a processs ranking might be increased because other processes are dependent on itmdasha

process that is serving another process can never be ranked lower than the process it is serving For

example if a content provider in process A is serving a client in process B or if a service in process A

is bound to a component in process B process A is always considered at least as important as

process B

Because a process running a service is ranked higher than a process with background activities an

activity that initiates a long-running operation might do well to start a service for that operation rather

than simply create a worker threadmdashparticularly if the operation will likely outlast the activity For

example an activity thats uploading a picture to a web site should start a service to perform the

upload so that the upload can continue in the background even if the user leaves the activity Using a

service guarantees that the operation will have at least service process priority regardless of what

happens to the activity This is the same reason that broadcast receivers should employ services

rather than simply put time-consuming operations in a thread

Threads

When an application is launched the system creates a thread of execution for the application called

main This thread is very important because it is in charge of dispatching events to the appropriate

user interface widgets including drawing events It is also the thread in which your application interacts

with components from the Android UI toolkit (components from the androidwidget and androidview

packages) As such the main thread is also sometimes called the UI thread

The system does not create a separate thread for each instance of a component All components that

run in the same process are instantiated in the UI thread and system calls to each component are

dispatched from that thread Consequently methods that respond to system callbacks (such as

onKeyDown() to report user actions or a lifecycle callback method) always run in the UI thread of the

process

For instance when the user touches a button on the screen your apps UI thread dispatches the touch

event to the widget which in turn sets its pressed state and posts an invalidate request to the event

queue The UI thread dequeues the request and notifies the widget that it should redraw itself

When your app performs intensive work in response to user interaction this single thread model can

yield poor performance unless you implement your application properly Specifically if everything is

happening in the UI thread performing long operations such as network access or database queries

will block the whole UI When the thread is blocked no events can be dispatched including drawing

events From the users perspective the application appears to hang Even worse if the UI thread is

blocked for more than a few seconds (about 5 seconds currently) the user is presented with the

infamous application not responding (ANR) dialog The user might then decide to quit your

application and uninstall it if they are unhappy

Additionally the Andoid UI toolkit is not thread-safe So you must not manipulate your UI from a

worker threadmdashyou must do all manipulation to your user interface from the UI thread Thus there are

simply two rules to Androids single thread model

1 Do not block the UI thread

2 Do not access the Android UI toolkit from outside the UI thread

Worker threads

Because of the single thread model described above its vital to the responsiveness of your

applications UI that you do not block the UI thread If you have operations to perform that are not

instantaneous you should make sure to do them in separate threads (background or worker

threads)

For example below is some code for a click listener that downloads an image from a separate thread

and displays it in an ImageView

public void onClick(View v) new Thread(new Runnable() public void run() Bitmap b = loadImageFromNetwork(httpexamplecomimagepng) mImageViewsetImageBitmap(b) )start()

At first this seems to work fine because it creates a new thread to handle the network operation

However it violates the second rule of the single-threaded model do not access the Android UI toolkit

from outside the UI threadmdashthis sample modifies the ImageView from the worker thread instead of the

UI thread This can result in undefined and unexpected behavior which can be difficult and time-

consuming to track down

To fix this problem Android offers several ways to access the UI thread from other threads Here is a

list of methods that can help

ActivityrunOnUiThread(Runnable)

Viewpost(Runnable)

ViewpostDelayed(Runnable long)

For example you can fix the above code by using the Viewpost(Runnable) method

public void onClick(View v) new Thread(new Runnable() public void run() final Bitmap bitmap = loadImageFromNetwork(httpexamplecomimagepng) mImageViewpost(new Runnable() public void run() mImageViewsetImageBitmap(bitmap) ) )start()

Now this implementation is thread-safe the network operation is done from a separate thread while

the ImageView is manipulated from the UI thread

However as the complexity of the operation grows this kind of code can get complicated and difficult

to maintain To handle more complex interactions with a worker thread you might consider using a

Handler in your worker thread to process messages delivered from the UI thread Perhaps the best

solution though is to extend the AsyncTask class which simplifies the execution of worker thread

tasks that need to interact with the UI

Using AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface It performs the blocking

operations in a worker thread and then publishes the results on the UI thread without requiring you to

handle threads andor handlers yourself

To use it you must subclass AsyncTask and implement the doInBackground() callback method which

runs in a pool of background threads To update your UI you should implement onPostExecute()

which delivers the result from doInBackground() and runs in the UI thread so you can safely update

your UI You can then run the task by calling execute() from the UI thread

For example you can implement the previous example using AsyncTask this way

public void onClick(View v) new DownloadImageTask()execute(httpexamplecomimagepng) private class DownloadImageTask extends AsyncTaskltString Void Bitmapgt The system calls this to perform work in a worker thread and delivers it the parameters given to AsyncTaskexecute() protected Bitmap doInBackground(String urls) return loadImageFromNetwork(urls[0])

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 23: 03 services

onServiceDisconnected()

The Android system calls this when the connection to the service is unexpectedly lost such as

when the service has crashed or has been killed This is not called when the client unbinds

2 Call bindService() passing the ServiceConnection implementation

3 When the system calls your onServiceConnected() callback method you can begin making calls to the

service using the methods defined by the interface

4 To disconnect from the service call unbindService()

When your client is destroyed it will unbind from the service but you should always unbind when

youre done interacting with the service or when your activity pauses so that the service can shutdown

while its not being used (Appropriate times to bind and unbind is discussed more below)

For example the following snippet connects the client to the service created above by extending the

Binder class so all it must do is cast the returned IBinder to the LocalService class and request the

LocalService instance

LocalService mService private ServiceConnection mConnection = new ServiceConnection() Called when the connection with the service is established public void onServiceConnected(ComponentName className IBinder service) Because we have bound to an explicit service that is running in our own process we can cast its IBinder to a concrete class and directly access it LocalBinder binder = (LocalBinder) service mService = bindergetService() mBound = true Called when the connection with the service disconnects unexpectedly public void onServiceDisconnected(ComponentName className) Loge(TAG onServiceDisconnected) mBound = false

With this ServiceConnection the client can bind to a service by passing this it to bindService() For

example

Intent intent = new Intent(this LocalServiceclass) bindService(intent mConnection ContextBIND_AUTO_CREATE)

The first parameter of bindService() is an Intent that explicitly names the service to bind (thought the

intent could be implicit)

The second parameter is the ServiceConnection object

The third parameter is a flag indicating options for the binding It should usually be

BIND_AUTO_CREATE in order to create the service if its not already alive Other possible values are

BIND_DEBUG_UNBIND and BIND_NOT_FOREGROUND or 0 for none

Additional notes

Here are some important notes about binding to a service

You should always trap DeadObjectException exceptions which are thrown when the connection has

broken This is the only exception thrown by remote methods

Objects are reference counted across processes

You should usually pair the binding and unbinding during matching bring-up and tear-down moments

of the clients lifecycle For example

o If you only need to interact with the service while your activity is visible you should bind during

onStart() and unbind during onStop()

o If you want your activity to receive responses even while it is stopped in the background then you can

bind during onCreate() and unbind during onDestroy() Beware that this implies that your activity needs

to use the service the entire time its running (even in the background) so if the service is in another

process then you increase the weight of the process and it becomes more likely that the system will

kill it

Note You should usually not bind and unbind during your activitys onResume() and onPause()

because these callbacks occur at every lifecycle transition and you should keep the processing that

occurs at these transitions to a minimum Also if multiple activities in your application bind to the same

service and there is a transition between two of those activities the service may be destroyed and

recreated as the current activity unbinds (during pause) before the next one binds (during resume)

(This activity transition for how activities coordinate their lifecycles is described in the Activities

document)

For more sample code showing how to bind to a service see the RemoteServicejava class in

ApiDemos

Managing the Lifecycle of a Bound Service

Figure 1 The lifecycle for a service

that is started and also allows binding

When a service is unbound from all

clients the Android system destroys it

(unless it was also started with

onStartCommand()) As such you

dont have to manage the lifecycle of

your service if its purely a bound

servicemdashthe Android system manages

it for you based on whether it is bound

to any clients

However if you choose to implement

the onStartCommand() callback

method then you must explicitly stop

the service because the service is

now considered to be started In this

case the service runs until the service

stops itself with stopSelf() or another

component calls stopService()

regardless of whether it is bound to

any clients

Additionally if your service is started and accepts binding then when the system calls your onUnbind()

method you can optionally return true if you would like to receive a call to onRebind() the next time a

client binds to the service (instead of receiving a call to onBind()) onRebind() returns void but the

client still receives the IBinder in its onServiceConnected() callback Below figure 1 illustrates the logic

for this kind of lifecycle

For more information about the lifecycle of an started service see the Services document

Content Providers

Content providers store and retrieve data and make it accessible to all applications Theyre the only

way to share data across applications theres no common storage area that all Android packages can

access

Android ships with a number of content providers for common data types (audio video images

personal contact information and so on) You can see some of them listed in the androidprovider

package You can query these providers for the data they contain (although for some you must

acquire the proper permission to read the data)

If you want to make your own data public you have two options You can create your own content

provider (a ContentProvider subclass) or you can add the data to an existing provider mdash if theres one

that controls the same type of data and you have permission to write to it

This document is an introduction to using content providers After a brief discussion of the

fundamentals it explores how to query a content provider how to modify data controlled by a provider

and how to create a content provider of your own

Content Provider Basics

How a content provider actually stores its data under the covers is up to its designer But all content

providers implement a common interface for querying the provider and returning results mdash as well as

for adding altering and deleting data Its an interface that clients use indirectly most generally

through ContentResolver objects You get a ContentResolver by calling getContentResolver() from

within the implementation of an Activity or other application component

ContentResolver cr = getContentResolver()

You can then use the ContentResolvers methods to interact with whatever content providers youre

interested in When a query is initiated the Android system identifies the content provider thats the

target of the query and makes sure that it is up and running The system instantiates all

ContentProvider objects you never need to do it on your own In fact you never deal directly with

ContentProvider objects at all Typically theres just a single instance of each type of ContentProvider

But it can communicate with multiple ContentResolver objects in different applications and processes

The interaction between processes is handled by the ContentResolver and ContentProvider classes

The data model

Content providers expose their data as a simple table on a database model where each row is a

record and each column is data of a particular type and meaning For example information about

people and their phone numbers might be exposed as follows

_ID NUMBER NUMBER_KEY LABEL NAME TYPE

13 (425) 555 6677 425 555 6677 Kirkland office Bully Pulpit TYPE_WORK

44 (212) 555-1234 212 555 1234 NY apartment Alan Vain TYPE_HOME

45 (212) 555-6657 212 555 6657 Downtown office Alan Vain TYPE_MOBILE

53 2015554433 201 555 4433 Love Nest Rex Cars TYPE_HOME

Every record includes a numeric _ID field that uniquely identifies the record within the table IDs can be

used to match records in related tables mdash for example to find a persons phone number in one table

and pictures of that person in another

A query returns a Cursor object that can move from record to record and column to column to read the

contents of each field It has specialized methods for reading each type of data So to read a field you

must know what type of data the field contains (Theres more on query results and Cursor objects

later)

URIs

Each content provider exposes a public URI (wrapped as a Uri object) that uniquely identifies its data

set A content provider that controls multiple data sets (multiple tables) exposes a separate URI for

each one All URIs for providers begin with the string content The content scheme identifies the

data as being controlled by a content provider

If youre defining a content provider its a good idea to also define a constant for its URI to simplify

client code and make future updates cleaner Android defines CONTENT_URI constants for all the

providers that come with the platform For example the URI for the table that matches phone numbers

to people and the URI for the table that holds pictures of people (both controlled by the Contacts

content provider) are

androidproviderContactsPhonesCONTENT_URI

androidproviderContactsPhotosCONTENT_URI

The URI constant is used in all interactions with the content provider Every ContentResolver method

takes the URI as its first argument Its what identifies which provider the ContentResolver should talk

to and which table of the provider is being targeted

Querying a Content Provider

You need three pieces of information to query a content provider

The URI that identifies the provider

The names of the data fields you want to receive

The data types for those fields

If youre querying a particular record you also need the ID for that record

Making the query

To query a content provider you can use either the ContentResolverquery() method or the

ActivitymanagedQuery() method Both methods take the same set of arguments and both return a

Cursor object However managedQuery() causes the activity to manage the life cycle of the Cursor A

managed Cursor handles all of the niceties such as unloading itself when the activity pauses and

requerying itself when the activity restarts You can ask an Activity to begin managing an unmanaged

Cursor object for you by calling ActivitystartManagingCursor()

The first argument to either query() or managedQuery() is the provider URI mdash the CONTENT_URI

constant that identifies a particular ContentProvider and data set (see URIs earlier)

To restrict a query to just one record you can append the _ID value for that record to the URI mdash that

is place a string matching the ID as the last segment of the path part of the URI For example if the ID

is 23 the URI would be

content 23

There are some helper methods particularly ContentUriswithAppendedId() and

UriwithAppendedPath() that make it easy to append an ID to a URI Both are static methods that

return a Uri object with the ID added So for example if you were looking for record 23 in the database

of people contacts you might construct a query as follows

import androidproviderContactsPeople import androidcontentContentUris import androidnetUri import androiddatabaseCursor Use the ContentUris method to produce the base URI for the contact with _ID == 23 Uri myPerson = ContentUriswithAppendedId(PeopleCONTENT_URI 23) Alternatively use the Uri method to produce the base URI It takes a string rather than an integer Uri myPerson = UriwithAppendedPath(PeopleCONTENT_URI 23) Then query for this specific record Cursor cur = managedQuery(myPerson null null null null)

The other arguments to the query() and managedQuery() methods delimit the query in more detail

They are

The names of the data columns that should be returned A null value returns all columns Otherwise

only columns that are listed by name are returned All the content providers that come with the

platform define constants for their columns For example the androidproviderContactsPhones class

defines constants for the names of the columns in the phone table illustrated earlier ampmdash _ID

NUMBER NUMBER_KEY NAME and so on

A filter detailing which rows to return formatted as an SQL WHERE clause (excluding the WHERE

itself) A null value returns all rows (unless the URI limits the query to a single record)

Selection arguments

A sorting order for the rows that are returned formatted as an SQL ORDER BY clause (excluding the

ORDER BY itself) A null value returns the records in the default order for the table which may be

unordered

Lets look at an example query to retrieve a list of contact names and their primary phone numbers

import androidproviderContactsPeople import androiddatabaseCursor Form an array specifying which columns to return String[] projection = new String[] People_ID People_COUNT PeopleNAME PeopleNUMBER Get the base URI for the People table in the Contacts content provider Uri contacts = PeopleCONTENT_URI Make the query Cursor managedCursor = managedQuery(contacts projection Which columns to return null Which rows to return (all rows) null Selection arguments (none) Put the results in ascending order by name PeopleNAME + ASC)

This query retrieves data from the People table of the Contacts content provider It gets the name

primary phone number and unique record ID for each contact It also reports the number of records

that are returned as the _COUNT field of each record

The constants for the names of the columns are defined in various interfaces mdash _ID and _COUNT in

BaseColumns NAME in PeopleColumns and NUMBER in PhoneColumns The ContactsPeople

class implements each of these interfaces which is why the code example above could refer to them

using just the class name

What a query returns

A query returns a set of zero or more database records The names of the columns their default order

and their data types are specific to each content provider But every provider has an _ID column

which holds a unique numeric ID for each record Every provider can also report the number of records

returned as the _COUNT column its value is the same for all rows

Here is an example result set for the query in the previous section

_ID _COUNT NAME NUMBER

44 3 Alan Vain 212 555 1234

13 3 Bully Pulpit 425 555 6677

53 3 Rex Cars 201 555 4433

The retrieved data is exposed by a Cursor object that can be used to iterate backward or forward

through the result set You can use this object only to read the data To add modify or delete data

you must use a ContentResolver object

Reading retrieved data

The Cursor object returned by a query provides access to a recordset of results If you have queried

for a specific record by ID this set will contain only one value Otherwise it can contain multiple

values (If there are no matches it can also be empty) You can read data from specific fields in the

record but you must know the data type of the field because the Cursor object has a separate method

for reading each type of data mdash such as getString() getInt() and getFloat() (However for most types

if you call the method for reading strings the Cursor object will give you the String representation of

the data) The Cursor lets you request the column name from the index of the column or the index

number from the column name

The following snippet demonstrates reading names and phone numbers from the query illustrated

earlier

import androidproviderContactsPeople private void getColumnData(Cursor cur) if (curmoveToFirst()) String name String phoneNumber int nameColumn = curgetColumnIndex(PeopleNAME) int phoneColumn = curgetColumnIndex(PeopleNUMBER) String imagePath do Get the field values name = curgetString(nameColumn) phoneNumber = curgetString(phoneColumn) Do something with the values while (curmoveToNext())

If a query can return binary data such as an image or sound the data may be directly entered in the

table or the table entry for that data may be a string specifying a content URI that you can use to get

the data In general smaller amounts of data (say from 20 to 50K or less) are most often directly

entered in the table and can be read by calling CursorgetBlob() It returns a byte array

If the table entry is a content URI you should never try to open and read the file directly (for one thing

permissions problems can make this fail) Instead you should call ContentResolveropenInputStream()

to get an InputStream object that you can use to read the data

Modifying Data

Data kept by a content provider can be modified by

Adding new records

Adding new values to existing records

Batch updating existing records

Deleting records

All data modification is accomplished using ContentResolver methods Some content providers require

a more restrictive permission for writing data than they do for reading it If you dont have permission to

write to a content provider the ContentResolver methods will fail

Adding records

To add a new record to a content provider first set up a map of key-value pairs in a ContentValues

object where each key matches the name of a column in the content provider and the value is the

desired value for the new record in that column Then call ContentResolverinsert() and pass it the URI

of the provider and the ContentValues map This method returns the full URI of the new record mdash that

is the providers URI with the appended ID for the new record You can then use this URI to query and

get a Cursor over the new record and to further modify the record Heres an example

import androidproviderContactsPeople import androidcontentContentResolver import androidcontentContentValues ContentValues values = new ContentValues() Add Abraham Lincoln to contacts and make him a favorite valuesput(PeopleNAME Abraham Lincoln) 1 = the new contact is added to favorites 0 = the new contact is not added to favorites valuesput(PeopleSTARRED 1) Uri uri = getContentResolver()insert(PeopleCONTENT_URI values)

Adding new values

Once a record exists you can add new information to it or modify existing information For example

the next step in the example above would be to add contact information mdash like a phone number or an

IM or e-mail address mdash to the new entry

The best way to add to a record in the Contacts database is to append the name of the table where the

new data goes to the URI for the record then use the amended URI to add the new data values Each

Contacts table exposes a name for this purpose as a CONTENT_DIRECTORY constant The following

code continues the previous example by adding a phone number and e-mail address for the record

just created

Uri phoneUri = null Uri emailUri = null Add a phone number for Abraham Lincoln Begin with the URI for the new record just returned by insert() it ends with the _ID of the new record so we dont have to add the ID ourselves Then append the designation for the phone table to this URI and use the resulting URI to insert the phone number phoneUri = UriwithAppendedPath(uri PeoplePhonesCONTENT_DIRECTORY) valuesclear() valuesput(PeoplePhonesTYPE PeoplePhonesTYPE_MOBILE) valuesput(PeoplePhonesNUMBER 1233214567) getContentResolver()insert(phoneUri values) Now add an email address in the same way emailUri = UriwithAppendedPath(uri PeopleContactMethodsCONTENT_DIRECTORY) valuesclear() ContactMethodsKIND is used to distinguish different kinds of contact methods such as email IM etc valuesput(PeopleContactMethodsKIND ContactsKIND_EMAIL) valuesput(PeopleContactMethodsDATA testexamplecom) valuesput(PeopleContactMethodsTYPE PeopleContactMethodsTYPE_HOME) getContentResolver()insert(emailUri values)

You can place small amounts of binary data into a table by calling the version of ContentValuesput()

that takes a byte array That would work for a small icon-like image or a short audio clip for example

However if you have a large amount of binary data to add such as a photograph or a complete song

put a content URI for the data in the table and call ContentResolveropenOutputStream() with the files

URI (That causes the content provider to store the data in a file and record the file path in a hidden

field of the record)

In this regard the MediaStore content provider the main provider that dispenses image audio and

video data employs a special convention The same URI that is used with query() or managedQuery()

to get meta-information about the binary data (such as the caption of a photograph or the date it was

taken) is used with openInputStream() to get the data itself Similarly the same URI that is used with

insert() to put meta-information into a MediaStore record is used with openOutputStream() to place the

binary data there The following code snippet illustrates this convention

import androidproviderMediaStoreImagesMedia import androidcontentContentValues import javaioOutputStream Save the name and description of an image in a ContentValues map ContentValues values = new ContentValues(3) valuesput(MediaDISPLAY_NAME road_trip_1) valuesput(MediaDESCRIPTION Day 1 trip to Los Angeles) valuesput(MediaMIME_TYPE imagejpeg) Add a new record without the bitmap but with the values just set insert() returns the URI of the new record Uri uri = getContentResolver()insert(MediaEXTERNAL_CONTENT_URI values) Now get a handle to the file for that record and save the data into it Here sourceBitmap is a Bitmap object representing the file to save to the database try OutputStream outStream = getContentResolver()openOutputStream(uri) sourceBitmapcompress(BitmapCompressFormatJPEG 50 outStream) outStreamclose() catch (Exception e) Loge(TAG exception while writing image e)

Batch updating records

To batch update a group of records (for example to change NY to New York in all fields) call the

ContentResolverupdate() method with the columns and values to change

Deleting a record

To delete a single record call ContentResolverdelete() with the URI of a specific row

To delete multiple rows call ContentResolverdelete() with the URI of the type of record to delete (for

example androidproviderContactsPeopleCONTENT_URI) and an SQL WHERE clause defining

which rows to delete (Caution Be sure to include a valid WHERE clause if youre deleting a general

type or you risk deleting more records than you intended)

Creating a Content Provider

To create a content provider you must

Set up a system for storing the data Most content providers store their data using Androids file

storage methods or SQLite databases but you can store your data any way you want Android

provides the SQLiteOpenHelper class to help you create a database and SQLiteDatabase to manage

it

Extend the ContentProvider class to provide access to the data

Declare the content provider in the manifest file for your application (AndroidManifestxml)

The following sections have notes on the last two of these tasks

Extending the ContentProvider class

You define a ContentProvider subclass to expose your data to others using the conventions expected

by ContentResolver and Cursor objects Principally this means implementing six abstract methods

declared in the ContentProvider class

query()

insert()

update()

delete()

getType()

onCreate()

The query() method must return a Cursor object that can iterate over the requested data Cursor itself

is an interface but Android provides some ready-made Cursor objects that you can use For example

SQLiteCursor can iterate over data stored in an SQLite database You get the Cursor object by calling

any of the SQLiteDatabase classs query() methods There are other Cursor implementations mdash such

as MatrixCursor mdash for data not stored in a database

Because these ContentProvider methods can be called from various ContentResolver objects in

different processes and threads they must be implemented in a thread-safe manner

As a courtesy you might also want to call ContentResolvernotifyChange() to notify listeners when

there are modifications to the data

Beyond defining the subclass itself there are other steps you should take to simplify the work of clients

and make the class more accessible

Define a public static final Uri named CONTENT_URI This is the string that represents the full content

URI that your content provider handles You must define a unique string for this value The best

solution is to use the fully-qualified class name of the content provider (made lowercase) So for

example the URI for a TransportationProvider class could be defined as follows

public static final Uri CONTENT_URI = Uriparse(contentcomexamplecodelabtransportationprovider)

If the provider has subtables also define CONTENT_URI constants for each of the subtables These

URIs should all have the same authority (since that identifies the content provider) and be

distinguished only by their paths For example

contentcomexamplecodelabtransportationprovidertrain

contentcomexamplecodelabtransportationproviderairdomestic

contentcomexamplecodelabtransportationproviderairinternational

For an overview of content URIs see the Content URI Summary at the end of this document

Define the column names that the content provider will return to clients If you are using an underlying

database these column names are typically identical to the SQL database column names they

represent Also define public static String constants that clients can use to specify the columns in

queries and other instructions

Be sure to include an integer column named _id (with the constant _ID) for the IDs of the records

You should have this field whether or not you have another field (such as a URL) that is also unique

among all records If youre using the SQLite database the _ID field should be the following type

INTEGER PRIMARY KEY AUTOINCREMENT

The AUTOINCREMENT descriptor is optional But without it SQLite increments an ID counter field to

the next number above the largest existing number in the column If you delete the last row the next

row added will have the same ID as the deleted row AUTOINCREMENT avoids this by having SQLite

increment to the next largest value whether deleted or not

Carefully document the data type of each column Clients need this information to read the data

If you are handling a new data type you must define a new MIME type to return in your

implementation of ContentProvidergetType() The type depends in part on whether or not the content

URI submitted to getType() limits the request to a specific record Theres one form of the MIME type

for a single record and another for multiple records Use the Uri methods to help determine what is

being requested Here is the general format for each type

o For a single record vndandroidcursoritemvndyourcompanynamecontenttype

For example a request for train record 122 like this URI

contentcomexampletransportationprovidertrains122

might return this MIME type

vndandroidcursoritemvndexamplerail

o For multiple records vndandroidcursordirvndyourcompanynamecontenttype

For example a request for all train records like the following URI

contentcomexampletransportationprovidertrains

might return this MIME type

vndandroidcursordirvndexamplerail

If you are exposing byte data thats too big to put in the table itself mdash such as a large bitmap file mdash the

field that exposes the data to clients should actually contain a content URI string This is the field that

gives clients access to the data file The record should also have another field named _data that lists

the exact file path on the device for that file This field is not intended to be read by the client but by

the ContentResolver The client will call ContentResolveropenInputStream() on the user-facing field

holding the URI for the item The ContentResolver will request the _data field for that record and

because it has higher permissions than a client it should be able to access that file directly and return

a read wrapper for the file to the client

For an example of a private content provider implementation see the NodePadProvider class in the

Notepad sample application that ships with the SDK

Declaring the content provider

To let the Android system know about the content provider youve developed declare it with a

ltprovidergt element in the applications AndroidManifestxml file Content providers that are not

declared in the manifest are not visible to the Android system

The name attribute is the fully qualified name of the ContentProvider subclass The authorities attribute

is the authority part of the content URI that identifies the provider For example if the ContentProvider

subclass is AutoInfoProvider the ltprovidergt element might look like this

ltprovider androidname=comexampleautosAutoInfoProvider androidauthorities=comexampleautosautoinfoprovider gt ltprovidergt

Note that the authorities attribute omits the path part of a content URI For example if

AutoInfoProvider controlled subtables for different types of autos or different manufacturers

contentcomexampleautosautoinfoproviderhonda

contentcomexampleautosautoinfoprovidergmcompact

contentcomexampleautosautoinfoprovidergmsuv

those paths would not be declared in the manifest The authority is what identifies the provider not the

path your provider can interpret the path part of the URI in any way you choose

Other ltprovidergt attributes can set permissions to read and write data provide for an icon and text

that can be displayed to users enable and disable the provider and so on Set the multiprocess

attribute to true if data does not need to be synchronized between multiple running versions of the

content provider This permits an instance of the provider to be created in each client process

eliminating the need to perform IPC

Content URI Summary

Here is a recap of the important parts of a content URI

A Standard prefix indicating that the data is controlled by a content provider Its never modified

B The authority part of the URI it identifies the content provider For third-party applications this should

be a fully-qualified class name (reduced to lowercase) to ensure uniqueness The authority is declared

in the ltprovidergt elements authorities attribute

ltprovider androidname=TransportationProvider androidauthorities=comexampletransportationprovider gt

C The path that the content provider uses to determine what kind of data is being requested This can be

zero or more segments long If the content provider exposes only one type of data (only trains for

example) it can be absent If the provider exposes several types including subtypes it can be several

segments long mdash for example landbus landtrain seaship and seasubmarine to give four

possibilities

D The ID of the specific record being requested if any This is the _ID value of the requested record If

the request is not limited to a single record this segment and the trailing slash are omitted

contentcomexampletransportationprovidertrains

Intent and intent filters

Three of the core components of an application mdash activities services and broadcast receivers mdash 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 mdash 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 ContextstartActivity() or ActivitystartActivityForResult() to launch an

activity or get an existing activity to do something new (It can also be passed to ActivitysetResult() to

return information to the activity that called startActivityForResult())

An Intent object is passed to ContextstartService() to initiate a service or deliver new instructions to an

ongoing service Similarly an intent can be passed to ContextbindService() to establish a connection

between the calling component and a target service It can optionally initiate the service if its not

already running

Intent objects passed to any of the broadcast methods (such as ContextsendBroadcast()

ContextsendOrderedBroadcast() or ContextsendStickyBroadcast()) 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 mdash how it resolves which component should receive an intent message For

intents that dont explicitly name a target component this process involves testing the Intent object

against intent filters associated with potential targets

Intent Objects

An Intent object is a bundle of information It contains information of interest to the component that

receives the intent (such as the action to be taken and the data to act on) plus information of interest to

the Android system (such as the category of component that should handle the intent and instructions

on how to launch a target activity) Principally it can contain the following

Component name

The name of the component that should handle the intent This field is a ComponentName

object mdash a combination of the fully qualified class name of the target component (for example

comexampleprojectappFreneticActivity) and the package name set in the manifest file of the

application where the component resides (for example comexampleproject) The package

part of the component name and the package name set in the manifest do not necessarily have

to match

The component name is optional If it is set the Intent object is delivered to an instance of the

designated class If it is not set Android uses other information in the Intent object to locate a

suitable target mdash see Intent Resolution later in this document

The component name is set by setComponent() setClass() or setClassName() and read by

getComponent()

Action

A string naming the action to be performed mdash or in the case of broadcast intents the action

that took place and is being reported The Intent class defines a number of action constants

including these

Constant Target

component

Action

ACTION_CALL activity Initiate a phone call

ACTION_EDIT activity Display data for the user to edit

ACTION_MAIN activity Start up as the initial activity of a task

with no data input and no returned

output

ACTION_SYNC activity Synchronize data on a server with

data on the mobile device

ACTION_BATTERY_LOW broadcast

receiver

A warning that the battery is low

ACTION_HEADSET_PLUG broadcast

receiver

A headset has been plugged into the

device or unplugged from it

ACTION_SCREEN_ON broadcast

receiver

The screen has been turned on

ACTION_TIMEZONE_CHANGED broadcast

receiver

The setting for the time zone has

changed

See the Intent class description for a list of pre-defined constants for generic actions Other

actions are defined elsewhere in the Android API You can also define your own action strings

for activating the components in your application Those you invent should include the

application package as a prefix mdash for example comexampleprojectSHOW_COLOR

The action largely determines how the rest of the intent is structured mdash particularly the data and

extras fields mdash much as a method name determines a set of arguments and a return value For

this reason its a good idea to use action names that are as specific as possible and to couple

them tightly to the other fields of the intent In other words instead of defining an action in

isolation define an entire protocol for the Intent objects your components can handle

The action in an Intent object is set by the setAction() method and read by getAction()

Data

The URI of the data to be acted on and the MIME type of that data Different actions are paired

with different kinds of data specifications For example if the action field is ACTION_EDIT the

data field would contain the URI of the document to be displayed for editing If the action is

ACTION_CALL the data field would be a tel URI with the number to call Similarly if the action

is ACTION_VIEW and the data field is an http URI the receiving activity would be called upon

to download and display whatever data the URI refers to

When matching an intent to a component that is capable of handling the data its often

important to know the type of data (its MIME type) in addition to its URI For example a

component able to display image data should not be called upon to play an audio file

In many cases the data type can be inferred from the URI mdash particularly content URIs which

indicate that the data is located on the device and controlled by a content provider (see the

separate discussion on content providers) But the type can also be explicitly set in the Intent

object The setData() method specifies data only as a URI setType() specifies it only as a

MIME type and setDataAndType() specifies it as both a URI and a MIME type The URI is read

by getData() and the type by getType()

Category

A string containing additional information about the kind of component that should handle the

intent Any number of category descriptions can be placed in an Intent object As it does for

actions the Intent class defines several category constants including these

Constant Meaning

CATEGORY_BROWSABLE The target activity can be safely invoked by the browser to

display data referenced by a link mdash for example an image or

an e-mail message

CATEGORY_GADGET The activity can be embedded inside of another activity that

hosts gadgets

CATEGORY_HOME The activity displays the home screen the first screen the

user sees when the device is turned on or when the HOME

key is pressed

CATEGORY_LAUNCHER The activity can be the initial activity of a task and is listed in

the top-level application launcher

CATEGORY_PREFERENCE The target activity is a preference panel

See the Intent class description for the full list of categories

The addCategory() method places a category in an Intent object removeCategory() deletes a

category previously added and getCategories() gets the set of all categories currently in the

object

Extras

Key-value pairs for additional information that should be delivered to the component handling

the intent Just as some actions are paired with particular kinds of data URIs some are paired

with particular extras For example an ACTION_TIMEZONE_CHANGED intent has a time-

zone extra that identifies the new time zone and ACTION_HEADSET_PLUG has a state

extra indicating whether the headset is now plugged in or unplugged as well as a name extra

for the type of headset If you were to invent a SHOW_COLOR action the color value would be

set in an extra key-value pair

The Intent object has a series of put() methods for inserting various types of extra data and a

similar set of get() methods for reading the data These methods parallel those for Bundle

objects In fact the extras can be installed and read as a Bundle using the putExtras() and

getExtras() methods

Flags

Flags of various sorts Many instruct the Android system how to launch an activity (for example

which task the activity should belong to) and how to treat it after its launched (for example

whether it belongs in the list of recent activities) All these flags are defined in the Intent class

The Android system and the applications that come with the platform employ Intent objects both to

send out system-originated broadcasts and to activate system-defined components To see how to

structure an intent to activate a system component consult the list of intents in the reference

Intent Resolution

Intents can be divided into two groups

Explicit intents designate the target component by its name (the component name field mentioned

earlier has a value set) Since component names would generally not be known to developers of other

applications explicit intents are typically used for application-internal messages mdash such as an activity

starting a subordinate service or launching a sister activity

Implicit intents do not name a target (the field for the component name is blank) Implicit intents are

often used to activate components in other applications

Android delivers an explicit intent to an instance of the designated target class Nothing in the Intent

object other than the component name matters for determining which component should get the intent

A different strategy is needed for implicit intents In the absence of a designated target the Android

system must find the best component (or components) to handle the intent mdash a single activity or

service to perform the requested action or the set of broadcast receivers to respond to the broadcast

announcement It does so by comparing the contents of the Intent object to intent filters structures

associated with components that can potentially receive intents Filters advertise the capabilities of a

component and delimit the intents it can handle They open the component to the possibility of

receiving implicit intents of the advertised type If a component does not have any intent filters it can

receive only explicit intents A component with filters can receive both explicit and implicit intents

Only three aspects of an Intent object are consulted when the object is tested against an intent filter

action

data (both URI and data type)

category

The extras and flags play no part in resolving which component receives an intent

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 mdash but only unwanted implicit intents (those that dont 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

components 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 mdash 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 Pads filters are described in the Note Pad Example

section later)

Filters and security

An intent filter cannot be relied on for security While it opens a component to receiving only certain

kinds of implicit intents it does nothing to prevent explicit intents from targeting the component Even

though a filter restricts the intents a component will be asked to handle to certain actions and data

sources someone could always put together an explicit intent with a different action and data source

and name the component as the target

An intent filter is an instance of the IntentFilter class However since the Android system must know

about the capabilities of a component before it can launch that component intent filters are generally

not set up in Java code but in the applications manifest file (AndroidManifestxml) as ltintent-filtergt

elements (The one exception would be filters for broadcast receivers that are registered dynamically

by calling ContextregisterReceiver() they are directly created as IntentFilter objects)

A filter has fields that parallel the action data and category fields of an Intent object An implicit intent

is tested against the filter in all three areas To be delivered to the component that owns the filter it

must pass all three tests If it fails even one of them the Android system wont deliver it to the

component mdash at least not on the basis of that filter However since a component can have multiple

intent filters an intent that does not pass through one of a components filters might make it through on

another

Each of the three tests is described in detail below

Action test

An ltintent-filtergt element in the manifest file lists actions as ltactiongt subelements For

example

ltintent-filter gt ltaction androidname=comexampleprojectSHOW_CURRENT gt ltaction androidname=comexampleprojectSHOW_RECENT gt ltaction androidname=comexampleprojectSHOW_PENDING gt ltintent-filtergt

As the example shows while an Intent object names just a single action a filter may list more

than one The list cannot be empty a filter must contain at least one ltactiongt element or it will

block all intents

To pass this test the action specified in the Intent object must match one of the actions listed in

the filter If the object or the filter does not specify an action the results are as follows

If the filter fails to list any actions there is nothing for an intent to match so all intents fail the

test No intents can get through the filter

On the other hand an Intent object that doesnt specify an action automatically passes the test

mdash as long as the filter contains at least one action

Category test

An ltintent-filtergt element also lists categories as subelements For example

ltintent-filter gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryBROWSABLE gt ltintent-filtergt

Note that the constants described earlier for actions and categories are not used in the manifest

file The full string values are used instead For instance the

androidintentcategoryBROWSABLE string in the example above corresponds to the

CATEGORY_BROWSABLE constant mentioned earlier in this document Similarly the string

androidintentactionEDIT corresponds to the ACTION_EDIT constant

For an intent to pass the category test every category in the Intent object must match a

category in the filter The filter can list additional categories but it cannot omit any that are in the

intent

In principle therefore an Intent object with no categories should always pass this test

regardless of whats in the filter Thats mostly true However with one exception Android treats

all implicit intents passed to startActivity() as if they contained at least one category

androidintentcategoryDEFAULT (the CATEGORY_DEFAULT constant) Therefore activities

that are willing to receive implicit intents must include androidintentcategoryDEFAULT in

their intent filters (Filters with androidintentactionMAIN and

androidintentcategoryLAUNCHER settings are the exception They mark activities that begin

new tasks and that are represented on the launcher screen They can include

androidintentcategoryDEFAULT in the list of categories but dont need to) See Using intent

matching later for more on these filters)

Data test

Like the action and categories the data specification for an intent filter is contained in a

subelement And as in those cases the subelement can appear multiple times or not at all For

example

ltintent-filter gt ltdata androidmimeType=videompeg androidscheme=http gt ltdata androidmimeType=audiompeg androidscheme=http gt ltintent-filtergt

Each ltdatagt element can specify a URI and a data type (MIME media type) There are

separate attributes mdash scheme host port and path mdash for each part of the URI

schemehostportpath

For example in the following URI

contentcomexampleproject200foldersubfolderetc

the scheme is content the host is comexampleproject the port is 200 and the path is

foldersubfolderetc The host and port together constitute the URI authority if a host is not

specified the port is ignored

Each of these attributes is optional but they are not independent of each other For an authority

to be meaningful a scheme must also be specified For a path to be meaningful both a scheme

and an authority must be specified

When the URI in an Intent object is compared to a URI specification in a filter its compared

only to the parts of the URI actually mentioned in the filter For example if a filter specifies only

a scheme all URIs with that scheme match the filter If a filter specifies a scheme and an

authority but no path all URIs with the same scheme and authority match regardless of their

paths If a filter specifies a scheme an authority and a path only URIs with the same scheme

authority and path match However a path specification in the filter can contain wildcards to

require only a partial match of the path

The type attribute of a ltdatagt element specifies the MIME type of the data Its more common in

filters than a URI Both the Intent object and the filter can use a wildcard for the subtype field

mdash for example text or audio mdash indicating any subtype matches

The data test compares both the URI and the data type in the Intent object to a URI and data

type specified in the filter The rules are as follows

a An Intent object that contains neither a URI nor a data type passes the test only if the filter

likewise does not specify any URIs or data types

b An Intent object that contains a URI but no data type (and a type cannot be inferred from the

URI) passes the test only if its URI matches a URI in the filter and the filter likewise does not

specify a type This will be the case only for URIs like mailto and tel that do not refer to actual

data

c An Intent object that contains a data type but not a URI passes the test only if the filter lists the

same data type and similarly does not specify a URI

d An Intent object that contains both a URI and a data type (or a data type can be inferred from

the URI) passes the data type part of the test only if its type matches a type listed in the filter It

passes the URI part of the test either if its URI matches a URI in the filter or if it has a content

or file URI and the filter does not specify a URI In other words a component is presumed to

support content and file data if its filter lists only a data type

If an intent can pass through the filters of more than one activity or service the user may be asked

which component to activate An exception is raised if no target can be found

Common cases

The last rule shown above for the data test rule (d) reflects the expectation that components are able

to get local data from a file or content provider Therefore their filters can list just a data type and do

not need to explicitly name the content and file schemes This is a typical case A ltdatagt element like

the following for example tells Android that the component can get image data from a content

provider and display it

ltdata androidmimeType=image gt

Since most available data is dispensed by content providers filters that specify a data type but not a

URI are perhaps the most common

Another common configuration is filters with a scheme and a data type For example a ltdatagt

element like the following tells Android that the component can get video data from the network and

display it

ltdata androidscheme=http androidtype=video gt

Consider for example what the browser application does when the user follows a link on a web page

It first tries to display the data (as it could if the link was to an HTML page) If it cant display the data it

puts together an implicit intent with the scheme and data type and tries to start an activity that can do

the job If there are no takers it asks the download manager to download the data That puts it under

the control of a content provider so a potentially larger pool of activities (those with filters that just

name a data type) can respond

Most applications also have a way to start fresh without a reference to any particular data Activities

that can initiate applications have filters with androidintentactionMAIN specified as the action If

they are to be represented in the application launcher they also specify the

androidintentcategoryLAUNCHER category

ltintent-filter gt ltaction androidname=code androidintentactionMAIN gt ltcategory androidname=code androidintentcategoryLAUNCHER gt ltintent-filtergt

Using intent matching

Intents are matched against intent filters not only to discover a target component to activate but also

to discover something about the set of components on the device For example the Android system

populates the application launcher the top-level screen that shows the applications that are available

for the user to launch by finding all the activities with intent filters that specify the

androidintentactionMAIN action and androidintentcategoryLAUNCHER category (as illustrated

in the previous section) It then displays the icons and labels of those activities in the launcher

Similarly it discovers the home screen by looking for the activity with androidintentcategoryHOME

in its filter

Your application can use intent matching is a similar way The PackageManager has a set of query()

methods that return all components that can accept a particular intent and a similar series of

resolve() methods that determine the best component to respond to an intent For example

queryIntentActivities() returns a list of all activities that can perform the intent passed as an argument

and queryIntentServices() returns a similar list of services Neither method activates the components

they just list the ones that can respond Theres a similar method queryBroadcastReceivers() for

broadcast receivers

Note Pad Example

The Note Pad sample application enables users to browse through a list of notes view details about

individual items in the list edit the items and add a new item to the list This section looks at the intent

filters declared in its manifest file (If youre working offline in the SDK you can find all the source files

for this sample application including its manifest file at ltsdkgtsamplesNotePadindexhtml If youre

viewing the documentation online the source files are in the Tutorials and Sample Code section here)

In its manifest file the Note Pad application declares three activities each with at least one intent filter

It also declares a content provider that manages the note data Here is the manifest file in its entirety

ltmanifest xmlnsandroid=httpschemasandroidcomapkresandroid package=comexampleandroidnotepadgt ltapplication androidicon=drawableapp_notes androidlabel=stringapp_name gt ltprovider androidname=NotePadProvider androidauthorities=comgoogleproviderNotePad gt ltactivity androidname=NotesList androidlabel=stringtitle_notes_listgt ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltactivity androidname=NoteEditor androidtheme=androidstyleThemeLight androidlabel=stringtitle_note gt ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltactivitygt

ltactivity androidname=TitleEditor androidlabel=stringtitle_edit_title androidtheme=androidstyleThemeDialoggt ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltapplicationgt ltmanifestgt

The first activity NotesList is distinguished from the other activities by the fact that it operates on a

directory of notes (the note list) rather than on a single note It would generally serve as the initial user

interface into the application It can do three things as described by its three intent filters

1 ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt

This filter declares the main entry point into the Note Pad application The standard MAIN action is an

entry point that does not require any other information in the Intent (no data specification for example)

and the LAUNCHER category says that this entry point should be listed in the application launcher

2 ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

This filter declares the things that the activity can do on a directory of notes It can allow the user to

view or edit the directory (via the VIEW and EDIT actions) or to pick a particular note from the

directory (via the PICK action)

The mimeType attribute of the ltdatagt element specifies the kind of data that these actions operate on

It indicates that the activity can get a Cursor over zero or more items (vndandroidcursordir) from a

content provider that holds Note Pad data (vndgooglenote) The Intent object that launches the

activity would include a content URI specifying the exact data of this type that the activity should open

Note also the DEFAULT category supplied in this filter Its there because the ContextstartActivity()

and ActivitystartActivityForResult() methods treat all intents as if they contained the DEFAULT

category mdash with just two exceptions

o Intents that explicitly name the target activity

o Intents consisting of the MAIN action and LAUNCHER category

Therefore the DEFAULT category is required for all filters mdash except for those with the MAIN action

and LAUNCHER category (Intent filters are not consulted for explicit intents)

3 ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

This filter describes the activitys ability to return a note selected by the user without requiring any

specification of the directory the user should choose from The GET_CONTENT action is similar to the

PICK action In both cases the activity returns the URI for a note selected by the user (In each case

its returned to the activity that called startActivityForResult() to start the NoteList activity) Here

however the caller specifies the type of data desired instead of the directory of data the user will be

picking from

The data type vndandroidcursoritemvndgooglenote indicates the type of data the activity can

return mdash a URI for a single note From the returned URI the caller can get a Cursor for exactly one

item (vndandroidcursoritem) from the content provider that holds Note Pad data (vndgooglenote)

In other words for the PICK action in the previous filter the data type indicates the type of data the

activity could display to the user For the GET_CONTENT filter it indicates the type of data the activity

can return to the caller

Given these capabilities the following intents will resolve to the NotesList activity

action androidintentactionMAIN

Launches the activity with no data specified

action androidintentactionMAIN

category androidintentcategoryLAUNCHER

Launches the activity with no data selected specified This is the actual intent used by the

Launcher to populate its top-level list All activities with filters that match this action and

category are added to the list

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of all the notes under

contentcomgoogleproviderNotePadnotes The user can then browse through the list and

get information about the items in it

action androidintentactionPICK

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of the notes under

contentcomgoogleproviderNotePadnotes The user can then pick a note from the list and

the activity will return the URI for that item back to the activity that started the NoteList activity

action androidintentactionGET_CONTENT

data type vndandroidcursoritemvndgooglenote

Asks the activity to supply a single item of Note Pad data

The second activity NoteEditor shows users a single note entry and allows them to edit it It can do

two things as described by its two intent filters

1 ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The first primary purpose of this activity is to enable the user to interact with a single note ampmdash to

either VIEW the note or EDIT it (The EDIT_NOTE category is a synonym for EDIT) The intent would

contain the URI for data matching the MIME type vndandroidcursoritemvndgooglenote mdash that is

the URI for a single specific note It would typically be a URI that was returned by the PICK or

GET_CONTENT actions of the NoteList activity

As before this filter lists the DEFAULT category so that the activity can be launched by intents that

dont explicitly specify the NoteEditor class

2 ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

The secondary purpose of this activity is to enable the user to create a new note which it will INSERT

into an existing directory of notes The intent would contain the URI for data matching the MIME type

vndandroidcursordirvndgooglenote mdash that is the URI for the directory where the note should be

placed

Given these capabilities the following intents will resolve to the NoteEditor activity

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID (For details on how content

URIs specify individual members of a group see Content Providers)

action androidintentactionEDIT

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID and to let the user edit it If

the user saves the changes the activity updates the data for the note in the content provider

action androidintentactionINSERT

data contentcomgoogleproviderNotePadnotes

Asks the activity to create a new empty note in the notes list at

contentcomgoogleproviderNotePadnotes and allow the user to edit it If the user saves the

note its URI is returned to the caller

The last activity TitleEditor enables the user to edit the title of a note This could be implemented by

directly invoking the activity (by explicitly setting its component name in the Intent) without using an

intent filter But here we take the opportunity to show how to publish alternative operations on existing

data

ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The single intent filter for this activity uses a custom action called

comandroidnotepadactionEDIT_TITLE It must be invoked on a specific note (data type

vndandroidcursoritemvndgooglenote) like the previous VIEW and EDIT actions However here the

activity displays the title contained in the note data not the content of the note itself

In addition to supporting the usual DEFAULT category the title editor also supports two other standard

categories ALTERNATIVE and SELECTED_ALTERNATIVE These categories identify activities that

can be presented to users in a menu of options (much as the LAUNCHER category identifies activities

that should be presented to user in the application launcher) Note that the filter also supplies an

explicit label (via androidlabel=stringresolve_title) to better control what users see when

presented with this activity as an alternative action to the data they are currently viewing (For more

information on these categories and building options menus see the

PackageManagerqueryIntentActivityOptions() and MenuaddIntentOptions() methods)

Given these capabilities the following intent will resolve to the TitleEditor activity

action comandroidnotepadactionEDIT_TITLE

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the title associated with note ID and allow the user to edit the title

Processes and Threads

When an application component starts and the application does not have any other components

running the Android system starts a new Linux process for the application with a single thread of

execution By default all components of the same application run in the same process and thread

(called the main thread) If an application component starts and there already exists a process for

that application (because another component from the application exists) then the component is

started within that process and uses the same thread of execution However you can arrange for

different components in your application to run in separate processes and you can create additional

threads for any process

This document discusses how processes and threads work in an Android application

Processes

By default all components of the same application run in the same process and most applications

should not change this However if you find that you need to control which process a certain

component belongs to you can do so in the manifest file

The manifest entry for each type of component elementmdashltactivitygt ltservicegt ltreceivergt and

ltprovidergtmdashsupports an androidprocess attribute that can specify a process in which that component

should run You can set this attribute so that each component runs in its own process or so that some

components share a process while others do not You can also set androidprocess so that

components of different applications run in the same processmdashprovided that the applications share the

same Linux user ID and are signed with the same certificates

The ltapplicationgt element also supports an androidprocess attribute to set a default value that

applies to all components

Android might 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 thats killed are consequently destroyed A process is started again for those components

when theres again work for them to do

When deciding which processes to kill the Android system weighs their relative importance to the

user For example it more readily shuts down a process hosting activities that are no longer visible on

screen compared to a process hosting visible activities The decision whether to terminate a process

therefore depends on the state of the components running in that process The rules used to decide

which processes to terminate is discussed below

Process lifecycle

The Android system tries to maintain an application process for as long as possible but eventually

needs to remove old processes to reclaim memory for new or more important processes To determine

which processes to keep and which to kill the system places each process into an importance

hierarchy based on the components running in the process and the state of those components

Processes with the lowest importance are eliminated first then those with the next lowest importance

and so on as necessary to recover system resources

There are five levels in the importance hierarchy The following list presents the different types of

processes in order of importance (the first process is most important and is killed last)

1 Foreground process

A process that is required for what the user is currently doing A process is considered to be in the

foreground if any of the following conditions are true

o It hosts an Activity that the user is interacting with (the Activitys onResume() method has been called)

o It hosts a Service thats bound to the activity that the user is interacting with

o It hosts a Service thats running in the foregroundmdashthe service has called startForeground()

o It hosts a Service thats executing one of its lifecycle callbacks (onCreate() onStart() or onDestroy())

o It hosts a BroadcastReceiver thats executing its onReceive() method

Generally only a few foreground processes exist at any given time They are killed only as a last

resortmdashif memory is so low that they cannot all continue to run Generally at that point the device has

reached a memory paging state so killing some foreground processes is required to keep the user

interface responsive

2 Visible process

A process that doesnt have any foreground components but still can affect what the user sees on

screen A process is considered to be visible if either of the following conditions are true

o It hosts an Activity that is not in the foreground but is still visible to the user (its onPause() method has

been called) This might occur for example if the foreground activity started a dialog which allows the

previous activity to be seen behind it

o It hosts a Service thats bound to a visible (or foreground) activity

A visible process is considered extremely important and will not be killed unless doing so is required to

keep all foreground processes running

3 Service process

A process that is running a service that has been started with the startService() method and does not

fall into either of the two higher categories Although service processes are not directly tied to anything

the user sees they are generally doing things that the user cares about (such as playing music in the

background or downloading data on the network) so the system keeps them running unless theres

not enough memory to retain them along with all foreground and visible processes

4 Background process

A process holding an activity thats not currently visible to the user (the activitys onStop() method has

been called) These processes have no direct impact on the user experience and the system can kill

them at any time to reclaim memory for a foreground visible or service process Usually there are

many background processes running so they are kept in an LRU (least recently used) list to ensure

that the process with the activity that was most recently seen by the user is the last to be killed If an

activity implements its lifecycle methods correctly and saves its current state killing its process will not

have a visible effect on the user experience because when the user navigates back to the activity the

activity restores all of its visible state See the Activities document for information about saving and

restoring state

5 Empty process

A process that doesnt hold any active application components The only reason to keep this kind of

process alive is for caching purposes to improve startup time the next time a component needs to run

in it The system often kills these processes in order to balance overall system resources between

process caches and the underlying kernel caches

Android ranks a process at the highest level it can based upon the importance of the components

currently active in the process For example if a process hosts a service and a visible activity the

process is ranked as a visible process not a service process

In addition a processs ranking might be increased because other processes are dependent on itmdasha

process that is serving another process can never be ranked lower than the process it is serving For

example if a content provider in process A is serving a client in process B or if a service in process A

is bound to a component in process B process A is always considered at least as important as

process B

Because a process running a service is ranked higher than a process with background activities an

activity that initiates a long-running operation might do well to start a service for that operation rather

than simply create a worker threadmdashparticularly if the operation will likely outlast the activity For

example an activity thats uploading a picture to a web site should start a service to perform the

upload so that the upload can continue in the background even if the user leaves the activity Using a

service guarantees that the operation will have at least service process priority regardless of what

happens to the activity This is the same reason that broadcast receivers should employ services

rather than simply put time-consuming operations in a thread

Threads

When an application is launched the system creates a thread of execution for the application called

main This thread is very important because it is in charge of dispatching events to the appropriate

user interface widgets including drawing events It is also the thread in which your application interacts

with components from the Android UI toolkit (components from the androidwidget and androidview

packages) As such the main thread is also sometimes called the UI thread

The system does not create a separate thread for each instance of a component All components that

run in the same process are instantiated in the UI thread and system calls to each component are

dispatched from that thread Consequently methods that respond to system callbacks (such as

onKeyDown() to report user actions or a lifecycle callback method) always run in the UI thread of the

process

For instance when the user touches a button on the screen your apps UI thread dispatches the touch

event to the widget which in turn sets its pressed state and posts an invalidate request to the event

queue The UI thread dequeues the request and notifies the widget that it should redraw itself

When your app performs intensive work in response to user interaction this single thread model can

yield poor performance unless you implement your application properly Specifically if everything is

happening in the UI thread performing long operations such as network access or database queries

will block the whole UI When the thread is blocked no events can be dispatched including drawing

events From the users perspective the application appears to hang Even worse if the UI thread is

blocked for more than a few seconds (about 5 seconds currently) the user is presented with the

infamous application not responding (ANR) dialog The user might then decide to quit your

application and uninstall it if they are unhappy

Additionally the Andoid UI toolkit is not thread-safe So you must not manipulate your UI from a

worker threadmdashyou must do all manipulation to your user interface from the UI thread Thus there are

simply two rules to Androids single thread model

1 Do not block the UI thread

2 Do not access the Android UI toolkit from outside the UI thread

Worker threads

Because of the single thread model described above its vital to the responsiveness of your

applications UI that you do not block the UI thread If you have operations to perform that are not

instantaneous you should make sure to do them in separate threads (background or worker

threads)

For example below is some code for a click listener that downloads an image from a separate thread

and displays it in an ImageView

public void onClick(View v) new Thread(new Runnable() public void run() Bitmap b = loadImageFromNetwork(httpexamplecomimagepng) mImageViewsetImageBitmap(b) )start()

At first this seems to work fine because it creates a new thread to handle the network operation

However it violates the second rule of the single-threaded model do not access the Android UI toolkit

from outside the UI threadmdashthis sample modifies the ImageView from the worker thread instead of the

UI thread This can result in undefined and unexpected behavior which can be difficult and time-

consuming to track down

To fix this problem Android offers several ways to access the UI thread from other threads Here is a

list of methods that can help

ActivityrunOnUiThread(Runnable)

Viewpost(Runnable)

ViewpostDelayed(Runnable long)

For example you can fix the above code by using the Viewpost(Runnable) method

public void onClick(View v) new Thread(new Runnable() public void run() final Bitmap bitmap = loadImageFromNetwork(httpexamplecomimagepng) mImageViewpost(new Runnable() public void run() mImageViewsetImageBitmap(bitmap) ) )start()

Now this implementation is thread-safe the network operation is done from a separate thread while

the ImageView is manipulated from the UI thread

However as the complexity of the operation grows this kind of code can get complicated and difficult

to maintain To handle more complex interactions with a worker thread you might consider using a

Handler in your worker thread to process messages delivered from the UI thread Perhaps the best

solution though is to extend the AsyncTask class which simplifies the execution of worker thread

tasks that need to interact with the UI

Using AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface It performs the blocking

operations in a worker thread and then publishes the results on the UI thread without requiring you to

handle threads andor handlers yourself

To use it you must subclass AsyncTask and implement the doInBackground() callback method which

runs in a pool of background threads To update your UI you should implement onPostExecute()

which delivers the result from doInBackground() and runs in the UI thread so you can safely update

your UI You can then run the task by calling execute() from the UI thread

For example you can implement the previous example using AsyncTask this way

public void onClick(View v) new DownloadImageTask()execute(httpexamplecomimagepng) private class DownloadImageTask extends AsyncTaskltString Void Bitmapgt The system calls this to perform work in a worker thread and delivers it the parameters given to AsyncTaskexecute() protected Bitmap doInBackground(String urls) return loadImageFromNetwork(urls[0])

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 24: 03 services

The third parameter is a flag indicating options for the binding It should usually be

BIND_AUTO_CREATE in order to create the service if its not already alive Other possible values are

BIND_DEBUG_UNBIND and BIND_NOT_FOREGROUND or 0 for none

Additional notes

Here are some important notes about binding to a service

You should always trap DeadObjectException exceptions which are thrown when the connection has

broken This is the only exception thrown by remote methods

Objects are reference counted across processes

You should usually pair the binding and unbinding during matching bring-up and tear-down moments

of the clients lifecycle For example

o If you only need to interact with the service while your activity is visible you should bind during

onStart() and unbind during onStop()

o If you want your activity to receive responses even while it is stopped in the background then you can

bind during onCreate() and unbind during onDestroy() Beware that this implies that your activity needs

to use the service the entire time its running (even in the background) so if the service is in another

process then you increase the weight of the process and it becomes more likely that the system will

kill it

Note You should usually not bind and unbind during your activitys onResume() and onPause()

because these callbacks occur at every lifecycle transition and you should keep the processing that

occurs at these transitions to a minimum Also if multiple activities in your application bind to the same

service and there is a transition between two of those activities the service may be destroyed and

recreated as the current activity unbinds (during pause) before the next one binds (during resume)

(This activity transition for how activities coordinate their lifecycles is described in the Activities

document)

For more sample code showing how to bind to a service see the RemoteServicejava class in

ApiDemos

Managing the Lifecycle of a Bound Service

Figure 1 The lifecycle for a service

that is started and also allows binding

When a service is unbound from all

clients the Android system destroys it

(unless it was also started with

onStartCommand()) As such you

dont have to manage the lifecycle of

your service if its purely a bound

servicemdashthe Android system manages

it for you based on whether it is bound

to any clients

However if you choose to implement

the onStartCommand() callback

method then you must explicitly stop

the service because the service is

now considered to be started In this

case the service runs until the service

stops itself with stopSelf() or another

component calls stopService()

regardless of whether it is bound to

any clients

Additionally if your service is started and accepts binding then when the system calls your onUnbind()

method you can optionally return true if you would like to receive a call to onRebind() the next time a

client binds to the service (instead of receiving a call to onBind()) onRebind() returns void but the

client still receives the IBinder in its onServiceConnected() callback Below figure 1 illustrates the logic

for this kind of lifecycle

For more information about the lifecycle of an started service see the Services document

Content Providers

Content providers store and retrieve data and make it accessible to all applications Theyre the only

way to share data across applications theres no common storage area that all Android packages can

access

Android ships with a number of content providers for common data types (audio video images

personal contact information and so on) You can see some of them listed in the androidprovider

package You can query these providers for the data they contain (although for some you must

acquire the proper permission to read the data)

If you want to make your own data public you have two options You can create your own content

provider (a ContentProvider subclass) or you can add the data to an existing provider mdash if theres one

that controls the same type of data and you have permission to write to it

This document is an introduction to using content providers After a brief discussion of the

fundamentals it explores how to query a content provider how to modify data controlled by a provider

and how to create a content provider of your own

Content Provider Basics

How a content provider actually stores its data under the covers is up to its designer But all content

providers implement a common interface for querying the provider and returning results mdash as well as

for adding altering and deleting data Its an interface that clients use indirectly most generally

through ContentResolver objects You get a ContentResolver by calling getContentResolver() from

within the implementation of an Activity or other application component

ContentResolver cr = getContentResolver()

You can then use the ContentResolvers methods to interact with whatever content providers youre

interested in When a query is initiated the Android system identifies the content provider thats the

target of the query and makes sure that it is up and running The system instantiates all

ContentProvider objects you never need to do it on your own In fact you never deal directly with

ContentProvider objects at all Typically theres just a single instance of each type of ContentProvider

But it can communicate with multiple ContentResolver objects in different applications and processes

The interaction between processes is handled by the ContentResolver and ContentProvider classes

The data model

Content providers expose their data as a simple table on a database model where each row is a

record and each column is data of a particular type and meaning For example information about

people and their phone numbers might be exposed as follows

_ID NUMBER NUMBER_KEY LABEL NAME TYPE

13 (425) 555 6677 425 555 6677 Kirkland office Bully Pulpit TYPE_WORK

44 (212) 555-1234 212 555 1234 NY apartment Alan Vain TYPE_HOME

45 (212) 555-6657 212 555 6657 Downtown office Alan Vain TYPE_MOBILE

53 2015554433 201 555 4433 Love Nest Rex Cars TYPE_HOME

Every record includes a numeric _ID field that uniquely identifies the record within the table IDs can be

used to match records in related tables mdash for example to find a persons phone number in one table

and pictures of that person in another

A query returns a Cursor object that can move from record to record and column to column to read the

contents of each field It has specialized methods for reading each type of data So to read a field you

must know what type of data the field contains (Theres more on query results and Cursor objects

later)

URIs

Each content provider exposes a public URI (wrapped as a Uri object) that uniquely identifies its data

set A content provider that controls multiple data sets (multiple tables) exposes a separate URI for

each one All URIs for providers begin with the string content The content scheme identifies the

data as being controlled by a content provider

If youre defining a content provider its a good idea to also define a constant for its URI to simplify

client code and make future updates cleaner Android defines CONTENT_URI constants for all the

providers that come with the platform For example the URI for the table that matches phone numbers

to people and the URI for the table that holds pictures of people (both controlled by the Contacts

content provider) are

androidproviderContactsPhonesCONTENT_URI

androidproviderContactsPhotosCONTENT_URI

The URI constant is used in all interactions with the content provider Every ContentResolver method

takes the URI as its first argument Its what identifies which provider the ContentResolver should talk

to and which table of the provider is being targeted

Querying a Content Provider

You need three pieces of information to query a content provider

The URI that identifies the provider

The names of the data fields you want to receive

The data types for those fields

If youre querying a particular record you also need the ID for that record

Making the query

To query a content provider you can use either the ContentResolverquery() method or the

ActivitymanagedQuery() method Both methods take the same set of arguments and both return a

Cursor object However managedQuery() causes the activity to manage the life cycle of the Cursor A

managed Cursor handles all of the niceties such as unloading itself when the activity pauses and

requerying itself when the activity restarts You can ask an Activity to begin managing an unmanaged

Cursor object for you by calling ActivitystartManagingCursor()

The first argument to either query() or managedQuery() is the provider URI mdash the CONTENT_URI

constant that identifies a particular ContentProvider and data set (see URIs earlier)

To restrict a query to just one record you can append the _ID value for that record to the URI mdash that

is place a string matching the ID as the last segment of the path part of the URI For example if the ID

is 23 the URI would be

content 23

There are some helper methods particularly ContentUriswithAppendedId() and

UriwithAppendedPath() that make it easy to append an ID to a URI Both are static methods that

return a Uri object with the ID added So for example if you were looking for record 23 in the database

of people contacts you might construct a query as follows

import androidproviderContactsPeople import androidcontentContentUris import androidnetUri import androiddatabaseCursor Use the ContentUris method to produce the base URI for the contact with _ID == 23 Uri myPerson = ContentUriswithAppendedId(PeopleCONTENT_URI 23) Alternatively use the Uri method to produce the base URI It takes a string rather than an integer Uri myPerson = UriwithAppendedPath(PeopleCONTENT_URI 23) Then query for this specific record Cursor cur = managedQuery(myPerson null null null null)

The other arguments to the query() and managedQuery() methods delimit the query in more detail

They are

The names of the data columns that should be returned A null value returns all columns Otherwise

only columns that are listed by name are returned All the content providers that come with the

platform define constants for their columns For example the androidproviderContactsPhones class

defines constants for the names of the columns in the phone table illustrated earlier ampmdash _ID

NUMBER NUMBER_KEY NAME and so on

A filter detailing which rows to return formatted as an SQL WHERE clause (excluding the WHERE

itself) A null value returns all rows (unless the URI limits the query to a single record)

Selection arguments

A sorting order for the rows that are returned formatted as an SQL ORDER BY clause (excluding the

ORDER BY itself) A null value returns the records in the default order for the table which may be

unordered

Lets look at an example query to retrieve a list of contact names and their primary phone numbers

import androidproviderContactsPeople import androiddatabaseCursor Form an array specifying which columns to return String[] projection = new String[] People_ID People_COUNT PeopleNAME PeopleNUMBER Get the base URI for the People table in the Contacts content provider Uri contacts = PeopleCONTENT_URI Make the query Cursor managedCursor = managedQuery(contacts projection Which columns to return null Which rows to return (all rows) null Selection arguments (none) Put the results in ascending order by name PeopleNAME + ASC)

This query retrieves data from the People table of the Contacts content provider It gets the name

primary phone number and unique record ID for each contact It also reports the number of records

that are returned as the _COUNT field of each record

The constants for the names of the columns are defined in various interfaces mdash _ID and _COUNT in

BaseColumns NAME in PeopleColumns and NUMBER in PhoneColumns The ContactsPeople

class implements each of these interfaces which is why the code example above could refer to them

using just the class name

What a query returns

A query returns a set of zero or more database records The names of the columns their default order

and their data types are specific to each content provider But every provider has an _ID column

which holds a unique numeric ID for each record Every provider can also report the number of records

returned as the _COUNT column its value is the same for all rows

Here is an example result set for the query in the previous section

_ID _COUNT NAME NUMBER

44 3 Alan Vain 212 555 1234

13 3 Bully Pulpit 425 555 6677

53 3 Rex Cars 201 555 4433

The retrieved data is exposed by a Cursor object that can be used to iterate backward or forward

through the result set You can use this object only to read the data To add modify or delete data

you must use a ContentResolver object

Reading retrieved data

The Cursor object returned by a query provides access to a recordset of results If you have queried

for a specific record by ID this set will contain only one value Otherwise it can contain multiple

values (If there are no matches it can also be empty) You can read data from specific fields in the

record but you must know the data type of the field because the Cursor object has a separate method

for reading each type of data mdash such as getString() getInt() and getFloat() (However for most types

if you call the method for reading strings the Cursor object will give you the String representation of

the data) The Cursor lets you request the column name from the index of the column or the index

number from the column name

The following snippet demonstrates reading names and phone numbers from the query illustrated

earlier

import androidproviderContactsPeople private void getColumnData(Cursor cur) if (curmoveToFirst()) String name String phoneNumber int nameColumn = curgetColumnIndex(PeopleNAME) int phoneColumn = curgetColumnIndex(PeopleNUMBER) String imagePath do Get the field values name = curgetString(nameColumn) phoneNumber = curgetString(phoneColumn) Do something with the values while (curmoveToNext())

If a query can return binary data such as an image or sound the data may be directly entered in the

table or the table entry for that data may be a string specifying a content URI that you can use to get

the data In general smaller amounts of data (say from 20 to 50K or less) are most often directly

entered in the table and can be read by calling CursorgetBlob() It returns a byte array

If the table entry is a content URI you should never try to open and read the file directly (for one thing

permissions problems can make this fail) Instead you should call ContentResolveropenInputStream()

to get an InputStream object that you can use to read the data

Modifying Data

Data kept by a content provider can be modified by

Adding new records

Adding new values to existing records

Batch updating existing records

Deleting records

All data modification is accomplished using ContentResolver methods Some content providers require

a more restrictive permission for writing data than they do for reading it If you dont have permission to

write to a content provider the ContentResolver methods will fail

Adding records

To add a new record to a content provider first set up a map of key-value pairs in a ContentValues

object where each key matches the name of a column in the content provider and the value is the

desired value for the new record in that column Then call ContentResolverinsert() and pass it the URI

of the provider and the ContentValues map This method returns the full URI of the new record mdash that

is the providers URI with the appended ID for the new record You can then use this URI to query and

get a Cursor over the new record and to further modify the record Heres an example

import androidproviderContactsPeople import androidcontentContentResolver import androidcontentContentValues ContentValues values = new ContentValues() Add Abraham Lincoln to contacts and make him a favorite valuesput(PeopleNAME Abraham Lincoln) 1 = the new contact is added to favorites 0 = the new contact is not added to favorites valuesput(PeopleSTARRED 1) Uri uri = getContentResolver()insert(PeopleCONTENT_URI values)

Adding new values

Once a record exists you can add new information to it or modify existing information For example

the next step in the example above would be to add contact information mdash like a phone number or an

IM or e-mail address mdash to the new entry

The best way to add to a record in the Contacts database is to append the name of the table where the

new data goes to the URI for the record then use the amended URI to add the new data values Each

Contacts table exposes a name for this purpose as a CONTENT_DIRECTORY constant The following

code continues the previous example by adding a phone number and e-mail address for the record

just created

Uri phoneUri = null Uri emailUri = null Add a phone number for Abraham Lincoln Begin with the URI for the new record just returned by insert() it ends with the _ID of the new record so we dont have to add the ID ourselves Then append the designation for the phone table to this URI and use the resulting URI to insert the phone number phoneUri = UriwithAppendedPath(uri PeoplePhonesCONTENT_DIRECTORY) valuesclear() valuesput(PeoplePhonesTYPE PeoplePhonesTYPE_MOBILE) valuesput(PeoplePhonesNUMBER 1233214567) getContentResolver()insert(phoneUri values) Now add an email address in the same way emailUri = UriwithAppendedPath(uri PeopleContactMethodsCONTENT_DIRECTORY) valuesclear() ContactMethodsKIND is used to distinguish different kinds of contact methods such as email IM etc valuesput(PeopleContactMethodsKIND ContactsKIND_EMAIL) valuesput(PeopleContactMethodsDATA testexamplecom) valuesput(PeopleContactMethodsTYPE PeopleContactMethodsTYPE_HOME) getContentResolver()insert(emailUri values)

You can place small amounts of binary data into a table by calling the version of ContentValuesput()

that takes a byte array That would work for a small icon-like image or a short audio clip for example

However if you have a large amount of binary data to add such as a photograph or a complete song

put a content URI for the data in the table and call ContentResolveropenOutputStream() with the files

URI (That causes the content provider to store the data in a file and record the file path in a hidden

field of the record)

In this regard the MediaStore content provider the main provider that dispenses image audio and

video data employs a special convention The same URI that is used with query() or managedQuery()

to get meta-information about the binary data (such as the caption of a photograph or the date it was

taken) is used with openInputStream() to get the data itself Similarly the same URI that is used with

insert() to put meta-information into a MediaStore record is used with openOutputStream() to place the

binary data there The following code snippet illustrates this convention

import androidproviderMediaStoreImagesMedia import androidcontentContentValues import javaioOutputStream Save the name and description of an image in a ContentValues map ContentValues values = new ContentValues(3) valuesput(MediaDISPLAY_NAME road_trip_1) valuesput(MediaDESCRIPTION Day 1 trip to Los Angeles) valuesput(MediaMIME_TYPE imagejpeg) Add a new record without the bitmap but with the values just set insert() returns the URI of the new record Uri uri = getContentResolver()insert(MediaEXTERNAL_CONTENT_URI values) Now get a handle to the file for that record and save the data into it Here sourceBitmap is a Bitmap object representing the file to save to the database try OutputStream outStream = getContentResolver()openOutputStream(uri) sourceBitmapcompress(BitmapCompressFormatJPEG 50 outStream) outStreamclose() catch (Exception e) Loge(TAG exception while writing image e)

Batch updating records

To batch update a group of records (for example to change NY to New York in all fields) call the

ContentResolverupdate() method with the columns and values to change

Deleting a record

To delete a single record call ContentResolverdelete() with the URI of a specific row

To delete multiple rows call ContentResolverdelete() with the URI of the type of record to delete (for

example androidproviderContactsPeopleCONTENT_URI) and an SQL WHERE clause defining

which rows to delete (Caution Be sure to include a valid WHERE clause if youre deleting a general

type or you risk deleting more records than you intended)

Creating a Content Provider

To create a content provider you must

Set up a system for storing the data Most content providers store their data using Androids file

storage methods or SQLite databases but you can store your data any way you want Android

provides the SQLiteOpenHelper class to help you create a database and SQLiteDatabase to manage

it

Extend the ContentProvider class to provide access to the data

Declare the content provider in the manifest file for your application (AndroidManifestxml)

The following sections have notes on the last two of these tasks

Extending the ContentProvider class

You define a ContentProvider subclass to expose your data to others using the conventions expected

by ContentResolver and Cursor objects Principally this means implementing six abstract methods

declared in the ContentProvider class

query()

insert()

update()

delete()

getType()

onCreate()

The query() method must return a Cursor object that can iterate over the requested data Cursor itself

is an interface but Android provides some ready-made Cursor objects that you can use For example

SQLiteCursor can iterate over data stored in an SQLite database You get the Cursor object by calling

any of the SQLiteDatabase classs query() methods There are other Cursor implementations mdash such

as MatrixCursor mdash for data not stored in a database

Because these ContentProvider methods can be called from various ContentResolver objects in

different processes and threads they must be implemented in a thread-safe manner

As a courtesy you might also want to call ContentResolvernotifyChange() to notify listeners when

there are modifications to the data

Beyond defining the subclass itself there are other steps you should take to simplify the work of clients

and make the class more accessible

Define a public static final Uri named CONTENT_URI This is the string that represents the full content

URI that your content provider handles You must define a unique string for this value The best

solution is to use the fully-qualified class name of the content provider (made lowercase) So for

example the URI for a TransportationProvider class could be defined as follows

public static final Uri CONTENT_URI = Uriparse(contentcomexamplecodelabtransportationprovider)

If the provider has subtables also define CONTENT_URI constants for each of the subtables These

URIs should all have the same authority (since that identifies the content provider) and be

distinguished only by their paths For example

contentcomexamplecodelabtransportationprovidertrain

contentcomexamplecodelabtransportationproviderairdomestic

contentcomexamplecodelabtransportationproviderairinternational

For an overview of content URIs see the Content URI Summary at the end of this document

Define the column names that the content provider will return to clients If you are using an underlying

database these column names are typically identical to the SQL database column names they

represent Also define public static String constants that clients can use to specify the columns in

queries and other instructions

Be sure to include an integer column named _id (with the constant _ID) for the IDs of the records

You should have this field whether or not you have another field (such as a URL) that is also unique

among all records If youre using the SQLite database the _ID field should be the following type

INTEGER PRIMARY KEY AUTOINCREMENT

The AUTOINCREMENT descriptor is optional But without it SQLite increments an ID counter field to

the next number above the largest existing number in the column If you delete the last row the next

row added will have the same ID as the deleted row AUTOINCREMENT avoids this by having SQLite

increment to the next largest value whether deleted or not

Carefully document the data type of each column Clients need this information to read the data

If you are handling a new data type you must define a new MIME type to return in your

implementation of ContentProvidergetType() The type depends in part on whether or not the content

URI submitted to getType() limits the request to a specific record Theres one form of the MIME type

for a single record and another for multiple records Use the Uri methods to help determine what is

being requested Here is the general format for each type

o For a single record vndandroidcursoritemvndyourcompanynamecontenttype

For example a request for train record 122 like this URI

contentcomexampletransportationprovidertrains122

might return this MIME type

vndandroidcursoritemvndexamplerail

o For multiple records vndandroidcursordirvndyourcompanynamecontenttype

For example a request for all train records like the following URI

contentcomexampletransportationprovidertrains

might return this MIME type

vndandroidcursordirvndexamplerail

If you are exposing byte data thats too big to put in the table itself mdash such as a large bitmap file mdash the

field that exposes the data to clients should actually contain a content URI string This is the field that

gives clients access to the data file The record should also have another field named _data that lists

the exact file path on the device for that file This field is not intended to be read by the client but by

the ContentResolver The client will call ContentResolveropenInputStream() on the user-facing field

holding the URI for the item The ContentResolver will request the _data field for that record and

because it has higher permissions than a client it should be able to access that file directly and return

a read wrapper for the file to the client

For an example of a private content provider implementation see the NodePadProvider class in the

Notepad sample application that ships with the SDK

Declaring the content provider

To let the Android system know about the content provider youve developed declare it with a

ltprovidergt element in the applications AndroidManifestxml file Content providers that are not

declared in the manifest are not visible to the Android system

The name attribute is the fully qualified name of the ContentProvider subclass The authorities attribute

is the authority part of the content URI that identifies the provider For example if the ContentProvider

subclass is AutoInfoProvider the ltprovidergt element might look like this

ltprovider androidname=comexampleautosAutoInfoProvider androidauthorities=comexampleautosautoinfoprovider gt ltprovidergt

Note that the authorities attribute omits the path part of a content URI For example if

AutoInfoProvider controlled subtables for different types of autos or different manufacturers

contentcomexampleautosautoinfoproviderhonda

contentcomexampleautosautoinfoprovidergmcompact

contentcomexampleautosautoinfoprovidergmsuv

those paths would not be declared in the manifest The authority is what identifies the provider not the

path your provider can interpret the path part of the URI in any way you choose

Other ltprovidergt attributes can set permissions to read and write data provide for an icon and text

that can be displayed to users enable and disable the provider and so on Set the multiprocess

attribute to true if data does not need to be synchronized between multiple running versions of the

content provider This permits an instance of the provider to be created in each client process

eliminating the need to perform IPC

Content URI Summary

Here is a recap of the important parts of a content URI

A Standard prefix indicating that the data is controlled by a content provider Its never modified

B The authority part of the URI it identifies the content provider For third-party applications this should

be a fully-qualified class name (reduced to lowercase) to ensure uniqueness The authority is declared

in the ltprovidergt elements authorities attribute

ltprovider androidname=TransportationProvider androidauthorities=comexampletransportationprovider gt

C The path that the content provider uses to determine what kind of data is being requested This can be

zero or more segments long If the content provider exposes only one type of data (only trains for

example) it can be absent If the provider exposes several types including subtypes it can be several

segments long mdash for example landbus landtrain seaship and seasubmarine to give four

possibilities

D The ID of the specific record being requested if any This is the _ID value of the requested record If

the request is not limited to a single record this segment and the trailing slash are omitted

contentcomexampletransportationprovidertrains

Intent and intent filters

Three of the core components of an application mdash activities services and broadcast receivers mdash 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 mdash 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 ContextstartActivity() or ActivitystartActivityForResult() to launch an

activity or get an existing activity to do something new (It can also be passed to ActivitysetResult() to

return information to the activity that called startActivityForResult())

An Intent object is passed to ContextstartService() to initiate a service or deliver new instructions to an

ongoing service Similarly an intent can be passed to ContextbindService() to establish a connection

between the calling component and a target service It can optionally initiate the service if its not

already running

Intent objects passed to any of the broadcast methods (such as ContextsendBroadcast()

ContextsendOrderedBroadcast() or ContextsendStickyBroadcast()) 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 mdash how it resolves which component should receive an intent message For

intents that dont explicitly name a target component this process involves testing the Intent object

against intent filters associated with potential targets

Intent Objects

An Intent object is a bundle of information It contains information of interest to the component that

receives the intent (such as the action to be taken and the data to act on) plus information of interest to

the Android system (such as the category of component that should handle the intent and instructions

on how to launch a target activity) Principally it can contain the following

Component name

The name of the component that should handle the intent This field is a ComponentName

object mdash a combination of the fully qualified class name of the target component (for example

comexampleprojectappFreneticActivity) and the package name set in the manifest file of the

application where the component resides (for example comexampleproject) The package

part of the component name and the package name set in the manifest do not necessarily have

to match

The component name is optional If it is set the Intent object is delivered to an instance of the

designated class If it is not set Android uses other information in the Intent object to locate a

suitable target mdash see Intent Resolution later in this document

The component name is set by setComponent() setClass() or setClassName() and read by

getComponent()

Action

A string naming the action to be performed mdash or in the case of broadcast intents the action

that took place and is being reported The Intent class defines a number of action constants

including these

Constant Target

component

Action

ACTION_CALL activity Initiate a phone call

ACTION_EDIT activity Display data for the user to edit

ACTION_MAIN activity Start up as the initial activity of a task

with no data input and no returned

output

ACTION_SYNC activity Synchronize data on a server with

data on the mobile device

ACTION_BATTERY_LOW broadcast

receiver

A warning that the battery is low

ACTION_HEADSET_PLUG broadcast

receiver

A headset has been plugged into the

device or unplugged from it

ACTION_SCREEN_ON broadcast

receiver

The screen has been turned on

ACTION_TIMEZONE_CHANGED broadcast

receiver

The setting for the time zone has

changed

See the Intent class description for a list of pre-defined constants for generic actions Other

actions are defined elsewhere in the Android API You can also define your own action strings

for activating the components in your application Those you invent should include the

application package as a prefix mdash for example comexampleprojectSHOW_COLOR

The action largely determines how the rest of the intent is structured mdash particularly the data and

extras fields mdash much as a method name determines a set of arguments and a return value For

this reason its a good idea to use action names that are as specific as possible and to couple

them tightly to the other fields of the intent In other words instead of defining an action in

isolation define an entire protocol for the Intent objects your components can handle

The action in an Intent object is set by the setAction() method and read by getAction()

Data

The URI of the data to be acted on and the MIME type of that data Different actions are paired

with different kinds of data specifications For example if the action field is ACTION_EDIT the

data field would contain the URI of the document to be displayed for editing If the action is

ACTION_CALL the data field would be a tel URI with the number to call Similarly if the action

is ACTION_VIEW and the data field is an http URI the receiving activity would be called upon

to download and display whatever data the URI refers to

When matching an intent to a component that is capable of handling the data its often

important to know the type of data (its MIME type) in addition to its URI For example a

component able to display image data should not be called upon to play an audio file

In many cases the data type can be inferred from the URI mdash particularly content URIs which

indicate that the data is located on the device and controlled by a content provider (see the

separate discussion on content providers) But the type can also be explicitly set in the Intent

object The setData() method specifies data only as a URI setType() specifies it only as a

MIME type and setDataAndType() specifies it as both a URI and a MIME type The URI is read

by getData() and the type by getType()

Category

A string containing additional information about the kind of component that should handle the

intent Any number of category descriptions can be placed in an Intent object As it does for

actions the Intent class defines several category constants including these

Constant Meaning

CATEGORY_BROWSABLE The target activity can be safely invoked by the browser to

display data referenced by a link mdash for example an image or

an e-mail message

CATEGORY_GADGET The activity can be embedded inside of another activity that

hosts gadgets

CATEGORY_HOME The activity displays the home screen the first screen the

user sees when the device is turned on or when the HOME

key is pressed

CATEGORY_LAUNCHER The activity can be the initial activity of a task and is listed in

the top-level application launcher

CATEGORY_PREFERENCE The target activity is a preference panel

See the Intent class description for the full list of categories

The addCategory() method places a category in an Intent object removeCategory() deletes a

category previously added and getCategories() gets the set of all categories currently in the

object

Extras

Key-value pairs for additional information that should be delivered to the component handling

the intent Just as some actions are paired with particular kinds of data URIs some are paired

with particular extras For example an ACTION_TIMEZONE_CHANGED intent has a time-

zone extra that identifies the new time zone and ACTION_HEADSET_PLUG has a state

extra indicating whether the headset is now plugged in or unplugged as well as a name extra

for the type of headset If you were to invent a SHOW_COLOR action the color value would be

set in an extra key-value pair

The Intent object has a series of put() methods for inserting various types of extra data and a

similar set of get() methods for reading the data These methods parallel those for Bundle

objects In fact the extras can be installed and read as a Bundle using the putExtras() and

getExtras() methods

Flags

Flags of various sorts Many instruct the Android system how to launch an activity (for example

which task the activity should belong to) and how to treat it after its launched (for example

whether it belongs in the list of recent activities) All these flags are defined in the Intent class

The Android system and the applications that come with the platform employ Intent objects both to

send out system-originated broadcasts and to activate system-defined components To see how to

structure an intent to activate a system component consult the list of intents in the reference

Intent Resolution

Intents can be divided into two groups

Explicit intents designate the target component by its name (the component name field mentioned

earlier has a value set) Since component names would generally not be known to developers of other

applications explicit intents are typically used for application-internal messages mdash such as an activity

starting a subordinate service or launching a sister activity

Implicit intents do not name a target (the field for the component name is blank) Implicit intents are

often used to activate components in other applications

Android delivers an explicit intent to an instance of the designated target class Nothing in the Intent

object other than the component name matters for determining which component should get the intent

A different strategy is needed for implicit intents In the absence of a designated target the Android

system must find the best component (or components) to handle the intent mdash a single activity or

service to perform the requested action or the set of broadcast receivers to respond to the broadcast

announcement It does so by comparing the contents of the Intent object to intent filters structures

associated with components that can potentially receive intents Filters advertise the capabilities of a

component and delimit the intents it can handle They open the component to the possibility of

receiving implicit intents of the advertised type If a component does not have any intent filters it can

receive only explicit intents A component with filters can receive both explicit and implicit intents

Only three aspects of an Intent object are consulted when the object is tested against an intent filter

action

data (both URI and data type)

category

The extras and flags play no part in resolving which component receives an intent

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 mdash but only unwanted implicit intents (those that dont 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

components 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 mdash 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 Pads filters are described in the Note Pad Example

section later)

Filters and security

An intent filter cannot be relied on for security While it opens a component to receiving only certain

kinds of implicit intents it does nothing to prevent explicit intents from targeting the component Even

though a filter restricts the intents a component will be asked to handle to certain actions and data

sources someone could always put together an explicit intent with a different action and data source

and name the component as the target

An intent filter is an instance of the IntentFilter class However since the Android system must know

about the capabilities of a component before it can launch that component intent filters are generally

not set up in Java code but in the applications manifest file (AndroidManifestxml) as ltintent-filtergt

elements (The one exception would be filters for broadcast receivers that are registered dynamically

by calling ContextregisterReceiver() they are directly created as IntentFilter objects)

A filter has fields that parallel the action data and category fields of an Intent object An implicit intent

is tested against the filter in all three areas To be delivered to the component that owns the filter it

must pass all three tests If it fails even one of them the Android system wont deliver it to the

component mdash at least not on the basis of that filter However since a component can have multiple

intent filters an intent that does not pass through one of a components filters might make it through on

another

Each of the three tests is described in detail below

Action test

An ltintent-filtergt element in the manifest file lists actions as ltactiongt subelements For

example

ltintent-filter gt ltaction androidname=comexampleprojectSHOW_CURRENT gt ltaction androidname=comexampleprojectSHOW_RECENT gt ltaction androidname=comexampleprojectSHOW_PENDING gt ltintent-filtergt

As the example shows while an Intent object names just a single action a filter may list more

than one The list cannot be empty a filter must contain at least one ltactiongt element or it will

block all intents

To pass this test the action specified in the Intent object must match one of the actions listed in

the filter If the object or the filter does not specify an action the results are as follows

If the filter fails to list any actions there is nothing for an intent to match so all intents fail the

test No intents can get through the filter

On the other hand an Intent object that doesnt specify an action automatically passes the test

mdash as long as the filter contains at least one action

Category test

An ltintent-filtergt element also lists categories as subelements For example

ltintent-filter gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryBROWSABLE gt ltintent-filtergt

Note that the constants described earlier for actions and categories are not used in the manifest

file The full string values are used instead For instance the

androidintentcategoryBROWSABLE string in the example above corresponds to the

CATEGORY_BROWSABLE constant mentioned earlier in this document Similarly the string

androidintentactionEDIT corresponds to the ACTION_EDIT constant

For an intent to pass the category test every category in the Intent object must match a

category in the filter The filter can list additional categories but it cannot omit any that are in the

intent

In principle therefore an Intent object with no categories should always pass this test

regardless of whats in the filter Thats mostly true However with one exception Android treats

all implicit intents passed to startActivity() as if they contained at least one category

androidintentcategoryDEFAULT (the CATEGORY_DEFAULT constant) Therefore activities

that are willing to receive implicit intents must include androidintentcategoryDEFAULT in

their intent filters (Filters with androidintentactionMAIN and

androidintentcategoryLAUNCHER settings are the exception They mark activities that begin

new tasks and that are represented on the launcher screen They can include

androidintentcategoryDEFAULT in the list of categories but dont need to) See Using intent

matching later for more on these filters)

Data test

Like the action and categories the data specification for an intent filter is contained in a

subelement And as in those cases the subelement can appear multiple times or not at all For

example

ltintent-filter gt ltdata androidmimeType=videompeg androidscheme=http gt ltdata androidmimeType=audiompeg androidscheme=http gt ltintent-filtergt

Each ltdatagt element can specify a URI and a data type (MIME media type) There are

separate attributes mdash scheme host port and path mdash for each part of the URI

schemehostportpath

For example in the following URI

contentcomexampleproject200foldersubfolderetc

the scheme is content the host is comexampleproject the port is 200 and the path is

foldersubfolderetc The host and port together constitute the URI authority if a host is not

specified the port is ignored

Each of these attributes is optional but they are not independent of each other For an authority

to be meaningful a scheme must also be specified For a path to be meaningful both a scheme

and an authority must be specified

When the URI in an Intent object is compared to a URI specification in a filter its compared

only to the parts of the URI actually mentioned in the filter For example if a filter specifies only

a scheme all URIs with that scheme match the filter If a filter specifies a scheme and an

authority but no path all URIs with the same scheme and authority match regardless of their

paths If a filter specifies a scheme an authority and a path only URIs with the same scheme

authority and path match However a path specification in the filter can contain wildcards to

require only a partial match of the path

The type attribute of a ltdatagt element specifies the MIME type of the data Its more common in

filters than a URI Both the Intent object and the filter can use a wildcard for the subtype field

mdash for example text or audio mdash indicating any subtype matches

The data test compares both the URI and the data type in the Intent object to a URI and data

type specified in the filter The rules are as follows

a An Intent object that contains neither a URI nor a data type passes the test only if the filter

likewise does not specify any URIs or data types

b An Intent object that contains a URI but no data type (and a type cannot be inferred from the

URI) passes the test only if its URI matches a URI in the filter and the filter likewise does not

specify a type This will be the case only for URIs like mailto and tel that do not refer to actual

data

c An Intent object that contains a data type but not a URI passes the test only if the filter lists the

same data type and similarly does not specify a URI

d An Intent object that contains both a URI and a data type (or a data type can be inferred from

the URI) passes the data type part of the test only if its type matches a type listed in the filter It

passes the URI part of the test either if its URI matches a URI in the filter or if it has a content

or file URI and the filter does not specify a URI In other words a component is presumed to

support content and file data if its filter lists only a data type

If an intent can pass through the filters of more than one activity or service the user may be asked

which component to activate An exception is raised if no target can be found

Common cases

The last rule shown above for the data test rule (d) reflects the expectation that components are able

to get local data from a file or content provider Therefore their filters can list just a data type and do

not need to explicitly name the content and file schemes This is a typical case A ltdatagt element like

the following for example tells Android that the component can get image data from a content

provider and display it

ltdata androidmimeType=image gt

Since most available data is dispensed by content providers filters that specify a data type but not a

URI are perhaps the most common

Another common configuration is filters with a scheme and a data type For example a ltdatagt

element like the following tells Android that the component can get video data from the network and

display it

ltdata androidscheme=http androidtype=video gt

Consider for example what the browser application does when the user follows a link on a web page

It first tries to display the data (as it could if the link was to an HTML page) If it cant display the data it

puts together an implicit intent with the scheme and data type and tries to start an activity that can do

the job If there are no takers it asks the download manager to download the data That puts it under

the control of a content provider so a potentially larger pool of activities (those with filters that just

name a data type) can respond

Most applications also have a way to start fresh without a reference to any particular data Activities

that can initiate applications have filters with androidintentactionMAIN specified as the action If

they are to be represented in the application launcher they also specify the

androidintentcategoryLAUNCHER category

ltintent-filter gt ltaction androidname=code androidintentactionMAIN gt ltcategory androidname=code androidintentcategoryLAUNCHER gt ltintent-filtergt

Using intent matching

Intents are matched against intent filters not only to discover a target component to activate but also

to discover something about the set of components on the device For example the Android system

populates the application launcher the top-level screen that shows the applications that are available

for the user to launch by finding all the activities with intent filters that specify the

androidintentactionMAIN action and androidintentcategoryLAUNCHER category (as illustrated

in the previous section) It then displays the icons and labels of those activities in the launcher

Similarly it discovers the home screen by looking for the activity with androidintentcategoryHOME

in its filter

Your application can use intent matching is a similar way The PackageManager has a set of query()

methods that return all components that can accept a particular intent and a similar series of

resolve() methods that determine the best component to respond to an intent For example

queryIntentActivities() returns a list of all activities that can perform the intent passed as an argument

and queryIntentServices() returns a similar list of services Neither method activates the components

they just list the ones that can respond Theres a similar method queryBroadcastReceivers() for

broadcast receivers

Note Pad Example

The Note Pad sample application enables users to browse through a list of notes view details about

individual items in the list edit the items and add a new item to the list This section looks at the intent

filters declared in its manifest file (If youre working offline in the SDK you can find all the source files

for this sample application including its manifest file at ltsdkgtsamplesNotePadindexhtml If youre

viewing the documentation online the source files are in the Tutorials and Sample Code section here)

In its manifest file the Note Pad application declares three activities each with at least one intent filter

It also declares a content provider that manages the note data Here is the manifest file in its entirety

ltmanifest xmlnsandroid=httpschemasandroidcomapkresandroid package=comexampleandroidnotepadgt ltapplication androidicon=drawableapp_notes androidlabel=stringapp_name gt ltprovider androidname=NotePadProvider androidauthorities=comgoogleproviderNotePad gt ltactivity androidname=NotesList androidlabel=stringtitle_notes_listgt ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltactivity androidname=NoteEditor androidtheme=androidstyleThemeLight androidlabel=stringtitle_note gt ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltactivitygt

ltactivity androidname=TitleEditor androidlabel=stringtitle_edit_title androidtheme=androidstyleThemeDialoggt ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltapplicationgt ltmanifestgt

The first activity NotesList is distinguished from the other activities by the fact that it operates on a

directory of notes (the note list) rather than on a single note It would generally serve as the initial user

interface into the application It can do three things as described by its three intent filters

1 ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt

This filter declares the main entry point into the Note Pad application The standard MAIN action is an

entry point that does not require any other information in the Intent (no data specification for example)

and the LAUNCHER category says that this entry point should be listed in the application launcher

2 ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

This filter declares the things that the activity can do on a directory of notes It can allow the user to

view or edit the directory (via the VIEW and EDIT actions) or to pick a particular note from the

directory (via the PICK action)

The mimeType attribute of the ltdatagt element specifies the kind of data that these actions operate on

It indicates that the activity can get a Cursor over zero or more items (vndandroidcursordir) from a

content provider that holds Note Pad data (vndgooglenote) The Intent object that launches the

activity would include a content URI specifying the exact data of this type that the activity should open

Note also the DEFAULT category supplied in this filter Its there because the ContextstartActivity()

and ActivitystartActivityForResult() methods treat all intents as if they contained the DEFAULT

category mdash with just two exceptions

o Intents that explicitly name the target activity

o Intents consisting of the MAIN action and LAUNCHER category

Therefore the DEFAULT category is required for all filters mdash except for those with the MAIN action

and LAUNCHER category (Intent filters are not consulted for explicit intents)

3 ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

This filter describes the activitys ability to return a note selected by the user without requiring any

specification of the directory the user should choose from The GET_CONTENT action is similar to the

PICK action In both cases the activity returns the URI for a note selected by the user (In each case

its returned to the activity that called startActivityForResult() to start the NoteList activity) Here

however the caller specifies the type of data desired instead of the directory of data the user will be

picking from

The data type vndandroidcursoritemvndgooglenote indicates the type of data the activity can

return mdash a URI for a single note From the returned URI the caller can get a Cursor for exactly one

item (vndandroidcursoritem) from the content provider that holds Note Pad data (vndgooglenote)

In other words for the PICK action in the previous filter the data type indicates the type of data the

activity could display to the user For the GET_CONTENT filter it indicates the type of data the activity

can return to the caller

Given these capabilities the following intents will resolve to the NotesList activity

action androidintentactionMAIN

Launches the activity with no data specified

action androidintentactionMAIN

category androidintentcategoryLAUNCHER

Launches the activity with no data selected specified This is the actual intent used by the

Launcher to populate its top-level list All activities with filters that match this action and

category are added to the list

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of all the notes under

contentcomgoogleproviderNotePadnotes The user can then browse through the list and

get information about the items in it

action androidintentactionPICK

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of the notes under

contentcomgoogleproviderNotePadnotes The user can then pick a note from the list and

the activity will return the URI for that item back to the activity that started the NoteList activity

action androidintentactionGET_CONTENT

data type vndandroidcursoritemvndgooglenote

Asks the activity to supply a single item of Note Pad data

The second activity NoteEditor shows users a single note entry and allows them to edit it It can do

two things as described by its two intent filters

1 ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The first primary purpose of this activity is to enable the user to interact with a single note ampmdash to

either VIEW the note or EDIT it (The EDIT_NOTE category is a synonym for EDIT) The intent would

contain the URI for data matching the MIME type vndandroidcursoritemvndgooglenote mdash that is

the URI for a single specific note It would typically be a URI that was returned by the PICK or

GET_CONTENT actions of the NoteList activity

As before this filter lists the DEFAULT category so that the activity can be launched by intents that

dont explicitly specify the NoteEditor class

2 ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

The secondary purpose of this activity is to enable the user to create a new note which it will INSERT

into an existing directory of notes The intent would contain the URI for data matching the MIME type

vndandroidcursordirvndgooglenote mdash that is the URI for the directory where the note should be

placed

Given these capabilities the following intents will resolve to the NoteEditor activity

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID (For details on how content

URIs specify individual members of a group see Content Providers)

action androidintentactionEDIT

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID and to let the user edit it If

the user saves the changes the activity updates the data for the note in the content provider

action androidintentactionINSERT

data contentcomgoogleproviderNotePadnotes

Asks the activity to create a new empty note in the notes list at

contentcomgoogleproviderNotePadnotes and allow the user to edit it If the user saves the

note its URI is returned to the caller

The last activity TitleEditor enables the user to edit the title of a note This could be implemented by

directly invoking the activity (by explicitly setting its component name in the Intent) without using an

intent filter But here we take the opportunity to show how to publish alternative operations on existing

data

ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The single intent filter for this activity uses a custom action called

comandroidnotepadactionEDIT_TITLE It must be invoked on a specific note (data type

vndandroidcursoritemvndgooglenote) like the previous VIEW and EDIT actions However here the

activity displays the title contained in the note data not the content of the note itself

In addition to supporting the usual DEFAULT category the title editor also supports two other standard

categories ALTERNATIVE and SELECTED_ALTERNATIVE These categories identify activities that

can be presented to users in a menu of options (much as the LAUNCHER category identifies activities

that should be presented to user in the application launcher) Note that the filter also supplies an

explicit label (via androidlabel=stringresolve_title) to better control what users see when

presented with this activity as an alternative action to the data they are currently viewing (For more

information on these categories and building options menus see the

PackageManagerqueryIntentActivityOptions() and MenuaddIntentOptions() methods)

Given these capabilities the following intent will resolve to the TitleEditor activity

action comandroidnotepadactionEDIT_TITLE

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the title associated with note ID and allow the user to edit the title

Processes and Threads

When an application component starts and the application does not have any other components

running the Android system starts a new Linux process for the application with a single thread of

execution By default all components of the same application run in the same process and thread

(called the main thread) If an application component starts and there already exists a process for

that application (because another component from the application exists) then the component is

started within that process and uses the same thread of execution However you can arrange for

different components in your application to run in separate processes and you can create additional

threads for any process

This document discusses how processes and threads work in an Android application

Processes

By default all components of the same application run in the same process and most applications

should not change this However if you find that you need to control which process a certain

component belongs to you can do so in the manifest file

The manifest entry for each type of component elementmdashltactivitygt ltservicegt ltreceivergt and

ltprovidergtmdashsupports an androidprocess attribute that can specify a process in which that component

should run You can set this attribute so that each component runs in its own process or so that some

components share a process while others do not You can also set androidprocess so that

components of different applications run in the same processmdashprovided that the applications share the

same Linux user ID and are signed with the same certificates

The ltapplicationgt element also supports an androidprocess attribute to set a default value that

applies to all components

Android might 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 thats killed are consequently destroyed A process is started again for those components

when theres again work for them to do

When deciding which processes to kill the Android system weighs their relative importance to the

user For example it more readily shuts down a process hosting activities that are no longer visible on

screen compared to a process hosting visible activities The decision whether to terminate a process

therefore depends on the state of the components running in that process The rules used to decide

which processes to terminate is discussed below

Process lifecycle

The Android system tries to maintain an application process for as long as possible but eventually

needs to remove old processes to reclaim memory for new or more important processes To determine

which processes to keep and which to kill the system places each process into an importance

hierarchy based on the components running in the process and the state of those components

Processes with the lowest importance are eliminated first then those with the next lowest importance

and so on as necessary to recover system resources

There are five levels in the importance hierarchy The following list presents the different types of

processes in order of importance (the first process is most important and is killed last)

1 Foreground process

A process that is required for what the user is currently doing A process is considered to be in the

foreground if any of the following conditions are true

o It hosts an Activity that the user is interacting with (the Activitys onResume() method has been called)

o It hosts a Service thats bound to the activity that the user is interacting with

o It hosts a Service thats running in the foregroundmdashthe service has called startForeground()

o It hosts a Service thats executing one of its lifecycle callbacks (onCreate() onStart() or onDestroy())

o It hosts a BroadcastReceiver thats executing its onReceive() method

Generally only a few foreground processes exist at any given time They are killed only as a last

resortmdashif memory is so low that they cannot all continue to run Generally at that point the device has

reached a memory paging state so killing some foreground processes is required to keep the user

interface responsive

2 Visible process

A process that doesnt have any foreground components but still can affect what the user sees on

screen A process is considered to be visible if either of the following conditions are true

o It hosts an Activity that is not in the foreground but is still visible to the user (its onPause() method has

been called) This might occur for example if the foreground activity started a dialog which allows the

previous activity to be seen behind it

o It hosts a Service thats bound to a visible (or foreground) activity

A visible process is considered extremely important and will not be killed unless doing so is required to

keep all foreground processes running

3 Service process

A process that is running a service that has been started with the startService() method and does not

fall into either of the two higher categories Although service processes are not directly tied to anything

the user sees they are generally doing things that the user cares about (such as playing music in the

background or downloading data on the network) so the system keeps them running unless theres

not enough memory to retain them along with all foreground and visible processes

4 Background process

A process holding an activity thats not currently visible to the user (the activitys onStop() method has

been called) These processes have no direct impact on the user experience and the system can kill

them at any time to reclaim memory for a foreground visible or service process Usually there are

many background processes running so they are kept in an LRU (least recently used) list to ensure

that the process with the activity that was most recently seen by the user is the last to be killed If an

activity implements its lifecycle methods correctly and saves its current state killing its process will not

have a visible effect on the user experience because when the user navigates back to the activity the

activity restores all of its visible state See the Activities document for information about saving and

restoring state

5 Empty process

A process that doesnt hold any active application components The only reason to keep this kind of

process alive is for caching purposes to improve startup time the next time a component needs to run

in it The system often kills these processes in order to balance overall system resources between

process caches and the underlying kernel caches

Android ranks a process at the highest level it can based upon the importance of the components

currently active in the process For example if a process hosts a service and a visible activity the

process is ranked as a visible process not a service process

In addition a processs ranking might be increased because other processes are dependent on itmdasha

process that is serving another process can never be ranked lower than the process it is serving For

example if a content provider in process A is serving a client in process B or if a service in process A

is bound to a component in process B process A is always considered at least as important as

process B

Because a process running a service is ranked higher than a process with background activities an

activity that initiates a long-running operation might do well to start a service for that operation rather

than simply create a worker threadmdashparticularly if the operation will likely outlast the activity For

example an activity thats uploading a picture to a web site should start a service to perform the

upload so that the upload can continue in the background even if the user leaves the activity Using a

service guarantees that the operation will have at least service process priority regardless of what

happens to the activity This is the same reason that broadcast receivers should employ services

rather than simply put time-consuming operations in a thread

Threads

When an application is launched the system creates a thread of execution for the application called

main This thread is very important because it is in charge of dispatching events to the appropriate

user interface widgets including drawing events It is also the thread in which your application interacts

with components from the Android UI toolkit (components from the androidwidget and androidview

packages) As such the main thread is also sometimes called the UI thread

The system does not create a separate thread for each instance of a component All components that

run in the same process are instantiated in the UI thread and system calls to each component are

dispatched from that thread Consequently methods that respond to system callbacks (such as

onKeyDown() to report user actions or a lifecycle callback method) always run in the UI thread of the

process

For instance when the user touches a button on the screen your apps UI thread dispatches the touch

event to the widget which in turn sets its pressed state and posts an invalidate request to the event

queue The UI thread dequeues the request and notifies the widget that it should redraw itself

When your app performs intensive work in response to user interaction this single thread model can

yield poor performance unless you implement your application properly Specifically if everything is

happening in the UI thread performing long operations such as network access or database queries

will block the whole UI When the thread is blocked no events can be dispatched including drawing

events From the users perspective the application appears to hang Even worse if the UI thread is

blocked for more than a few seconds (about 5 seconds currently) the user is presented with the

infamous application not responding (ANR) dialog The user might then decide to quit your

application and uninstall it if they are unhappy

Additionally the Andoid UI toolkit is not thread-safe So you must not manipulate your UI from a

worker threadmdashyou must do all manipulation to your user interface from the UI thread Thus there are

simply two rules to Androids single thread model

1 Do not block the UI thread

2 Do not access the Android UI toolkit from outside the UI thread

Worker threads

Because of the single thread model described above its vital to the responsiveness of your

applications UI that you do not block the UI thread If you have operations to perform that are not

instantaneous you should make sure to do them in separate threads (background or worker

threads)

For example below is some code for a click listener that downloads an image from a separate thread

and displays it in an ImageView

public void onClick(View v) new Thread(new Runnable() public void run() Bitmap b = loadImageFromNetwork(httpexamplecomimagepng) mImageViewsetImageBitmap(b) )start()

At first this seems to work fine because it creates a new thread to handle the network operation

However it violates the second rule of the single-threaded model do not access the Android UI toolkit

from outside the UI threadmdashthis sample modifies the ImageView from the worker thread instead of the

UI thread This can result in undefined and unexpected behavior which can be difficult and time-

consuming to track down

To fix this problem Android offers several ways to access the UI thread from other threads Here is a

list of methods that can help

ActivityrunOnUiThread(Runnable)

Viewpost(Runnable)

ViewpostDelayed(Runnable long)

For example you can fix the above code by using the Viewpost(Runnable) method

public void onClick(View v) new Thread(new Runnable() public void run() final Bitmap bitmap = loadImageFromNetwork(httpexamplecomimagepng) mImageViewpost(new Runnable() public void run() mImageViewsetImageBitmap(bitmap) ) )start()

Now this implementation is thread-safe the network operation is done from a separate thread while

the ImageView is manipulated from the UI thread

However as the complexity of the operation grows this kind of code can get complicated and difficult

to maintain To handle more complex interactions with a worker thread you might consider using a

Handler in your worker thread to process messages delivered from the UI thread Perhaps the best

solution though is to extend the AsyncTask class which simplifies the execution of worker thread

tasks that need to interact with the UI

Using AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface It performs the blocking

operations in a worker thread and then publishes the results on the UI thread without requiring you to

handle threads andor handlers yourself

To use it you must subclass AsyncTask and implement the doInBackground() callback method which

runs in a pool of background threads To update your UI you should implement onPostExecute()

which delivers the result from doInBackground() and runs in the UI thread so you can safely update

your UI You can then run the task by calling execute() from the UI thread

For example you can implement the previous example using AsyncTask this way

public void onClick(View v) new DownloadImageTask()execute(httpexamplecomimagepng) private class DownloadImageTask extends AsyncTaskltString Void Bitmapgt The system calls this to perform work in a worker thread and delivers it the parameters given to AsyncTaskexecute() protected Bitmap doInBackground(String urls) return loadImageFromNetwork(urls[0])

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 25: 03 services

Managing the Lifecycle of a Bound Service

Figure 1 The lifecycle for a service

that is started and also allows binding

When a service is unbound from all

clients the Android system destroys it

(unless it was also started with

onStartCommand()) As such you

dont have to manage the lifecycle of

your service if its purely a bound

servicemdashthe Android system manages

it for you based on whether it is bound

to any clients

However if you choose to implement

the onStartCommand() callback

method then you must explicitly stop

the service because the service is

now considered to be started In this

case the service runs until the service

stops itself with stopSelf() or another

component calls stopService()

regardless of whether it is bound to

any clients

Additionally if your service is started and accepts binding then when the system calls your onUnbind()

method you can optionally return true if you would like to receive a call to onRebind() the next time a

client binds to the service (instead of receiving a call to onBind()) onRebind() returns void but the

client still receives the IBinder in its onServiceConnected() callback Below figure 1 illustrates the logic

for this kind of lifecycle

For more information about the lifecycle of an started service see the Services document

Content Providers

Content providers store and retrieve data and make it accessible to all applications Theyre the only

way to share data across applications theres no common storage area that all Android packages can

access

Android ships with a number of content providers for common data types (audio video images

personal contact information and so on) You can see some of them listed in the androidprovider

package You can query these providers for the data they contain (although for some you must

acquire the proper permission to read the data)

If you want to make your own data public you have two options You can create your own content

provider (a ContentProvider subclass) or you can add the data to an existing provider mdash if theres one

that controls the same type of data and you have permission to write to it

This document is an introduction to using content providers After a brief discussion of the

fundamentals it explores how to query a content provider how to modify data controlled by a provider

and how to create a content provider of your own

Content Provider Basics

How a content provider actually stores its data under the covers is up to its designer But all content

providers implement a common interface for querying the provider and returning results mdash as well as

for adding altering and deleting data Its an interface that clients use indirectly most generally

through ContentResolver objects You get a ContentResolver by calling getContentResolver() from

within the implementation of an Activity or other application component

ContentResolver cr = getContentResolver()

You can then use the ContentResolvers methods to interact with whatever content providers youre

interested in When a query is initiated the Android system identifies the content provider thats the

target of the query and makes sure that it is up and running The system instantiates all

ContentProvider objects you never need to do it on your own In fact you never deal directly with

ContentProvider objects at all Typically theres just a single instance of each type of ContentProvider

But it can communicate with multiple ContentResolver objects in different applications and processes

The interaction between processes is handled by the ContentResolver and ContentProvider classes

The data model

Content providers expose their data as a simple table on a database model where each row is a

record and each column is data of a particular type and meaning For example information about

people and their phone numbers might be exposed as follows

_ID NUMBER NUMBER_KEY LABEL NAME TYPE

13 (425) 555 6677 425 555 6677 Kirkland office Bully Pulpit TYPE_WORK

44 (212) 555-1234 212 555 1234 NY apartment Alan Vain TYPE_HOME

45 (212) 555-6657 212 555 6657 Downtown office Alan Vain TYPE_MOBILE

53 2015554433 201 555 4433 Love Nest Rex Cars TYPE_HOME

Every record includes a numeric _ID field that uniquely identifies the record within the table IDs can be

used to match records in related tables mdash for example to find a persons phone number in one table

and pictures of that person in another

A query returns a Cursor object that can move from record to record and column to column to read the

contents of each field It has specialized methods for reading each type of data So to read a field you

must know what type of data the field contains (Theres more on query results and Cursor objects

later)

URIs

Each content provider exposes a public URI (wrapped as a Uri object) that uniquely identifies its data

set A content provider that controls multiple data sets (multiple tables) exposes a separate URI for

each one All URIs for providers begin with the string content The content scheme identifies the

data as being controlled by a content provider

If youre defining a content provider its a good idea to also define a constant for its URI to simplify

client code and make future updates cleaner Android defines CONTENT_URI constants for all the

providers that come with the platform For example the URI for the table that matches phone numbers

to people and the URI for the table that holds pictures of people (both controlled by the Contacts

content provider) are

androidproviderContactsPhonesCONTENT_URI

androidproviderContactsPhotosCONTENT_URI

The URI constant is used in all interactions with the content provider Every ContentResolver method

takes the URI as its first argument Its what identifies which provider the ContentResolver should talk

to and which table of the provider is being targeted

Querying a Content Provider

You need three pieces of information to query a content provider

The URI that identifies the provider

The names of the data fields you want to receive

The data types for those fields

If youre querying a particular record you also need the ID for that record

Making the query

To query a content provider you can use either the ContentResolverquery() method or the

ActivitymanagedQuery() method Both methods take the same set of arguments and both return a

Cursor object However managedQuery() causes the activity to manage the life cycle of the Cursor A

managed Cursor handles all of the niceties such as unloading itself when the activity pauses and

requerying itself when the activity restarts You can ask an Activity to begin managing an unmanaged

Cursor object for you by calling ActivitystartManagingCursor()

The first argument to either query() or managedQuery() is the provider URI mdash the CONTENT_URI

constant that identifies a particular ContentProvider and data set (see URIs earlier)

To restrict a query to just one record you can append the _ID value for that record to the URI mdash that

is place a string matching the ID as the last segment of the path part of the URI For example if the ID

is 23 the URI would be

content 23

There are some helper methods particularly ContentUriswithAppendedId() and

UriwithAppendedPath() that make it easy to append an ID to a URI Both are static methods that

return a Uri object with the ID added So for example if you were looking for record 23 in the database

of people contacts you might construct a query as follows

import androidproviderContactsPeople import androidcontentContentUris import androidnetUri import androiddatabaseCursor Use the ContentUris method to produce the base URI for the contact with _ID == 23 Uri myPerson = ContentUriswithAppendedId(PeopleCONTENT_URI 23) Alternatively use the Uri method to produce the base URI It takes a string rather than an integer Uri myPerson = UriwithAppendedPath(PeopleCONTENT_URI 23) Then query for this specific record Cursor cur = managedQuery(myPerson null null null null)

The other arguments to the query() and managedQuery() methods delimit the query in more detail

They are

The names of the data columns that should be returned A null value returns all columns Otherwise

only columns that are listed by name are returned All the content providers that come with the

platform define constants for their columns For example the androidproviderContactsPhones class

defines constants for the names of the columns in the phone table illustrated earlier ampmdash _ID

NUMBER NUMBER_KEY NAME and so on

A filter detailing which rows to return formatted as an SQL WHERE clause (excluding the WHERE

itself) A null value returns all rows (unless the URI limits the query to a single record)

Selection arguments

A sorting order for the rows that are returned formatted as an SQL ORDER BY clause (excluding the

ORDER BY itself) A null value returns the records in the default order for the table which may be

unordered

Lets look at an example query to retrieve a list of contact names and their primary phone numbers

import androidproviderContactsPeople import androiddatabaseCursor Form an array specifying which columns to return String[] projection = new String[] People_ID People_COUNT PeopleNAME PeopleNUMBER Get the base URI for the People table in the Contacts content provider Uri contacts = PeopleCONTENT_URI Make the query Cursor managedCursor = managedQuery(contacts projection Which columns to return null Which rows to return (all rows) null Selection arguments (none) Put the results in ascending order by name PeopleNAME + ASC)

This query retrieves data from the People table of the Contacts content provider It gets the name

primary phone number and unique record ID for each contact It also reports the number of records

that are returned as the _COUNT field of each record

The constants for the names of the columns are defined in various interfaces mdash _ID and _COUNT in

BaseColumns NAME in PeopleColumns and NUMBER in PhoneColumns The ContactsPeople

class implements each of these interfaces which is why the code example above could refer to them

using just the class name

What a query returns

A query returns a set of zero or more database records The names of the columns their default order

and their data types are specific to each content provider But every provider has an _ID column

which holds a unique numeric ID for each record Every provider can also report the number of records

returned as the _COUNT column its value is the same for all rows

Here is an example result set for the query in the previous section

_ID _COUNT NAME NUMBER

44 3 Alan Vain 212 555 1234

13 3 Bully Pulpit 425 555 6677

53 3 Rex Cars 201 555 4433

The retrieved data is exposed by a Cursor object that can be used to iterate backward or forward

through the result set You can use this object only to read the data To add modify or delete data

you must use a ContentResolver object

Reading retrieved data

The Cursor object returned by a query provides access to a recordset of results If you have queried

for a specific record by ID this set will contain only one value Otherwise it can contain multiple

values (If there are no matches it can also be empty) You can read data from specific fields in the

record but you must know the data type of the field because the Cursor object has a separate method

for reading each type of data mdash such as getString() getInt() and getFloat() (However for most types

if you call the method for reading strings the Cursor object will give you the String representation of

the data) The Cursor lets you request the column name from the index of the column or the index

number from the column name

The following snippet demonstrates reading names and phone numbers from the query illustrated

earlier

import androidproviderContactsPeople private void getColumnData(Cursor cur) if (curmoveToFirst()) String name String phoneNumber int nameColumn = curgetColumnIndex(PeopleNAME) int phoneColumn = curgetColumnIndex(PeopleNUMBER) String imagePath do Get the field values name = curgetString(nameColumn) phoneNumber = curgetString(phoneColumn) Do something with the values while (curmoveToNext())

If a query can return binary data such as an image or sound the data may be directly entered in the

table or the table entry for that data may be a string specifying a content URI that you can use to get

the data In general smaller amounts of data (say from 20 to 50K or less) are most often directly

entered in the table and can be read by calling CursorgetBlob() It returns a byte array

If the table entry is a content URI you should never try to open and read the file directly (for one thing

permissions problems can make this fail) Instead you should call ContentResolveropenInputStream()

to get an InputStream object that you can use to read the data

Modifying Data

Data kept by a content provider can be modified by

Adding new records

Adding new values to existing records

Batch updating existing records

Deleting records

All data modification is accomplished using ContentResolver methods Some content providers require

a more restrictive permission for writing data than they do for reading it If you dont have permission to

write to a content provider the ContentResolver methods will fail

Adding records

To add a new record to a content provider first set up a map of key-value pairs in a ContentValues

object where each key matches the name of a column in the content provider and the value is the

desired value for the new record in that column Then call ContentResolverinsert() and pass it the URI

of the provider and the ContentValues map This method returns the full URI of the new record mdash that

is the providers URI with the appended ID for the new record You can then use this URI to query and

get a Cursor over the new record and to further modify the record Heres an example

import androidproviderContactsPeople import androidcontentContentResolver import androidcontentContentValues ContentValues values = new ContentValues() Add Abraham Lincoln to contacts and make him a favorite valuesput(PeopleNAME Abraham Lincoln) 1 = the new contact is added to favorites 0 = the new contact is not added to favorites valuesput(PeopleSTARRED 1) Uri uri = getContentResolver()insert(PeopleCONTENT_URI values)

Adding new values

Once a record exists you can add new information to it or modify existing information For example

the next step in the example above would be to add contact information mdash like a phone number or an

IM or e-mail address mdash to the new entry

The best way to add to a record in the Contacts database is to append the name of the table where the

new data goes to the URI for the record then use the amended URI to add the new data values Each

Contacts table exposes a name for this purpose as a CONTENT_DIRECTORY constant The following

code continues the previous example by adding a phone number and e-mail address for the record

just created

Uri phoneUri = null Uri emailUri = null Add a phone number for Abraham Lincoln Begin with the URI for the new record just returned by insert() it ends with the _ID of the new record so we dont have to add the ID ourselves Then append the designation for the phone table to this URI and use the resulting URI to insert the phone number phoneUri = UriwithAppendedPath(uri PeoplePhonesCONTENT_DIRECTORY) valuesclear() valuesput(PeoplePhonesTYPE PeoplePhonesTYPE_MOBILE) valuesput(PeoplePhonesNUMBER 1233214567) getContentResolver()insert(phoneUri values) Now add an email address in the same way emailUri = UriwithAppendedPath(uri PeopleContactMethodsCONTENT_DIRECTORY) valuesclear() ContactMethodsKIND is used to distinguish different kinds of contact methods such as email IM etc valuesput(PeopleContactMethodsKIND ContactsKIND_EMAIL) valuesput(PeopleContactMethodsDATA testexamplecom) valuesput(PeopleContactMethodsTYPE PeopleContactMethodsTYPE_HOME) getContentResolver()insert(emailUri values)

You can place small amounts of binary data into a table by calling the version of ContentValuesput()

that takes a byte array That would work for a small icon-like image or a short audio clip for example

However if you have a large amount of binary data to add such as a photograph or a complete song

put a content URI for the data in the table and call ContentResolveropenOutputStream() with the files

URI (That causes the content provider to store the data in a file and record the file path in a hidden

field of the record)

In this regard the MediaStore content provider the main provider that dispenses image audio and

video data employs a special convention The same URI that is used with query() or managedQuery()

to get meta-information about the binary data (such as the caption of a photograph or the date it was

taken) is used with openInputStream() to get the data itself Similarly the same URI that is used with

insert() to put meta-information into a MediaStore record is used with openOutputStream() to place the

binary data there The following code snippet illustrates this convention

import androidproviderMediaStoreImagesMedia import androidcontentContentValues import javaioOutputStream Save the name and description of an image in a ContentValues map ContentValues values = new ContentValues(3) valuesput(MediaDISPLAY_NAME road_trip_1) valuesput(MediaDESCRIPTION Day 1 trip to Los Angeles) valuesput(MediaMIME_TYPE imagejpeg) Add a new record without the bitmap but with the values just set insert() returns the URI of the new record Uri uri = getContentResolver()insert(MediaEXTERNAL_CONTENT_URI values) Now get a handle to the file for that record and save the data into it Here sourceBitmap is a Bitmap object representing the file to save to the database try OutputStream outStream = getContentResolver()openOutputStream(uri) sourceBitmapcompress(BitmapCompressFormatJPEG 50 outStream) outStreamclose() catch (Exception e) Loge(TAG exception while writing image e)

Batch updating records

To batch update a group of records (for example to change NY to New York in all fields) call the

ContentResolverupdate() method with the columns and values to change

Deleting a record

To delete a single record call ContentResolverdelete() with the URI of a specific row

To delete multiple rows call ContentResolverdelete() with the URI of the type of record to delete (for

example androidproviderContactsPeopleCONTENT_URI) and an SQL WHERE clause defining

which rows to delete (Caution Be sure to include a valid WHERE clause if youre deleting a general

type or you risk deleting more records than you intended)

Creating a Content Provider

To create a content provider you must

Set up a system for storing the data Most content providers store their data using Androids file

storage methods or SQLite databases but you can store your data any way you want Android

provides the SQLiteOpenHelper class to help you create a database and SQLiteDatabase to manage

it

Extend the ContentProvider class to provide access to the data

Declare the content provider in the manifest file for your application (AndroidManifestxml)

The following sections have notes on the last two of these tasks

Extending the ContentProvider class

You define a ContentProvider subclass to expose your data to others using the conventions expected

by ContentResolver and Cursor objects Principally this means implementing six abstract methods

declared in the ContentProvider class

query()

insert()

update()

delete()

getType()

onCreate()

The query() method must return a Cursor object that can iterate over the requested data Cursor itself

is an interface but Android provides some ready-made Cursor objects that you can use For example

SQLiteCursor can iterate over data stored in an SQLite database You get the Cursor object by calling

any of the SQLiteDatabase classs query() methods There are other Cursor implementations mdash such

as MatrixCursor mdash for data not stored in a database

Because these ContentProvider methods can be called from various ContentResolver objects in

different processes and threads they must be implemented in a thread-safe manner

As a courtesy you might also want to call ContentResolvernotifyChange() to notify listeners when

there are modifications to the data

Beyond defining the subclass itself there are other steps you should take to simplify the work of clients

and make the class more accessible

Define a public static final Uri named CONTENT_URI This is the string that represents the full content

URI that your content provider handles You must define a unique string for this value The best

solution is to use the fully-qualified class name of the content provider (made lowercase) So for

example the URI for a TransportationProvider class could be defined as follows

public static final Uri CONTENT_URI = Uriparse(contentcomexamplecodelabtransportationprovider)

If the provider has subtables also define CONTENT_URI constants for each of the subtables These

URIs should all have the same authority (since that identifies the content provider) and be

distinguished only by their paths For example

contentcomexamplecodelabtransportationprovidertrain

contentcomexamplecodelabtransportationproviderairdomestic

contentcomexamplecodelabtransportationproviderairinternational

For an overview of content URIs see the Content URI Summary at the end of this document

Define the column names that the content provider will return to clients If you are using an underlying

database these column names are typically identical to the SQL database column names they

represent Also define public static String constants that clients can use to specify the columns in

queries and other instructions

Be sure to include an integer column named _id (with the constant _ID) for the IDs of the records

You should have this field whether or not you have another field (such as a URL) that is also unique

among all records If youre using the SQLite database the _ID field should be the following type

INTEGER PRIMARY KEY AUTOINCREMENT

The AUTOINCREMENT descriptor is optional But without it SQLite increments an ID counter field to

the next number above the largest existing number in the column If you delete the last row the next

row added will have the same ID as the deleted row AUTOINCREMENT avoids this by having SQLite

increment to the next largest value whether deleted or not

Carefully document the data type of each column Clients need this information to read the data

If you are handling a new data type you must define a new MIME type to return in your

implementation of ContentProvidergetType() The type depends in part on whether or not the content

URI submitted to getType() limits the request to a specific record Theres one form of the MIME type

for a single record and another for multiple records Use the Uri methods to help determine what is

being requested Here is the general format for each type

o For a single record vndandroidcursoritemvndyourcompanynamecontenttype

For example a request for train record 122 like this URI

contentcomexampletransportationprovidertrains122

might return this MIME type

vndandroidcursoritemvndexamplerail

o For multiple records vndandroidcursordirvndyourcompanynamecontenttype

For example a request for all train records like the following URI

contentcomexampletransportationprovidertrains

might return this MIME type

vndandroidcursordirvndexamplerail

If you are exposing byte data thats too big to put in the table itself mdash such as a large bitmap file mdash the

field that exposes the data to clients should actually contain a content URI string This is the field that

gives clients access to the data file The record should also have another field named _data that lists

the exact file path on the device for that file This field is not intended to be read by the client but by

the ContentResolver The client will call ContentResolveropenInputStream() on the user-facing field

holding the URI for the item The ContentResolver will request the _data field for that record and

because it has higher permissions than a client it should be able to access that file directly and return

a read wrapper for the file to the client

For an example of a private content provider implementation see the NodePadProvider class in the

Notepad sample application that ships with the SDK

Declaring the content provider

To let the Android system know about the content provider youve developed declare it with a

ltprovidergt element in the applications AndroidManifestxml file Content providers that are not

declared in the manifest are not visible to the Android system

The name attribute is the fully qualified name of the ContentProvider subclass The authorities attribute

is the authority part of the content URI that identifies the provider For example if the ContentProvider

subclass is AutoInfoProvider the ltprovidergt element might look like this

ltprovider androidname=comexampleautosAutoInfoProvider androidauthorities=comexampleautosautoinfoprovider gt ltprovidergt

Note that the authorities attribute omits the path part of a content URI For example if

AutoInfoProvider controlled subtables for different types of autos or different manufacturers

contentcomexampleautosautoinfoproviderhonda

contentcomexampleautosautoinfoprovidergmcompact

contentcomexampleautosautoinfoprovidergmsuv

those paths would not be declared in the manifest The authority is what identifies the provider not the

path your provider can interpret the path part of the URI in any way you choose

Other ltprovidergt attributes can set permissions to read and write data provide for an icon and text

that can be displayed to users enable and disable the provider and so on Set the multiprocess

attribute to true if data does not need to be synchronized between multiple running versions of the

content provider This permits an instance of the provider to be created in each client process

eliminating the need to perform IPC

Content URI Summary

Here is a recap of the important parts of a content URI

A Standard prefix indicating that the data is controlled by a content provider Its never modified

B The authority part of the URI it identifies the content provider For third-party applications this should

be a fully-qualified class name (reduced to lowercase) to ensure uniqueness The authority is declared

in the ltprovidergt elements authorities attribute

ltprovider androidname=TransportationProvider androidauthorities=comexampletransportationprovider gt

C The path that the content provider uses to determine what kind of data is being requested This can be

zero or more segments long If the content provider exposes only one type of data (only trains for

example) it can be absent If the provider exposes several types including subtypes it can be several

segments long mdash for example landbus landtrain seaship and seasubmarine to give four

possibilities

D The ID of the specific record being requested if any This is the _ID value of the requested record If

the request is not limited to a single record this segment and the trailing slash are omitted

contentcomexampletransportationprovidertrains

Intent and intent filters

Three of the core components of an application mdash activities services and broadcast receivers mdash 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 mdash 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 ContextstartActivity() or ActivitystartActivityForResult() to launch an

activity or get an existing activity to do something new (It can also be passed to ActivitysetResult() to

return information to the activity that called startActivityForResult())

An Intent object is passed to ContextstartService() to initiate a service or deliver new instructions to an

ongoing service Similarly an intent can be passed to ContextbindService() to establish a connection

between the calling component and a target service It can optionally initiate the service if its not

already running

Intent objects passed to any of the broadcast methods (such as ContextsendBroadcast()

ContextsendOrderedBroadcast() or ContextsendStickyBroadcast()) 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 mdash how it resolves which component should receive an intent message For

intents that dont explicitly name a target component this process involves testing the Intent object

against intent filters associated with potential targets

Intent Objects

An Intent object is a bundle of information It contains information of interest to the component that

receives the intent (such as the action to be taken and the data to act on) plus information of interest to

the Android system (such as the category of component that should handle the intent and instructions

on how to launch a target activity) Principally it can contain the following

Component name

The name of the component that should handle the intent This field is a ComponentName

object mdash a combination of the fully qualified class name of the target component (for example

comexampleprojectappFreneticActivity) and the package name set in the manifest file of the

application where the component resides (for example comexampleproject) The package

part of the component name and the package name set in the manifest do not necessarily have

to match

The component name is optional If it is set the Intent object is delivered to an instance of the

designated class If it is not set Android uses other information in the Intent object to locate a

suitable target mdash see Intent Resolution later in this document

The component name is set by setComponent() setClass() or setClassName() and read by

getComponent()

Action

A string naming the action to be performed mdash or in the case of broadcast intents the action

that took place and is being reported The Intent class defines a number of action constants

including these

Constant Target

component

Action

ACTION_CALL activity Initiate a phone call

ACTION_EDIT activity Display data for the user to edit

ACTION_MAIN activity Start up as the initial activity of a task

with no data input and no returned

output

ACTION_SYNC activity Synchronize data on a server with

data on the mobile device

ACTION_BATTERY_LOW broadcast

receiver

A warning that the battery is low

ACTION_HEADSET_PLUG broadcast

receiver

A headset has been plugged into the

device or unplugged from it

ACTION_SCREEN_ON broadcast

receiver

The screen has been turned on

ACTION_TIMEZONE_CHANGED broadcast

receiver

The setting for the time zone has

changed

See the Intent class description for a list of pre-defined constants for generic actions Other

actions are defined elsewhere in the Android API You can also define your own action strings

for activating the components in your application Those you invent should include the

application package as a prefix mdash for example comexampleprojectSHOW_COLOR

The action largely determines how the rest of the intent is structured mdash particularly the data and

extras fields mdash much as a method name determines a set of arguments and a return value For

this reason its a good idea to use action names that are as specific as possible and to couple

them tightly to the other fields of the intent In other words instead of defining an action in

isolation define an entire protocol for the Intent objects your components can handle

The action in an Intent object is set by the setAction() method and read by getAction()

Data

The URI of the data to be acted on and the MIME type of that data Different actions are paired

with different kinds of data specifications For example if the action field is ACTION_EDIT the

data field would contain the URI of the document to be displayed for editing If the action is

ACTION_CALL the data field would be a tel URI with the number to call Similarly if the action

is ACTION_VIEW and the data field is an http URI the receiving activity would be called upon

to download and display whatever data the URI refers to

When matching an intent to a component that is capable of handling the data its often

important to know the type of data (its MIME type) in addition to its URI For example a

component able to display image data should not be called upon to play an audio file

In many cases the data type can be inferred from the URI mdash particularly content URIs which

indicate that the data is located on the device and controlled by a content provider (see the

separate discussion on content providers) But the type can also be explicitly set in the Intent

object The setData() method specifies data only as a URI setType() specifies it only as a

MIME type and setDataAndType() specifies it as both a URI and a MIME type The URI is read

by getData() and the type by getType()

Category

A string containing additional information about the kind of component that should handle the

intent Any number of category descriptions can be placed in an Intent object As it does for

actions the Intent class defines several category constants including these

Constant Meaning

CATEGORY_BROWSABLE The target activity can be safely invoked by the browser to

display data referenced by a link mdash for example an image or

an e-mail message

CATEGORY_GADGET The activity can be embedded inside of another activity that

hosts gadgets

CATEGORY_HOME The activity displays the home screen the first screen the

user sees when the device is turned on or when the HOME

key is pressed

CATEGORY_LAUNCHER The activity can be the initial activity of a task and is listed in

the top-level application launcher

CATEGORY_PREFERENCE The target activity is a preference panel

See the Intent class description for the full list of categories

The addCategory() method places a category in an Intent object removeCategory() deletes a

category previously added and getCategories() gets the set of all categories currently in the

object

Extras

Key-value pairs for additional information that should be delivered to the component handling

the intent Just as some actions are paired with particular kinds of data URIs some are paired

with particular extras For example an ACTION_TIMEZONE_CHANGED intent has a time-

zone extra that identifies the new time zone and ACTION_HEADSET_PLUG has a state

extra indicating whether the headset is now plugged in or unplugged as well as a name extra

for the type of headset If you were to invent a SHOW_COLOR action the color value would be

set in an extra key-value pair

The Intent object has a series of put() methods for inserting various types of extra data and a

similar set of get() methods for reading the data These methods parallel those for Bundle

objects In fact the extras can be installed and read as a Bundle using the putExtras() and

getExtras() methods

Flags

Flags of various sorts Many instruct the Android system how to launch an activity (for example

which task the activity should belong to) and how to treat it after its launched (for example

whether it belongs in the list of recent activities) All these flags are defined in the Intent class

The Android system and the applications that come with the platform employ Intent objects both to

send out system-originated broadcasts and to activate system-defined components To see how to

structure an intent to activate a system component consult the list of intents in the reference

Intent Resolution

Intents can be divided into two groups

Explicit intents designate the target component by its name (the component name field mentioned

earlier has a value set) Since component names would generally not be known to developers of other

applications explicit intents are typically used for application-internal messages mdash such as an activity

starting a subordinate service or launching a sister activity

Implicit intents do not name a target (the field for the component name is blank) Implicit intents are

often used to activate components in other applications

Android delivers an explicit intent to an instance of the designated target class Nothing in the Intent

object other than the component name matters for determining which component should get the intent

A different strategy is needed for implicit intents In the absence of a designated target the Android

system must find the best component (or components) to handle the intent mdash a single activity or

service to perform the requested action or the set of broadcast receivers to respond to the broadcast

announcement It does so by comparing the contents of the Intent object to intent filters structures

associated with components that can potentially receive intents Filters advertise the capabilities of a

component and delimit the intents it can handle They open the component to the possibility of

receiving implicit intents of the advertised type If a component does not have any intent filters it can

receive only explicit intents A component with filters can receive both explicit and implicit intents

Only three aspects of an Intent object are consulted when the object is tested against an intent filter

action

data (both URI and data type)

category

The extras and flags play no part in resolving which component receives an intent

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 mdash but only unwanted implicit intents (those that dont 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

components 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 mdash 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 Pads filters are described in the Note Pad Example

section later)

Filters and security

An intent filter cannot be relied on for security While it opens a component to receiving only certain

kinds of implicit intents it does nothing to prevent explicit intents from targeting the component Even

though a filter restricts the intents a component will be asked to handle to certain actions and data

sources someone could always put together an explicit intent with a different action and data source

and name the component as the target

An intent filter is an instance of the IntentFilter class However since the Android system must know

about the capabilities of a component before it can launch that component intent filters are generally

not set up in Java code but in the applications manifest file (AndroidManifestxml) as ltintent-filtergt

elements (The one exception would be filters for broadcast receivers that are registered dynamically

by calling ContextregisterReceiver() they are directly created as IntentFilter objects)

A filter has fields that parallel the action data and category fields of an Intent object An implicit intent

is tested against the filter in all three areas To be delivered to the component that owns the filter it

must pass all three tests If it fails even one of them the Android system wont deliver it to the

component mdash at least not on the basis of that filter However since a component can have multiple

intent filters an intent that does not pass through one of a components filters might make it through on

another

Each of the three tests is described in detail below

Action test

An ltintent-filtergt element in the manifest file lists actions as ltactiongt subelements For

example

ltintent-filter gt ltaction androidname=comexampleprojectSHOW_CURRENT gt ltaction androidname=comexampleprojectSHOW_RECENT gt ltaction androidname=comexampleprojectSHOW_PENDING gt ltintent-filtergt

As the example shows while an Intent object names just a single action a filter may list more

than one The list cannot be empty a filter must contain at least one ltactiongt element or it will

block all intents

To pass this test the action specified in the Intent object must match one of the actions listed in

the filter If the object or the filter does not specify an action the results are as follows

If the filter fails to list any actions there is nothing for an intent to match so all intents fail the

test No intents can get through the filter

On the other hand an Intent object that doesnt specify an action automatically passes the test

mdash as long as the filter contains at least one action

Category test

An ltintent-filtergt element also lists categories as subelements For example

ltintent-filter gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryBROWSABLE gt ltintent-filtergt

Note that the constants described earlier for actions and categories are not used in the manifest

file The full string values are used instead For instance the

androidintentcategoryBROWSABLE string in the example above corresponds to the

CATEGORY_BROWSABLE constant mentioned earlier in this document Similarly the string

androidintentactionEDIT corresponds to the ACTION_EDIT constant

For an intent to pass the category test every category in the Intent object must match a

category in the filter The filter can list additional categories but it cannot omit any that are in the

intent

In principle therefore an Intent object with no categories should always pass this test

regardless of whats in the filter Thats mostly true However with one exception Android treats

all implicit intents passed to startActivity() as if they contained at least one category

androidintentcategoryDEFAULT (the CATEGORY_DEFAULT constant) Therefore activities

that are willing to receive implicit intents must include androidintentcategoryDEFAULT in

their intent filters (Filters with androidintentactionMAIN and

androidintentcategoryLAUNCHER settings are the exception They mark activities that begin

new tasks and that are represented on the launcher screen They can include

androidintentcategoryDEFAULT in the list of categories but dont need to) See Using intent

matching later for more on these filters)

Data test

Like the action and categories the data specification for an intent filter is contained in a

subelement And as in those cases the subelement can appear multiple times or not at all For

example

ltintent-filter gt ltdata androidmimeType=videompeg androidscheme=http gt ltdata androidmimeType=audiompeg androidscheme=http gt ltintent-filtergt

Each ltdatagt element can specify a URI and a data type (MIME media type) There are

separate attributes mdash scheme host port and path mdash for each part of the URI

schemehostportpath

For example in the following URI

contentcomexampleproject200foldersubfolderetc

the scheme is content the host is comexampleproject the port is 200 and the path is

foldersubfolderetc The host and port together constitute the URI authority if a host is not

specified the port is ignored

Each of these attributes is optional but they are not independent of each other For an authority

to be meaningful a scheme must also be specified For a path to be meaningful both a scheme

and an authority must be specified

When the URI in an Intent object is compared to a URI specification in a filter its compared

only to the parts of the URI actually mentioned in the filter For example if a filter specifies only

a scheme all URIs with that scheme match the filter If a filter specifies a scheme and an

authority but no path all URIs with the same scheme and authority match regardless of their

paths If a filter specifies a scheme an authority and a path only URIs with the same scheme

authority and path match However a path specification in the filter can contain wildcards to

require only a partial match of the path

The type attribute of a ltdatagt element specifies the MIME type of the data Its more common in

filters than a URI Both the Intent object and the filter can use a wildcard for the subtype field

mdash for example text or audio mdash indicating any subtype matches

The data test compares both the URI and the data type in the Intent object to a URI and data

type specified in the filter The rules are as follows

a An Intent object that contains neither a URI nor a data type passes the test only if the filter

likewise does not specify any URIs or data types

b An Intent object that contains a URI but no data type (and a type cannot be inferred from the

URI) passes the test only if its URI matches a URI in the filter and the filter likewise does not

specify a type This will be the case only for URIs like mailto and tel that do not refer to actual

data

c An Intent object that contains a data type but not a URI passes the test only if the filter lists the

same data type and similarly does not specify a URI

d An Intent object that contains both a URI and a data type (or a data type can be inferred from

the URI) passes the data type part of the test only if its type matches a type listed in the filter It

passes the URI part of the test either if its URI matches a URI in the filter or if it has a content

or file URI and the filter does not specify a URI In other words a component is presumed to

support content and file data if its filter lists only a data type

If an intent can pass through the filters of more than one activity or service the user may be asked

which component to activate An exception is raised if no target can be found

Common cases

The last rule shown above for the data test rule (d) reflects the expectation that components are able

to get local data from a file or content provider Therefore their filters can list just a data type and do

not need to explicitly name the content and file schemes This is a typical case A ltdatagt element like

the following for example tells Android that the component can get image data from a content

provider and display it

ltdata androidmimeType=image gt

Since most available data is dispensed by content providers filters that specify a data type but not a

URI are perhaps the most common

Another common configuration is filters with a scheme and a data type For example a ltdatagt

element like the following tells Android that the component can get video data from the network and

display it

ltdata androidscheme=http androidtype=video gt

Consider for example what the browser application does when the user follows a link on a web page

It first tries to display the data (as it could if the link was to an HTML page) If it cant display the data it

puts together an implicit intent with the scheme and data type and tries to start an activity that can do

the job If there are no takers it asks the download manager to download the data That puts it under

the control of a content provider so a potentially larger pool of activities (those with filters that just

name a data type) can respond

Most applications also have a way to start fresh without a reference to any particular data Activities

that can initiate applications have filters with androidintentactionMAIN specified as the action If

they are to be represented in the application launcher they also specify the

androidintentcategoryLAUNCHER category

ltintent-filter gt ltaction androidname=code androidintentactionMAIN gt ltcategory androidname=code androidintentcategoryLAUNCHER gt ltintent-filtergt

Using intent matching

Intents are matched against intent filters not only to discover a target component to activate but also

to discover something about the set of components on the device For example the Android system

populates the application launcher the top-level screen that shows the applications that are available

for the user to launch by finding all the activities with intent filters that specify the

androidintentactionMAIN action and androidintentcategoryLAUNCHER category (as illustrated

in the previous section) It then displays the icons and labels of those activities in the launcher

Similarly it discovers the home screen by looking for the activity with androidintentcategoryHOME

in its filter

Your application can use intent matching is a similar way The PackageManager has a set of query()

methods that return all components that can accept a particular intent and a similar series of

resolve() methods that determine the best component to respond to an intent For example

queryIntentActivities() returns a list of all activities that can perform the intent passed as an argument

and queryIntentServices() returns a similar list of services Neither method activates the components

they just list the ones that can respond Theres a similar method queryBroadcastReceivers() for

broadcast receivers

Note Pad Example

The Note Pad sample application enables users to browse through a list of notes view details about

individual items in the list edit the items and add a new item to the list This section looks at the intent

filters declared in its manifest file (If youre working offline in the SDK you can find all the source files

for this sample application including its manifest file at ltsdkgtsamplesNotePadindexhtml If youre

viewing the documentation online the source files are in the Tutorials and Sample Code section here)

In its manifest file the Note Pad application declares three activities each with at least one intent filter

It also declares a content provider that manages the note data Here is the manifest file in its entirety

ltmanifest xmlnsandroid=httpschemasandroidcomapkresandroid package=comexampleandroidnotepadgt ltapplication androidicon=drawableapp_notes androidlabel=stringapp_name gt ltprovider androidname=NotePadProvider androidauthorities=comgoogleproviderNotePad gt ltactivity androidname=NotesList androidlabel=stringtitle_notes_listgt ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltactivity androidname=NoteEditor androidtheme=androidstyleThemeLight androidlabel=stringtitle_note gt ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltactivitygt

ltactivity androidname=TitleEditor androidlabel=stringtitle_edit_title androidtheme=androidstyleThemeDialoggt ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltapplicationgt ltmanifestgt

The first activity NotesList is distinguished from the other activities by the fact that it operates on a

directory of notes (the note list) rather than on a single note It would generally serve as the initial user

interface into the application It can do three things as described by its three intent filters

1 ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt

This filter declares the main entry point into the Note Pad application The standard MAIN action is an

entry point that does not require any other information in the Intent (no data specification for example)

and the LAUNCHER category says that this entry point should be listed in the application launcher

2 ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

This filter declares the things that the activity can do on a directory of notes It can allow the user to

view or edit the directory (via the VIEW and EDIT actions) or to pick a particular note from the

directory (via the PICK action)

The mimeType attribute of the ltdatagt element specifies the kind of data that these actions operate on

It indicates that the activity can get a Cursor over zero or more items (vndandroidcursordir) from a

content provider that holds Note Pad data (vndgooglenote) The Intent object that launches the

activity would include a content URI specifying the exact data of this type that the activity should open

Note also the DEFAULT category supplied in this filter Its there because the ContextstartActivity()

and ActivitystartActivityForResult() methods treat all intents as if they contained the DEFAULT

category mdash with just two exceptions

o Intents that explicitly name the target activity

o Intents consisting of the MAIN action and LAUNCHER category

Therefore the DEFAULT category is required for all filters mdash except for those with the MAIN action

and LAUNCHER category (Intent filters are not consulted for explicit intents)

3 ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

This filter describes the activitys ability to return a note selected by the user without requiring any

specification of the directory the user should choose from The GET_CONTENT action is similar to the

PICK action In both cases the activity returns the URI for a note selected by the user (In each case

its returned to the activity that called startActivityForResult() to start the NoteList activity) Here

however the caller specifies the type of data desired instead of the directory of data the user will be

picking from

The data type vndandroidcursoritemvndgooglenote indicates the type of data the activity can

return mdash a URI for a single note From the returned URI the caller can get a Cursor for exactly one

item (vndandroidcursoritem) from the content provider that holds Note Pad data (vndgooglenote)

In other words for the PICK action in the previous filter the data type indicates the type of data the

activity could display to the user For the GET_CONTENT filter it indicates the type of data the activity

can return to the caller

Given these capabilities the following intents will resolve to the NotesList activity

action androidintentactionMAIN

Launches the activity with no data specified

action androidintentactionMAIN

category androidintentcategoryLAUNCHER

Launches the activity with no data selected specified This is the actual intent used by the

Launcher to populate its top-level list All activities with filters that match this action and

category are added to the list

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of all the notes under

contentcomgoogleproviderNotePadnotes The user can then browse through the list and

get information about the items in it

action androidintentactionPICK

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of the notes under

contentcomgoogleproviderNotePadnotes The user can then pick a note from the list and

the activity will return the URI for that item back to the activity that started the NoteList activity

action androidintentactionGET_CONTENT

data type vndandroidcursoritemvndgooglenote

Asks the activity to supply a single item of Note Pad data

The second activity NoteEditor shows users a single note entry and allows them to edit it It can do

two things as described by its two intent filters

1 ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The first primary purpose of this activity is to enable the user to interact with a single note ampmdash to

either VIEW the note or EDIT it (The EDIT_NOTE category is a synonym for EDIT) The intent would

contain the URI for data matching the MIME type vndandroidcursoritemvndgooglenote mdash that is

the URI for a single specific note It would typically be a URI that was returned by the PICK or

GET_CONTENT actions of the NoteList activity

As before this filter lists the DEFAULT category so that the activity can be launched by intents that

dont explicitly specify the NoteEditor class

2 ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

The secondary purpose of this activity is to enable the user to create a new note which it will INSERT

into an existing directory of notes The intent would contain the URI for data matching the MIME type

vndandroidcursordirvndgooglenote mdash that is the URI for the directory where the note should be

placed

Given these capabilities the following intents will resolve to the NoteEditor activity

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID (For details on how content

URIs specify individual members of a group see Content Providers)

action androidintentactionEDIT

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID and to let the user edit it If

the user saves the changes the activity updates the data for the note in the content provider

action androidintentactionINSERT

data contentcomgoogleproviderNotePadnotes

Asks the activity to create a new empty note in the notes list at

contentcomgoogleproviderNotePadnotes and allow the user to edit it If the user saves the

note its URI is returned to the caller

The last activity TitleEditor enables the user to edit the title of a note This could be implemented by

directly invoking the activity (by explicitly setting its component name in the Intent) without using an

intent filter But here we take the opportunity to show how to publish alternative operations on existing

data

ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The single intent filter for this activity uses a custom action called

comandroidnotepadactionEDIT_TITLE It must be invoked on a specific note (data type

vndandroidcursoritemvndgooglenote) like the previous VIEW and EDIT actions However here the

activity displays the title contained in the note data not the content of the note itself

In addition to supporting the usual DEFAULT category the title editor also supports two other standard

categories ALTERNATIVE and SELECTED_ALTERNATIVE These categories identify activities that

can be presented to users in a menu of options (much as the LAUNCHER category identifies activities

that should be presented to user in the application launcher) Note that the filter also supplies an

explicit label (via androidlabel=stringresolve_title) to better control what users see when

presented with this activity as an alternative action to the data they are currently viewing (For more

information on these categories and building options menus see the

PackageManagerqueryIntentActivityOptions() and MenuaddIntentOptions() methods)

Given these capabilities the following intent will resolve to the TitleEditor activity

action comandroidnotepadactionEDIT_TITLE

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the title associated with note ID and allow the user to edit the title

Processes and Threads

When an application component starts and the application does not have any other components

running the Android system starts a new Linux process for the application with a single thread of

execution By default all components of the same application run in the same process and thread

(called the main thread) If an application component starts and there already exists a process for

that application (because another component from the application exists) then the component is

started within that process and uses the same thread of execution However you can arrange for

different components in your application to run in separate processes and you can create additional

threads for any process

This document discusses how processes and threads work in an Android application

Processes

By default all components of the same application run in the same process and most applications

should not change this However if you find that you need to control which process a certain

component belongs to you can do so in the manifest file

The manifest entry for each type of component elementmdashltactivitygt ltservicegt ltreceivergt and

ltprovidergtmdashsupports an androidprocess attribute that can specify a process in which that component

should run You can set this attribute so that each component runs in its own process or so that some

components share a process while others do not You can also set androidprocess so that

components of different applications run in the same processmdashprovided that the applications share the

same Linux user ID and are signed with the same certificates

The ltapplicationgt element also supports an androidprocess attribute to set a default value that

applies to all components

Android might 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 thats killed are consequently destroyed A process is started again for those components

when theres again work for them to do

When deciding which processes to kill the Android system weighs their relative importance to the

user For example it more readily shuts down a process hosting activities that are no longer visible on

screen compared to a process hosting visible activities The decision whether to terminate a process

therefore depends on the state of the components running in that process The rules used to decide

which processes to terminate is discussed below

Process lifecycle

The Android system tries to maintain an application process for as long as possible but eventually

needs to remove old processes to reclaim memory for new or more important processes To determine

which processes to keep and which to kill the system places each process into an importance

hierarchy based on the components running in the process and the state of those components

Processes with the lowest importance are eliminated first then those with the next lowest importance

and so on as necessary to recover system resources

There are five levels in the importance hierarchy The following list presents the different types of

processes in order of importance (the first process is most important and is killed last)

1 Foreground process

A process that is required for what the user is currently doing A process is considered to be in the

foreground if any of the following conditions are true

o It hosts an Activity that the user is interacting with (the Activitys onResume() method has been called)

o It hosts a Service thats bound to the activity that the user is interacting with

o It hosts a Service thats running in the foregroundmdashthe service has called startForeground()

o It hosts a Service thats executing one of its lifecycle callbacks (onCreate() onStart() or onDestroy())

o It hosts a BroadcastReceiver thats executing its onReceive() method

Generally only a few foreground processes exist at any given time They are killed only as a last

resortmdashif memory is so low that they cannot all continue to run Generally at that point the device has

reached a memory paging state so killing some foreground processes is required to keep the user

interface responsive

2 Visible process

A process that doesnt have any foreground components but still can affect what the user sees on

screen A process is considered to be visible if either of the following conditions are true

o It hosts an Activity that is not in the foreground but is still visible to the user (its onPause() method has

been called) This might occur for example if the foreground activity started a dialog which allows the

previous activity to be seen behind it

o It hosts a Service thats bound to a visible (or foreground) activity

A visible process is considered extremely important and will not be killed unless doing so is required to

keep all foreground processes running

3 Service process

A process that is running a service that has been started with the startService() method and does not

fall into either of the two higher categories Although service processes are not directly tied to anything

the user sees they are generally doing things that the user cares about (such as playing music in the

background or downloading data on the network) so the system keeps them running unless theres

not enough memory to retain them along with all foreground and visible processes

4 Background process

A process holding an activity thats not currently visible to the user (the activitys onStop() method has

been called) These processes have no direct impact on the user experience and the system can kill

them at any time to reclaim memory for a foreground visible or service process Usually there are

many background processes running so they are kept in an LRU (least recently used) list to ensure

that the process with the activity that was most recently seen by the user is the last to be killed If an

activity implements its lifecycle methods correctly and saves its current state killing its process will not

have a visible effect on the user experience because when the user navigates back to the activity the

activity restores all of its visible state See the Activities document for information about saving and

restoring state

5 Empty process

A process that doesnt hold any active application components The only reason to keep this kind of

process alive is for caching purposes to improve startup time the next time a component needs to run

in it The system often kills these processes in order to balance overall system resources between

process caches and the underlying kernel caches

Android ranks a process at the highest level it can based upon the importance of the components

currently active in the process For example if a process hosts a service and a visible activity the

process is ranked as a visible process not a service process

In addition a processs ranking might be increased because other processes are dependent on itmdasha

process that is serving another process can never be ranked lower than the process it is serving For

example if a content provider in process A is serving a client in process B or if a service in process A

is bound to a component in process B process A is always considered at least as important as

process B

Because a process running a service is ranked higher than a process with background activities an

activity that initiates a long-running operation might do well to start a service for that operation rather

than simply create a worker threadmdashparticularly if the operation will likely outlast the activity For

example an activity thats uploading a picture to a web site should start a service to perform the

upload so that the upload can continue in the background even if the user leaves the activity Using a

service guarantees that the operation will have at least service process priority regardless of what

happens to the activity This is the same reason that broadcast receivers should employ services

rather than simply put time-consuming operations in a thread

Threads

When an application is launched the system creates a thread of execution for the application called

main This thread is very important because it is in charge of dispatching events to the appropriate

user interface widgets including drawing events It is also the thread in which your application interacts

with components from the Android UI toolkit (components from the androidwidget and androidview

packages) As such the main thread is also sometimes called the UI thread

The system does not create a separate thread for each instance of a component All components that

run in the same process are instantiated in the UI thread and system calls to each component are

dispatched from that thread Consequently methods that respond to system callbacks (such as

onKeyDown() to report user actions or a lifecycle callback method) always run in the UI thread of the

process

For instance when the user touches a button on the screen your apps UI thread dispatches the touch

event to the widget which in turn sets its pressed state and posts an invalidate request to the event

queue The UI thread dequeues the request and notifies the widget that it should redraw itself

When your app performs intensive work in response to user interaction this single thread model can

yield poor performance unless you implement your application properly Specifically if everything is

happening in the UI thread performing long operations such as network access or database queries

will block the whole UI When the thread is blocked no events can be dispatched including drawing

events From the users perspective the application appears to hang Even worse if the UI thread is

blocked for more than a few seconds (about 5 seconds currently) the user is presented with the

infamous application not responding (ANR) dialog The user might then decide to quit your

application and uninstall it if they are unhappy

Additionally the Andoid UI toolkit is not thread-safe So you must not manipulate your UI from a

worker threadmdashyou must do all manipulation to your user interface from the UI thread Thus there are

simply two rules to Androids single thread model

1 Do not block the UI thread

2 Do not access the Android UI toolkit from outside the UI thread

Worker threads

Because of the single thread model described above its vital to the responsiveness of your

applications UI that you do not block the UI thread If you have operations to perform that are not

instantaneous you should make sure to do them in separate threads (background or worker

threads)

For example below is some code for a click listener that downloads an image from a separate thread

and displays it in an ImageView

public void onClick(View v) new Thread(new Runnable() public void run() Bitmap b = loadImageFromNetwork(httpexamplecomimagepng) mImageViewsetImageBitmap(b) )start()

At first this seems to work fine because it creates a new thread to handle the network operation

However it violates the second rule of the single-threaded model do not access the Android UI toolkit

from outside the UI threadmdashthis sample modifies the ImageView from the worker thread instead of the

UI thread This can result in undefined and unexpected behavior which can be difficult and time-

consuming to track down

To fix this problem Android offers several ways to access the UI thread from other threads Here is a

list of methods that can help

ActivityrunOnUiThread(Runnable)

Viewpost(Runnable)

ViewpostDelayed(Runnable long)

For example you can fix the above code by using the Viewpost(Runnable) method

public void onClick(View v) new Thread(new Runnable() public void run() final Bitmap bitmap = loadImageFromNetwork(httpexamplecomimagepng) mImageViewpost(new Runnable() public void run() mImageViewsetImageBitmap(bitmap) ) )start()

Now this implementation is thread-safe the network operation is done from a separate thread while

the ImageView is manipulated from the UI thread

However as the complexity of the operation grows this kind of code can get complicated and difficult

to maintain To handle more complex interactions with a worker thread you might consider using a

Handler in your worker thread to process messages delivered from the UI thread Perhaps the best

solution though is to extend the AsyncTask class which simplifies the execution of worker thread

tasks that need to interact with the UI

Using AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface It performs the blocking

operations in a worker thread and then publishes the results on the UI thread without requiring you to

handle threads andor handlers yourself

To use it you must subclass AsyncTask and implement the doInBackground() callback method which

runs in a pool of background threads To update your UI you should implement onPostExecute()

which delivers the result from doInBackground() and runs in the UI thread so you can safely update

your UI You can then run the task by calling execute() from the UI thread

For example you can implement the previous example using AsyncTask this way

public void onClick(View v) new DownloadImageTask()execute(httpexamplecomimagepng) private class DownloadImageTask extends AsyncTaskltString Void Bitmapgt The system calls this to perform work in a worker thread and delivers it the parameters given to AsyncTaskexecute() protected Bitmap doInBackground(String urls) return loadImageFromNetwork(urls[0])

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 26: 03 services

If you want to make your own data public you have two options You can create your own content

provider (a ContentProvider subclass) or you can add the data to an existing provider mdash if theres one

that controls the same type of data and you have permission to write to it

This document is an introduction to using content providers After a brief discussion of the

fundamentals it explores how to query a content provider how to modify data controlled by a provider

and how to create a content provider of your own

Content Provider Basics

How a content provider actually stores its data under the covers is up to its designer But all content

providers implement a common interface for querying the provider and returning results mdash as well as

for adding altering and deleting data Its an interface that clients use indirectly most generally

through ContentResolver objects You get a ContentResolver by calling getContentResolver() from

within the implementation of an Activity or other application component

ContentResolver cr = getContentResolver()

You can then use the ContentResolvers methods to interact with whatever content providers youre

interested in When a query is initiated the Android system identifies the content provider thats the

target of the query and makes sure that it is up and running The system instantiates all

ContentProvider objects you never need to do it on your own In fact you never deal directly with

ContentProvider objects at all Typically theres just a single instance of each type of ContentProvider

But it can communicate with multiple ContentResolver objects in different applications and processes

The interaction between processes is handled by the ContentResolver and ContentProvider classes

The data model

Content providers expose their data as a simple table on a database model where each row is a

record and each column is data of a particular type and meaning For example information about

people and their phone numbers might be exposed as follows

_ID NUMBER NUMBER_KEY LABEL NAME TYPE

13 (425) 555 6677 425 555 6677 Kirkland office Bully Pulpit TYPE_WORK

44 (212) 555-1234 212 555 1234 NY apartment Alan Vain TYPE_HOME

45 (212) 555-6657 212 555 6657 Downtown office Alan Vain TYPE_MOBILE

53 2015554433 201 555 4433 Love Nest Rex Cars TYPE_HOME

Every record includes a numeric _ID field that uniquely identifies the record within the table IDs can be

used to match records in related tables mdash for example to find a persons phone number in one table

and pictures of that person in another

A query returns a Cursor object that can move from record to record and column to column to read the

contents of each field It has specialized methods for reading each type of data So to read a field you

must know what type of data the field contains (Theres more on query results and Cursor objects

later)

URIs

Each content provider exposes a public URI (wrapped as a Uri object) that uniquely identifies its data

set A content provider that controls multiple data sets (multiple tables) exposes a separate URI for

each one All URIs for providers begin with the string content The content scheme identifies the

data as being controlled by a content provider

If youre defining a content provider its a good idea to also define a constant for its URI to simplify

client code and make future updates cleaner Android defines CONTENT_URI constants for all the

providers that come with the platform For example the URI for the table that matches phone numbers

to people and the URI for the table that holds pictures of people (both controlled by the Contacts

content provider) are

androidproviderContactsPhonesCONTENT_URI

androidproviderContactsPhotosCONTENT_URI

The URI constant is used in all interactions with the content provider Every ContentResolver method

takes the URI as its first argument Its what identifies which provider the ContentResolver should talk

to and which table of the provider is being targeted

Querying a Content Provider

You need three pieces of information to query a content provider

The URI that identifies the provider

The names of the data fields you want to receive

The data types for those fields

If youre querying a particular record you also need the ID for that record

Making the query

To query a content provider you can use either the ContentResolverquery() method or the

ActivitymanagedQuery() method Both methods take the same set of arguments and both return a

Cursor object However managedQuery() causes the activity to manage the life cycle of the Cursor A

managed Cursor handles all of the niceties such as unloading itself when the activity pauses and

requerying itself when the activity restarts You can ask an Activity to begin managing an unmanaged

Cursor object for you by calling ActivitystartManagingCursor()

The first argument to either query() or managedQuery() is the provider URI mdash the CONTENT_URI

constant that identifies a particular ContentProvider and data set (see URIs earlier)

To restrict a query to just one record you can append the _ID value for that record to the URI mdash that

is place a string matching the ID as the last segment of the path part of the URI For example if the ID

is 23 the URI would be

content 23

There are some helper methods particularly ContentUriswithAppendedId() and

UriwithAppendedPath() that make it easy to append an ID to a URI Both are static methods that

return a Uri object with the ID added So for example if you were looking for record 23 in the database

of people contacts you might construct a query as follows

import androidproviderContactsPeople import androidcontentContentUris import androidnetUri import androiddatabaseCursor Use the ContentUris method to produce the base URI for the contact with _ID == 23 Uri myPerson = ContentUriswithAppendedId(PeopleCONTENT_URI 23) Alternatively use the Uri method to produce the base URI It takes a string rather than an integer Uri myPerson = UriwithAppendedPath(PeopleCONTENT_URI 23) Then query for this specific record Cursor cur = managedQuery(myPerson null null null null)

The other arguments to the query() and managedQuery() methods delimit the query in more detail

They are

The names of the data columns that should be returned A null value returns all columns Otherwise

only columns that are listed by name are returned All the content providers that come with the

platform define constants for their columns For example the androidproviderContactsPhones class

defines constants for the names of the columns in the phone table illustrated earlier ampmdash _ID

NUMBER NUMBER_KEY NAME and so on

A filter detailing which rows to return formatted as an SQL WHERE clause (excluding the WHERE

itself) A null value returns all rows (unless the URI limits the query to a single record)

Selection arguments

A sorting order for the rows that are returned formatted as an SQL ORDER BY clause (excluding the

ORDER BY itself) A null value returns the records in the default order for the table which may be

unordered

Lets look at an example query to retrieve a list of contact names and their primary phone numbers

import androidproviderContactsPeople import androiddatabaseCursor Form an array specifying which columns to return String[] projection = new String[] People_ID People_COUNT PeopleNAME PeopleNUMBER Get the base URI for the People table in the Contacts content provider Uri contacts = PeopleCONTENT_URI Make the query Cursor managedCursor = managedQuery(contacts projection Which columns to return null Which rows to return (all rows) null Selection arguments (none) Put the results in ascending order by name PeopleNAME + ASC)

This query retrieves data from the People table of the Contacts content provider It gets the name

primary phone number and unique record ID for each contact It also reports the number of records

that are returned as the _COUNT field of each record

The constants for the names of the columns are defined in various interfaces mdash _ID and _COUNT in

BaseColumns NAME in PeopleColumns and NUMBER in PhoneColumns The ContactsPeople

class implements each of these interfaces which is why the code example above could refer to them

using just the class name

What a query returns

A query returns a set of zero or more database records The names of the columns their default order

and their data types are specific to each content provider But every provider has an _ID column

which holds a unique numeric ID for each record Every provider can also report the number of records

returned as the _COUNT column its value is the same for all rows

Here is an example result set for the query in the previous section

_ID _COUNT NAME NUMBER

44 3 Alan Vain 212 555 1234

13 3 Bully Pulpit 425 555 6677

53 3 Rex Cars 201 555 4433

The retrieved data is exposed by a Cursor object that can be used to iterate backward or forward

through the result set You can use this object only to read the data To add modify or delete data

you must use a ContentResolver object

Reading retrieved data

The Cursor object returned by a query provides access to a recordset of results If you have queried

for a specific record by ID this set will contain only one value Otherwise it can contain multiple

values (If there are no matches it can also be empty) You can read data from specific fields in the

record but you must know the data type of the field because the Cursor object has a separate method

for reading each type of data mdash such as getString() getInt() and getFloat() (However for most types

if you call the method for reading strings the Cursor object will give you the String representation of

the data) The Cursor lets you request the column name from the index of the column or the index

number from the column name

The following snippet demonstrates reading names and phone numbers from the query illustrated

earlier

import androidproviderContactsPeople private void getColumnData(Cursor cur) if (curmoveToFirst()) String name String phoneNumber int nameColumn = curgetColumnIndex(PeopleNAME) int phoneColumn = curgetColumnIndex(PeopleNUMBER) String imagePath do Get the field values name = curgetString(nameColumn) phoneNumber = curgetString(phoneColumn) Do something with the values while (curmoveToNext())

If a query can return binary data such as an image or sound the data may be directly entered in the

table or the table entry for that data may be a string specifying a content URI that you can use to get

the data In general smaller amounts of data (say from 20 to 50K or less) are most often directly

entered in the table and can be read by calling CursorgetBlob() It returns a byte array

If the table entry is a content URI you should never try to open and read the file directly (for one thing

permissions problems can make this fail) Instead you should call ContentResolveropenInputStream()

to get an InputStream object that you can use to read the data

Modifying Data

Data kept by a content provider can be modified by

Adding new records

Adding new values to existing records

Batch updating existing records

Deleting records

All data modification is accomplished using ContentResolver methods Some content providers require

a more restrictive permission for writing data than they do for reading it If you dont have permission to

write to a content provider the ContentResolver methods will fail

Adding records

To add a new record to a content provider first set up a map of key-value pairs in a ContentValues

object where each key matches the name of a column in the content provider and the value is the

desired value for the new record in that column Then call ContentResolverinsert() and pass it the URI

of the provider and the ContentValues map This method returns the full URI of the new record mdash that

is the providers URI with the appended ID for the new record You can then use this URI to query and

get a Cursor over the new record and to further modify the record Heres an example

import androidproviderContactsPeople import androidcontentContentResolver import androidcontentContentValues ContentValues values = new ContentValues() Add Abraham Lincoln to contacts and make him a favorite valuesput(PeopleNAME Abraham Lincoln) 1 = the new contact is added to favorites 0 = the new contact is not added to favorites valuesput(PeopleSTARRED 1) Uri uri = getContentResolver()insert(PeopleCONTENT_URI values)

Adding new values

Once a record exists you can add new information to it or modify existing information For example

the next step in the example above would be to add contact information mdash like a phone number or an

IM or e-mail address mdash to the new entry

The best way to add to a record in the Contacts database is to append the name of the table where the

new data goes to the URI for the record then use the amended URI to add the new data values Each

Contacts table exposes a name for this purpose as a CONTENT_DIRECTORY constant The following

code continues the previous example by adding a phone number and e-mail address for the record

just created

Uri phoneUri = null Uri emailUri = null Add a phone number for Abraham Lincoln Begin with the URI for the new record just returned by insert() it ends with the _ID of the new record so we dont have to add the ID ourselves Then append the designation for the phone table to this URI and use the resulting URI to insert the phone number phoneUri = UriwithAppendedPath(uri PeoplePhonesCONTENT_DIRECTORY) valuesclear() valuesput(PeoplePhonesTYPE PeoplePhonesTYPE_MOBILE) valuesput(PeoplePhonesNUMBER 1233214567) getContentResolver()insert(phoneUri values) Now add an email address in the same way emailUri = UriwithAppendedPath(uri PeopleContactMethodsCONTENT_DIRECTORY) valuesclear() ContactMethodsKIND is used to distinguish different kinds of contact methods such as email IM etc valuesput(PeopleContactMethodsKIND ContactsKIND_EMAIL) valuesput(PeopleContactMethodsDATA testexamplecom) valuesput(PeopleContactMethodsTYPE PeopleContactMethodsTYPE_HOME) getContentResolver()insert(emailUri values)

You can place small amounts of binary data into a table by calling the version of ContentValuesput()

that takes a byte array That would work for a small icon-like image or a short audio clip for example

However if you have a large amount of binary data to add such as a photograph or a complete song

put a content URI for the data in the table and call ContentResolveropenOutputStream() with the files

URI (That causes the content provider to store the data in a file and record the file path in a hidden

field of the record)

In this regard the MediaStore content provider the main provider that dispenses image audio and

video data employs a special convention The same URI that is used with query() or managedQuery()

to get meta-information about the binary data (such as the caption of a photograph or the date it was

taken) is used with openInputStream() to get the data itself Similarly the same URI that is used with

insert() to put meta-information into a MediaStore record is used with openOutputStream() to place the

binary data there The following code snippet illustrates this convention

import androidproviderMediaStoreImagesMedia import androidcontentContentValues import javaioOutputStream Save the name and description of an image in a ContentValues map ContentValues values = new ContentValues(3) valuesput(MediaDISPLAY_NAME road_trip_1) valuesput(MediaDESCRIPTION Day 1 trip to Los Angeles) valuesput(MediaMIME_TYPE imagejpeg) Add a new record without the bitmap but with the values just set insert() returns the URI of the new record Uri uri = getContentResolver()insert(MediaEXTERNAL_CONTENT_URI values) Now get a handle to the file for that record and save the data into it Here sourceBitmap is a Bitmap object representing the file to save to the database try OutputStream outStream = getContentResolver()openOutputStream(uri) sourceBitmapcompress(BitmapCompressFormatJPEG 50 outStream) outStreamclose() catch (Exception e) Loge(TAG exception while writing image e)

Batch updating records

To batch update a group of records (for example to change NY to New York in all fields) call the

ContentResolverupdate() method with the columns and values to change

Deleting a record

To delete a single record call ContentResolverdelete() with the URI of a specific row

To delete multiple rows call ContentResolverdelete() with the URI of the type of record to delete (for

example androidproviderContactsPeopleCONTENT_URI) and an SQL WHERE clause defining

which rows to delete (Caution Be sure to include a valid WHERE clause if youre deleting a general

type or you risk deleting more records than you intended)

Creating a Content Provider

To create a content provider you must

Set up a system for storing the data Most content providers store their data using Androids file

storage methods or SQLite databases but you can store your data any way you want Android

provides the SQLiteOpenHelper class to help you create a database and SQLiteDatabase to manage

it

Extend the ContentProvider class to provide access to the data

Declare the content provider in the manifest file for your application (AndroidManifestxml)

The following sections have notes on the last two of these tasks

Extending the ContentProvider class

You define a ContentProvider subclass to expose your data to others using the conventions expected

by ContentResolver and Cursor objects Principally this means implementing six abstract methods

declared in the ContentProvider class

query()

insert()

update()

delete()

getType()

onCreate()

The query() method must return a Cursor object that can iterate over the requested data Cursor itself

is an interface but Android provides some ready-made Cursor objects that you can use For example

SQLiteCursor can iterate over data stored in an SQLite database You get the Cursor object by calling

any of the SQLiteDatabase classs query() methods There are other Cursor implementations mdash such

as MatrixCursor mdash for data not stored in a database

Because these ContentProvider methods can be called from various ContentResolver objects in

different processes and threads they must be implemented in a thread-safe manner

As a courtesy you might also want to call ContentResolvernotifyChange() to notify listeners when

there are modifications to the data

Beyond defining the subclass itself there are other steps you should take to simplify the work of clients

and make the class more accessible

Define a public static final Uri named CONTENT_URI This is the string that represents the full content

URI that your content provider handles You must define a unique string for this value The best

solution is to use the fully-qualified class name of the content provider (made lowercase) So for

example the URI for a TransportationProvider class could be defined as follows

public static final Uri CONTENT_URI = Uriparse(contentcomexamplecodelabtransportationprovider)

If the provider has subtables also define CONTENT_URI constants for each of the subtables These

URIs should all have the same authority (since that identifies the content provider) and be

distinguished only by their paths For example

contentcomexamplecodelabtransportationprovidertrain

contentcomexamplecodelabtransportationproviderairdomestic

contentcomexamplecodelabtransportationproviderairinternational

For an overview of content URIs see the Content URI Summary at the end of this document

Define the column names that the content provider will return to clients If you are using an underlying

database these column names are typically identical to the SQL database column names they

represent Also define public static String constants that clients can use to specify the columns in

queries and other instructions

Be sure to include an integer column named _id (with the constant _ID) for the IDs of the records

You should have this field whether or not you have another field (such as a URL) that is also unique

among all records If youre using the SQLite database the _ID field should be the following type

INTEGER PRIMARY KEY AUTOINCREMENT

The AUTOINCREMENT descriptor is optional But without it SQLite increments an ID counter field to

the next number above the largest existing number in the column If you delete the last row the next

row added will have the same ID as the deleted row AUTOINCREMENT avoids this by having SQLite

increment to the next largest value whether deleted or not

Carefully document the data type of each column Clients need this information to read the data

If you are handling a new data type you must define a new MIME type to return in your

implementation of ContentProvidergetType() The type depends in part on whether or not the content

URI submitted to getType() limits the request to a specific record Theres one form of the MIME type

for a single record and another for multiple records Use the Uri methods to help determine what is

being requested Here is the general format for each type

o For a single record vndandroidcursoritemvndyourcompanynamecontenttype

For example a request for train record 122 like this URI

contentcomexampletransportationprovidertrains122

might return this MIME type

vndandroidcursoritemvndexamplerail

o For multiple records vndandroidcursordirvndyourcompanynamecontenttype

For example a request for all train records like the following URI

contentcomexampletransportationprovidertrains

might return this MIME type

vndandroidcursordirvndexamplerail

If you are exposing byte data thats too big to put in the table itself mdash such as a large bitmap file mdash the

field that exposes the data to clients should actually contain a content URI string This is the field that

gives clients access to the data file The record should also have another field named _data that lists

the exact file path on the device for that file This field is not intended to be read by the client but by

the ContentResolver The client will call ContentResolveropenInputStream() on the user-facing field

holding the URI for the item The ContentResolver will request the _data field for that record and

because it has higher permissions than a client it should be able to access that file directly and return

a read wrapper for the file to the client

For an example of a private content provider implementation see the NodePadProvider class in the

Notepad sample application that ships with the SDK

Declaring the content provider

To let the Android system know about the content provider youve developed declare it with a

ltprovidergt element in the applications AndroidManifestxml file Content providers that are not

declared in the manifest are not visible to the Android system

The name attribute is the fully qualified name of the ContentProvider subclass The authorities attribute

is the authority part of the content URI that identifies the provider For example if the ContentProvider

subclass is AutoInfoProvider the ltprovidergt element might look like this

ltprovider androidname=comexampleautosAutoInfoProvider androidauthorities=comexampleautosautoinfoprovider gt ltprovidergt

Note that the authorities attribute omits the path part of a content URI For example if

AutoInfoProvider controlled subtables for different types of autos or different manufacturers

contentcomexampleautosautoinfoproviderhonda

contentcomexampleautosautoinfoprovidergmcompact

contentcomexampleautosautoinfoprovidergmsuv

those paths would not be declared in the manifest The authority is what identifies the provider not the

path your provider can interpret the path part of the URI in any way you choose

Other ltprovidergt attributes can set permissions to read and write data provide for an icon and text

that can be displayed to users enable and disable the provider and so on Set the multiprocess

attribute to true if data does not need to be synchronized between multiple running versions of the

content provider This permits an instance of the provider to be created in each client process

eliminating the need to perform IPC

Content URI Summary

Here is a recap of the important parts of a content URI

A Standard prefix indicating that the data is controlled by a content provider Its never modified

B The authority part of the URI it identifies the content provider For third-party applications this should

be a fully-qualified class name (reduced to lowercase) to ensure uniqueness The authority is declared

in the ltprovidergt elements authorities attribute

ltprovider androidname=TransportationProvider androidauthorities=comexampletransportationprovider gt

C The path that the content provider uses to determine what kind of data is being requested This can be

zero or more segments long If the content provider exposes only one type of data (only trains for

example) it can be absent If the provider exposes several types including subtypes it can be several

segments long mdash for example landbus landtrain seaship and seasubmarine to give four

possibilities

D The ID of the specific record being requested if any This is the _ID value of the requested record If

the request is not limited to a single record this segment and the trailing slash are omitted

contentcomexampletransportationprovidertrains

Intent and intent filters

Three of the core components of an application mdash activities services and broadcast receivers mdash 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 mdash 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 ContextstartActivity() or ActivitystartActivityForResult() to launch an

activity or get an existing activity to do something new (It can also be passed to ActivitysetResult() to

return information to the activity that called startActivityForResult())

An Intent object is passed to ContextstartService() to initiate a service or deliver new instructions to an

ongoing service Similarly an intent can be passed to ContextbindService() to establish a connection

between the calling component and a target service It can optionally initiate the service if its not

already running

Intent objects passed to any of the broadcast methods (such as ContextsendBroadcast()

ContextsendOrderedBroadcast() or ContextsendStickyBroadcast()) 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 mdash how it resolves which component should receive an intent message For

intents that dont explicitly name a target component this process involves testing the Intent object

against intent filters associated with potential targets

Intent Objects

An Intent object is a bundle of information It contains information of interest to the component that

receives the intent (such as the action to be taken and the data to act on) plus information of interest to

the Android system (such as the category of component that should handle the intent and instructions

on how to launch a target activity) Principally it can contain the following

Component name

The name of the component that should handle the intent This field is a ComponentName

object mdash a combination of the fully qualified class name of the target component (for example

comexampleprojectappFreneticActivity) and the package name set in the manifest file of the

application where the component resides (for example comexampleproject) The package

part of the component name and the package name set in the manifest do not necessarily have

to match

The component name is optional If it is set the Intent object is delivered to an instance of the

designated class If it is not set Android uses other information in the Intent object to locate a

suitable target mdash see Intent Resolution later in this document

The component name is set by setComponent() setClass() or setClassName() and read by

getComponent()

Action

A string naming the action to be performed mdash or in the case of broadcast intents the action

that took place and is being reported The Intent class defines a number of action constants

including these

Constant Target

component

Action

ACTION_CALL activity Initiate a phone call

ACTION_EDIT activity Display data for the user to edit

ACTION_MAIN activity Start up as the initial activity of a task

with no data input and no returned

output

ACTION_SYNC activity Synchronize data on a server with

data on the mobile device

ACTION_BATTERY_LOW broadcast

receiver

A warning that the battery is low

ACTION_HEADSET_PLUG broadcast

receiver

A headset has been plugged into the

device or unplugged from it

ACTION_SCREEN_ON broadcast

receiver

The screen has been turned on

ACTION_TIMEZONE_CHANGED broadcast

receiver

The setting for the time zone has

changed

See the Intent class description for a list of pre-defined constants for generic actions Other

actions are defined elsewhere in the Android API You can also define your own action strings

for activating the components in your application Those you invent should include the

application package as a prefix mdash for example comexampleprojectSHOW_COLOR

The action largely determines how the rest of the intent is structured mdash particularly the data and

extras fields mdash much as a method name determines a set of arguments and a return value For

this reason its a good idea to use action names that are as specific as possible and to couple

them tightly to the other fields of the intent In other words instead of defining an action in

isolation define an entire protocol for the Intent objects your components can handle

The action in an Intent object is set by the setAction() method and read by getAction()

Data

The URI of the data to be acted on and the MIME type of that data Different actions are paired

with different kinds of data specifications For example if the action field is ACTION_EDIT the

data field would contain the URI of the document to be displayed for editing If the action is

ACTION_CALL the data field would be a tel URI with the number to call Similarly if the action

is ACTION_VIEW and the data field is an http URI the receiving activity would be called upon

to download and display whatever data the URI refers to

When matching an intent to a component that is capable of handling the data its often

important to know the type of data (its MIME type) in addition to its URI For example a

component able to display image data should not be called upon to play an audio file

In many cases the data type can be inferred from the URI mdash particularly content URIs which

indicate that the data is located on the device and controlled by a content provider (see the

separate discussion on content providers) But the type can also be explicitly set in the Intent

object The setData() method specifies data only as a URI setType() specifies it only as a

MIME type and setDataAndType() specifies it as both a URI and a MIME type The URI is read

by getData() and the type by getType()

Category

A string containing additional information about the kind of component that should handle the

intent Any number of category descriptions can be placed in an Intent object As it does for

actions the Intent class defines several category constants including these

Constant Meaning

CATEGORY_BROWSABLE The target activity can be safely invoked by the browser to

display data referenced by a link mdash for example an image or

an e-mail message

CATEGORY_GADGET The activity can be embedded inside of another activity that

hosts gadgets

CATEGORY_HOME The activity displays the home screen the first screen the

user sees when the device is turned on or when the HOME

key is pressed

CATEGORY_LAUNCHER The activity can be the initial activity of a task and is listed in

the top-level application launcher

CATEGORY_PREFERENCE The target activity is a preference panel

See the Intent class description for the full list of categories

The addCategory() method places a category in an Intent object removeCategory() deletes a

category previously added and getCategories() gets the set of all categories currently in the

object

Extras

Key-value pairs for additional information that should be delivered to the component handling

the intent Just as some actions are paired with particular kinds of data URIs some are paired

with particular extras For example an ACTION_TIMEZONE_CHANGED intent has a time-

zone extra that identifies the new time zone and ACTION_HEADSET_PLUG has a state

extra indicating whether the headset is now plugged in or unplugged as well as a name extra

for the type of headset If you were to invent a SHOW_COLOR action the color value would be

set in an extra key-value pair

The Intent object has a series of put() methods for inserting various types of extra data and a

similar set of get() methods for reading the data These methods parallel those for Bundle

objects In fact the extras can be installed and read as a Bundle using the putExtras() and

getExtras() methods

Flags

Flags of various sorts Many instruct the Android system how to launch an activity (for example

which task the activity should belong to) and how to treat it after its launched (for example

whether it belongs in the list of recent activities) All these flags are defined in the Intent class

The Android system and the applications that come with the platform employ Intent objects both to

send out system-originated broadcasts and to activate system-defined components To see how to

structure an intent to activate a system component consult the list of intents in the reference

Intent Resolution

Intents can be divided into two groups

Explicit intents designate the target component by its name (the component name field mentioned

earlier has a value set) Since component names would generally not be known to developers of other

applications explicit intents are typically used for application-internal messages mdash such as an activity

starting a subordinate service or launching a sister activity

Implicit intents do not name a target (the field for the component name is blank) Implicit intents are

often used to activate components in other applications

Android delivers an explicit intent to an instance of the designated target class Nothing in the Intent

object other than the component name matters for determining which component should get the intent

A different strategy is needed for implicit intents In the absence of a designated target the Android

system must find the best component (or components) to handle the intent mdash a single activity or

service to perform the requested action or the set of broadcast receivers to respond to the broadcast

announcement It does so by comparing the contents of the Intent object to intent filters structures

associated with components that can potentially receive intents Filters advertise the capabilities of a

component and delimit the intents it can handle They open the component to the possibility of

receiving implicit intents of the advertised type If a component does not have any intent filters it can

receive only explicit intents A component with filters can receive both explicit and implicit intents

Only three aspects of an Intent object are consulted when the object is tested against an intent filter

action

data (both URI and data type)

category

The extras and flags play no part in resolving which component receives an intent

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 mdash but only unwanted implicit intents (those that dont 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

components 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 mdash 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 Pads filters are described in the Note Pad Example

section later)

Filters and security

An intent filter cannot be relied on for security While it opens a component to receiving only certain

kinds of implicit intents it does nothing to prevent explicit intents from targeting the component Even

though a filter restricts the intents a component will be asked to handle to certain actions and data

sources someone could always put together an explicit intent with a different action and data source

and name the component as the target

An intent filter is an instance of the IntentFilter class However since the Android system must know

about the capabilities of a component before it can launch that component intent filters are generally

not set up in Java code but in the applications manifest file (AndroidManifestxml) as ltintent-filtergt

elements (The one exception would be filters for broadcast receivers that are registered dynamically

by calling ContextregisterReceiver() they are directly created as IntentFilter objects)

A filter has fields that parallel the action data and category fields of an Intent object An implicit intent

is tested against the filter in all three areas To be delivered to the component that owns the filter it

must pass all three tests If it fails even one of them the Android system wont deliver it to the

component mdash at least not on the basis of that filter However since a component can have multiple

intent filters an intent that does not pass through one of a components filters might make it through on

another

Each of the three tests is described in detail below

Action test

An ltintent-filtergt element in the manifest file lists actions as ltactiongt subelements For

example

ltintent-filter gt ltaction androidname=comexampleprojectSHOW_CURRENT gt ltaction androidname=comexampleprojectSHOW_RECENT gt ltaction androidname=comexampleprojectSHOW_PENDING gt ltintent-filtergt

As the example shows while an Intent object names just a single action a filter may list more

than one The list cannot be empty a filter must contain at least one ltactiongt element or it will

block all intents

To pass this test the action specified in the Intent object must match one of the actions listed in

the filter If the object or the filter does not specify an action the results are as follows

If the filter fails to list any actions there is nothing for an intent to match so all intents fail the

test No intents can get through the filter

On the other hand an Intent object that doesnt specify an action automatically passes the test

mdash as long as the filter contains at least one action

Category test

An ltintent-filtergt element also lists categories as subelements For example

ltintent-filter gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryBROWSABLE gt ltintent-filtergt

Note that the constants described earlier for actions and categories are not used in the manifest

file The full string values are used instead For instance the

androidintentcategoryBROWSABLE string in the example above corresponds to the

CATEGORY_BROWSABLE constant mentioned earlier in this document Similarly the string

androidintentactionEDIT corresponds to the ACTION_EDIT constant

For an intent to pass the category test every category in the Intent object must match a

category in the filter The filter can list additional categories but it cannot omit any that are in the

intent

In principle therefore an Intent object with no categories should always pass this test

regardless of whats in the filter Thats mostly true However with one exception Android treats

all implicit intents passed to startActivity() as if they contained at least one category

androidintentcategoryDEFAULT (the CATEGORY_DEFAULT constant) Therefore activities

that are willing to receive implicit intents must include androidintentcategoryDEFAULT in

their intent filters (Filters with androidintentactionMAIN and

androidintentcategoryLAUNCHER settings are the exception They mark activities that begin

new tasks and that are represented on the launcher screen They can include

androidintentcategoryDEFAULT in the list of categories but dont need to) See Using intent

matching later for more on these filters)

Data test

Like the action and categories the data specification for an intent filter is contained in a

subelement And as in those cases the subelement can appear multiple times or not at all For

example

ltintent-filter gt ltdata androidmimeType=videompeg androidscheme=http gt ltdata androidmimeType=audiompeg androidscheme=http gt ltintent-filtergt

Each ltdatagt element can specify a URI and a data type (MIME media type) There are

separate attributes mdash scheme host port and path mdash for each part of the URI

schemehostportpath

For example in the following URI

contentcomexampleproject200foldersubfolderetc

the scheme is content the host is comexampleproject the port is 200 and the path is

foldersubfolderetc The host and port together constitute the URI authority if a host is not

specified the port is ignored

Each of these attributes is optional but they are not independent of each other For an authority

to be meaningful a scheme must also be specified For a path to be meaningful both a scheme

and an authority must be specified

When the URI in an Intent object is compared to a URI specification in a filter its compared

only to the parts of the URI actually mentioned in the filter For example if a filter specifies only

a scheme all URIs with that scheme match the filter If a filter specifies a scheme and an

authority but no path all URIs with the same scheme and authority match regardless of their

paths If a filter specifies a scheme an authority and a path only URIs with the same scheme

authority and path match However a path specification in the filter can contain wildcards to

require only a partial match of the path

The type attribute of a ltdatagt element specifies the MIME type of the data Its more common in

filters than a URI Both the Intent object and the filter can use a wildcard for the subtype field

mdash for example text or audio mdash indicating any subtype matches

The data test compares both the URI and the data type in the Intent object to a URI and data

type specified in the filter The rules are as follows

a An Intent object that contains neither a URI nor a data type passes the test only if the filter

likewise does not specify any URIs or data types

b An Intent object that contains a URI but no data type (and a type cannot be inferred from the

URI) passes the test only if its URI matches a URI in the filter and the filter likewise does not

specify a type This will be the case only for URIs like mailto and tel that do not refer to actual

data

c An Intent object that contains a data type but not a URI passes the test only if the filter lists the

same data type and similarly does not specify a URI

d An Intent object that contains both a URI and a data type (or a data type can be inferred from

the URI) passes the data type part of the test only if its type matches a type listed in the filter It

passes the URI part of the test either if its URI matches a URI in the filter or if it has a content

or file URI and the filter does not specify a URI In other words a component is presumed to

support content and file data if its filter lists only a data type

If an intent can pass through the filters of more than one activity or service the user may be asked

which component to activate An exception is raised if no target can be found

Common cases

The last rule shown above for the data test rule (d) reflects the expectation that components are able

to get local data from a file or content provider Therefore their filters can list just a data type and do

not need to explicitly name the content and file schemes This is a typical case A ltdatagt element like

the following for example tells Android that the component can get image data from a content

provider and display it

ltdata androidmimeType=image gt

Since most available data is dispensed by content providers filters that specify a data type but not a

URI are perhaps the most common

Another common configuration is filters with a scheme and a data type For example a ltdatagt

element like the following tells Android that the component can get video data from the network and

display it

ltdata androidscheme=http androidtype=video gt

Consider for example what the browser application does when the user follows a link on a web page

It first tries to display the data (as it could if the link was to an HTML page) If it cant display the data it

puts together an implicit intent with the scheme and data type and tries to start an activity that can do

the job If there are no takers it asks the download manager to download the data That puts it under

the control of a content provider so a potentially larger pool of activities (those with filters that just

name a data type) can respond

Most applications also have a way to start fresh without a reference to any particular data Activities

that can initiate applications have filters with androidintentactionMAIN specified as the action If

they are to be represented in the application launcher they also specify the

androidintentcategoryLAUNCHER category

ltintent-filter gt ltaction androidname=code androidintentactionMAIN gt ltcategory androidname=code androidintentcategoryLAUNCHER gt ltintent-filtergt

Using intent matching

Intents are matched against intent filters not only to discover a target component to activate but also

to discover something about the set of components on the device For example the Android system

populates the application launcher the top-level screen that shows the applications that are available

for the user to launch by finding all the activities with intent filters that specify the

androidintentactionMAIN action and androidintentcategoryLAUNCHER category (as illustrated

in the previous section) It then displays the icons and labels of those activities in the launcher

Similarly it discovers the home screen by looking for the activity with androidintentcategoryHOME

in its filter

Your application can use intent matching is a similar way The PackageManager has a set of query()

methods that return all components that can accept a particular intent and a similar series of

resolve() methods that determine the best component to respond to an intent For example

queryIntentActivities() returns a list of all activities that can perform the intent passed as an argument

and queryIntentServices() returns a similar list of services Neither method activates the components

they just list the ones that can respond Theres a similar method queryBroadcastReceivers() for

broadcast receivers

Note Pad Example

The Note Pad sample application enables users to browse through a list of notes view details about

individual items in the list edit the items and add a new item to the list This section looks at the intent

filters declared in its manifest file (If youre working offline in the SDK you can find all the source files

for this sample application including its manifest file at ltsdkgtsamplesNotePadindexhtml If youre

viewing the documentation online the source files are in the Tutorials and Sample Code section here)

In its manifest file the Note Pad application declares three activities each with at least one intent filter

It also declares a content provider that manages the note data Here is the manifest file in its entirety

ltmanifest xmlnsandroid=httpschemasandroidcomapkresandroid package=comexampleandroidnotepadgt ltapplication androidicon=drawableapp_notes androidlabel=stringapp_name gt ltprovider androidname=NotePadProvider androidauthorities=comgoogleproviderNotePad gt ltactivity androidname=NotesList androidlabel=stringtitle_notes_listgt ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltactivity androidname=NoteEditor androidtheme=androidstyleThemeLight androidlabel=stringtitle_note gt ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltactivitygt

ltactivity androidname=TitleEditor androidlabel=stringtitle_edit_title androidtheme=androidstyleThemeDialoggt ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltapplicationgt ltmanifestgt

The first activity NotesList is distinguished from the other activities by the fact that it operates on a

directory of notes (the note list) rather than on a single note It would generally serve as the initial user

interface into the application It can do three things as described by its three intent filters

1 ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt

This filter declares the main entry point into the Note Pad application The standard MAIN action is an

entry point that does not require any other information in the Intent (no data specification for example)

and the LAUNCHER category says that this entry point should be listed in the application launcher

2 ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

This filter declares the things that the activity can do on a directory of notes It can allow the user to

view or edit the directory (via the VIEW and EDIT actions) or to pick a particular note from the

directory (via the PICK action)

The mimeType attribute of the ltdatagt element specifies the kind of data that these actions operate on

It indicates that the activity can get a Cursor over zero or more items (vndandroidcursordir) from a

content provider that holds Note Pad data (vndgooglenote) The Intent object that launches the

activity would include a content URI specifying the exact data of this type that the activity should open

Note also the DEFAULT category supplied in this filter Its there because the ContextstartActivity()

and ActivitystartActivityForResult() methods treat all intents as if they contained the DEFAULT

category mdash with just two exceptions

o Intents that explicitly name the target activity

o Intents consisting of the MAIN action and LAUNCHER category

Therefore the DEFAULT category is required for all filters mdash except for those with the MAIN action

and LAUNCHER category (Intent filters are not consulted for explicit intents)

3 ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

This filter describes the activitys ability to return a note selected by the user without requiring any

specification of the directory the user should choose from The GET_CONTENT action is similar to the

PICK action In both cases the activity returns the URI for a note selected by the user (In each case

its returned to the activity that called startActivityForResult() to start the NoteList activity) Here

however the caller specifies the type of data desired instead of the directory of data the user will be

picking from

The data type vndandroidcursoritemvndgooglenote indicates the type of data the activity can

return mdash a URI for a single note From the returned URI the caller can get a Cursor for exactly one

item (vndandroidcursoritem) from the content provider that holds Note Pad data (vndgooglenote)

In other words for the PICK action in the previous filter the data type indicates the type of data the

activity could display to the user For the GET_CONTENT filter it indicates the type of data the activity

can return to the caller

Given these capabilities the following intents will resolve to the NotesList activity

action androidintentactionMAIN

Launches the activity with no data specified

action androidintentactionMAIN

category androidintentcategoryLAUNCHER

Launches the activity with no data selected specified This is the actual intent used by the

Launcher to populate its top-level list All activities with filters that match this action and

category are added to the list

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of all the notes under

contentcomgoogleproviderNotePadnotes The user can then browse through the list and

get information about the items in it

action androidintentactionPICK

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of the notes under

contentcomgoogleproviderNotePadnotes The user can then pick a note from the list and

the activity will return the URI for that item back to the activity that started the NoteList activity

action androidintentactionGET_CONTENT

data type vndandroidcursoritemvndgooglenote

Asks the activity to supply a single item of Note Pad data

The second activity NoteEditor shows users a single note entry and allows them to edit it It can do

two things as described by its two intent filters

1 ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The first primary purpose of this activity is to enable the user to interact with a single note ampmdash to

either VIEW the note or EDIT it (The EDIT_NOTE category is a synonym for EDIT) The intent would

contain the URI for data matching the MIME type vndandroidcursoritemvndgooglenote mdash that is

the URI for a single specific note It would typically be a URI that was returned by the PICK or

GET_CONTENT actions of the NoteList activity

As before this filter lists the DEFAULT category so that the activity can be launched by intents that

dont explicitly specify the NoteEditor class

2 ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

The secondary purpose of this activity is to enable the user to create a new note which it will INSERT

into an existing directory of notes The intent would contain the URI for data matching the MIME type

vndandroidcursordirvndgooglenote mdash that is the URI for the directory where the note should be

placed

Given these capabilities the following intents will resolve to the NoteEditor activity

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID (For details on how content

URIs specify individual members of a group see Content Providers)

action androidintentactionEDIT

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID and to let the user edit it If

the user saves the changes the activity updates the data for the note in the content provider

action androidintentactionINSERT

data contentcomgoogleproviderNotePadnotes

Asks the activity to create a new empty note in the notes list at

contentcomgoogleproviderNotePadnotes and allow the user to edit it If the user saves the

note its URI is returned to the caller

The last activity TitleEditor enables the user to edit the title of a note This could be implemented by

directly invoking the activity (by explicitly setting its component name in the Intent) without using an

intent filter But here we take the opportunity to show how to publish alternative operations on existing

data

ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The single intent filter for this activity uses a custom action called

comandroidnotepadactionEDIT_TITLE It must be invoked on a specific note (data type

vndandroidcursoritemvndgooglenote) like the previous VIEW and EDIT actions However here the

activity displays the title contained in the note data not the content of the note itself

In addition to supporting the usual DEFAULT category the title editor also supports two other standard

categories ALTERNATIVE and SELECTED_ALTERNATIVE These categories identify activities that

can be presented to users in a menu of options (much as the LAUNCHER category identifies activities

that should be presented to user in the application launcher) Note that the filter also supplies an

explicit label (via androidlabel=stringresolve_title) to better control what users see when

presented with this activity as an alternative action to the data they are currently viewing (For more

information on these categories and building options menus see the

PackageManagerqueryIntentActivityOptions() and MenuaddIntentOptions() methods)

Given these capabilities the following intent will resolve to the TitleEditor activity

action comandroidnotepadactionEDIT_TITLE

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the title associated with note ID and allow the user to edit the title

Processes and Threads

When an application component starts and the application does not have any other components

running the Android system starts a new Linux process for the application with a single thread of

execution By default all components of the same application run in the same process and thread

(called the main thread) If an application component starts and there already exists a process for

that application (because another component from the application exists) then the component is

started within that process and uses the same thread of execution However you can arrange for

different components in your application to run in separate processes and you can create additional

threads for any process

This document discusses how processes and threads work in an Android application

Processes

By default all components of the same application run in the same process and most applications

should not change this However if you find that you need to control which process a certain

component belongs to you can do so in the manifest file

The manifest entry for each type of component elementmdashltactivitygt ltservicegt ltreceivergt and

ltprovidergtmdashsupports an androidprocess attribute that can specify a process in which that component

should run You can set this attribute so that each component runs in its own process or so that some

components share a process while others do not You can also set androidprocess so that

components of different applications run in the same processmdashprovided that the applications share the

same Linux user ID and are signed with the same certificates

The ltapplicationgt element also supports an androidprocess attribute to set a default value that

applies to all components

Android might 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 thats killed are consequently destroyed A process is started again for those components

when theres again work for them to do

When deciding which processes to kill the Android system weighs their relative importance to the

user For example it more readily shuts down a process hosting activities that are no longer visible on

screen compared to a process hosting visible activities The decision whether to terminate a process

therefore depends on the state of the components running in that process The rules used to decide

which processes to terminate is discussed below

Process lifecycle

The Android system tries to maintain an application process for as long as possible but eventually

needs to remove old processes to reclaim memory for new or more important processes To determine

which processes to keep and which to kill the system places each process into an importance

hierarchy based on the components running in the process and the state of those components

Processes with the lowest importance are eliminated first then those with the next lowest importance

and so on as necessary to recover system resources

There are five levels in the importance hierarchy The following list presents the different types of

processes in order of importance (the first process is most important and is killed last)

1 Foreground process

A process that is required for what the user is currently doing A process is considered to be in the

foreground if any of the following conditions are true

o It hosts an Activity that the user is interacting with (the Activitys onResume() method has been called)

o It hosts a Service thats bound to the activity that the user is interacting with

o It hosts a Service thats running in the foregroundmdashthe service has called startForeground()

o It hosts a Service thats executing one of its lifecycle callbacks (onCreate() onStart() or onDestroy())

o It hosts a BroadcastReceiver thats executing its onReceive() method

Generally only a few foreground processes exist at any given time They are killed only as a last

resortmdashif memory is so low that they cannot all continue to run Generally at that point the device has

reached a memory paging state so killing some foreground processes is required to keep the user

interface responsive

2 Visible process

A process that doesnt have any foreground components but still can affect what the user sees on

screen A process is considered to be visible if either of the following conditions are true

o It hosts an Activity that is not in the foreground but is still visible to the user (its onPause() method has

been called) This might occur for example if the foreground activity started a dialog which allows the

previous activity to be seen behind it

o It hosts a Service thats bound to a visible (or foreground) activity

A visible process is considered extremely important and will not be killed unless doing so is required to

keep all foreground processes running

3 Service process

A process that is running a service that has been started with the startService() method and does not

fall into either of the two higher categories Although service processes are not directly tied to anything

the user sees they are generally doing things that the user cares about (such as playing music in the

background or downloading data on the network) so the system keeps them running unless theres

not enough memory to retain them along with all foreground and visible processes

4 Background process

A process holding an activity thats not currently visible to the user (the activitys onStop() method has

been called) These processes have no direct impact on the user experience and the system can kill

them at any time to reclaim memory for a foreground visible or service process Usually there are

many background processes running so they are kept in an LRU (least recently used) list to ensure

that the process with the activity that was most recently seen by the user is the last to be killed If an

activity implements its lifecycle methods correctly and saves its current state killing its process will not

have a visible effect on the user experience because when the user navigates back to the activity the

activity restores all of its visible state See the Activities document for information about saving and

restoring state

5 Empty process

A process that doesnt hold any active application components The only reason to keep this kind of

process alive is for caching purposes to improve startup time the next time a component needs to run

in it The system often kills these processes in order to balance overall system resources between

process caches and the underlying kernel caches

Android ranks a process at the highest level it can based upon the importance of the components

currently active in the process For example if a process hosts a service and a visible activity the

process is ranked as a visible process not a service process

In addition a processs ranking might be increased because other processes are dependent on itmdasha

process that is serving another process can never be ranked lower than the process it is serving For

example if a content provider in process A is serving a client in process B or if a service in process A

is bound to a component in process B process A is always considered at least as important as

process B

Because a process running a service is ranked higher than a process with background activities an

activity that initiates a long-running operation might do well to start a service for that operation rather

than simply create a worker threadmdashparticularly if the operation will likely outlast the activity For

example an activity thats uploading a picture to a web site should start a service to perform the

upload so that the upload can continue in the background even if the user leaves the activity Using a

service guarantees that the operation will have at least service process priority regardless of what

happens to the activity This is the same reason that broadcast receivers should employ services

rather than simply put time-consuming operations in a thread

Threads

When an application is launched the system creates a thread of execution for the application called

main This thread is very important because it is in charge of dispatching events to the appropriate

user interface widgets including drawing events It is also the thread in which your application interacts

with components from the Android UI toolkit (components from the androidwidget and androidview

packages) As such the main thread is also sometimes called the UI thread

The system does not create a separate thread for each instance of a component All components that

run in the same process are instantiated in the UI thread and system calls to each component are

dispatched from that thread Consequently methods that respond to system callbacks (such as

onKeyDown() to report user actions or a lifecycle callback method) always run in the UI thread of the

process

For instance when the user touches a button on the screen your apps UI thread dispatches the touch

event to the widget which in turn sets its pressed state and posts an invalidate request to the event

queue The UI thread dequeues the request and notifies the widget that it should redraw itself

When your app performs intensive work in response to user interaction this single thread model can

yield poor performance unless you implement your application properly Specifically if everything is

happening in the UI thread performing long operations such as network access or database queries

will block the whole UI When the thread is blocked no events can be dispatched including drawing

events From the users perspective the application appears to hang Even worse if the UI thread is

blocked for more than a few seconds (about 5 seconds currently) the user is presented with the

infamous application not responding (ANR) dialog The user might then decide to quit your

application and uninstall it if they are unhappy

Additionally the Andoid UI toolkit is not thread-safe So you must not manipulate your UI from a

worker threadmdashyou must do all manipulation to your user interface from the UI thread Thus there are

simply two rules to Androids single thread model

1 Do not block the UI thread

2 Do not access the Android UI toolkit from outside the UI thread

Worker threads

Because of the single thread model described above its vital to the responsiveness of your

applications UI that you do not block the UI thread If you have operations to perform that are not

instantaneous you should make sure to do them in separate threads (background or worker

threads)

For example below is some code for a click listener that downloads an image from a separate thread

and displays it in an ImageView

public void onClick(View v) new Thread(new Runnable() public void run() Bitmap b = loadImageFromNetwork(httpexamplecomimagepng) mImageViewsetImageBitmap(b) )start()

At first this seems to work fine because it creates a new thread to handle the network operation

However it violates the second rule of the single-threaded model do not access the Android UI toolkit

from outside the UI threadmdashthis sample modifies the ImageView from the worker thread instead of the

UI thread This can result in undefined and unexpected behavior which can be difficult and time-

consuming to track down

To fix this problem Android offers several ways to access the UI thread from other threads Here is a

list of methods that can help

ActivityrunOnUiThread(Runnable)

Viewpost(Runnable)

ViewpostDelayed(Runnable long)

For example you can fix the above code by using the Viewpost(Runnable) method

public void onClick(View v) new Thread(new Runnable() public void run() final Bitmap bitmap = loadImageFromNetwork(httpexamplecomimagepng) mImageViewpost(new Runnable() public void run() mImageViewsetImageBitmap(bitmap) ) )start()

Now this implementation is thread-safe the network operation is done from a separate thread while

the ImageView is manipulated from the UI thread

However as the complexity of the operation grows this kind of code can get complicated and difficult

to maintain To handle more complex interactions with a worker thread you might consider using a

Handler in your worker thread to process messages delivered from the UI thread Perhaps the best

solution though is to extend the AsyncTask class which simplifies the execution of worker thread

tasks that need to interact with the UI

Using AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface It performs the blocking

operations in a worker thread and then publishes the results on the UI thread without requiring you to

handle threads andor handlers yourself

To use it you must subclass AsyncTask and implement the doInBackground() callback method which

runs in a pool of background threads To update your UI you should implement onPostExecute()

which delivers the result from doInBackground() and runs in the UI thread so you can safely update

your UI You can then run the task by calling execute() from the UI thread

For example you can implement the previous example using AsyncTask this way

public void onClick(View v) new DownloadImageTask()execute(httpexamplecomimagepng) private class DownloadImageTask extends AsyncTaskltString Void Bitmapgt The system calls this to perform work in a worker thread and delivers it the parameters given to AsyncTaskexecute() protected Bitmap doInBackground(String urls) return loadImageFromNetwork(urls[0])

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 27: 03 services

Every record includes a numeric _ID field that uniquely identifies the record within the table IDs can be

used to match records in related tables mdash for example to find a persons phone number in one table

and pictures of that person in another

A query returns a Cursor object that can move from record to record and column to column to read the

contents of each field It has specialized methods for reading each type of data So to read a field you

must know what type of data the field contains (Theres more on query results and Cursor objects

later)

URIs

Each content provider exposes a public URI (wrapped as a Uri object) that uniquely identifies its data

set A content provider that controls multiple data sets (multiple tables) exposes a separate URI for

each one All URIs for providers begin with the string content The content scheme identifies the

data as being controlled by a content provider

If youre defining a content provider its a good idea to also define a constant for its URI to simplify

client code and make future updates cleaner Android defines CONTENT_URI constants for all the

providers that come with the platform For example the URI for the table that matches phone numbers

to people and the URI for the table that holds pictures of people (both controlled by the Contacts

content provider) are

androidproviderContactsPhonesCONTENT_URI

androidproviderContactsPhotosCONTENT_URI

The URI constant is used in all interactions with the content provider Every ContentResolver method

takes the URI as its first argument Its what identifies which provider the ContentResolver should talk

to and which table of the provider is being targeted

Querying a Content Provider

You need three pieces of information to query a content provider

The URI that identifies the provider

The names of the data fields you want to receive

The data types for those fields

If youre querying a particular record you also need the ID for that record

Making the query

To query a content provider you can use either the ContentResolverquery() method or the

ActivitymanagedQuery() method Both methods take the same set of arguments and both return a

Cursor object However managedQuery() causes the activity to manage the life cycle of the Cursor A

managed Cursor handles all of the niceties such as unloading itself when the activity pauses and

requerying itself when the activity restarts You can ask an Activity to begin managing an unmanaged

Cursor object for you by calling ActivitystartManagingCursor()

The first argument to either query() or managedQuery() is the provider URI mdash the CONTENT_URI

constant that identifies a particular ContentProvider and data set (see URIs earlier)

To restrict a query to just one record you can append the _ID value for that record to the URI mdash that

is place a string matching the ID as the last segment of the path part of the URI For example if the ID

is 23 the URI would be

content 23

There are some helper methods particularly ContentUriswithAppendedId() and

UriwithAppendedPath() that make it easy to append an ID to a URI Both are static methods that

return a Uri object with the ID added So for example if you were looking for record 23 in the database

of people contacts you might construct a query as follows

import androidproviderContactsPeople import androidcontentContentUris import androidnetUri import androiddatabaseCursor Use the ContentUris method to produce the base URI for the contact with _ID == 23 Uri myPerson = ContentUriswithAppendedId(PeopleCONTENT_URI 23) Alternatively use the Uri method to produce the base URI It takes a string rather than an integer Uri myPerson = UriwithAppendedPath(PeopleCONTENT_URI 23) Then query for this specific record Cursor cur = managedQuery(myPerson null null null null)

The other arguments to the query() and managedQuery() methods delimit the query in more detail

They are

The names of the data columns that should be returned A null value returns all columns Otherwise

only columns that are listed by name are returned All the content providers that come with the

platform define constants for their columns For example the androidproviderContactsPhones class

defines constants for the names of the columns in the phone table illustrated earlier ampmdash _ID

NUMBER NUMBER_KEY NAME and so on

A filter detailing which rows to return formatted as an SQL WHERE clause (excluding the WHERE

itself) A null value returns all rows (unless the URI limits the query to a single record)

Selection arguments

A sorting order for the rows that are returned formatted as an SQL ORDER BY clause (excluding the

ORDER BY itself) A null value returns the records in the default order for the table which may be

unordered

Lets look at an example query to retrieve a list of contact names and their primary phone numbers

import androidproviderContactsPeople import androiddatabaseCursor Form an array specifying which columns to return String[] projection = new String[] People_ID People_COUNT PeopleNAME PeopleNUMBER Get the base URI for the People table in the Contacts content provider Uri contacts = PeopleCONTENT_URI Make the query Cursor managedCursor = managedQuery(contacts projection Which columns to return null Which rows to return (all rows) null Selection arguments (none) Put the results in ascending order by name PeopleNAME + ASC)

This query retrieves data from the People table of the Contacts content provider It gets the name

primary phone number and unique record ID for each contact It also reports the number of records

that are returned as the _COUNT field of each record

The constants for the names of the columns are defined in various interfaces mdash _ID and _COUNT in

BaseColumns NAME in PeopleColumns and NUMBER in PhoneColumns The ContactsPeople

class implements each of these interfaces which is why the code example above could refer to them

using just the class name

What a query returns

A query returns a set of zero or more database records The names of the columns their default order

and their data types are specific to each content provider But every provider has an _ID column

which holds a unique numeric ID for each record Every provider can also report the number of records

returned as the _COUNT column its value is the same for all rows

Here is an example result set for the query in the previous section

_ID _COUNT NAME NUMBER

44 3 Alan Vain 212 555 1234

13 3 Bully Pulpit 425 555 6677

53 3 Rex Cars 201 555 4433

The retrieved data is exposed by a Cursor object that can be used to iterate backward or forward

through the result set You can use this object only to read the data To add modify or delete data

you must use a ContentResolver object

Reading retrieved data

The Cursor object returned by a query provides access to a recordset of results If you have queried

for a specific record by ID this set will contain only one value Otherwise it can contain multiple

values (If there are no matches it can also be empty) You can read data from specific fields in the

record but you must know the data type of the field because the Cursor object has a separate method

for reading each type of data mdash such as getString() getInt() and getFloat() (However for most types

if you call the method for reading strings the Cursor object will give you the String representation of

the data) The Cursor lets you request the column name from the index of the column or the index

number from the column name

The following snippet demonstrates reading names and phone numbers from the query illustrated

earlier

import androidproviderContactsPeople private void getColumnData(Cursor cur) if (curmoveToFirst()) String name String phoneNumber int nameColumn = curgetColumnIndex(PeopleNAME) int phoneColumn = curgetColumnIndex(PeopleNUMBER) String imagePath do Get the field values name = curgetString(nameColumn) phoneNumber = curgetString(phoneColumn) Do something with the values while (curmoveToNext())

If a query can return binary data such as an image or sound the data may be directly entered in the

table or the table entry for that data may be a string specifying a content URI that you can use to get

the data In general smaller amounts of data (say from 20 to 50K or less) are most often directly

entered in the table and can be read by calling CursorgetBlob() It returns a byte array

If the table entry is a content URI you should never try to open and read the file directly (for one thing

permissions problems can make this fail) Instead you should call ContentResolveropenInputStream()

to get an InputStream object that you can use to read the data

Modifying Data

Data kept by a content provider can be modified by

Adding new records

Adding new values to existing records

Batch updating existing records

Deleting records

All data modification is accomplished using ContentResolver methods Some content providers require

a more restrictive permission for writing data than they do for reading it If you dont have permission to

write to a content provider the ContentResolver methods will fail

Adding records

To add a new record to a content provider first set up a map of key-value pairs in a ContentValues

object where each key matches the name of a column in the content provider and the value is the

desired value for the new record in that column Then call ContentResolverinsert() and pass it the URI

of the provider and the ContentValues map This method returns the full URI of the new record mdash that

is the providers URI with the appended ID for the new record You can then use this URI to query and

get a Cursor over the new record and to further modify the record Heres an example

import androidproviderContactsPeople import androidcontentContentResolver import androidcontentContentValues ContentValues values = new ContentValues() Add Abraham Lincoln to contacts and make him a favorite valuesput(PeopleNAME Abraham Lincoln) 1 = the new contact is added to favorites 0 = the new contact is not added to favorites valuesput(PeopleSTARRED 1) Uri uri = getContentResolver()insert(PeopleCONTENT_URI values)

Adding new values

Once a record exists you can add new information to it or modify existing information For example

the next step in the example above would be to add contact information mdash like a phone number or an

IM or e-mail address mdash to the new entry

The best way to add to a record in the Contacts database is to append the name of the table where the

new data goes to the URI for the record then use the amended URI to add the new data values Each

Contacts table exposes a name for this purpose as a CONTENT_DIRECTORY constant The following

code continues the previous example by adding a phone number and e-mail address for the record

just created

Uri phoneUri = null Uri emailUri = null Add a phone number for Abraham Lincoln Begin with the URI for the new record just returned by insert() it ends with the _ID of the new record so we dont have to add the ID ourselves Then append the designation for the phone table to this URI and use the resulting URI to insert the phone number phoneUri = UriwithAppendedPath(uri PeoplePhonesCONTENT_DIRECTORY) valuesclear() valuesput(PeoplePhonesTYPE PeoplePhonesTYPE_MOBILE) valuesput(PeoplePhonesNUMBER 1233214567) getContentResolver()insert(phoneUri values) Now add an email address in the same way emailUri = UriwithAppendedPath(uri PeopleContactMethodsCONTENT_DIRECTORY) valuesclear() ContactMethodsKIND is used to distinguish different kinds of contact methods such as email IM etc valuesput(PeopleContactMethodsKIND ContactsKIND_EMAIL) valuesput(PeopleContactMethodsDATA testexamplecom) valuesput(PeopleContactMethodsTYPE PeopleContactMethodsTYPE_HOME) getContentResolver()insert(emailUri values)

You can place small amounts of binary data into a table by calling the version of ContentValuesput()

that takes a byte array That would work for a small icon-like image or a short audio clip for example

However if you have a large amount of binary data to add such as a photograph or a complete song

put a content URI for the data in the table and call ContentResolveropenOutputStream() with the files

URI (That causes the content provider to store the data in a file and record the file path in a hidden

field of the record)

In this regard the MediaStore content provider the main provider that dispenses image audio and

video data employs a special convention The same URI that is used with query() or managedQuery()

to get meta-information about the binary data (such as the caption of a photograph or the date it was

taken) is used with openInputStream() to get the data itself Similarly the same URI that is used with

insert() to put meta-information into a MediaStore record is used with openOutputStream() to place the

binary data there The following code snippet illustrates this convention

import androidproviderMediaStoreImagesMedia import androidcontentContentValues import javaioOutputStream Save the name and description of an image in a ContentValues map ContentValues values = new ContentValues(3) valuesput(MediaDISPLAY_NAME road_trip_1) valuesput(MediaDESCRIPTION Day 1 trip to Los Angeles) valuesput(MediaMIME_TYPE imagejpeg) Add a new record without the bitmap but with the values just set insert() returns the URI of the new record Uri uri = getContentResolver()insert(MediaEXTERNAL_CONTENT_URI values) Now get a handle to the file for that record and save the data into it Here sourceBitmap is a Bitmap object representing the file to save to the database try OutputStream outStream = getContentResolver()openOutputStream(uri) sourceBitmapcompress(BitmapCompressFormatJPEG 50 outStream) outStreamclose() catch (Exception e) Loge(TAG exception while writing image e)

Batch updating records

To batch update a group of records (for example to change NY to New York in all fields) call the

ContentResolverupdate() method with the columns and values to change

Deleting a record

To delete a single record call ContentResolverdelete() with the URI of a specific row

To delete multiple rows call ContentResolverdelete() with the URI of the type of record to delete (for

example androidproviderContactsPeopleCONTENT_URI) and an SQL WHERE clause defining

which rows to delete (Caution Be sure to include a valid WHERE clause if youre deleting a general

type or you risk deleting more records than you intended)

Creating a Content Provider

To create a content provider you must

Set up a system for storing the data Most content providers store their data using Androids file

storage methods or SQLite databases but you can store your data any way you want Android

provides the SQLiteOpenHelper class to help you create a database and SQLiteDatabase to manage

it

Extend the ContentProvider class to provide access to the data

Declare the content provider in the manifest file for your application (AndroidManifestxml)

The following sections have notes on the last two of these tasks

Extending the ContentProvider class

You define a ContentProvider subclass to expose your data to others using the conventions expected

by ContentResolver and Cursor objects Principally this means implementing six abstract methods

declared in the ContentProvider class

query()

insert()

update()

delete()

getType()

onCreate()

The query() method must return a Cursor object that can iterate over the requested data Cursor itself

is an interface but Android provides some ready-made Cursor objects that you can use For example

SQLiteCursor can iterate over data stored in an SQLite database You get the Cursor object by calling

any of the SQLiteDatabase classs query() methods There are other Cursor implementations mdash such

as MatrixCursor mdash for data not stored in a database

Because these ContentProvider methods can be called from various ContentResolver objects in

different processes and threads they must be implemented in a thread-safe manner

As a courtesy you might also want to call ContentResolvernotifyChange() to notify listeners when

there are modifications to the data

Beyond defining the subclass itself there are other steps you should take to simplify the work of clients

and make the class more accessible

Define a public static final Uri named CONTENT_URI This is the string that represents the full content

URI that your content provider handles You must define a unique string for this value The best

solution is to use the fully-qualified class name of the content provider (made lowercase) So for

example the URI for a TransportationProvider class could be defined as follows

public static final Uri CONTENT_URI = Uriparse(contentcomexamplecodelabtransportationprovider)

If the provider has subtables also define CONTENT_URI constants for each of the subtables These

URIs should all have the same authority (since that identifies the content provider) and be

distinguished only by their paths For example

contentcomexamplecodelabtransportationprovidertrain

contentcomexamplecodelabtransportationproviderairdomestic

contentcomexamplecodelabtransportationproviderairinternational

For an overview of content URIs see the Content URI Summary at the end of this document

Define the column names that the content provider will return to clients If you are using an underlying

database these column names are typically identical to the SQL database column names they

represent Also define public static String constants that clients can use to specify the columns in

queries and other instructions

Be sure to include an integer column named _id (with the constant _ID) for the IDs of the records

You should have this field whether or not you have another field (such as a URL) that is also unique

among all records If youre using the SQLite database the _ID field should be the following type

INTEGER PRIMARY KEY AUTOINCREMENT

The AUTOINCREMENT descriptor is optional But without it SQLite increments an ID counter field to

the next number above the largest existing number in the column If you delete the last row the next

row added will have the same ID as the deleted row AUTOINCREMENT avoids this by having SQLite

increment to the next largest value whether deleted or not

Carefully document the data type of each column Clients need this information to read the data

If you are handling a new data type you must define a new MIME type to return in your

implementation of ContentProvidergetType() The type depends in part on whether or not the content

URI submitted to getType() limits the request to a specific record Theres one form of the MIME type

for a single record and another for multiple records Use the Uri methods to help determine what is

being requested Here is the general format for each type

o For a single record vndandroidcursoritemvndyourcompanynamecontenttype

For example a request for train record 122 like this URI

contentcomexampletransportationprovidertrains122

might return this MIME type

vndandroidcursoritemvndexamplerail

o For multiple records vndandroidcursordirvndyourcompanynamecontenttype

For example a request for all train records like the following URI

contentcomexampletransportationprovidertrains

might return this MIME type

vndandroidcursordirvndexamplerail

If you are exposing byte data thats too big to put in the table itself mdash such as a large bitmap file mdash the

field that exposes the data to clients should actually contain a content URI string This is the field that

gives clients access to the data file The record should also have another field named _data that lists

the exact file path on the device for that file This field is not intended to be read by the client but by

the ContentResolver The client will call ContentResolveropenInputStream() on the user-facing field

holding the URI for the item The ContentResolver will request the _data field for that record and

because it has higher permissions than a client it should be able to access that file directly and return

a read wrapper for the file to the client

For an example of a private content provider implementation see the NodePadProvider class in the

Notepad sample application that ships with the SDK

Declaring the content provider

To let the Android system know about the content provider youve developed declare it with a

ltprovidergt element in the applications AndroidManifestxml file Content providers that are not

declared in the manifest are not visible to the Android system

The name attribute is the fully qualified name of the ContentProvider subclass The authorities attribute

is the authority part of the content URI that identifies the provider For example if the ContentProvider

subclass is AutoInfoProvider the ltprovidergt element might look like this

ltprovider androidname=comexampleautosAutoInfoProvider androidauthorities=comexampleautosautoinfoprovider gt ltprovidergt

Note that the authorities attribute omits the path part of a content URI For example if

AutoInfoProvider controlled subtables for different types of autos or different manufacturers

contentcomexampleautosautoinfoproviderhonda

contentcomexampleautosautoinfoprovidergmcompact

contentcomexampleautosautoinfoprovidergmsuv

those paths would not be declared in the manifest The authority is what identifies the provider not the

path your provider can interpret the path part of the URI in any way you choose

Other ltprovidergt attributes can set permissions to read and write data provide for an icon and text

that can be displayed to users enable and disable the provider and so on Set the multiprocess

attribute to true if data does not need to be synchronized between multiple running versions of the

content provider This permits an instance of the provider to be created in each client process

eliminating the need to perform IPC

Content URI Summary

Here is a recap of the important parts of a content URI

A Standard prefix indicating that the data is controlled by a content provider Its never modified

B The authority part of the URI it identifies the content provider For third-party applications this should

be a fully-qualified class name (reduced to lowercase) to ensure uniqueness The authority is declared

in the ltprovidergt elements authorities attribute

ltprovider androidname=TransportationProvider androidauthorities=comexampletransportationprovider gt

C The path that the content provider uses to determine what kind of data is being requested This can be

zero or more segments long If the content provider exposes only one type of data (only trains for

example) it can be absent If the provider exposes several types including subtypes it can be several

segments long mdash for example landbus landtrain seaship and seasubmarine to give four

possibilities

D The ID of the specific record being requested if any This is the _ID value of the requested record If

the request is not limited to a single record this segment and the trailing slash are omitted

contentcomexampletransportationprovidertrains

Intent and intent filters

Three of the core components of an application mdash activities services and broadcast receivers mdash 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 mdash 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 ContextstartActivity() or ActivitystartActivityForResult() to launch an

activity or get an existing activity to do something new (It can also be passed to ActivitysetResult() to

return information to the activity that called startActivityForResult())

An Intent object is passed to ContextstartService() to initiate a service or deliver new instructions to an

ongoing service Similarly an intent can be passed to ContextbindService() to establish a connection

between the calling component and a target service It can optionally initiate the service if its not

already running

Intent objects passed to any of the broadcast methods (such as ContextsendBroadcast()

ContextsendOrderedBroadcast() or ContextsendStickyBroadcast()) 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 mdash how it resolves which component should receive an intent message For

intents that dont explicitly name a target component this process involves testing the Intent object

against intent filters associated with potential targets

Intent Objects

An Intent object is a bundle of information It contains information of interest to the component that

receives the intent (such as the action to be taken and the data to act on) plus information of interest to

the Android system (such as the category of component that should handle the intent and instructions

on how to launch a target activity) Principally it can contain the following

Component name

The name of the component that should handle the intent This field is a ComponentName

object mdash a combination of the fully qualified class name of the target component (for example

comexampleprojectappFreneticActivity) and the package name set in the manifest file of the

application where the component resides (for example comexampleproject) The package

part of the component name and the package name set in the manifest do not necessarily have

to match

The component name is optional If it is set the Intent object is delivered to an instance of the

designated class If it is not set Android uses other information in the Intent object to locate a

suitable target mdash see Intent Resolution later in this document

The component name is set by setComponent() setClass() or setClassName() and read by

getComponent()

Action

A string naming the action to be performed mdash or in the case of broadcast intents the action

that took place and is being reported The Intent class defines a number of action constants

including these

Constant Target

component

Action

ACTION_CALL activity Initiate a phone call

ACTION_EDIT activity Display data for the user to edit

ACTION_MAIN activity Start up as the initial activity of a task

with no data input and no returned

output

ACTION_SYNC activity Synchronize data on a server with

data on the mobile device

ACTION_BATTERY_LOW broadcast

receiver

A warning that the battery is low

ACTION_HEADSET_PLUG broadcast

receiver

A headset has been plugged into the

device or unplugged from it

ACTION_SCREEN_ON broadcast

receiver

The screen has been turned on

ACTION_TIMEZONE_CHANGED broadcast

receiver

The setting for the time zone has

changed

See the Intent class description for a list of pre-defined constants for generic actions Other

actions are defined elsewhere in the Android API You can also define your own action strings

for activating the components in your application Those you invent should include the

application package as a prefix mdash for example comexampleprojectSHOW_COLOR

The action largely determines how the rest of the intent is structured mdash particularly the data and

extras fields mdash much as a method name determines a set of arguments and a return value For

this reason its a good idea to use action names that are as specific as possible and to couple

them tightly to the other fields of the intent In other words instead of defining an action in

isolation define an entire protocol for the Intent objects your components can handle

The action in an Intent object is set by the setAction() method and read by getAction()

Data

The URI of the data to be acted on and the MIME type of that data Different actions are paired

with different kinds of data specifications For example if the action field is ACTION_EDIT the

data field would contain the URI of the document to be displayed for editing If the action is

ACTION_CALL the data field would be a tel URI with the number to call Similarly if the action

is ACTION_VIEW and the data field is an http URI the receiving activity would be called upon

to download and display whatever data the URI refers to

When matching an intent to a component that is capable of handling the data its often

important to know the type of data (its MIME type) in addition to its URI For example a

component able to display image data should not be called upon to play an audio file

In many cases the data type can be inferred from the URI mdash particularly content URIs which

indicate that the data is located on the device and controlled by a content provider (see the

separate discussion on content providers) But the type can also be explicitly set in the Intent

object The setData() method specifies data only as a URI setType() specifies it only as a

MIME type and setDataAndType() specifies it as both a URI and a MIME type The URI is read

by getData() and the type by getType()

Category

A string containing additional information about the kind of component that should handle the

intent Any number of category descriptions can be placed in an Intent object As it does for

actions the Intent class defines several category constants including these

Constant Meaning

CATEGORY_BROWSABLE The target activity can be safely invoked by the browser to

display data referenced by a link mdash for example an image or

an e-mail message

CATEGORY_GADGET The activity can be embedded inside of another activity that

hosts gadgets

CATEGORY_HOME The activity displays the home screen the first screen the

user sees when the device is turned on or when the HOME

key is pressed

CATEGORY_LAUNCHER The activity can be the initial activity of a task and is listed in

the top-level application launcher

CATEGORY_PREFERENCE The target activity is a preference panel

See the Intent class description for the full list of categories

The addCategory() method places a category in an Intent object removeCategory() deletes a

category previously added and getCategories() gets the set of all categories currently in the

object

Extras

Key-value pairs for additional information that should be delivered to the component handling

the intent Just as some actions are paired with particular kinds of data URIs some are paired

with particular extras For example an ACTION_TIMEZONE_CHANGED intent has a time-

zone extra that identifies the new time zone and ACTION_HEADSET_PLUG has a state

extra indicating whether the headset is now plugged in or unplugged as well as a name extra

for the type of headset If you were to invent a SHOW_COLOR action the color value would be

set in an extra key-value pair

The Intent object has a series of put() methods for inserting various types of extra data and a

similar set of get() methods for reading the data These methods parallel those for Bundle

objects In fact the extras can be installed and read as a Bundle using the putExtras() and

getExtras() methods

Flags

Flags of various sorts Many instruct the Android system how to launch an activity (for example

which task the activity should belong to) and how to treat it after its launched (for example

whether it belongs in the list of recent activities) All these flags are defined in the Intent class

The Android system and the applications that come with the platform employ Intent objects both to

send out system-originated broadcasts and to activate system-defined components To see how to

structure an intent to activate a system component consult the list of intents in the reference

Intent Resolution

Intents can be divided into two groups

Explicit intents designate the target component by its name (the component name field mentioned

earlier has a value set) Since component names would generally not be known to developers of other

applications explicit intents are typically used for application-internal messages mdash such as an activity

starting a subordinate service or launching a sister activity

Implicit intents do not name a target (the field for the component name is blank) Implicit intents are

often used to activate components in other applications

Android delivers an explicit intent to an instance of the designated target class Nothing in the Intent

object other than the component name matters for determining which component should get the intent

A different strategy is needed for implicit intents In the absence of a designated target the Android

system must find the best component (or components) to handle the intent mdash a single activity or

service to perform the requested action or the set of broadcast receivers to respond to the broadcast

announcement It does so by comparing the contents of the Intent object to intent filters structures

associated with components that can potentially receive intents Filters advertise the capabilities of a

component and delimit the intents it can handle They open the component to the possibility of

receiving implicit intents of the advertised type If a component does not have any intent filters it can

receive only explicit intents A component with filters can receive both explicit and implicit intents

Only three aspects of an Intent object are consulted when the object is tested against an intent filter

action

data (both URI and data type)

category

The extras and flags play no part in resolving which component receives an intent

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 mdash but only unwanted implicit intents (those that dont 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

components 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 mdash 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 Pads filters are described in the Note Pad Example

section later)

Filters and security

An intent filter cannot be relied on for security While it opens a component to receiving only certain

kinds of implicit intents it does nothing to prevent explicit intents from targeting the component Even

though a filter restricts the intents a component will be asked to handle to certain actions and data

sources someone could always put together an explicit intent with a different action and data source

and name the component as the target

An intent filter is an instance of the IntentFilter class However since the Android system must know

about the capabilities of a component before it can launch that component intent filters are generally

not set up in Java code but in the applications manifest file (AndroidManifestxml) as ltintent-filtergt

elements (The one exception would be filters for broadcast receivers that are registered dynamically

by calling ContextregisterReceiver() they are directly created as IntentFilter objects)

A filter has fields that parallel the action data and category fields of an Intent object An implicit intent

is tested against the filter in all three areas To be delivered to the component that owns the filter it

must pass all three tests If it fails even one of them the Android system wont deliver it to the

component mdash at least not on the basis of that filter However since a component can have multiple

intent filters an intent that does not pass through one of a components filters might make it through on

another

Each of the three tests is described in detail below

Action test

An ltintent-filtergt element in the manifest file lists actions as ltactiongt subelements For

example

ltintent-filter gt ltaction androidname=comexampleprojectSHOW_CURRENT gt ltaction androidname=comexampleprojectSHOW_RECENT gt ltaction androidname=comexampleprojectSHOW_PENDING gt ltintent-filtergt

As the example shows while an Intent object names just a single action a filter may list more

than one The list cannot be empty a filter must contain at least one ltactiongt element or it will

block all intents

To pass this test the action specified in the Intent object must match one of the actions listed in

the filter If the object or the filter does not specify an action the results are as follows

If the filter fails to list any actions there is nothing for an intent to match so all intents fail the

test No intents can get through the filter

On the other hand an Intent object that doesnt specify an action automatically passes the test

mdash as long as the filter contains at least one action

Category test

An ltintent-filtergt element also lists categories as subelements For example

ltintent-filter gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryBROWSABLE gt ltintent-filtergt

Note that the constants described earlier for actions and categories are not used in the manifest

file The full string values are used instead For instance the

androidintentcategoryBROWSABLE string in the example above corresponds to the

CATEGORY_BROWSABLE constant mentioned earlier in this document Similarly the string

androidintentactionEDIT corresponds to the ACTION_EDIT constant

For an intent to pass the category test every category in the Intent object must match a

category in the filter The filter can list additional categories but it cannot omit any that are in the

intent

In principle therefore an Intent object with no categories should always pass this test

regardless of whats in the filter Thats mostly true However with one exception Android treats

all implicit intents passed to startActivity() as if they contained at least one category

androidintentcategoryDEFAULT (the CATEGORY_DEFAULT constant) Therefore activities

that are willing to receive implicit intents must include androidintentcategoryDEFAULT in

their intent filters (Filters with androidintentactionMAIN and

androidintentcategoryLAUNCHER settings are the exception They mark activities that begin

new tasks and that are represented on the launcher screen They can include

androidintentcategoryDEFAULT in the list of categories but dont need to) See Using intent

matching later for more on these filters)

Data test

Like the action and categories the data specification for an intent filter is contained in a

subelement And as in those cases the subelement can appear multiple times or not at all For

example

ltintent-filter gt ltdata androidmimeType=videompeg androidscheme=http gt ltdata androidmimeType=audiompeg androidscheme=http gt ltintent-filtergt

Each ltdatagt element can specify a URI and a data type (MIME media type) There are

separate attributes mdash scheme host port and path mdash for each part of the URI

schemehostportpath

For example in the following URI

contentcomexampleproject200foldersubfolderetc

the scheme is content the host is comexampleproject the port is 200 and the path is

foldersubfolderetc The host and port together constitute the URI authority if a host is not

specified the port is ignored

Each of these attributes is optional but they are not independent of each other For an authority

to be meaningful a scheme must also be specified For a path to be meaningful both a scheme

and an authority must be specified

When the URI in an Intent object is compared to a URI specification in a filter its compared

only to the parts of the URI actually mentioned in the filter For example if a filter specifies only

a scheme all URIs with that scheme match the filter If a filter specifies a scheme and an

authority but no path all URIs with the same scheme and authority match regardless of their

paths If a filter specifies a scheme an authority and a path only URIs with the same scheme

authority and path match However a path specification in the filter can contain wildcards to

require only a partial match of the path

The type attribute of a ltdatagt element specifies the MIME type of the data Its more common in

filters than a URI Both the Intent object and the filter can use a wildcard for the subtype field

mdash for example text or audio mdash indicating any subtype matches

The data test compares both the URI and the data type in the Intent object to a URI and data

type specified in the filter The rules are as follows

a An Intent object that contains neither a URI nor a data type passes the test only if the filter

likewise does not specify any URIs or data types

b An Intent object that contains a URI but no data type (and a type cannot be inferred from the

URI) passes the test only if its URI matches a URI in the filter and the filter likewise does not

specify a type This will be the case only for URIs like mailto and tel that do not refer to actual

data

c An Intent object that contains a data type but not a URI passes the test only if the filter lists the

same data type and similarly does not specify a URI

d An Intent object that contains both a URI and a data type (or a data type can be inferred from

the URI) passes the data type part of the test only if its type matches a type listed in the filter It

passes the URI part of the test either if its URI matches a URI in the filter or if it has a content

or file URI and the filter does not specify a URI In other words a component is presumed to

support content and file data if its filter lists only a data type

If an intent can pass through the filters of more than one activity or service the user may be asked

which component to activate An exception is raised if no target can be found

Common cases

The last rule shown above for the data test rule (d) reflects the expectation that components are able

to get local data from a file or content provider Therefore their filters can list just a data type and do

not need to explicitly name the content and file schemes This is a typical case A ltdatagt element like

the following for example tells Android that the component can get image data from a content

provider and display it

ltdata androidmimeType=image gt

Since most available data is dispensed by content providers filters that specify a data type but not a

URI are perhaps the most common

Another common configuration is filters with a scheme and a data type For example a ltdatagt

element like the following tells Android that the component can get video data from the network and

display it

ltdata androidscheme=http androidtype=video gt

Consider for example what the browser application does when the user follows a link on a web page

It first tries to display the data (as it could if the link was to an HTML page) If it cant display the data it

puts together an implicit intent with the scheme and data type and tries to start an activity that can do

the job If there are no takers it asks the download manager to download the data That puts it under

the control of a content provider so a potentially larger pool of activities (those with filters that just

name a data type) can respond

Most applications also have a way to start fresh without a reference to any particular data Activities

that can initiate applications have filters with androidintentactionMAIN specified as the action If

they are to be represented in the application launcher they also specify the

androidintentcategoryLAUNCHER category

ltintent-filter gt ltaction androidname=code androidintentactionMAIN gt ltcategory androidname=code androidintentcategoryLAUNCHER gt ltintent-filtergt

Using intent matching

Intents are matched against intent filters not only to discover a target component to activate but also

to discover something about the set of components on the device For example the Android system

populates the application launcher the top-level screen that shows the applications that are available

for the user to launch by finding all the activities with intent filters that specify the

androidintentactionMAIN action and androidintentcategoryLAUNCHER category (as illustrated

in the previous section) It then displays the icons and labels of those activities in the launcher

Similarly it discovers the home screen by looking for the activity with androidintentcategoryHOME

in its filter

Your application can use intent matching is a similar way The PackageManager has a set of query()

methods that return all components that can accept a particular intent and a similar series of

resolve() methods that determine the best component to respond to an intent For example

queryIntentActivities() returns a list of all activities that can perform the intent passed as an argument

and queryIntentServices() returns a similar list of services Neither method activates the components

they just list the ones that can respond Theres a similar method queryBroadcastReceivers() for

broadcast receivers

Note Pad Example

The Note Pad sample application enables users to browse through a list of notes view details about

individual items in the list edit the items and add a new item to the list This section looks at the intent

filters declared in its manifest file (If youre working offline in the SDK you can find all the source files

for this sample application including its manifest file at ltsdkgtsamplesNotePadindexhtml If youre

viewing the documentation online the source files are in the Tutorials and Sample Code section here)

In its manifest file the Note Pad application declares three activities each with at least one intent filter

It also declares a content provider that manages the note data Here is the manifest file in its entirety

ltmanifest xmlnsandroid=httpschemasandroidcomapkresandroid package=comexampleandroidnotepadgt ltapplication androidicon=drawableapp_notes androidlabel=stringapp_name gt ltprovider androidname=NotePadProvider androidauthorities=comgoogleproviderNotePad gt ltactivity androidname=NotesList androidlabel=stringtitle_notes_listgt ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltactivity androidname=NoteEditor androidtheme=androidstyleThemeLight androidlabel=stringtitle_note gt ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltactivitygt

ltactivity androidname=TitleEditor androidlabel=stringtitle_edit_title androidtheme=androidstyleThemeDialoggt ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltapplicationgt ltmanifestgt

The first activity NotesList is distinguished from the other activities by the fact that it operates on a

directory of notes (the note list) rather than on a single note It would generally serve as the initial user

interface into the application It can do three things as described by its three intent filters

1 ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt

This filter declares the main entry point into the Note Pad application The standard MAIN action is an

entry point that does not require any other information in the Intent (no data specification for example)

and the LAUNCHER category says that this entry point should be listed in the application launcher

2 ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

This filter declares the things that the activity can do on a directory of notes It can allow the user to

view or edit the directory (via the VIEW and EDIT actions) or to pick a particular note from the

directory (via the PICK action)

The mimeType attribute of the ltdatagt element specifies the kind of data that these actions operate on

It indicates that the activity can get a Cursor over zero or more items (vndandroidcursordir) from a

content provider that holds Note Pad data (vndgooglenote) The Intent object that launches the

activity would include a content URI specifying the exact data of this type that the activity should open

Note also the DEFAULT category supplied in this filter Its there because the ContextstartActivity()

and ActivitystartActivityForResult() methods treat all intents as if they contained the DEFAULT

category mdash with just two exceptions

o Intents that explicitly name the target activity

o Intents consisting of the MAIN action and LAUNCHER category

Therefore the DEFAULT category is required for all filters mdash except for those with the MAIN action

and LAUNCHER category (Intent filters are not consulted for explicit intents)

3 ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

This filter describes the activitys ability to return a note selected by the user without requiring any

specification of the directory the user should choose from The GET_CONTENT action is similar to the

PICK action In both cases the activity returns the URI for a note selected by the user (In each case

its returned to the activity that called startActivityForResult() to start the NoteList activity) Here

however the caller specifies the type of data desired instead of the directory of data the user will be

picking from

The data type vndandroidcursoritemvndgooglenote indicates the type of data the activity can

return mdash a URI for a single note From the returned URI the caller can get a Cursor for exactly one

item (vndandroidcursoritem) from the content provider that holds Note Pad data (vndgooglenote)

In other words for the PICK action in the previous filter the data type indicates the type of data the

activity could display to the user For the GET_CONTENT filter it indicates the type of data the activity

can return to the caller

Given these capabilities the following intents will resolve to the NotesList activity

action androidintentactionMAIN

Launches the activity with no data specified

action androidintentactionMAIN

category androidintentcategoryLAUNCHER

Launches the activity with no data selected specified This is the actual intent used by the

Launcher to populate its top-level list All activities with filters that match this action and

category are added to the list

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of all the notes under

contentcomgoogleproviderNotePadnotes The user can then browse through the list and

get information about the items in it

action androidintentactionPICK

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of the notes under

contentcomgoogleproviderNotePadnotes The user can then pick a note from the list and

the activity will return the URI for that item back to the activity that started the NoteList activity

action androidintentactionGET_CONTENT

data type vndandroidcursoritemvndgooglenote

Asks the activity to supply a single item of Note Pad data

The second activity NoteEditor shows users a single note entry and allows them to edit it It can do

two things as described by its two intent filters

1 ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The first primary purpose of this activity is to enable the user to interact with a single note ampmdash to

either VIEW the note or EDIT it (The EDIT_NOTE category is a synonym for EDIT) The intent would

contain the URI for data matching the MIME type vndandroidcursoritemvndgooglenote mdash that is

the URI for a single specific note It would typically be a URI that was returned by the PICK or

GET_CONTENT actions of the NoteList activity

As before this filter lists the DEFAULT category so that the activity can be launched by intents that

dont explicitly specify the NoteEditor class

2 ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

The secondary purpose of this activity is to enable the user to create a new note which it will INSERT

into an existing directory of notes The intent would contain the URI for data matching the MIME type

vndandroidcursordirvndgooglenote mdash that is the URI for the directory where the note should be

placed

Given these capabilities the following intents will resolve to the NoteEditor activity

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID (For details on how content

URIs specify individual members of a group see Content Providers)

action androidintentactionEDIT

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID and to let the user edit it If

the user saves the changes the activity updates the data for the note in the content provider

action androidintentactionINSERT

data contentcomgoogleproviderNotePadnotes

Asks the activity to create a new empty note in the notes list at

contentcomgoogleproviderNotePadnotes and allow the user to edit it If the user saves the

note its URI is returned to the caller

The last activity TitleEditor enables the user to edit the title of a note This could be implemented by

directly invoking the activity (by explicitly setting its component name in the Intent) without using an

intent filter But here we take the opportunity to show how to publish alternative operations on existing

data

ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The single intent filter for this activity uses a custom action called

comandroidnotepadactionEDIT_TITLE It must be invoked on a specific note (data type

vndandroidcursoritemvndgooglenote) like the previous VIEW and EDIT actions However here the

activity displays the title contained in the note data not the content of the note itself

In addition to supporting the usual DEFAULT category the title editor also supports two other standard

categories ALTERNATIVE and SELECTED_ALTERNATIVE These categories identify activities that

can be presented to users in a menu of options (much as the LAUNCHER category identifies activities

that should be presented to user in the application launcher) Note that the filter also supplies an

explicit label (via androidlabel=stringresolve_title) to better control what users see when

presented with this activity as an alternative action to the data they are currently viewing (For more

information on these categories and building options menus see the

PackageManagerqueryIntentActivityOptions() and MenuaddIntentOptions() methods)

Given these capabilities the following intent will resolve to the TitleEditor activity

action comandroidnotepadactionEDIT_TITLE

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the title associated with note ID and allow the user to edit the title

Processes and Threads

When an application component starts and the application does not have any other components

running the Android system starts a new Linux process for the application with a single thread of

execution By default all components of the same application run in the same process and thread

(called the main thread) If an application component starts and there already exists a process for

that application (because another component from the application exists) then the component is

started within that process and uses the same thread of execution However you can arrange for

different components in your application to run in separate processes and you can create additional

threads for any process

This document discusses how processes and threads work in an Android application

Processes

By default all components of the same application run in the same process and most applications

should not change this However if you find that you need to control which process a certain

component belongs to you can do so in the manifest file

The manifest entry for each type of component elementmdashltactivitygt ltservicegt ltreceivergt and

ltprovidergtmdashsupports an androidprocess attribute that can specify a process in which that component

should run You can set this attribute so that each component runs in its own process or so that some

components share a process while others do not You can also set androidprocess so that

components of different applications run in the same processmdashprovided that the applications share the

same Linux user ID and are signed with the same certificates

The ltapplicationgt element also supports an androidprocess attribute to set a default value that

applies to all components

Android might 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 thats killed are consequently destroyed A process is started again for those components

when theres again work for them to do

When deciding which processes to kill the Android system weighs their relative importance to the

user For example it more readily shuts down a process hosting activities that are no longer visible on

screen compared to a process hosting visible activities The decision whether to terminate a process

therefore depends on the state of the components running in that process The rules used to decide

which processes to terminate is discussed below

Process lifecycle

The Android system tries to maintain an application process for as long as possible but eventually

needs to remove old processes to reclaim memory for new or more important processes To determine

which processes to keep and which to kill the system places each process into an importance

hierarchy based on the components running in the process and the state of those components

Processes with the lowest importance are eliminated first then those with the next lowest importance

and so on as necessary to recover system resources

There are five levels in the importance hierarchy The following list presents the different types of

processes in order of importance (the first process is most important and is killed last)

1 Foreground process

A process that is required for what the user is currently doing A process is considered to be in the

foreground if any of the following conditions are true

o It hosts an Activity that the user is interacting with (the Activitys onResume() method has been called)

o It hosts a Service thats bound to the activity that the user is interacting with

o It hosts a Service thats running in the foregroundmdashthe service has called startForeground()

o It hosts a Service thats executing one of its lifecycle callbacks (onCreate() onStart() or onDestroy())

o It hosts a BroadcastReceiver thats executing its onReceive() method

Generally only a few foreground processes exist at any given time They are killed only as a last

resortmdashif memory is so low that they cannot all continue to run Generally at that point the device has

reached a memory paging state so killing some foreground processes is required to keep the user

interface responsive

2 Visible process

A process that doesnt have any foreground components but still can affect what the user sees on

screen A process is considered to be visible if either of the following conditions are true

o It hosts an Activity that is not in the foreground but is still visible to the user (its onPause() method has

been called) This might occur for example if the foreground activity started a dialog which allows the

previous activity to be seen behind it

o It hosts a Service thats bound to a visible (or foreground) activity

A visible process is considered extremely important and will not be killed unless doing so is required to

keep all foreground processes running

3 Service process

A process that is running a service that has been started with the startService() method and does not

fall into either of the two higher categories Although service processes are not directly tied to anything

the user sees they are generally doing things that the user cares about (such as playing music in the

background or downloading data on the network) so the system keeps them running unless theres

not enough memory to retain them along with all foreground and visible processes

4 Background process

A process holding an activity thats not currently visible to the user (the activitys onStop() method has

been called) These processes have no direct impact on the user experience and the system can kill

them at any time to reclaim memory for a foreground visible or service process Usually there are

many background processes running so they are kept in an LRU (least recently used) list to ensure

that the process with the activity that was most recently seen by the user is the last to be killed If an

activity implements its lifecycle methods correctly and saves its current state killing its process will not

have a visible effect on the user experience because when the user navigates back to the activity the

activity restores all of its visible state See the Activities document for information about saving and

restoring state

5 Empty process

A process that doesnt hold any active application components The only reason to keep this kind of

process alive is for caching purposes to improve startup time the next time a component needs to run

in it The system often kills these processes in order to balance overall system resources between

process caches and the underlying kernel caches

Android ranks a process at the highest level it can based upon the importance of the components

currently active in the process For example if a process hosts a service and a visible activity the

process is ranked as a visible process not a service process

In addition a processs ranking might be increased because other processes are dependent on itmdasha

process that is serving another process can never be ranked lower than the process it is serving For

example if a content provider in process A is serving a client in process B or if a service in process A

is bound to a component in process B process A is always considered at least as important as

process B

Because a process running a service is ranked higher than a process with background activities an

activity that initiates a long-running operation might do well to start a service for that operation rather

than simply create a worker threadmdashparticularly if the operation will likely outlast the activity For

example an activity thats uploading a picture to a web site should start a service to perform the

upload so that the upload can continue in the background even if the user leaves the activity Using a

service guarantees that the operation will have at least service process priority regardless of what

happens to the activity This is the same reason that broadcast receivers should employ services

rather than simply put time-consuming operations in a thread

Threads

When an application is launched the system creates a thread of execution for the application called

main This thread is very important because it is in charge of dispatching events to the appropriate

user interface widgets including drawing events It is also the thread in which your application interacts

with components from the Android UI toolkit (components from the androidwidget and androidview

packages) As such the main thread is also sometimes called the UI thread

The system does not create a separate thread for each instance of a component All components that

run in the same process are instantiated in the UI thread and system calls to each component are

dispatched from that thread Consequently methods that respond to system callbacks (such as

onKeyDown() to report user actions or a lifecycle callback method) always run in the UI thread of the

process

For instance when the user touches a button on the screen your apps UI thread dispatches the touch

event to the widget which in turn sets its pressed state and posts an invalidate request to the event

queue The UI thread dequeues the request and notifies the widget that it should redraw itself

When your app performs intensive work in response to user interaction this single thread model can

yield poor performance unless you implement your application properly Specifically if everything is

happening in the UI thread performing long operations such as network access or database queries

will block the whole UI When the thread is blocked no events can be dispatched including drawing

events From the users perspective the application appears to hang Even worse if the UI thread is

blocked for more than a few seconds (about 5 seconds currently) the user is presented with the

infamous application not responding (ANR) dialog The user might then decide to quit your

application and uninstall it if they are unhappy

Additionally the Andoid UI toolkit is not thread-safe So you must not manipulate your UI from a

worker threadmdashyou must do all manipulation to your user interface from the UI thread Thus there are

simply two rules to Androids single thread model

1 Do not block the UI thread

2 Do not access the Android UI toolkit from outside the UI thread

Worker threads

Because of the single thread model described above its vital to the responsiveness of your

applications UI that you do not block the UI thread If you have operations to perform that are not

instantaneous you should make sure to do them in separate threads (background or worker

threads)

For example below is some code for a click listener that downloads an image from a separate thread

and displays it in an ImageView

public void onClick(View v) new Thread(new Runnable() public void run() Bitmap b = loadImageFromNetwork(httpexamplecomimagepng) mImageViewsetImageBitmap(b) )start()

At first this seems to work fine because it creates a new thread to handle the network operation

However it violates the second rule of the single-threaded model do not access the Android UI toolkit

from outside the UI threadmdashthis sample modifies the ImageView from the worker thread instead of the

UI thread This can result in undefined and unexpected behavior which can be difficult and time-

consuming to track down

To fix this problem Android offers several ways to access the UI thread from other threads Here is a

list of methods that can help

ActivityrunOnUiThread(Runnable)

Viewpost(Runnable)

ViewpostDelayed(Runnable long)

For example you can fix the above code by using the Viewpost(Runnable) method

public void onClick(View v) new Thread(new Runnable() public void run() final Bitmap bitmap = loadImageFromNetwork(httpexamplecomimagepng) mImageViewpost(new Runnable() public void run() mImageViewsetImageBitmap(bitmap) ) )start()

Now this implementation is thread-safe the network operation is done from a separate thread while

the ImageView is manipulated from the UI thread

However as the complexity of the operation grows this kind of code can get complicated and difficult

to maintain To handle more complex interactions with a worker thread you might consider using a

Handler in your worker thread to process messages delivered from the UI thread Perhaps the best

solution though is to extend the AsyncTask class which simplifies the execution of worker thread

tasks that need to interact with the UI

Using AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface It performs the blocking

operations in a worker thread and then publishes the results on the UI thread without requiring you to

handle threads andor handlers yourself

To use it you must subclass AsyncTask and implement the doInBackground() callback method which

runs in a pool of background threads To update your UI you should implement onPostExecute()

which delivers the result from doInBackground() and runs in the UI thread so you can safely update

your UI You can then run the task by calling execute() from the UI thread

For example you can implement the previous example using AsyncTask this way

public void onClick(View v) new DownloadImageTask()execute(httpexamplecomimagepng) private class DownloadImageTask extends AsyncTaskltString Void Bitmapgt The system calls this to perform work in a worker thread and delivers it the parameters given to AsyncTaskexecute() protected Bitmap doInBackground(String urls) return loadImageFromNetwork(urls[0])

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 28: 03 services

requerying itself when the activity restarts You can ask an Activity to begin managing an unmanaged

Cursor object for you by calling ActivitystartManagingCursor()

The first argument to either query() or managedQuery() is the provider URI mdash the CONTENT_URI

constant that identifies a particular ContentProvider and data set (see URIs earlier)

To restrict a query to just one record you can append the _ID value for that record to the URI mdash that

is place a string matching the ID as the last segment of the path part of the URI For example if the ID

is 23 the URI would be

content 23

There are some helper methods particularly ContentUriswithAppendedId() and

UriwithAppendedPath() that make it easy to append an ID to a URI Both are static methods that

return a Uri object with the ID added So for example if you were looking for record 23 in the database

of people contacts you might construct a query as follows

import androidproviderContactsPeople import androidcontentContentUris import androidnetUri import androiddatabaseCursor Use the ContentUris method to produce the base URI for the contact with _ID == 23 Uri myPerson = ContentUriswithAppendedId(PeopleCONTENT_URI 23) Alternatively use the Uri method to produce the base URI It takes a string rather than an integer Uri myPerson = UriwithAppendedPath(PeopleCONTENT_URI 23) Then query for this specific record Cursor cur = managedQuery(myPerson null null null null)

The other arguments to the query() and managedQuery() methods delimit the query in more detail

They are

The names of the data columns that should be returned A null value returns all columns Otherwise

only columns that are listed by name are returned All the content providers that come with the

platform define constants for their columns For example the androidproviderContactsPhones class

defines constants for the names of the columns in the phone table illustrated earlier ampmdash _ID

NUMBER NUMBER_KEY NAME and so on

A filter detailing which rows to return formatted as an SQL WHERE clause (excluding the WHERE

itself) A null value returns all rows (unless the URI limits the query to a single record)

Selection arguments

A sorting order for the rows that are returned formatted as an SQL ORDER BY clause (excluding the

ORDER BY itself) A null value returns the records in the default order for the table which may be

unordered

Lets look at an example query to retrieve a list of contact names and their primary phone numbers

import androidproviderContactsPeople import androiddatabaseCursor Form an array specifying which columns to return String[] projection = new String[] People_ID People_COUNT PeopleNAME PeopleNUMBER Get the base URI for the People table in the Contacts content provider Uri contacts = PeopleCONTENT_URI Make the query Cursor managedCursor = managedQuery(contacts projection Which columns to return null Which rows to return (all rows) null Selection arguments (none) Put the results in ascending order by name PeopleNAME + ASC)

This query retrieves data from the People table of the Contacts content provider It gets the name

primary phone number and unique record ID for each contact It also reports the number of records

that are returned as the _COUNT field of each record

The constants for the names of the columns are defined in various interfaces mdash _ID and _COUNT in

BaseColumns NAME in PeopleColumns and NUMBER in PhoneColumns The ContactsPeople

class implements each of these interfaces which is why the code example above could refer to them

using just the class name

What a query returns

A query returns a set of zero or more database records The names of the columns their default order

and their data types are specific to each content provider But every provider has an _ID column

which holds a unique numeric ID for each record Every provider can also report the number of records

returned as the _COUNT column its value is the same for all rows

Here is an example result set for the query in the previous section

_ID _COUNT NAME NUMBER

44 3 Alan Vain 212 555 1234

13 3 Bully Pulpit 425 555 6677

53 3 Rex Cars 201 555 4433

The retrieved data is exposed by a Cursor object that can be used to iterate backward or forward

through the result set You can use this object only to read the data To add modify or delete data

you must use a ContentResolver object

Reading retrieved data

The Cursor object returned by a query provides access to a recordset of results If you have queried

for a specific record by ID this set will contain only one value Otherwise it can contain multiple

values (If there are no matches it can also be empty) You can read data from specific fields in the

record but you must know the data type of the field because the Cursor object has a separate method

for reading each type of data mdash such as getString() getInt() and getFloat() (However for most types

if you call the method for reading strings the Cursor object will give you the String representation of

the data) The Cursor lets you request the column name from the index of the column or the index

number from the column name

The following snippet demonstrates reading names and phone numbers from the query illustrated

earlier

import androidproviderContactsPeople private void getColumnData(Cursor cur) if (curmoveToFirst()) String name String phoneNumber int nameColumn = curgetColumnIndex(PeopleNAME) int phoneColumn = curgetColumnIndex(PeopleNUMBER) String imagePath do Get the field values name = curgetString(nameColumn) phoneNumber = curgetString(phoneColumn) Do something with the values while (curmoveToNext())

If a query can return binary data such as an image or sound the data may be directly entered in the

table or the table entry for that data may be a string specifying a content URI that you can use to get

the data In general smaller amounts of data (say from 20 to 50K or less) are most often directly

entered in the table and can be read by calling CursorgetBlob() It returns a byte array

If the table entry is a content URI you should never try to open and read the file directly (for one thing

permissions problems can make this fail) Instead you should call ContentResolveropenInputStream()

to get an InputStream object that you can use to read the data

Modifying Data

Data kept by a content provider can be modified by

Adding new records

Adding new values to existing records

Batch updating existing records

Deleting records

All data modification is accomplished using ContentResolver methods Some content providers require

a more restrictive permission for writing data than they do for reading it If you dont have permission to

write to a content provider the ContentResolver methods will fail

Adding records

To add a new record to a content provider first set up a map of key-value pairs in a ContentValues

object where each key matches the name of a column in the content provider and the value is the

desired value for the new record in that column Then call ContentResolverinsert() and pass it the URI

of the provider and the ContentValues map This method returns the full URI of the new record mdash that

is the providers URI with the appended ID for the new record You can then use this URI to query and

get a Cursor over the new record and to further modify the record Heres an example

import androidproviderContactsPeople import androidcontentContentResolver import androidcontentContentValues ContentValues values = new ContentValues() Add Abraham Lincoln to contacts and make him a favorite valuesput(PeopleNAME Abraham Lincoln) 1 = the new contact is added to favorites 0 = the new contact is not added to favorites valuesput(PeopleSTARRED 1) Uri uri = getContentResolver()insert(PeopleCONTENT_URI values)

Adding new values

Once a record exists you can add new information to it or modify existing information For example

the next step in the example above would be to add contact information mdash like a phone number or an

IM or e-mail address mdash to the new entry

The best way to add to a record in the Contacts database is to append the name of the table where the

new data goes to the URI for the record then use the amended URI to add the new data values Each

Contacts table exposes a name for this purpose as a CONTENT_DIRECTORY constant The following

code continues the previous example by adding a phone number and e-mail address for the record

just created

Uri phoneUri = null Uri emailUri = null Add a phone number for Abraham Lincoln Begin with the URI for the new record just returned by insert() it ends with the _ID of the new record so we dont have to add the ID ourselves Then append the designation for the phone table to this URI and use the resulting URI to insert the phone number phoneUri = UriwithAppendedPath(uri PeoplePhonesCONTENT_DIRECTORY) valuesclear() valuesput(PeoplePhonesTYPE PeoplePhonesTYPE_MOBILE) valuesput(PeoplePhonesNUMBER 1233214567) getContentResolver()insert(phoneUri values) Now add an email address in the same way emailUri = UriwithAppendedPath(uri PeopleContactMethodsCONTENT_DIRECTORY) valuesclear() ContactMethodsKIND is used to distinguish different kinds of contact methods such as email IM etc valuesput(PeopleContactMethodsKIND ContactsKIND_EMAIL) valuesput(PeopleContactMethodsDATA testexamplecom) valuesput(PeopleContactMethodsTYPE PeopleContactMethodsTYPE_HOME) getContentResolver()insert(emailUri values)

You can place small amounts of binary data into a table by calling the version of ContentValuesput()

that takes a byte array That would work for a small icon-like image or a short audio clip for example

However if you have a large amount of binary data to add such as a photograph or a complete song

put a content URI for the data in the table and call ContentResolveropenOutputStream() with the files

URI (That causes the content provider to store the data in a file and record the file path in a hidden

field of the record)

In this regard the MediaStore content provider the main provider that dispenses image audio and

video data employs a special convention The same URI that is used with query() or managedQuery()

to get meta-information about the binary data (such as the caption of a photograph or the date it was

taken) is used with openInputStream() to get the data itself Similarly the same URI that is used with

insert() to put meta-information into a MediaStore record is used with openOutputStream() to place the

binary data there The following code snippet illustrates this convention

import androidproviderMediaStoreImagesMedia import androidcontentContentValues import javaioOutputStream Save the name and description of an image in a ContentValues map ContentValues values = new ContentValues(3) valuesput(MediaDISPLAY_NAME road_trip_1) valuesput(MediaDESCRIPTION Day 1 trip to Los Angeles) valuesput(MediaMIME_TYPE imagejpeg) Add a new record without the bitmap but with the values just set insert() returns the URI of the new record Uri uri = getContentResolver()insert(MediaEXTERNAL_CONTENT_URI values) Now get a handle to the file for that record and save the data into it Here sourceBitmap is a Bitmap object representing the file to save to the database try OutputStream outStream = getContentResolver()openOutputStream(uri) sourceBitmapcompress(BitmapCompressFormatJPEG 50 outStream) outStreamclose() catch (Exception e) Loge(TAG exception while writing image e)

Batch updating records

To batch update a group of records (for example to change NY to New York in all fields) call the

ContentResolverupdate() method with the columns and values to change

Deleting a record

To delete a single record call ContentResolverdelete() with the URI of a specific row

To delete multiple rows call ContentResolverdelete() with the URI of the type of record to delete (for

example androidproviderContactsPeopleCONTENT_URI) and an SQL WHERE clause defining

which rows to delete (Caution Be sure to include a valid WHERE clause if youre deleting a general

type or you risk deleting more records than you intended)

Creating a Content Provider

To create a content provider you must

Set up a system for storing the data Most content providers store their data using Androids file

storage methods or SQLite databases but you can store your data any way you want Android

provides the SQLiteOpenHelper class to help you create a database and SQLiteDatabase to manage

it

Extend the ContentProvider class to provide access to the data

Declare the content provider in the manifest file for your application (AndroidManifestxml)

The following sections have notes on the last two of these tasks

Extending the ContentProvider class

You define a ContentProvider subclass to expose your data to others using the conventions expected

by ContentResolver and Cursor objects Principally this means implementing six abstract methods

declared in the ContentProvider class

query()

insert()

update()

delete()

getType()

onCreate()

The query() method must return a Cursor object that can iterate over the requested data Cursor itself

is an interface but Android provides some ready-made Cursor objects that you can use For example

SQLiteCursor can iterate over data stored in an SQLite database You get the Cursor object by calling

any of the SQLiteDatabase classs query() methods There are other Cursor implementations mdash such

as MatrixCursor mdash for data not stored in a database

Because these ContentProvider methods can be called from various ContentResolver objects in

different processes and threads they must be implemented in a thread-safe manner

As a courtesy you might also want to call ContentResolvernotifyChange() to notify listeners when

there are modifications to the data

Beyond defining the subclass itself there are other steps you should take to simplify the work of clients

and make the class more accessible

Define a public static final Uri named CONTENT_URI This is the string that represents the full content

URI that your content provider handles You must define a unique string for this value The best

solution is to use the fully-qualified class name of the content provider (made lowercase) So for

example the URI for a TransportationProvider class could be defined as follows

public static final Uri CONTENT_URI = Uriparse(contentcomexamplecodelabtransportationprovider)

If the provider has subtables also define CONTENT_URI constants for each of the subtables These

URIs should all have the same authority (since that identifies the content provider) and be

distinguished only by their paths For example

contentcomexamplecodelabtransportationprovidertrain

contentcomexamplecodelabtransportationproviderairdomestic

contentcomexamplecodelabtransportationproviderairinternational

For an overview of content URIs see the Content URI Summary at the end of this document

Define the column names that the content provider will return to clients If you are using an underlying

database these column names are typically identical to the SQL database column names they

represent Also define public static String constants that clients can use to specify the columns in

queries and other instructions

Be sure to include an integer column named _id (with the constant _ID) for the IDs of the records

You should have this field whether or not you have another field (such as a URL) that is also unique

among all records If youre using the SQLite database the _ID field should be the following type

INTEGER PRIMARY KEY AUTOINCREMENT

The AUTOINCREMENT descriptor is optional But without it SQLite increments an ID counter field to

the next number above the largest existing number in the column If you delete the last row the next

row added will have the same ID as the deleted row AUTOINCREMENT avoids this by having SQLite

increment to the next largest value whether deleted or not

Carefully document the data type of each column Clients need this information to read the data

If you are handling a new data type you must define a new MIME type to return in your

implementation of ContentProvidergetType() The type depends in part on whether or not the content

URI submitted to getType() limits the request to a specific record Theres one form of the MIME type

for a single record and another for multiple records Use the Uri methods to help determine what is

being requested Here is the general format for each type

o For a single record vndandroidcursoritemvndyourcompanynamecontenttype

For example a request for train record 122 like this URI

contentcomexampletransportationprovidertrains122

might return this MIME type

vndandroidcursoritemvndexamplerail

o For multiple records vndandroidcursordirvndyourcompanynamecontenttype

For example a request for all train records like the following URI

contentcomexampletransportationprovidertrains

might return this MIME type

vndandroidcursordirvndexamplerail

If you are exposing byte data thats too big to put in the table itself mdash such as a large bitmap file mdash the

field that exposes the data to clients should actually contain a content URI string This is the field that

gives clients access to the data file The record should also have another field named _data that lists

the exact file path on the device for that file This field is not intended to be read by the client but by

the ContentResolver The client will call ContentResolveropenInputStream() on the user-facing field

holding the URI for the item The ContentResolver will request the _data field for that record and

because it has higher permissions than a client it should be able to access that file directly and return

a read wrapper for the file to the client

For an example of a private content provider implementation see the NodePadProvider class in the

Notepad sample application that ships with the SDK

Declaring the content provider

To let the Android system know about the content provider youve developed declare it with a

ltprovidergt element in the applications AndroidManifestxml file Content providers that are not

declared in the manifest are not visible to the Android system

The name attribute is the fully qualified name of the ContentProvider subclass The authorities attribute

is the authority part of the content URI that identifies the provider For example if the ContentProvider

subclass is AutoInfoProvider the ltprovidergt element might look like this

ltprovider androidname=comexampleautosAutoInfoProvider androidauthorities=comexampleautosautoinfoprovider gt ltprovidergt

Note that the authorities attribute omits the path part of a content URI For example if

AutoInfoProvider controlled subtables for different types of autos or different manufacturers

contentcomexampleautosautoinfoproviderhonda

contentcomexampleautosautoinfoprovidergmcompact

contentcomexampleautosautoinfoprovidergmsuv

those paths would not be declared in the manifest The authority is what identifies the provider not the

path your provider can interpret the path part of the URI in any way you choose

Other ltprovidergt attributes can set permissions to read and write data provide for an icon and text

that can be displayed to users enable and disable the provider and so on Set the multiprocess

attribute to true if data does not need to be synchronized between multiple running versions of the

content provider This permits an instance of the provider to be created in each client process

eliminating the need to perform IPC

Content URI Summary

Here is a recap of the important parts of a content URI

A Standard prefix indicating that the data is controlled by a content provider Its never modified

B The authority part of the URI it identifies the content provider For third-party applications this should

be a fully-qualified class name (reduced to lowercase) to ensure uniqueness The authority is declared

in the ltprovidergt elements authorities attribute

ltprovider androidname=TransportationProvider androidauthorities=comexampletransportationprovider gt

C The path that the content provider uses to determine what kind of data is being requested This can be

zero or more segments long If the content provider exposes only one type of data (only trains for

example) it can be absent If the provider exposes several types including subtypes it can be several

segments long mdash for example landbus landtrain seaship and seasubmarine to give four

possibilities

D The ID of the specific record being requested if any This is the _ID value of the requested record If

the request is not limited to a single record this segment and the trailing slash are omitted

contentcomexampletransportationprovidertrains

Intent and intent filters

Three of the core components of an application mdash activities services and broadcast receivers mdash 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 mdash 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 ContextstartActivity() or ActivitystartActivityForResult() to launch an

activity or get an existing activity to do something new (It can also be passed to ActivitysetResult() to

return information to the activity that called startActivityForResult())

An Intent object is passed to ContextstartService() to initiate a service or deliver new instructions to an

ongoing service Similarly an intent can be passed to ContextbindService() to establish a connection

between the calling component and a target service It can optionally initiate the service if its not

already running

Intent objects passed to any of the broadcast methods (such as ContextsendBroadcast()

ContextsendOrderedBroadcast() or ContextsendStickyBroadcast()) 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 mdash how it resolves which component should receive an intent message For

intents that dont explicitly name a target component this process involves testing the Intent object

against intent filters associated with potential targets

Intent Objects

An Intent object is a bundle of information It contains information of interest to the component that

receives the intent (such as the action to be taken and the data to act on) plus information of interest to

the Android system (such as the category of component that should handle the intent and instructions

on how to launch a target activity) Principally it can contain the following

Component name

The name of the component that should handle the intent This field is a ComponentName

object mdash a combination of the fully qualified class name of the target component (for example

comexampleprojectappFreneticActivity) and the package name set in the manifest file of the

application where the component resides (for example comexampleproject) The package

part of the component name and the package name set in the manifest do not necessarily have

to match

The component name is optional If it is set the Intent object is delivered to an instance of the

designated class If it is not set Android uses other information in the Intent object to locate a

suitable target mdash see Intent Resolution later in this document

The component name is set by setComponent() setClass() or setClassName() and read by

getComponent()

Action

A string naming the action to be performed mdash or in the case of broadcast intents the action

that took place and is being reported The Intent class defines a number of action constants

including these

Constant Target

component

Action

ACTION_CALL activity Initiate a phone call

ACTION_EDIT activity Display data for the user to edit

ACTION_MAIN activity Start up as the initial activity of a task

with no data input and no returned

output

ACTION_SYNC activity Synchronize data on a server with

data on the mobile device

ACTION_BATTERY_LOW broadcast

receiver

A warning that the battery is low

ACTION_HEADSET_PLUG broadcast

receiver

A headset has been plugged into the

device or unplugged from it

ACTION_SCREEN_ON broadcast

receiver

The screen has been turned on

ACTION_TIMEZONE_CHANGED broadcast

receiver

The setting for the time zone has

changed

See the Intent class description for a list of pre-defined constants for generic actions Other

actions are defined elsewhere in the Android API You can also define your own action strings

for activating the components in your application Those you invent should include the

application package as a prefix mdash for example comexampleprojectSHOW_COLOR

The action largely determines how the rest of the intent is structured mdash particularly the data and

extras fields mdash much as a method name determines a set of arguments and a return value For

this reason its a good idea to use action names that are as specific as possible and to couple

them tightly to the other fields of the intent In other words instead of defining an action in

isolation define an entire protocol for the Intent objects your components can handle

The action in an Intent object is set by the setAction() method and read by getAction()

Data

The URI of the data to be acted on and the MIME type of that data Different actions are paired

with different kinds of data specifications For example if the action field is ACTION_EDIT the

data field would contain the URI of the document to be displayed for editing If the action is

ACTION_CALL the data field would be a tel URI with the number to call Similarly if the action

is ACTION_VIEW and the data field is an http URI the receiving activity would be called upon

to download and display whatever data the URI refers to

When matching an intent to a component that is capable of handling the data its often

important to know the type of data (its MIME type) in addition to its URI For example a

component able to display image data should not be called upon to play an audio file

In many cases the data type can be inferred from the URI mdash particularly content URIs which

indicate that the data is located on the device and controlled by a content provider (see the

separate discussion on content providers) But the type can also be explicitly set in the Intent

object The setData() method specifies data only as a URI setType() specifies it only as a

MIME type and setDataAndType() specifies it as both a URI and a MIME type The URI is read

by getData() and the type by getType()

Category

A string containing additional information about the kind of component that should handle the

intent Any number of category descriptions can be placed in an Intent object As it does for

actions the Intent class defines several category constants including these

Constant Meaning

CATEGORY_BROWSABLE The target activity can be safely invoked by the browser to

display data referenced by a link mdash for example an image or

an e-mail message

CATEGORY_GADGET The activity can be embedded inside of another activity that

hosts gadgets

CATEGORY_HOME The activity displays the home screen the first screen the

user sees when the device is turned on or when the HOME

key is pressed

CATEGORY_LAUNCHER The activity can be the initial activity of a task and is listed in

the top-level application launcher

CATEGORY_PREFERENCE The target activity is a preference panel

See the Intent class description for the full list of categories

The addCategory() method places a category in an Intent object removeCategory() deletes a

category previously added and getCategories() gets the set of all categories currently in the

object

Extras

Key-value pairs for additional information that should be delivered to the component handling

the intent Just as some actions are paired with particular kinds of data URIs some are paired

with particular extras For example an ACTION_TIMEZONE_CHANGED intent has a time-

zone extra that identifies the new time zone and ACTION_HEADSET_PLUG has a state

extra indicating whether the headset is now plugged in or unplugged as well as a name extra

for the type of headset If you were to invent a SHOW_COLOR action the color value would be

set in an extra key-value pair

The Intent object has a series of put() methods for inserting various types of extra data and a

similar set of get() methods for reading the data These methods parallel those for Bundle

objects In fact the extras can be installed and read as a Bundle using the putExtras() and

getExtras() methods

Flags

Flags of various sorts Many instruct the Android system how to launch an activity (for example

which task the activity should belong to) and how to treat it after its launched (for example

whether it belongs in the list of recent activities) All these flags are defined in the Intent class

The Android system and the applications that come with the platform employ Intent objects both to

send out system-originated broadcasts and to activate system-defined components To see how to

structure an intent to activate a system component consult the list of intents in the reference

Intent Resolution

Intents can be divided into two groups

Explicit intents designate the target component by its name (the component name field mentioned

earlier has a value set) Since component names would generally not be known to developers of other

applications explicit intents are typically used for application-internal messages mdash such as an activity

starting a subordinate service or launching a sister activity

Implicit intents do not name a target (the field for the component name is blank) Implicit intents are

often used to activate components in other applications

Android delivers an explicit intent to an instance of the designated target class Nothing in the Intent

object other than the component name matters for determining which component should get the intent

A different strategy is needed for implicit intents In the absence of a designated target the Android

system must find the best component (or components) to handle the intent mdash a single activity or

service to perform the requested action or the set of broadcast receivers to respond to the broadcast

announcement It does so by comparing the contents of the Intent object to intent filters structures

associated with components that can potentially receive intents Filters advertise the capabilities of a

component and delimit the intents it can handle They open the component to the possibility of

receiving implicit intents of the advertised type If a component does not have any intent filters it can

receive only explicit intents A component with filters can receive both explicit and implicit intents

Only three aspects of an Intent object are consulted when the object is tested against an intent filter

action

data (both URI and data type)

category

The extras and flags play no part in resolving which component receives an intent

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 mdash but only unwanted implicit intents (those that dont 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

components 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 mdash 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 Pads filters are described in the Note Pad Example

section later)

Filters and security

An intent filter cannot be relied on for security While it opens a component to receiving only certain

kinds of implicit intents it does nothing to prevent explicit intents from targeting the component Even

though a filter restricts the intents a component will be asked to handle to certain actions and data

sources someone could always put together an explicit intent with a different action and data source

and name the component as the target

An intent filter is an instance of the IntentFilter class However since the Android system must know

about the capabilities of a component before it can launch that component intent filters are generally

not set up in Java code but in the applications manifest file (AndroidManifestxml) as ltintent-filtergt

elements (The one exception would be filters for broadcast receivers that are registered dynamically

by calling ContextregisterReceiver() they are directly created as IntentFilter objects)

A filter has fields that parallel the action data and category fields of an Intent object An implicit intent

is tested against the filter in all three areas To be delivered to the component that owns the filter it

must pass all three tests If it fails even one of them the Android system wont deliver it to the

component mdash at least not on the basis of that filter However since a component can have multiple

intent filters an intent that does not pass through one of a components filters might make it through on

another

Each of the three tests is described in detail below

Action test

An ltintent-filtergt element in the manifest file lists actions as ltactiongt subelements For

example

ltintent-filter gt ltaction androidname=comexampleprojectSHOW_CURRENT gt ltaction androidname=comexampleprojectSHOW_RECENT gt ltaction androidname=comexampleprojectSHOW_PENDING gt ltintent-filtergt

As the example shows while an Intent object names just a single action a filter may list more

than one The list cannot be empty a filter must contain at least one ltactiongt element or it will

block all intents

To pass this test the action specified in the Intent object must match one of the actions listed in

the filter If the object or the filter does not specify an action the results are as follows

If the filter fails to list any actions there is nothing for an intent to match so all intents fail the

test No intents can get through the filter

On the other hand an Intent object that doesnt specify an action automatically passes the test

mdash as long as the filter contains at least one action

Category test

An ltintent-filtergt element also lists categories as subelements For example

ltintent-filter gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryBROWSABLE gt ltintent-filtergt

Note that the constants described earlier for actions and categories are not used in the manifest

file The full string values are used instead For instance the

androidintentcategoryBROWSABLE string in the example above corresponds to the

CATEGORY_BROWSABLE constant mentioned earlier in this document Similarly the string

androidintentactionEDIT corresponds to the ACTION_EDIT constant

For an intent to pass the category test every category in the Intent object must match a

category in the filter The filter can list additional categories but it cannot omit any that are in the

intent

In principle therefore an Intent object with no categories should always pass this test

regardless of whats in the filter Thats mostly true However with one exception Android treats

all implicit intents passed to startActivity() as if they contained at least one category

androidintentcategoryDEFAULT (the CATEGORY_DEFAULT constant) Therefore activities

that are willing to receive implicit intents must include androidintentcategoryDEFAULT in

their intent filters (Filters with androidintentactionMAIN and

androidintentcategoryLAUNCHER settings are the exception They mark activities that begin

new tasks and that are represented on the launcher screen They can include

androidintentcategoryDEFAULT in the list of categories but dont need to) See Using intent

matching later for more on these filters)

Data test

Like the action and categories the data specification for an intent filter is contained in a

subelement And as in those cases the subelement can appear multiple times or not at all For

example

ltintent-filter gt ltdata androidmimeType=videompeg androidscheme=http gt ltdata androidmimeType=audiompeg androidscheme=http gt ltintent-filtergt

Each ltdatagt element can specify a URI and a data type (MIME media type) There are

separate attributes mdash scheme host port and path mdash for each part of the URI

schemehostportpath

For example in the following URI

contentcomexampleproject200foldersubfolderetc

the scheme is content the host is comexampleproject the port is 200 and the path is

foldersubfolderetc The host and port together constitute the URI authority if a host is not

specified the port is ignored

Each of these attributes is optional but they are not independent of each other For an authority

to be meaningful a scheme must also be specified For a path to be meaningful both a scheme

and an authority must be specified

When the URI in an Intent object is compared to a URI specification in a filter its compared

only to the parts of the URI actually mentioned in the filter For example if a filter specifies only

a scheme all URIs with that scheme match the filter If a filter specifies a scheme and an

authority but no path all URIs with the same scheme and authority match regardless of their

paths If a filter specifies a scheme an authority and a path only URIs with the same scheme

authority and path match However a path specification in the filter can contain wildcards to

require only a partial match of the path

The type attribute of a ltdatagt element specifies the MIME type of the data Its more common in

filters than a URI Both the Intent object and the filter can use a wildcard for the subtype field

mdash for example text or audio mdash indicating any subtype matches

The data test compares both the URI and the data type in the Intent object to a URI and data

type specified in the filter The rules are as follows

a An Intent object that contains neither a URI nor a data type passes the test only if the filter

likewise does not specify any URIs or data types

b An Intent object that contains a URI but no data type (and a type cannot be inferred from the

URI) passes the test only if its URI matches a URI in the filter and the filter likewise does not

specify a type This will be the case only for URIs like mailto and tel that do not refer to actual

data

c An Intent object that contains a data type but not a URI passes the test only if the filter lists the

same data type and similarly does not specify a URI

d An Intent object that contains both a URI and a data type (or a data type can be inferred from

the URI) passes the data type part of the test only if its type matches a type listed in the filter It

passes the URI part of the test either if its URI matches a URI in the filter or if it has a content

or file URI and the filter does not specify a URI In other words a component is presumed to

support content and file data if its filter lists only a data type

If an intent can pass through the filters of more than one activity or service the user may be asked

which component to activate An exception is raised if no target can be found

Common cases

The last rule shown above for the data test rule (d) reflects the expectation that components are able

to get local data from a file or content provider Therefore their filters can list just a data type and do

not need to explicitly name the content and file schemes This is a typical case A ltdatagt element like

the following for example tells Android that the component can get image data from a content

provider and display it

ltdata androidmimeType=image gt

Since most available data is dispensed by content providers filters that specify a data type but not a

URI are perhaps the most common

Another common configuration is filters with a scheme and a data type For example a ltdatagt

element like the following tells Android that the component can get video data from the network and

display it

ltdata androidscheme=http androidtype=video gt

Consider for example what the browser application does when the user follows a link on a web page

It first tries to display the data (as it could if the link was to an HTML page) If it cant display the data it

puts together an implicit intent with the scheme and data type and tries to start an activity that can do

the job If there are no takers it asks the download manager to download the data That puts it under

the control of a content provider so a potentially larger pool of activities (those with filters that just

name a data type) can respond

Most applications also have a way to start fresh without a reference to any particular data Activities

that can initiate applications have filters with androidintentactionMAIN specified as the action If

they are to be represented in the application launcher they also specify the

androidintentcategoryLAUNCHER category

ltintent-filter gt ltaction androidname=code androidintentactionMAIN gt ltcategory androidname=code androidintentcategoryLAUNCHER gt ltintent-filtergt

Using intent matching

Intents are matched against intent filters not only to discover a target component to activate but also

to discover something about the set of components on the device For example the Android system

populates the application launcher the top-level screen that shows the applications that are available

for the user to launch by finding all the activities with intent filters that specify the

androidintentactionMAIN action and androidintentcategoryLAUNCHER category (as illustrated

in the previous section) It then displays the icons and labels of those activities in the launcher

Similarly it discovers the home screen by looking for the activity with androidintentcategoryHOME

in its filter

Your application can use intent matching is a similar way The PackageManager has a set of query()

methods that return all components that can accept a particular intent and a similar series of

resolve() methods that determine the best component to respond to an intent For example

queryIntentActivities() returns a list of all activities that can perform the intent passed as an argument

and queryIntentServices() returns a similar list of services Neither method activates the components

they just list the ones that can respond Theres a similar method queryBroadcastReceivers() for

broadcast receivers

Note Pad Example

The Note Pad sample application enables users to browse through a list of notes view details about

individual items in the list edit the items and add a new item to the list This section looks at the intent

filters declared in its manifest file (If youre working offline in the SDK you can find all the source files

for this sample application including its manifest file at ltsdkgtsamplesNotePadindexhtml If youre

viewing the documentation online the source files are in the Tutorials and Sample Code section here)

In its manifest file the Note Pad application declares three activities each with at least one intent filter

It also declares a content provider that manages the note data Here is the manifest file in its entirety

ltmanifest xmlnsandroid=httpschemasandroidcomapkresandroid package=comexampleandroidnotepadgt ltapplication androidicon=drawableapp_notes androidlabel=stringapp_name gt ltprovider androidname=NotePadProvider androidauthorities=comgoogleproviderNotePad gt ltactivity androidname=NotesList androidlabel=stringtitle_notes_listgt ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltactivity androidname=NoteEditor androidtheme=androidstyleThemeLight androidlabel=stringtitle_note gt ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltactivitygt

ltactivity androidname=TitleEditor androidlabel=stringtitle_edit_title androidtheme=androidstyleThemeDialoggt ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltapplicationgt ltmanifestgt

The first activity NotesList is distinguished from the other activities by the fact that it operates on a

directory of notes (the note list) rather than on a single note It would generally serve as the initial user

interface into the application It can do three things as described by its three intent filters

1 ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt

This filter declares the main entry point into the Note Pad application The standard MAIN action is an

entry point that does not require any other information in the Intent (no data specification for example)

and the LAUNCHER category says that this entry point should be listed in the application launcher

2 ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

This filter declares the things that the activity can do on a directory of notes It can allow the user to

view or edit the directory (via the VIEW and EDIT actions) or to pick a particular note from the

directory (via the PICK action)

The mimeType attribute of the ltdatagt element specifies the kind of data that these actions operate on

It indicates that the activity can get a Cursor over zero or more items (vndandroidcursordir) from a

content provider that holds Note Pad data (vndgooglenote) The Intent object that launches the

activity would include a content URI specifying the exact data of this type that the activity should open

Note also the DEFAULT category supplied in this filter Its there because the ContextstartActivity()

and ActivitystartActivityForResult() methods treat all intents as if they contained the DEFAULT

category mdash with just two exceptions

o Intents that explicitly name the target activity

o Intents consisting of the MAIN action and LAUNCHER category

Therefore the DEFAULT category is required for all filters mdash except for those with the MAIN action

and LAUNCHER category (Intent filters are not consulted for explicit intents)

3 ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

This filter describes the activitys ability to return a note selected by the user without requiring any

specification of the directory the user should choose from The GET_CONTENT action is similar to the

PICK action In both cases the activity returns the URI for a note selected by the user (In each case

its returned to the activity that called startActivityForResult() to start the NoteList activity) Here

however the caller specifies the type of data desired instead of the directory of data the user will be

picking from

The data type vndandroidcursoritemvndgooglenote indicates the type of data the activity can

return mdash a URI for a single note From the returned URI the caller can get a Cursor for exactly one

item (vndandroidcursoritem) from the content provider that holds Note Pad data (vndgooglenote)

In other words for the PICK action in the previous filter the data type indicates the type of data the

activity could display to the user For the GET_CONTENT filter it indicates the type of data the activity

can return to the caller

Given these capabilities the following intents will resolve to the NotesList activity

action androidintentactionMAIN

Launches the activity with no data specified

action androidintentactionMAIN

category androidintentcategoryLAUNCHER

Launches the activity with no data selected specified This is the actual intent used by the

Launcher to populate its top-level list All activities with filters that match this action and

category are added to the list

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of all the notes under

contentcomgoogleproviderNotePadnotes The user can then browse through the list and

get information about the items in it

action androidintentactionPICK

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of the notes under

contentcomgoogleproviderNotePadnotes The user can then pick a note from the list and

the activity will return the URI for that item back to the activity that started the NoteList activity

action androidintentactionGET_CONTENT

data type vndandroidcursoritemvndgooglenote

Asks the activity to supply a single item of Note Pad data

The second activity NoteEditor shows users a single note entry and allows them to edit it It can do

two things as described by its two intent filters

1 ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The first primary purpose of this activity is to enable the user to interact with a single note ampmdash to

either VIEW the note or EDIT it (The EDIT_NOTE category is a synonym for EDIT) The intent would

contain the URI for data matching the MIME type vndandroidcursoritemvndgooglenote mdash that is

the URI for a single specific note It would typically be a URI that was returned by the PICK or

GET_CONTENT actions of the NoteList activity

As before this filter lists the DEFAULT category so that the activity can be launched by intents that

dont explicitly specify the NoteEditor class

2 ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

The secondary purpose of this activity is to enable the user to create a new note which it will INSERT

into an existing directory of notes The intent would contain the URI for data matching the MIME type

vndandroidcursordirvndgooglenote mdash that is the URI for the directory where the note should be

placed

Given these capabilities the following intents will resolve to the NoteEditor activity

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID (For details on how content

URIs specify individual members of a group see Content Providers)

action androidintentactionEDIT

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID and to let the user edit it If

the user saves the changes the activity updates the data for the note in the content provider

action androidintentactionINSERT

data contentcomgoogleproviderNotePadnotes

Asks the activity to create a new empty note in the notes list at

contentcomgoogleproviderNotePadnotes and allow the user to edit it If the user saves the

note its URI is returned to the caller

The last activity TitleEditor enables the user to edit the title of a note This could be implemented by

directly invoking the activity (by explicitly setting its component name in the Intent) without using an

intent filter But here we take the opportunity to show how to publish alternative operations on existing

data

ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The single intent filter for this activity uses a custom action called

comandroidnotepadactionEDIT_TITLE It must be invoked on a specific note (data type

vndandroidcursoritemvndgooglenote) like the previous VIEW and EDIT actions However here the

activity displays the title contained in the note data not the content of the note itself

In addition to supporting the usual DEFAULT category the title editor also supports two other standard

categories ALTERNATIVE and SELECTED_ALTERNATIVE These categories identify activities that

can be presented to users in a menu of options (much as the LAUNCHER category identifies activities

that should be presented to user in the application launcher) Note that the filter also supplies an

explicit label (via androidlabel=stringresolve_title) to better control what users see when

presented with this activity as an alternative action to the data they are currently viewing (For more

information on these categories and building options menus see the

PackageManagerqueryIntentActivityOptions() and MenuaddIntentOptions() methods)

Given these capabilities the following intent will resolve to the TitleEditor activity

action comandroidnotepadactionEDIT_TITLE

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the title associated with note ID and allow the user to edit the title

Processes and Threads

When an application component starts and the application does not have any other components

running the Android system starts a new Linux process for the application with a single thread of

execution By default all components of the same application run in the same process and thread

(called the main thread) If an application component starts and there already exists a process for

that application (because another component from the application exists) then the component is

started within that process and uses the same thread of execution However you can arrange for

different components in your application to run in separate processes and you can create additional

threads for any process

This document discusses how processes and threads work in an Android application

Processes

By default all components of the same application run in the same process and most applications

should not change this However if you find that you need to control which process a certain

component belongs to you can do so in the manifest file

The manifest entry for each type of component elementmdashltactivitygt ltservicegt ltreceivergt and

ltprovidergtmdashsupports an androidprocess attribute that can specify a process in which that component

should run You can set this attribute so that each component runs in its own process or so that some

components share a process while others do not You can also set androidprocess so that

components of different applications run in the same processmdashprovided that the applications share the

same Linux user ID and are signed with the same certificates

The ltapplicationgt element also supports an androidprocess attribute to set a default value that

applies to all components

Android might 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 thats killed are consequently destroyed A process is started again for those components

when theres again work for them to do

When deciding which processes to kill the Android system weighs their relative importance to the

user For example it more readily shuts down a process hosting activities that are no longer visible on

screen compared to a process hosting visible activities The decision whether to terminate a process

therefore depends on the state of the components running in that process The rules used to decide

which processes to terminate is discussed below

Process lifecycle

The Android system tries to maintain an application process for as long as possible but eventually

needs to remove old processes to reclaim memory for new or more important processes To determine

which processes to keep and which to kill the system places each process into an importance

hierarchy based on the components running in the process and the state of those components

Processes with the lowest importance are eliminated first then those with the next lowest importance

and so on as necessary to recover system resources

There are five levels in the importance hierarchy The following list presents the different types of

processes in order of importance (the first process is most important and is killed last)

1 Foreground process

A process that is required for what the user is currently doing A process is considered to be in the

foreground if any of the following conditions are true

o It hosts an Activity that the user is interacting with (the Activitys onResume() method has been called)

o It hosts a Service thats bound to the activity that the user is interacting with

o It hosts a Service thats running in the foregroundmdashthe service has called startForeground()

o It hosts a Service thats executing one of its lifecycle callbacks (onCreate() onStart() or onDestroy())

o It hosts a BroadcastReceiver thats executing its onReceive() method

Generally only a few foreground processes exist at any given time They are killed only as a last

resortmdashif memory is so low that they cannot all continue to run Generally at that point the device has

reached a memory paging state so killing some foreground processes is required to keep the user

interface responsive

2 Visible process

A process that doesnt have any foreground components but still can affect what the user sees on

screen A process is considered to be visible if either of the following conditions are true

o It hosts an Activity that is not in the foreground but is still visible to the user (its onPause() method has

been called) This might occur for example if the foreground activity started a dialog which allows the

previous activity to be seen behind it

o It hosts a Service thats bound to a visible (or foreground) activity

A visible process is considered extremely important and will not be killed unless doing so is required to

keep all foreground processes running

3 Service process

A process that is running a service that has been started with the startService() method and does not

fall into either of the two higher categories Although service processes are not directly tied to anything

the user sees they are generally doing things that the user cares about (such as playing music in the

background or downloading data on the network) so the system keeps them running unless theres

not enough memory to retain them along with all foreground and visible processes

4 Background process

A process holding an activity thats not currently visible to the user (the activitys onStop() method has

been called) These processes have no direct impact on the user experience and the system can kill

them at any time to reclaim memory for a foreground visible or service process Usually there are

many background processes running so they are kept in an LRU (least recently used) list to ensure

that the process with the activity that was most recently seen by the user is the last to be killed If an

activity implements its lifecycle methods correctly and saves its current state killing its process will not

have a visible effect on the user experience because when the user navigates back to the activity the

activity restores all of its visible state See the Activities document for information about saving and

restoring state

5 Empty process

A process that doesnt hold any active application components The only reason to keep this kind of

process alive is for caching purposes to improve startup time the next time a component needs to run

in it The system often kills these processes in order to balance overall system resources between

process caches and the underlying kernel caches

Android ranks a process at the highest level it can based upon the importance of the components

currently active in the process For example if a process hosts a service and a visible activity the

process is ranked as a visible process not a service process

In addition a processs ranking might be increased because other processes are dependent on itmdasha

process that is serving another process can never be ranked lower than the process it is serving For

example if a content provider in process A is serving a client in process B or if a service in process A

is bound to a component in process B process A is always considered at least as important as

process B

Because a process running a service is ranked higher than a process with background activities an

activity that initiates a long-running operation might do well to start a service for that operation rather

than simply create a worker threadmdashparticularly if the operation will likely outlast the activity For

example an activity thats uploading a picture to a web site should start a service to perform the

upload so that the upload can continue in the background even if the user leaves the activity Using a

service guarantees that the operation will have at least service process priority regardless of what

happens to the activity This is the same reason that broadcast receivers should employ services

rather than simply put time-consuming operations in a thread

Threads

When an application is launched the system creates a thread of execution for the application called

main This thread is very important because it is in charge of dispatching events to the appropriate

user interface widgets including drawing events It is also the thread in which your application interacts

with components from the Android UI toolkit (components from the androidwidget and androidview

packages) As such the main thread is also sometimes called the UI thread

The system does not create a separate thread for each instance of a component All components that

run in the same process are instantiated in the UI thread and system calls to each component are

dispatched from that thread Consequently methods that respond to system callbacks (such as

onKeyDown() to report user actions or a lifecycle callback method) always run in the UI thread of the

process

For instance when the user touches a button on the screen your apps UI thread dispatches the touch

event to the widget which in turn sets its pressed state and posts an invalidate request to the event

queue The UI thread dequeues the request and notifies the widget that it should redraw itself

When your app performs intensive work in response to user interaction this single thread model can

yield poor performance unless you implement your application properly Specifically if everything is

happening in the UI thread performing long operations such as network access or database queries

will block the whole UI When the thread is blocked no events can be dispatched including drawing

events From the users perspective the application appears to hang Even worse if the UI thread is

blocked for more than a few seconds (about 5 seconds currently) the user is presented with the

infamous application not responding (ANR) dialog The user might then decide to quit your

application and uninstall it if they are unhappy

Additionally the Andoid UI toolkit is not thread-safe So you must not manipulate your UI from a

worker threadmdashyou must do all manipulation to your user interface from the UI thread Thus there are

simply two rules to Androids single thread model

1 Do not block the UI thread

2 Do not access the Android UI toolkit from outside the UI thread

Worker threads

Because of the single thread model described above its vital to the responsiveness of your

applications UI that you do not block the UI thread If you have operations to perform that are not

instantaneous you should make sure to do them in separate threads (background or worker

threads)

For example below is some code for a click listener that downloads an image from a separate thread

and displays it in an ImageView

public void onClick(View v) new Thread(new Runnable() public void run() Bitmap b = loadImageFromNetwork(httpexamplecomimagepng) mImageViewsetImageBitmap(b) )start()

At first this seems to work fine because it creates a new thread to handle the network operation

However it violates the second rule of the single-threaded model do not access the Android UI toolkit

from outside the UI threadmdashthis sample modifies the ImageView from the worker thread instead of the

UI thread This can result in undefined and unexpected behavior which can be difficult and time-

consuming to track down

To fix this problem Android offers several ways to access the UI thread from other threads Here is a

list of methods that can help

ActivityrunOnUiThread(Runnable)

Viewpost(Runnable)

ViewpostDelayed(Runnable long)

For example you can fix the above code by using the Viewpost(Runnable) method

public void onClick(View v) new Thread(new Runnable() public void run() final Bitmap bitmap = loadImageFromNetwork(httpexamplecomimagepng) mImageViewpost(new Runnable() public void run() mImageViewsetImageBitmap(bitmap) ) )start()

Now this implementation is thread-safe the network operation is done from a separate thread while

the ImageView is manipulated from the UI thread

However as the complexity of the operation grows this kind of code can get complicated and difficult

to maintain To handle more complex interactions with a worker thread you might consider using a

Handler in your worker thread to process messages delivered from the UI thread Perhaps the best

solution though is to extend the AsyncTask class which simplifies the execution of worker thread

tasks that need to interact with the UI

Using AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface It performs the blocking

operations in a worker thread and then publishes the results on the UI thread without requiring you to

handle threads andor handlers yourself

To use it you must subclass AsyncTask and implement the doInBackground() callback method which

runs in a pool of background threads To update your UI you should implement onPostExecute()

which delivers the result from doInBackground() and runs in the UI thread so you can safely update

your UI You can then run the task by calling execute() from the UI thread

For example you can implement the previous example using AsyncTask this way

public void onClick(View v) new DownloadImageTask()execute(httpexamplecomimagepng) private class DownloadImageTask extends AsyncTaskltString Void Bitmapgt The system calls this to perform work in a worker thread and delivers it the parameters given to AsyncTaskexecute() protected Bitmap doInBackground(String urls) return loadImageFromNetwork(urls[0])

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 29: 03 services

Lets look at an example query to retrieve a list of contact names and their primary phone numbers

import androidproviderContactsPeople import androiddatabaseCursor Form an array specifying which columns to return String[] projection = new String[] People_ID People_COUNT PeopleNAME PeopleNUMBER Get the base URI for the People table in the Contacts content provider Uri contacts = PeopleCONTENT_URI Make the query Cursor managedCursor = managedQuery(contacts projection Which columns to return null Which rows to return (all rows) null Selection arguments (none) Put the results in ascending order by name PeopleNAME + ASC)

This query retrieves data from the People table of the Contacts content provider It gets the name

primary phone number and unique record ID for each contact It also reports the number of records

that are returned as the _COUNT field of each record

The constants for the names of the columns are defined in various interfaces mdash _ID and _COUNT in

BaseColumns NAME in PeopleColumns and NUMBER in PhoneColumns The ContactsPeople

class implements each of these interfaces which is why the code example above could refer to them

using just the class name

What a query returns

A query returns a set of zero or more database records The names of the columns their default order

and their data types are specific to each content provider But every provider has an _ID column

which holds a unique numeric ID for each record Every provider can also report the number of records

returned as the _COUNT column its value is the same for all rows

Here is an example result set for the query in the previous section

_ID _COUNT NAME NUMBER

44 3 Alan Vain 212 555 1234

13 3 Bully Pulpit 425 555 6677

53 3 Rex Cars 201 555 4433

The retrieved data is exposed by a Cursor object that can be used to iterate backward or forward

through the result set You can use this object only to read the data To add modify or delete data

you must use a ContentResolver object

Reading retrieved data

The Cursor object returned by a query provides access to a recordset of results If you have queried

for a specific record by ID this set will contain only one value Otherwise it can contain multiple

values (If there are no matches it can also be empty) You can read data from specific fields in the

record but you must know the data type of the field because the Cursor object has a separate method

for reading each type of data mdash such as getString() getInt() and getFloat() (However for most types

if you call the method for reading strings the Cursor object will give you the String representation of

the data) The Cursor lets you request the column name from the index of the column or the index

number from the column name

The following snippet demonstrates reading names and phone numbers from the query illustrated

earlier

import androidproviderContactsPeople private void getColumnData(Cursor cur) if (curmoveToFirst()) String name String phoneNumber int nameColumn = curgetColumnIndex(PeopleNAME) int phoneColumn = curgetColumnIndex(PeopleNUMBER) String imagePath do Get the field values name = curgetString(nameColumn) phoneNumber = curgetString(phoneColumn) Do something with the values while (curmoveToNext())

If a query can return binary data such as an image or sound the data may be directly entered in the

table or the table entry for that data may be a string specifying a content URI that you can use to get

the data In general smaller amounts of data (say from 20 to 50K or less) are most often directly

entered in the table and can be read by calling CursorgetBlob() It returns a byte array

If the table entry is a content URI you should never try to open and read the file directly (for one thing

permissions problems can make this fail) Instead you should call ContentResolveropenInputStream()

to get an InputStream object that you can use to read the data

Modifying Data

Data kept by a content provider can be modified by

Adding new records

Adding new values to existing records

Batch updating existing records

Deleting records

All data modification is accomplished using ContentResolver methods Some content providers require

a more restrictive permission for writing data than they do for reading it If you dont have permission to

write to a content provider the ContentResolver methods will fail

Adding records

To add a new record to a content provider first set up a map of key-value pairs in a ContentValues

object where each key matches the name of a column in the content provider and the value is the

desired value for the new record in that column Then call ContentResolverinsert() and pass it the URI

of the provider and the ContentValues map This method returns the full URI of the new record mdash that

is the providers URI with the appended ID for the new record You can then use this URI to query and

get a Cursor over the new record and to further modify the record Heres an example

import androidproviderContactsPeople import androidcontentContentResolver import androidcontentContentValues ContentValues values = new ContentValues() Add Abraham Lincoln to contacts and make him a favorite valuesput(PeopleNAME Abraham Lincoln) 1 = the new contact is added to favorites 0 = the new contact is not added to favorites valuesput(PeopleSTARRED 1) Uri uri = getContentResolver()insert(PeopleCONTENT_URI values)

Adding new values

Once a record exists you can add new information to it or modify existing information For example

the next step in the example above would be to add contact information mdash like a phone number or an

IM or e-mail address mdash to the new entry

The best way to add to a record in the Contacts database is to append the name of the table where the

new data goes to the URI for the record then use the amended URI to add the new data values Each

Contacts table exposes a name for this purpose as a CONTENT_DIRECTORY constant The following

code continues the previous example by adding a phone number and e-mail address for the record

just created

Uri phoneUri = null Uri emailUri = null Add a phone number for Abraham Lincoln Begin with the URI for the new record just returned by insert() it ends with the _ID of the new record so we dont have to add the ID ourselves Then append the designation for the phone table to this URI and use the resulting URI to insert the phone number phoneUri = UriwithAppendedPath(uri PeoplePhonesCONTENT_DIRECTORY) valuesclear() valuesput(PeoplePhonesTYPE PeoplePhonesTYPE_MOBILE) valuesput(PeoplePhonesNUMBER 1233214567) getContentResolver()insert(phoneUri values) Now add an email address in the same way emailUri = UriwithAppendedPath(uri PeopleContactMethodsCONTENT_DIRECTORY) valuesclear() ContactMethodsKIND is used to distinguish different kinds of contact methods such as email IM etc valuesput(PeopleContactMethodsKIND ContactsKIND_EMAIL) valuesput(PeopleContactMethodsDATA testexamplecom) valuesput(PeopleContactMethodsTYPE PeopleContactMethodsTYPE_HOME) getContentResolver()insert(emailUri values)

You can place small amounts of binary data into a table by calling the version of ContentValuesput()

that takes a byte array That would work for a small icon-like image or a short audio clip for example

However if you have a large amount of binary data to add such as a photograph or a complete song

put a content URI for the data in the table and call ContentResolveropenOutputStream() with the files

URI (That causes the content provider to store the data in a file and record the file path in a hidden

field of the record)

In this regard the MediaStore content provider the main provider that dispenses image audio and

video data employs a special convention The same URI that is used with query() or managedQuery()

to get meta-information about the binary data (such as the caption of a photograph or the date it was

taken) is used with openInputStream() to get the data itself Similarly the same URI that is used with

insert() to put meta-information into a MediaStore record is used with openOutputStream() to place the

binary data there The following code snippet illustrates this convention

import androidproviderMediaStoreImagesMedia import androidcontentContentValues import javaioOutputStream Save the name and description of an image in a ContentValues map ContentValues values = new ContentValues(3) valuesput(MediaDISPLAY_NAME road_trip_1) valuesput(MediaDESCRIPTION Day 1 trip to Los Angeles) valuesput(MediaMIME_TYPE imagejpeg) Add a new record without the bitmap but with the values just set insert() returns the URI of the new record Uri uri = getContentResolver()insert(MediaEXTERNAL_CONTENT_URI values) Now get a handle to the file for that record and save the data into it Here sourceBitmap is a Bitmap object representing the file to save to the database try OutputStream outStream = getContentResolver()openOutputStream(uri) sourceBitmapcompress(BitmapCompressFormatJPEG 50 outStream) outStreamclose() catch (Exception e) Loge(TAG exception while writing image e)

Batch updating records

To batch update a group of records (for example to change NY to New York in all fields) call the

ContentResolverupdate() method with the columns and values to change

Deleting a record

To delete a single record call ContentResolverdelete() with the URI of a specific row

To delete multiple rows call ContentResolverdelete() with the URI of the type of record to delete (for

example androidproviderContactsPeopleCONTENT_URI) and an SQL WHERE clause defining

which rows to delete (Caution Be sure to include a valid WHERE clause if youre deleting a general

type or you risk deleting more records than you intended)

Creating a Content Provider

To create a content provider you must

Set up a system for storing the data Most content providers store their data using Androids file

storage methods or SQLite databases but you can store your data any way you want Android

provides the SQLiteOpenHelper class to help you create a database and SQLiteDatabase to manage

it

Extend the ContentProvider class to provide access to the data

Declare the content provider in the manifest file for your application (AndroidManifestxml)

The following sections have notes on the last two of these tasks

Extending the ContentProvider class

You define a ContentProvider subclass to expose your data to others using the conventions expected

by ContentResolver and Cursor objects Principally this means implementing six abstract methods

declared in the ContentProvider class

query()

insert()

update()

delete()

getType()

onCreate()

The query() method must return a Cursor object that can iterate over the requested data Cursor itself

is an interface but Android provides some ready-made Cursor objects that you can use For example

SQLiteCursor can iterate over data stored in an SQLite database You get the Cursor object by calling

any of the SQLiteDatabase classs query() methods There are other Cursor implementations mdash such

as MatrixCursor mdash for data not stored in a database

Because these ContentProvider methods can be called from various ContentResolver objects in

different processes and threads they must be implemented in a thread-safe manner

As a courtesy you might also want to call ContentResolvernotifyChange() to notify listeners when

there are modifications to the data

Beyond defining the subclass itself there are other steps you should take to simplify the work of clients

and make the class more accessible

Define a public static final Uri named CONTENT_URI This is the string that represents the full content

URI that your content provider handles You must define a unique string for this value The best

solution is to use the fully-qualified class name of the content provider (made lowercase) So for

example the URI for a TransportationProvider class could be defined as follows

public static final Uri CONTENT_URI = Uriparse(contentcomexamplecodelabtransportationprovider)

If the provider has subtables also define CONTENT_URI constants for each of the subtables These

URIs should all have the same authority (since that identifies the content provider) and be

distinguished only by their paths For example

contentcomexamplecodelabtransportationprovidertrain

contentcomexamplecodelabtransportationproviderairdomestic

contentcomexamplecodelabtransportationproviderairinternational

For an overview of content URIs see the Content URI Summary at the end of this document

Define the column names that the content provider will return to clients If you are using an underlying

database these column names are typically identical to the SQL database column names they

represent Also define public static String constants that clients can use to specify the columns in

queries and other instructions

Be sure to include an integer column named _id (with the constant _ID) for the IDs of the records

You should have this field whether or not you have another field (such as a URL) that is also unique

among all records If youre using the SQLite database the _ID field should be the following type

INTEGER PRIMARY KEY AUTOINCREMENT

The AUTOINCREMENT descriptor is optional But without it SQLite increments an ID counter field to

the next number above the largest existing number in the column If you delete the last row the next

row added will have the same ID as the deleted row AUTOINCREMENT avoids this by having SQLite

increment to the next largest value whether deleted or not

Carefully document the data type of each column Clients need this information to read the data

If you are handling a new data type you must define a new MIME type to return in your

implementation of ContentProvidergetType() The type depends in part on whether or not the content

URI submitted to getType() limits the request to a specific record Theres one form of the MIME type

for a single record and another for multiple records Use the Uri methods to help determine what is

being requested Here is the general format for each type

o For a single record vndandroidcursoritemvndyourcompanynamecontenttype

For example a request for train record 122 like this URI

contentcomexampletransportationprovidertrains122

might return this MIME type

vndandroidcursoritemvndexamplerail

o For multiple records vndandroidcursordirvndyourcompanynamecontenttype

For example a request for all train records like the following URI

contentcomexampletransportationprovidertrains

might return this MIME type

vndandroidcursordirvndexamplerail

If you are exposing byte data thats too big to put in the table itself mdash such as a large bitmap file mdash the

field that exposes the data to clients should actually contain a content URI string This is the field that

gives clients access to the data file The record should also have another field named _data that lists

the exact file path on the device for that file This field is not intended to be read by the client but by

the ContentResolver The client will call ContentResolveropenInputStream() on the user-facing field

holding the URI for the item The ContentResolver will request the _data field for that record and

because it has higher permissions than a client it should be able to access that file directly and return

a read wrapper for the file to the client

For an example of a private content provider implementation see the NodePadProvider class in the

Notepad sample application that ships with the SDK

Declaring the content provider

To let the Android system know about the content provider youve developed declare it with a

ltprovidergt element in the applications AndroidManifestxml file Content providers that are not

declared in the manifest are not visible to the Android system

The name attribute is the fully qualified name of the ContentProvider subclass The authorities attribute

is the authority part of the content URI that identifies the provider For example if the ContentProvider

subclass is AutoInfoProvider the ltprovidergt element might look like this

ltprovider androidname=comexampleautosAutoInfoProvider androidauthorities=comexampleautosautoinfoprovider gt ltprovidergt

Note that the authorities attribute omits the path part of a content URI For example if

AutoInfoProvider controlled subtables for different types of autos or different manufacturers

contentcomexampleautosautoinfoproviderhonda

contentcomexampleautosautoinfoprovidergmcompact

contentcomexampleautosautoinfoprovidergmsuv

those paths would not be declared in the manifest The authority is what identifies the provider not the

path your provider can interpret the path part of the URI in any way you choose

Other ltprovidergt attributes can set permissions to read and write data provide for an icon and text

that can be displayed to users enable and disable the provider and so on Set the multiprocess

attribute to true if data does not need to be synchronized between multiple running versions of the

content provider This permits an instance of the provider to be created in each client process

eliminating the need to perform IPC

Content URI Summary

Here is a recap of the important parts of a content URI

A Standard prefix indicating that the data is controlled by a content provider Its never modified

B The authority part of the URI it identifies the content provider For third-party applications this should

be a fully-qualified class name (reduced to lowercase) to ensure uniqueness The authority is declared

in the ltprovidergt elements authorities attribute

ltprovider androidname=TransportationProvider androidauthorities=comexampletransportationprovider gt

C The path that the content provider uses to determine what kind of data is being requested This can be

zero or more segments long If the content provider exposes only one type of data (only trains for

example) it can be absent If the provider exposes several types including subtypes it can be several

segments long mdash for example landbus landtrain seaship and seasubmarine to give four

possibilities

D The ID of the specific record being requested if any This is the _ID value of the requested record If

the request is not limited to a single record this segment and the trailing slash are omitted

contentcomexampletransportationprovidertrains

Intent and intent filters

Three of the core components of an application mdash activities services and broadcast receivers mdash 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 mdash 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 ContextstartActivity() or ActivitystartActivityForResult() to launch an

activity or get an existing activity to do something new (It can also be passed to ActivitysetResult() to

return information to the activity that called startActivityForResult())

An Intent object is passed to ContextstartService() to initiate a service or deliver new instructions to an

ongoing service Similarly an intent can be passed to ContextbindService() to establish a connection

between the calling component and a target service It can optionally initiate the service if its not

already running

Intent objects passed to any of the broadcast methods (such as ContextsendBroadcast()

ContextsendOrderedBroadcast() or ContextsendStickyBroadcast()) 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 mdash how it resolves which component should receive an intent message For

intents that dont explicitly name a target component this process involves testing the Intent object

against intent filters associated with potential targets

Intent Objects

An Intent object is a bundle of information It contains information of interest to the component that

receives the intent (such as the action to be taken and the data to act on) plus information of interest to

the Android system (such as the category of component that should handle the intent and instructions

on how to launch a target activity) Principally it can contain the following

Component name

The name of the component that should handle the intent This field is a ComponentName

object mdash a combination of the fully qualified class name of the target component (for example

comexampleprojectappFreneticActivity) and the package name set in the manifest file of the

application where the component resides (for example comexampleproject) The package

part of the component name and the package name set in the manifest do not necessarily have

to match

The component name is optional If it is set the Intent object is delivered to an instance of the

designated class If it is not set Android uses other information in the Intent object to locate a

suitable target mdash see Intent Resolution later in this document

The component name is set by setComponent() setClass() or setClassName() and read by

getComponent()

Action

A string naming the action to be performed mdash or in the case of broadcast intents the action

that took place and is being reported The Intent class defines a number of action constants

including these

Constant Target

component

Action

ACTION_CALL activity Initiate a phone call

ACTION_EDIT activity Display data for the user to edit

ACTION_MAIN activity Start up as the initial activity of a task

with no data input and no returned

output

ACTION_SYNC activity Synchronize data on a server with

data on the mobile device

ACTION_BATTERY_LOW broadcast

receiver

A warning that the battery is low

ACTION_HEADSET_PLUG broadcast

receiver

A headset has been plugged into the

device or unplugged from it

ACTION_SCREEN_ON broadcast

receiver

The screen has been turned on

ACTION_TIMEZONE_CHANGED broadcast

receiver

The setting for the time zone has

changed

See the Intent class description for a list of pre-defined constants for generic actions Other

actions are defined elsewhere in the Android API You can also define your own action strings

for activating the components in your application Those you invent should include the

application package as a prefix mdash for example comexampleprojectSHOW_COLOR

The action largely determines how the rest of the intent is structured mdash particularly the data and

extras fields mdash much as a method name determines a set of arguments and a return value For

this reason its a good idea to use action names that are as specific as possible and to couple

them tightly to the other fields of the intent In other words instead of defining an action in

isolation define an entire protocol for the Intent objects your components can handle

The action in an Intent object is set by the setAction() method and read by getAction()

Data

The URI of the data to be acted on and the MIME type of that data Different actions are paired

with different kinds of data specifications For example if the action field is ACTION_EDIT the

data field would contain the URI of the document to be displayed for editing If the action is

ACTION_CALL the data field would be a tel URI with the number to call Similarly if the action

is ACTION_VIEW and the data field is an http URI the receiving activity would be called upon

to download and display whatever data the URI refers to

When matching an intent to a component that is capable of handling the data its often

important to know the type of data (its MIME type) in addition to its URI For example a

component able to display image data should not be called upon to play an audio file

In many cases the data type can be inferred from the URI mdash particularly content URIs which

indicate that the data is located on the device and controlled by a content provider (see the

separate discussion on content providers) But the type can also be explicitly set in the Intent

object The setData() method specifies data only as a URI setType() specifies it only as a

MIME type and setDataAndType() specifies it as both a URI and a MIME type The URI is read

by getData() and the type by getType()

Category

A string containing additional information about the kind of component that should handle the

intent Any number of category descriptions can be placed in an Intent object As it does for

actions the Intent class defines several category constants including these

Constant Meaning

CATEGORY_BROWSABLE The target activity can be safely invoked by the browser to

display data referenced by a link mdash for example an image or

an e-mail message

CATEGORY_GADGET The activity can be embedded inside of another activity that

hosts gadgets

CATEGORY_HOME The activity displays the home screen the first screen the

user sees when the device is turned on or when the HOME

key is pressed

CATEGORY_LAUNCHER The activity can be the initial activity of a task and is listed in

the top-level application launcher

CATEGORY_PREFERENCE The target activity is a preference panel

See the Intent class description for the full list of categories

The addCategory() method places a category in an Intent object removeCategory() deletes a

category previously added and getCategories() gets the set of all categories currently in the

object

Extras

Key-value pairs for additional information that should be delivered to the component handling

the intent Just as some actions are paired with particular kinds of data URIs some are paired

with particular extras For example an ACTION_TIMEZONE_CHANGED intent has a time-

zone extra that identifies the new time zone and ACTION_HEADSET_PLUG has a state

extra indicating whether the headset is now plugged in or unplugged as well as a name extra

for the type of headset If you were to invent a SHOW_COLOR action the color value would be

set in an extra key-value pair

The Intent object has a series of put() methods for inserting various types of extra data and a

similar set of get() methods for reading the data These methods parallel those for Bundle

objects In fact the extras can be installed and read as a Bundle using the putExtras() and

getExtras() methods

Flags

Flags of various sorts Many instruct the Android system how to launch an activity (for example

which task the activity should belong to) and how to treat it after its launched (for example

whether it belongs in the list of recent activities) All these flags are defined in the Intent class

The Android system and the applications that come with the platform employ Intent objects both to

send out system-originated broadcasts and to activate system-defined components To see how to

structure an intent to activate a system component consult the list of intents in the reference

Intent Resolution

Intents can be divided into two groups

Explicit intents designate the target component by its name (the component name field mentioned

earlier has a value set) Since component names would generally not be known to developers of other

applications explicit intents are typically used for application-internal messages mdash such as an activity

starting a subordinate service or launching a sister activity

Implicit intents do not name a target (the field for the component name is blank) Implicit intents are

often used to activate components in other applications

Android delivers an explicit intent to an instance of the designated target class Nothing in the Intent

object other than the component name matters for determining which component should get the intent

A different strategy is needed for implicit intents In the absence of a designated target the Android

system must find the best component (or components) to handle the intent mdash a single activity or

service to perform the requested action or the set of broadcast receivers to respond to the broadcast

announcement It does so by comparing the contents of the Intent object to intent filters structures

associated with components that can potentially receive intents Filters advertise the capabilities of a

component and delimit the intents it can handle They open the component to the possibility of

receiving implicit intents of the advertised type If a component does not have any intent filters it can

receive only explicit intents A component with filters can receive both explicit and implicit intents

Only three aspects of an Intent object are consulted when the object is tested against an intent filter

action

data (both URI and data type)

category

The extras and flags play no part in resolving which component receives an intent

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 mdash but only unwanted implicit intents (those that dont 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

components 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 mdash 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 Pads filters are described in the Note Pad Example

section later)

Filters and security

An intent filter cannot be relied on for security While it opens a component to receiving only certain

kinds of implicit intents it does nothing to prevent explicit intents from targeting the component Even

though a filter restricts the intents a component will be asked to handle to certain actions and data

sources someone could always put together an explicit intent with a different action and data source

and name the component as the target

An intent filter is an instance of the IntentFilter class However since the Android system must know

about the capabilities of a component before it can launch that component intent filters are generally

not set up in Java code but in the applications manifest file (AndroidManifestxml) as ltintent-filtergt

elements (The one exception would be filters for broadcast receivers that are registered dynamically

by calling ContextregisterReceiver() they are directly created as IntentFilter objects)

A filter has fields that parallel the action data and category fields of an Intent object An implicit intent

is tested against the filter in all three areas To be delivered to the component that owns the filter it

must pass all three tests If it fails even one of them the Android system wont deliver it to the

component mdash at least not on the basis of that filter However since a component can have multiple

intent filters an intent that does not pass through one of a components filters might make it through on

another

Each of the three tests is described in detail below

Action test

An ltintent-filtergt element in the manifest file lists actions as ltactiongt subelements For

example

ltintent-filter gt ltaction androidname=comexampleprojectSHOW_CURRENT gt ltaction androidname=comexampleprojectSHOW_RECENT gt ltaction androidname=comexampleprojectSHOW_PENDING gt ltintent-filtergt

As the example shows while an Intent object names just a single action a filter may list more

than one The list cannot be empty a filter must contain at least one ltactiongt element or it will

block all intents

To pass this test the action specified in the Intent object must match one of the actions listed in

the filter If the object or the filter does not specify an action the results are as follows

If the filter fails to list any actions there is nothing for an intent to match so all intents fail the

test No intents can get through the filter

On the other hand an Intent object that doesnt specify an action automatically passes the test

mdash as long as the filter contains at least one action

Category test

An ltintent-filtergt element also lists categories as subelements For example

ltintent-filter gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryBROWSABLE gt ltintent-filtergt

Note that the constants described earlier for actions and categories are not used in the manifest

file The full string values are used instead For instance the

androidintentcategoryBROWSABLE string in the example above corresponds to the

CATEGORY_BROWSABLE constant mentioned earlier in this document Similarly the string

androidintentactionEDIT corresponds to the ACTION_EDIT constant

For an intent to pass the category test every category in the Intent object must match a

category in the filter The filter can list additional categories but it cannot omit any that are in the

intent

In principle therefore an Intent object with no categories should always pass this test

regardless of whats in the filter Thats mostly true However with one exception Android treats

all implicit intents passed to startActivity() as if they contained at least one category

androidintentcategoryDEFAULT (the CATEGORY_DEFAULT constant) Therefore activities

that are willing to receive implicit intents must include androidintentcategoryDEFAULT in

their intent filters (Filters with androidintentactionMAIN and

androidintentcategoryLAUNCHER settings are the exception They mark activities that begin

new tasks and that are represented on the launcher screen They can include

androidintentcategoryDEFAULT in the list of categories but dont need to) See Using intent

matching later for more on these filters)

Data test

Like the action and categories the data specification for an intent filter is contained in a

subelement And as in those cases the subelement can appear multiple times or not at all For

example

ltintent-filter gt ltdata androidmimeType=videompeg androidscheme=http gt ltdata androidmimeType=audiompeg androidscheme=http gt ltintent-filtergt

Each ltdatagt element can specify a URI and a data type (MIME media type) There are

separate attributes mdash scheme host port and path mdash for each part of the URI

schemehostportpath

For example in the following URI

contentcomexampleproject200foldersubfolderetc

the scheme is content the host is comexampleproject the port is 200 and the path is

foldersubfolderetc The host and port together constitute the URI authority if a host is not

specified the port is ignored

Each of these attributes is optional but they are not independent of each other For an authority

to be meaningful a scheme must also be specified For a path to be meaningful both a scheme

and an authority must be specified

When the URI in an Intent object is compared to a URI specification in a filter its compared

only to the parts of the URI actually mentioned in the filter For example if a filter specifies only

a scheme all URIs with that scheme match the filter If a filter specifies a scheme and an

authority but no path all URIs with the same scheme and authority match regardless of their

paths If a filter specifies a scheme an authority and a path only URIs with the same scheme

authority and path match However a path specification in the filter can contain wildcards to

require only a partial match of the path

The type attribute of a ltdatagt element specifies the MIME type of the data Its more common in

filters than a URI Both the Intent object and the filter can use a wildcard for the subtype field

mdash for example text or audio mdash indicating any subtype matches

The data test compares both the URI and the data type in the Intent object to a URI and data

type specified in the filter The rules are as follows

a An Intent object that contains neither a URI nor a data type passes the test only if the filter

likewise does not specify any URIs or data types

b An Intent object that contains a URI but no data type (and a type cannot be inferred from the

URI) passes the test only if its URI matches a URI in the filter and the filter likewise does not

specify a type This will be the case only for URIs like mailto and tel that do not refer to actual

data

c An Intent object that contains a data type but not a URI passes the test only if the filter lists the

same data type and similarly does not specify a URI

d An Intent object that contains both a URI and a data type (or a data type can be inferred from

the URI) passes the data type part of the test only if its type matches a type listed in the filter It

passes the URI part of the test either if its URI matches a URI in the filter or if it has a content

or file URI and the filter does not specify a URI In other words a component is presumed to

support content and file data if its filter lists only a data type

If an intent can pass through the filters of more than one activity or service the user may be asked

which component to activate An exception is raised if no target can be found

Common cases

The last rule shown above for the data test rule (d) reflects the expectation that components are able

to get local data from a file or content provider Therefore their filters can list just a data type and do

not need to explicitly name the content and file schemes This is a typical case A ltdatagt element like

the following for example tells Android that the component can get image data from a content

provider and display it

ltdata androidmimeType=image gt

Since most available data is dispensed by content providers filters that specify a data type but not a

URI are perhaps the most common

Another common configuration is filters with a scheme and a data type For example a ltdatagt

element like the following tells Android that the component can get video data from the network and

display it

ltdata androidscheme=http androidtype=video gt

Consider for example what the browser application does when the user follows a link on a web page

It first tries to display the data (as it could if the link was to an HTML page) If it cant display the data it

puts together an implicit intent with the scheme and data type and tries to start an activity that can do

the job If there are no takers it asks the download manager to download the data That puts it under

the control of a content provider so a potentially larger pool of activities (those with filters that just

name a data type) can respond

Most applications also have a way to start fresh without a reference to any particular data Activities

that can initiate applications have filters with androidintentactionMAIN specified as the action If

they are to be represented in the application launcher they also specify the

androidintentcategoryLAUNCHER category

ltintent-filter gt ltaction androidname=code androidintentactionMAIN gt ltcategory androidname=code androidintentcategoryLAUNCHER gt ltintent-filtergt

Using intent matching

Intents are matched against intent filters not only to discover a target component to activate but also

to discover something about the set of components on the device For example the Android system

populates the application launcher the top-level screen that shows the applications that are available

for the user to launch by finding all the activities with intent filters that specify the

androidintentactionMAIN action and androidintentcategoryLAUNCHER category (as illustrated

in the previous section) It then displays the icons and labels of those activities in the launcher

Similarly it discovers the home screen by looking for the activity with androidintentcategoryHOME

in its filter

Your application can use intent matching is a similar way The PackageManager has a set of query()

methods that return all components that can accept a particular intent and a similar series of

resolve() methods that determine the best component to respond to an intent For example

queryIntentActivities() returns a list of all activities that can perform the intent passed as an argument

and queryIntentServices() returns a similar list of services Neither method activates the components

they just list the ones that can respond Theres a similar method queryBroadcastReceivers() for

broadcast receivers

Note Pad Example

The Note Pad sample application enables users to browse through a list of notes view details about

individual items in the list edit the items and add a new item to the list This section looks at the intent

filters declared in its manifest file (If youre working offline in the SDK you can find all the source files

for this sample application including its manifest file at ltsdkgtsamplesNotePadindexhtml If youre

viewing the documentation online the source files are in the Tutorials and Sample Code section here)

In its manifest file the Note Pad application declares three activities each with at least one intent filter

It also declares a content provider that manages the note data Here is the manifest file in its entirety

ltmanifest xmlnsandroid=httpschemasandroidcomapkresandroid package=comexampleandroidnotepadgt ltapplication androidicon=drawableapp_notes androidlabel=stringapp_name gt ltprovider androidname=NotePadProvider androidauthorities=comgoogleproviderNotePad gt ltactivity androidname=NotesList androidlabel=stringtitle_notes_listgt ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltactivity androidname=NoteEditor androidtheme=androidstyleThemeLight androidlabel=stringtitle_note gt ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltactivitygt

ltactivity androidname=TitleEditor androidlabel=stringtitle_edit_title androidtheme=androidstyleThemeDialoggt ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltapplicationgt ltmanifestgt

The first activity NotesList is distinguished from the other activities by the fact that it operates on a

directory of notes (the note list) rather than on a single note It would generally serve as the initial user

interface into the application It can do three things as described by its three intent filters

1 ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt

This filter declares the main entry point into the Note Pad application The standard MAIN action is an

entry point that does not require any other information in the Intent (no data specification for example)

and the LAUNCHER category says that this entry point should be listed in the application launcher

2 ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

This filter declares the things that the activity can do on a directory of notes It can allow the user to

view or edit the directory (via the VIEW and EDIT actions) or to pick a particular note from the

directory (via the PICK action)

The mimeType attribute of the ltdatagt element specifies the kind of data that these actions operate on

It indicates that the activity can get a Cursor over zero or more items (vndandroidcursordir) from a

content provider that holds Note Pad data (vndgooglenote) The Intent object that launches the

activity would include a content URI specifying the exact data of this type that the activity should open

Note also the DEFAULT category supplied in this filter Its there because the ContextstartActivity()

and ActivitystartActivityForResult() methods treat all intents as if they contained the DEFAULT

category mdash with just two exceptions

o Intents that explicitly name the target activity

o Intents consisting of the MAIN action and LAUNCHER category

Therefore the DEFAULT category is required for all filters mdash except for those with the MAIN action

and LAUNCHER category (Intent filters are not consulted for explicit intents)

3 ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

This filter describes the activitys ability to return a note selected by the user without requiring any

specification of the directory the user should choose from The GET_CONTENT action is similar to the

PICK action In both cases the activity returns the URI for a note selected by the user (In each case

its returned to the activity that called startActivityForResult() to start the NoteList activity) Here

however the caller specifies the type of data desired instead of the directory of data the user will be

picking from

The data type vndandroidcursoritemvndgooglenote indicates the type of data the activity can

return mdash a URI for a single note From the returned URI the caller can get a Cursor for exactly one

item (vndandroidcursoritem) from the content provider that holds Note Pad data (vndgooglenote)

In other words for the PICK action in the previous filter the data type indicates the type of data the

activity could display to the user For the GET_CONTENT filter it indicates the type of data the activity

can return to the caller

Given these capabilities the following intents will resolve to the NotesList activity

action androidintentactionMAIN

Launches the activity with no data specified

action androidintentactionMAIN

category androidintentcategoryLAUNCHER

Launches the activity with no data selected specified This is the actual intent used by the

Launcher to populate its top-level list All activities with filters that match this action and

category are added to the list

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of all the notes under

contentcomgoogleproviderNotePadnotes The user can then browse through the list and

get information about the items in it

action androidintentactionPICK

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of the notes under

contentcomgoogleproviderNotePadnotes The user can then pick a note from the list and

the activity will return the URI for that item back to the activity that started the NoteList activity

action androidintentactionGET_CONTENT

data type vndandroidcursoritemvndgooglenote

Asks the activity to supply a single item of Note Pad data

The second activity NoteEditor shows users a single note entry and allows them to edit it It can do

two things as described by its two intent filters

1 ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The first primary purpose of this activity is to enable the user to interact with a single note ampmdash to

either VIEW the note or EDIT it (The EDIT_NOTE category is a synonym for EDIT) The intent would

contain the URI for data matching the MIME type vndandroidcursoritemvndgooglenote mdash that is

the URI for a single specific note It would typically be a URI that was returned by the PICK or

GET_CONTENT actions of the NoteList activity

As before this filter lists the DEFAULT category so that the activity can be launched by intents that

dont explicitly specify the NoteEditor class

2 ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

The secondary purpose of this activity is to enable the user to create a new note which it will INSERT

into an existing directory of notes The intent would contain the URI for data matching the MIME type

vndandroidcursordirvndgooglenote mdash that is the URI for the directory where the note should be

placed

Given these capabilities the following intents will resolve to the NoteEditor activity

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID (For details on how content

URIs specify individual members of a group see Content Providers)

action androidintentactionEDIT

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID and to let the user edit it If

the user saves the changes the activity updates the data for the note in the content provider

action androidintentactionINSERT

data contentcomgoogleproviderNotePadnotes

Asks the activity to create a new empty note in the notes list at

contentcomgoogleproviderNotePadnotes and allow the user to edit it If the user saves the

note its URI is returned to the caller

The last activity TitleEditor enables the user to edit the title of a note This could be implemented by

directly invoking the activity (by explicitly setting its component name in the Intent) without using an

intent filter But here we take the opportunity to show how to publish alternative operations on existing

data

ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The single intent filter for this activity uses a custom action called

comandroidnotepadactionEDIT_TITLE It must be invoked on a specific note (data type

vndandroidcursoritemvndgooglenote) like the previous VIEW and EDIT actions However here the

activity displays the title contained in the note data not the content of the note itself

In addition to supporting the usual DEFAULT category the title editor also supports two other standard

categories ALTERNATIVE and SELECTED_ALTERNATIVE These categories identify activities that

can be presented to users in a menu of options (much as the LAUNCHER category identifies activities

that should be presented to user in the application launcher) Note that the filter also supplies an

explicit label (via androidlabel=stringresolve_title) to better control what users see when

presented with this activity as an alternative action to the data they are currently viewing (For more

information on these categories and building options menus see the

PackageManagerqueryIntentActivityOptions() and MenuaddIntentOptions() methods)

Given these capabilities the following intent will resolve to the TitleEditor activity

action comandroidnotepadactionEDIT_TITLE

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the title associated with note ID and allow the user to edit the title

Processes and Threads

When an application component starts and the application does not have any other components

running the Android system starts a new Linux process for the application with a single thread of

execution By default all components of the same application run in the same process and thread

(called the main thread) If an application component starts and there already exists a process for

that application (because another component from the application exists) then the component is

started within that process and uses the same thread of execution However you can arrange for

different components in your application to run in separate processes and you can create additional

threads for any process

This document discusses how processes and threads work in an Android application

Processes

By default all components of the same application run in the same process and most applications

should not change this However if you find that you need to control which process a certain

component belongs to you can do so in the manifest file

The manifest entry for each type of component elementmdashltactivitygt ltservicegt ltreceivergt and

ltprovidergtmdashsupports an androidprocess attribute that can specify a process in which that component

should run You can set this attribute so that each component runs in its own process or so that some

components share a process while others do not You can also set androidprocess so that

components of different applications run in the same processmdashprovided that the applications share the

same Linux user ID and are signed with the same certificates

The ltapplicationgt element also supports an androidprocess attribute to set a default value that

applies to all components

Android might 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 thats killed are consequently destroyed A process is started again for those components

when theres again work for them to do

When deciding which processes to kill the Android system weighs their relative importance to the

user For example it more readily shuts down a process hosting activities that are no longer visible on

screen compared to a process hosting visible activities The decision whether to terminate a process

therefore depends on the state of the components running in that process The rules used to decide

which processes to terminate is discussed below

Process lifecycle

The Android system tries to maintain an application process for as long as possible but eventually

needs to remove old processes to reclaim memory for new or more important processes To determine

which processes to keep and which to kill the system places each process into an importance

hierarchy based on the components running in the process and the state of those components

Processes with the lowest importance are eliminated first then those with the next lowest importance

and so on as necessary to recover system resources

There are five levels in the importance hierarchy The following list presents the different types of

processes in order of importance (the first process is most important and is killed last)

1 Foreground process

A process that is required for what the user is currently doing A process is considered to be in the

foreground if any of the following conditions are true

o It hosts an Activity that the user is interacting with (the Activitys onResume() method has been called)

o It hosts a Service thats bound to the activity that the user is interacting with

o It hosts a Service thats running in the foregroundmdashthe service has called startForeground()

o It hosts a Service thats executing one of its lifecycle callbacks (onCreate() onStart() or onDestroy())

o It hosts a BroadcastReceiver thats executing its onReceive() method

Generally only a few foreground processes exist at any given time They are killed only as a last

resortmdashif memory is so low that they cannot all continue to run Generally at that point the device has

reached a memory paging state so killing some foreground processes is required to keep the user

interface responsive

2 Visible process

A process that doesnt have any foreground components but still can affect what the user sees on

screen A process is considered to be visible if either of the following conditions are true

o It hosts an Activity that is not in the foreground but is still visible to the user (its onPause() method has

been called) This might occur for example if the foreground activity started a dialog which allows the

previous activity to be seen behind it

o It hosts a Service thats bound to a visible (or foreground) activity

A visible process is considered extremely important and will not be killed unless doing so is required to

keep all foreground processes running

3 Service process

A process that is running a service that has been started with the startService() method and does not

fall into either of the two higher categories Although service processes are not directly tied to anything

the user sees they are generally doing things that the user cares about (such as playing music in the

background or downloading data on the network) so the system keeps them running unless theres

not enough memory to retain them along with all foreground and visible processes

4 Background process

A process holding an activity thats not currently visible to the user (the activitys onStop() method has

been called) These processes have no direct impact on the user experience and the system can kill

them at any time to reclaim memory for a foreground visible or service process Usually there are

many background processes running so they are kept in an LRU (least recently used) list to ensure

that the process with the activity that was most recently seen by the user is the last to be killed If an

activity implements its lifecycle methods correctly and saves its current state killing its process will not

have a visible effect on the user experience because when the user navigates back to the activity the

activity restores all of its visible state See the Activities document for information about saving and

restoring state

5 Empty process

A process that doesnt hold any active application components The only reason to keep this kind of

process alive is for caching purposes to improve startup time the next time a component needs to run

in it The system often kills these processes in order to balance overall system resources between

process caches and the underlying kernel caches

Android ranks a process at the highest level it can based upon the importance of the components

currently active in the process For example if a process hosts a service and a visible activity the

process is ranked as a visible process not a service process

In addition a processs ranking might be increased because other processes are dependent on itmdasha

process that is serving another process can never be ranked lower than the process it is serving For

example if a content provider in process A is serving a client in process B or if a service in process A

is bound to a component in process B process A is always considered at least as important as

process B

Because a process running a service is ranked higher than a process with background activities an

activity that initiates a long-running operation might do well to start a service for that operation rather

than simply create a worker threadmdashparticularly if the operation will likely outlast the activity For

example an activity thats uploading a picture to a web site should start a service to perform the

upload so that the upload can continue in the background even if the user leaves the activity Using a

service guarantees that the operation will have at least service process priority regardless of what

happens to the activity This is the same reason that broadcast receivers should employ services

rather than simply put time-consuming operations in a thread

Threads

When an application is launched the system creates a thread of execution for the application called

main This thread is very important because it is in charge of dispatching events to the appropriate

user interface widgets including drawing events It is also the thread in which your application interacts

with components from the Android UI toolkit (components from the androidwidget and androidview

packages) As such the main thread is also sometimes called the UI thread

The system does not create a separate thread for each instance of a component All components that

run in the same process are instantiated in the UI thread and system calls to each component are

dispatched from that thread Consequently methods that respond to system callbacks (such as

onKeyDown() to report user actions or a lifecycle callback method) always run in the UI thread of the

process

For instance when the user touches a button on the screen your apps UI thread dispatches the touch

event to the widget which in turn sets its pressed state and posts an invalidate request to the event

queue The UI thread dequeues the request and notifies the widget that it should redraw itself

When your app performs intensive work in response to user interaction this single thread model can

yield poor performance unless you implement your application properly Specifically if everything is

happening in the UI thread performing long operations such as network access or database queries

will block the whole UI When the thread is blocked no events can be dispatched including drawing

events From the users perspective the application appears to hang Even worse if the UI thread is

blocked for more than a few seconds (about 5 seconds currently) the user is presented with the

infamous application not responding (ANR) dialog The user might then decide to quit your

application and uninstall it if they are unhappy

Additionally the Andoid UI toolkit is not thread-safe So you must not manipulate your UI from a

worker threadmdashyou must do all manipulation to your user interface from the UI thread Thus there are

simply two rules to Androids single thread model

1 Do not block the UI thread

2 Do not access the Android UI toolkit from outside the UI thread

Worker threads

Because of the single thread model described above its vital to the responsiveness of your

applications UI that you do not block the UI thread If you have operations to perform that are not

instantaneous you should make sure to do them in separate threads (background or worker

threads)

For example below is some code for a click listener that downloads an image from a separate thread

and displays it in an ImageView

public void onClick(View v) new Thread(new Runnable() public void run() Bitmap b = loadImageFromNetwork(httpexamplecomimagepng) mImageViewsetImageBitmap(b) )start()

At first this seems to work fine because it creates a new thread to handle the network operation

However it violates the second rule of the single-threaded model do not access the Android UI toolkit

from outside the UI threadmdashthis sample modifies the ImageView from the worker thread instead of the

UI thread This can result in undefined and unexpected behavior which can be difficult and time-

consuming to track down

To fix this problem Android offers several ways to access the UI thread from other threads Here is a

list of methods that can help

ActivityrunOnUiThread(Runnable)

Viewpost(Runnable)

ViewpostDelayed(Runnable long)

For example you can fix the above code by using the Viewpost(Runnable) method

public void onClick(View v) new Thread(new Runnable() public void run() final Bitmap bitmap = loadImageFromNetwork(httpexamplecomimagepng) mImageViewpost(new Runnable() public void run() mImageViewsetImageBitmap(bitmap) ) )start()

Now this implementation is thread-safe the network operation is done from a separate thread while

the ImageView is manipulated from the UI thread

However as the complexity of the operation grows this kind of code can get complicated and difficult

to maintain To handle more complex interactions with a worker thread you might consider using a

Handler in your worker thread to process messages delivered from the UI thread Perhaps the best

solution though is to extend the AsyncTask class which simplifies the execution of worker thread

tasks that need to interact with the UI

Using AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface It performs the blocking

operations in a worker thread and then publishes the results on the UI thread without requiring you to

handle threads andor handlers yourself

To use it you must subclass AsyncTask and implement the doInBackground() callback method which

runs in a pool of background threads To update your UI you should implement onPostExecute()

which delivers the result from doInBackground() and runs in the UI thread so you can safely update

your UI You can then run the task by calling execute() from the UI thread

For example you can implement the previous example using AsyncTask this way

public void onClick(View v) new DownloadImageTask()execute(httpexamplecomimagepng) private class DownloadImageTask extends AsyncTaskltString Void Bitmapgt The system calls this to perform work in a worker thread and delivers it the parameters given to AsyncTaskexecute() protected Bitmap doInBackground(String urls) return loadImageFromNetwork(urls[0])

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 30: 03 services

13 3 Bully Pulpit 425 555 6677

53 3 Rex Cars 201 555 4433

The retrieved data is exposed by a Cursor object that can be used to iterate backward or forward

through the result set You can use this object only to read the data To add modify or delete data

you must use a ContentResolver object

Reading retrieved data

The Cursor object returned by a query provides access to a recordset of results If you have queried

for a specific record by ID this set will contain only one value Otherwise it can contain multiple

values (If there are no matches it can also be empty) You can read data from specific fields in the

record but you must know the data type of the field because the Cursor object has a separate method

for reading each type of data mdash such as getString() getInt() and getFloat() (However for most types

if you call the method for reading strings the Cursor object will give you the String representation of

the data) The Cursor lets you request the column name from the index of the column or the index

number from the column name

The following snippet demonstrates reading names and phone numbers from the query illustrated

earlier

import androidproviderContactsPeople private void getColumnData(Cursor cur) if (curmoveToFirst()) String name String phoneNumber int nameColumn = curgetColumnIndex(PeopleNAME) int phoneColumn = curgetColumnIndex(PeopleNUMBER) String imagePath do Get the field values name = curgetString(nameColumn) phoneNumber = curgetString(phoneColumn) Do something with the values while (curmoveToNext())

If a query can return binary data such as an image or sound the data may be directly entered in the

table or the table entry for that data may be a string specifying a content URI that you can use to get

the data In general smaller amounts of data (say from 20 to 50K or less) are most often directly

entered in the table and can be read by calling CursorgetBlob() It returns a byte array

If the table entry is a content URI you should never try to open and read the file directly (for one thing

permissions problems can make this fail) Instead you should call ContentResolveropenInputStream()

to get an InputStream object that you can use to read the data

Modifying Data

Data kept by a content provider can be modified by

Adding new records

Adding new values to existing records

Batch updating existing records

Deleting records

All data modification is accomplished using ContentResolver methods Some content providers require

a more restrictive permission for writing data than they do for reading it If you dont have permission to

write to a content provider the ContentResolver methods will fail

Adding records

To add a new record to a content provider first set up a map of key-value pairs in a ContentValues

object where each key matches the name of a column in the content provider and the value is the

desired value for the new record in that column Then call ContentResolverinsert() and pass it the URI

of the provider and the ContentValues map This method returns the full URI of the new record mdash that

is the providers URI with the appended ID for the new record You can then use this URI to query and

get a Cursor over the new record and to further modify the record Heres an example

import androidproviderContactsPeople import androidcontentContentResolver import androidcontentContentValues ContentValues values = new ContentValues() Add Abraham Lincoln to contacts and make him a favorite valuesput(PeopleNAME Abraham Lincoln) 1 = the new contact is added to favorites 0 = the new contact is not added to favorites valuesput(PeopleSTARRED 1) Uri uri = getContentResolver()insert(PeopleCONTENT_URI values)

Adding new values

Once a record exists you can add new information to it or modify existing information For example

the next step in the example above would be to add contact information mdash like a phone number or an

IM or e-mail address mdash to the new entry

The best way to add to a record in the Contacts database is to append the name of the table where the

new data goes to the URI for the record then use the amended URI to add the new data values Each

Contacts table exposes a name for this purpose as a CONTENT_DIRECTORY constant The following

code continues the previous example by adding a phone number and e-mail address for the record

just created

Uri phoneUri = null Uri emailUri = null Add a phone number for Abraham Lincoln Begin with the URI for the new record just returned by insert() it ends with the _ID of the new record so we dont have to add the ID ourselves Then append the designation for the phone table to this URI and use the resulting URI to insert the phone number phoneUri = UriwithAppendedPath(uri PeoplePhonesCONTENT_DIRECTORY) valuesclear() valuesput(PeoplePhonesTYPE PeoplePhonesTYPE_MOBILE) valuesput(PeoplePhonesNUMBER 1233214567) getContentResolver()insert(phoneUri values) Now add an email address in the same way emailUri = UriwithAppendedPath(uri PeopleContactMethodsCONTENT_DIRECTORY) valuesclear() ContactMethodsKIND is used to distinguish different kinds of contact methods such as email IM etc valuesput(PeopleContactMethodsKIND ContactsKIND_EMAIL) valuesput(PeopleContactMethodsDATA testexamplecom) valuesput(PeopleContactMethodsTYPE PeopleContactMethodsTYPE_HOME) getContentResolver()insert(emailUri values)

You can place small amounts of binary data into a table by calling the version of ContentValuesput()

that takes a byte array That would work for a small icon-like image or a short audio clip for example

However if you have a large amount of binary data to add such as a photograph or a complete song

put a content URI for the data in the table and call ContentResolveropenOutputStream() with the files

URI (That causes the content provider to store the data in a file and record the file path in a hidden

field of the record)

In this regard the MediaStore content provider the main provider that dispenses image audio and

video data employs a special convention The same URI that is used with query() or managedQuery()

to get meta-information about the binary data (such as the caption of a photograph or the date it was

taken) is used with openInputStream() to get the data itself Similarly the same URI that is used with

insert() to put meta-information into a MediaStore record is used with openOutputStream() to place the

binary data there The following code snippet illustrates this convention

import androidproviderMediaStoreImagesMedia import androidcontentContentValues import javaioOutputStream Save the name and description of an image in a ContentValues map ContentValues values = new ContentValues(3) valuesput(MediaDISPLAY_NAME road_trip_1) valuesput(MediaDESCRIPTION Day 1 trip to Los Angeles) valuesput(MediaMIME_TYPE imagejpeg) Add a new record without the bitmap but with the values just set insert() returns the URI of the new record Uri uri = getContentResolver()insert(MediaEXTERNAL_CONTENT_URI values) Now get a handle to the file for that record and save the data into it Here sourceBitmap is a Bitmap object representing the file to save to the database try OutputStream outStream = getContentResolver()openOutputStream(uri) sourceBitmapcompress(BitmapCompressFormatJPEG 50 outStream) outStreamclose() catch (Exception e) Loge(TAG exception while writing image e)

Batch updating records

To batch update a group of records (for example to change NY to New York in all fields) call the

ContentResolverupdate() method with the columns and values to change

Deleting a record

To delete a single record call ContentResolverdelete() with the URI of a specific row

To delete multiple rows call ContentResolverdelete() with the URI of the type of record to delete (for

example androidproviderContactsPeopleCONTENT_URI) and an SQL WHERE clause defining

which rows to delete (Caution Be sure to include a valid WHERE clause if youre deleting a general

type or you risk deleting more records than you intended)

Creating a Content Provider

To create a content provider you must

Set up a system for storing the data Most content providers store their data using Androids file

storage methods or SQLite databases but you can store your data any way you want Android

provides the SQLiteOpenHelper class to help you create a database and SQLiteDatabase to manage

it

Extend the ContentProvider class to provide access to the data

Declare the content provider in the manifest file for your application (AndroidManifestxml)

The following sections have notes on the last two of these tasks

Extending the ContentProvider class

You define a ContentProvider subclass to expose your data to others using the conventions expected

by ContentResolver and Cursor objects Principally this means implementing six abstract methods

declared in the ContentProvider class

query()

insert()

update()

delete()

getType()

onCreate()

The query() method must return a Cursor object that can iterate over the requested data Cursor itself

is an interface but Android provides some ready-made Cursor objects that you can use For example

SQLiteCursor can iterate over data stored in an SQLite database You get the Cursor object by calling

any of the SQLiteDatabase classs query() methods There are other Cursor implementations mdash such

as MatrixCursor mdash for data not stored in a database

Because these ContentProvider methods can be called from various ContentResolver objects in

different processes and threads they must be implemented in a thread-safe manner

As a courtesy you might also want to call ContentResolvernotifyChange() to notify listeners when

there are modifications to the data

Beyond defining the subclass itself there are other steps you should take to simplify the work of clients

and make the class more accessible

Define a public static final Uri named CONTENT_URI This is the string that represents the full content

URI that your content provider handles You must define a unique string for this value The best

solution is to use the fully-qualified class name of the content provider (made lowercase) So for

example the URI for a TransportationProvider class could be defined as follows

public static final Uri CONTENT_URI = Uriparse(contentcomexamplecodelabtransportationprovider)

If the provider has subtables also define CONTENT_URI constants for each of the subtables These

URIs should all have the same authority (since that identifies the content provider) and be

distinguished only by their paths For example

contentcomexamplecodelabtransportationprovidertrain

contentcomexamplecodelabtransportationproviderairdomestic

contentcomexamplecodelabtransportationproviderairinternational

For an overview of content URIs see the Content URI Summary at the end of this document

Define the column names that the content provider will return to clients If you are using an underlying

database these column names are typically identical to the SQL database column names they

represent Also define public static String constants that clients can use to specify the columns in

queries and other instructions

Be sure to include an integer column named _id (with the constant _ID) for the IDs of the records

You should have this field whether or not you have another field (such as a URL) that is also unique

among all records If youre using the SQLite database the _ID field should be the following type

INTEGER PRIMARY KEY AUTOINCREMENT

The AUTOINCREMENT descriptor is optional But without it SQLite increments an ID counter field to

the next number above the largest existing number in the column If you delete the last row the next

row added will have the same ID as the deleted row AUTOINCREMENT avoids this by having SQLite

increment to the next largest value whether deleted or not

Carefully document the data type of each column Clients need this information to read the data

If you are handling a new data type you must define a new MIME type to return in your

implementation of ContentProvidergetType() The type depends in part on whether or not the content

URI submitted to getType() limits the request to a specific record Theres one form of the MIME type

for a single record and another for multiple records Use the Uri methods to help determine what is

being requested Here is the general format for each type

o For a single record vndandroidcursoritemvndyourcompanynamecontenttype

For example a request for train record 122 like this URI

contentcomexampletransportationprovidertrains122

might return this MIME type

vndandroidcursoritemvndexamplerail

o For multiple records vndandroidcursordirvndyourcompanynamecontenttype

For example a request for all train records like the following URI

contentcomexampletransportationprovidertrains

might return this MIME type

vndandroidcursordirvndexamplerail

If you are exposing byte data thats too big to put in the table itself mdash such as a large bitmap file mdash the

field that exposes the data to clients should actually contain a content URI string This is the field that

gives clients access to the data file The record should also have another field named _data that lists

the exact file path on the device for that file This field is not intended to be read by the client but by

the ContentResolver The client will call ContentResolveropenInputStream() on the user-facing field

holding the URI for the item The ContentResolver will request the _data field for that record and

because it has higher permissions than a client it should be able to access that file directly and return

a read wrapper for the file to the client

For an example of a private content provider implementation see the NodePadProvider class in the

Notepad sample application that ships with the SDK

Declaring the content provider

To let the Android system know about the content provider youve developed declare it with a

ltprovidergt element in the applications AndroidManifestxml file Content providers that are not

declared in the manifest are not visible to the Android system

The name attribute is the fully qualified name of the ContentProvider subclass The authorities attribute

is the authority part of the content URI that identifies the provider For example if the ContentProvider

subclass is AutoInfoProvider the ltprovidergt element might look like this

ltprovider androidname=comexampleautosAutoInfoProvider androidauthorities=comexampleautosautoinfoprovider gt ltprovidergt

Note that the authorities attribute omits the path part of a content URI For example if

AutoInfoProvider controlled subtables for different types of autos or different manufacturers

contentcomexampleautosautoinfoproviderhonda

contentcomexampleautosautoinfoprovidergmcompact

contentcomexampleautosautoinfoprovidergmsuv

those paths would not be declared in the manifest The authority is what identifies the provider not the

path your provider can interpret the path part of the URI in any way you choose

Other ltprovidergt attributes can set permissions to read and write data provide for an icon and text

that can be displayed to users enable and disable the provider and so on Set the multiprocess

attribute to true if data does not need to be synchronized between multiple running versions of the

content provider This permits an instance of the provider to be created in each client process

eliminating the need to perform IPC

Content URI Summary

Here is a recap of the important parts of a content URI

A Standard prefix indicating that the data is controlled by a content provider Its never modified

B The authority part of the URI it identifies the content provider For third-party applications this should

be a fully-qualified class name (reduced to lowercase) to ensure uniqueness The authority is declared

in the ltprovidergt elements authorities attribute

ltprovider androidname=TransportationProvider androidauthorities=comexampletransportationprovider gt

C The path that the content provider uses to determine what kind of data is being requested This can be

zero or more segments long If the content provider exposes only one type of data (only trains for

example) it can be absent If the provider exposes several types including subtypes it can be several

segments long mdash for example landbus landtrain seaship and seasubmarine to give four

possibilities

D The ID of the specific record being requested if any This is the _ID value of the requested record If

the request is not limited to a single record this segment and the trailing slash are omitted

contentcomexampletransportationprovidertrains

Intent and intent filters

Three of the core components of an application mdash activities services and broadcast receivers mdash 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 mdash 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 ContextstartActivity() or ActivitystartActivityForResult() to launch an

activity or get an existing activity to do something new (It can also be passed to ActivitysetResult() to

return information to the activity that called startActivityForResult())

An Intent object is passed to ContextstartService() to initiate a service or deliver new instructions to an

ongoing service Similarly an intent can be passed to ContextbindService() to establish a connection

between the calling component and a target service It can optionally initiate the service if its not

already running

Intent objects passed to any of the broadcast methods (such as ContextsendBroadcast()

ContextsendOrderedBroadcast() or ContextsendStickyBroadcast()) 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 mdash how it resolves which component should receive an intent message For

intents that dont explicitly name a target component this process involves testing the Intent object

against intent filters associated with potential targets

Intent Objects

An Intent object is a bundle of information It contains information of interest to the component that

receives the intent (such as the action to be taken and the data to act on) plus information of interest to

the Android system (such as the category of component that should handle the intent and instructions

on how to launch a target activity) Principally it can contain the following

Component name

The name of the component that should handle the intent This field is a ComponentName

object mdash a combination of the fully qualified class name of the target component (for example

comexampleprojectappFreneticActivity) and the package name set in the manifest file of the

application where the component resides (for example comexampleproject) The package

part of the component name and the package name set in the manifest do not necessarily have

to match

The component name is optional If it is set the Intent object is delivered to an instance of the

designated class If it is not set Android uses other information in the Intent object to locate a

suitable target mdash see Intent Resolution later in this document

The component name is set by setComponent() setClass() or setClassName() and read by

getComponent()

Action

A string naming the action to be performed mdash or in the case of broadcast intents the action

that took place and is being reported The Intent class defines a number of action constants

including these

Constant Target

component

Action

ACTION_CALL activity Initiate a phone call

ACTION_EDIT activity Display data for the user to edit

ACTION_MAIN activity Start up as the initial activity of a task

with no data input and no returned

output

ACTION_SYNC activity Synchronize data on a server with

data on the mobile device

ACTION_BATTERY_LOW broadcast

receiver

A warning that the battery is low

ACTION_HEADSET_PLUG broadcast

receiver

A headset has been plugged into the

device or unplugged from it

ACTION_SCREEN_ON broadcast

receiver

The screen has been turned on

ACTION_TIMEZONE_CHANGED broadcast

receiver

The setting for the time zone has

changed

See the Intent class description for a list of pre-defined constants for generic actions Other

actions are defined elsewhere in the Android API You can also define your own action strings

for activating the components in your application Those you invent should include the

application package as a prefix mdash for example comexampleprojectSHOW_COLOR

The action largely determines how the rest of the intent is structured mdash particularly the data and

extras fields mdash much as a method name determines a set of arguments and a return value For

this reason its a good idea to use action names that are as specific as possible and to couple

them tightly to the other fields of the intent In other words instead of defining an action in

isolation define an entire protocol for the Intent objects your components can handle

The action in an Intent object is set by the setAction() method and read by getAction()

Data

The URI of the data to be acted on and the MIME type of that data Different actions are paired

with different kinds of data specifications For example if the action field is ACTION_EDIT the

data field would contain the URI of the document to be displayed for editing If the action is

ACTION_CALL the data field would be a tel URI with the number to call Similarly if the action

is ACTION_VIEW and the data field is an http URI the receiving activity would be called upon

to download and display whatever data the URI refers to

When matching an intent to a component that is capable of handling the data its often

important to know the type of data (its MIME type) in addition to its URI For example a

component able to display image data should not be called upon to play an audio file

In many cases the data type can be inferred from the URI mdash particularly content URIs which

indicate that the data is located on the device and controlled by a content provider (see the

separate discussion on content providers) But the type can also be explicitly set in the Intent

object The setData() method specifies data only as a URI setType() specifies it only as a

MIME type and setDataAndType() specifies it as both a URI and a MIME type The URI is read

by getData() and the type by getType()

Category

A string containing additional information about the kind of component that should handle the

intent Any number of category descriptions can be placed in an Intent object As it does for

actions the Intent class defines several category constants including these

Constant Meaning

CATEGORY_BROWSABLE The target activity can be safely invoked by the browser to

display data referenced by a link mdash for example an image or

an e-mail message

CATEGORY_GADGET The activity can be embedded inside of another activity that

hosts gadgets

CATEGORY_HOME The activity displays the home screen the first screen the

user sees when the device is turned on or when the HOME

key is pressed

CATEGORY_LAUNCHER The activity can be the initial activity of a task and is listed in

the top-level application launcher

CATEGORY_PREFERENCE The target activity is a preference panel

See the Intent class description for the full list of categories

The addCategory() method places a category in an Intent object removeCategory() deletes a

category previously added and getCategories() gets the set of all categories currently in the

object

Extras

Key-value pairs for additional information that should be delivered to the component handling

the intent Just as some actions are paired with particular kinds of data URIs some are paired

with particular extras For example an ACTION_TIMEZONE_CHANGED intent has a time-

zone extra that identifies the new time zone and ACTION_HEADSET_PLUG has a state

extra indicating whether the headset is now plugged in or unplugged as well as a name extra

for the type of headset If you were to invent a SHOW_COLOR action the color value would be

set in an extra key-value pair

The Intent object has a series of put() methods for inserting various types of extra data and a

similar set of get() methods for reading the data These methods parallel those for Bundle

objects In fact the extras can be installed and read as a Bundle using the putExtras() and

getExtras() methods

Flags

Flags of various sorts Many instruct the Android system how to launch an activity (for example

which task the activity should belong to) and how to treat it after its launched (for example

whether it belongs in the list of recent activities) All these flags are defined in the Intent class

The Android system and the applications that come with the platform employ Intent objects both to

send out system-originated broadcasts and to activate system-defined components To see how to

structure an intent to activate a system component consult the list of intents in the reference

Intent Resolution

Intents can be divided into two groups

Explicit intents designate the target component by its name (the component name field mentioned

earlier has a value set) Since component names would generally not be known to developers of other

applications explicit intents are typically used for application-internal messages mdash such as an activity

starting a subordinate service or launching a sister activity

Implicit intents do not name a target (the field for the component name is blank) Implicit intents are

often used to activate components in other applications

Android delivers an explicit intent to an instance of the designated target class Nothing in the Intent

object other than the component name matters for determining which component should get the intent

A different strategy is needed for implicit intents In the absence of a designated target the Android

system must find the best component (or components) to handle the intent mdash a single activity or

service to perform the requested action or the set of broadcast receivers to respond to the broadcast

announcement It does so by comparing the contents of the Intent object to intent filters structures

associated with components that can potentially receive intents Filters advertise the capabilities of a

component and delimit the intents it can handle They open the component to the possibility of

receiving implicit intents of the advertised type If a component does not have any intent filters it can

receive only explicit intents A component with filters can receive both explicit and implicit intents

Only three aspects of an Intent object are consulted when the object is tested against an intent filter

action

data (both URI and data type)

category

The extras and flags play no part in resolving which component receives an intent

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 mdash but only unwanted implicit intents (those that dont 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

components 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 mdash 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 Pads filters are described in the Note Pad Example

section later)

Filters and security

An intent filter cannot be relied on for security While it opens a component to receiving only certain

kinds of implicit intents it does nothing to prevent explicit intents from targeting the component Even

though a filter restricts the intents a component will be asked to handle to certain actions and data

sources someone could always put together an explicit intent with a different action and data source

and name the component as the target

An intent filter is an instance of the IntentFilter class However since the Android system must know

about the capabilities of a component before it can launch that component intent filters are generally

not set up in Java code but in the applications manifest file (AndroidManifestxml) as ltintent-filtergt

elements (The one exception would be filters for broadcast receivers that are registered dynamically

by calling ContextregisterReceiver() they are directly created as IntentFilter objects)

A filter has fields that parallel the action data and category fields of an Intent object An implicit intent

is tested against the filter in all three areas To be delivered to the component that owns the filter it

must pass all three tests If it fails even one of them the Android system wont deliver it to the

component mdash at least not on the basis of that filter However since a component can have multiple

intent filters an intent that does not pass through one of a components filters might make it through on

another

Each of the three tests is described in detail below

Action test

An ltintent-filtergt element in the manifest file lists actions as ltactiongt subelements For

example

ltintent-filter gt ltaction androidname=comexampleprojectSHOW_CURRENT gt ltaction androidname=comexampleprojectSHOW_RECENT gt ltaction androidname=comexampleprojectSHOW_PENDING gt ltintent-filtergt

As the example shows while an Intent object names just a single action a filter may list more

than one The list cannot be empty a filter must contain at least one ltactiongt element or it will

block all intents

To pass this test the action specified in the Intent object must match one of the actions listed in

the filter If the object or the filter does not specify an action the results are as follows

If the filter fails to list any actions there is nothing for an intent to match so all intents fail the

test No intents can get through the filter

On the other hand an Intent object that doesnt specify an action automatically passes the test

mdash as long as the filter contains at least one action

Category test

An ltintent-filtergt element also lists categories as subelements For example

ltintent-filter gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryBROWSABLE gt ltintent-filtergt

Note that the constants described earlier for actions and categories are not used in the manifest

file The full string values are used instead For instance the

androidintentcategoryBROWSABLE string in the example above corresponds to the

CATEGORY_BROWSABLE constant mentioned earlier in this document Similarly the string

androidintentactionEDIT corresponds to the ACTION_EDIT constant

For an intent to pass the category test every category in the Intent object must match a

category in the filter The filter can list additional categories but it cannot omit any that are in the

intent

In principle therefore an Intent object with no categories should always pass this test

regardless of whats in the filter Thats mostly true However with one exception Android treats

all implicit intents passed to startActivity() as if they contained at least one category

androidintentcategoryDEFAULT (the CATEGORY_DEFAULT constant) Therefore activities

that are willing to receive implicit intents must include androidintentcategoryDEFAULT in

their intent filters (Filters with androidintentactionMAIN and

androidintentcategoryLAUNCHER settings are the exception They mark activities that begin

new tasks and that are represented on the launcher screen They can include

androidintentcategoryDEFAULT in the list of categories but dont need to) See Using intent

matching later for more on these filters)

Data test

Like the action and categories the data specification for an intent filter is contained in a

subelement And as in those cases the subelement can appear multiple times or not at all For

example

ltintent-filter gt ltdata androidmimeType=videompeg androidscheme=http gt ltdata androidmimeType=audiompeg androidscheme=http gt ltintent-filtergt

Each ltdatagt element can specify a URI and a data type (MIME media type) There are

separate attributes mdash scheme host port and path mdash for each part of the URI

schemehostportpath

For example in the following URI

contentcomexampleproject200foldersubfolderetc

the scheme is content the host is comexampleproject the port is 200 and the path is

foldersubfolderetc The host and port together constitute the URI authority if a host is not

specified the port is ignored

Each of these attributes is optional but they are not independent of each other For an authority

to be meaningful a scheme must also be specified For a path to be meaningful both a scheme

and an authority must be specified

When the URI in an Intent object is compared to a URI specification in a filter its compared

only to the parts of the URI actually mentioned in the filter For example if a filter specifies only

a scheme all URIs with that scheme match the filter If a filter specifies a scheme and an

authority but no path all URIs with the same scheme and authority match regardless of their

paths If a filter specifies a scheme an authority and a path only URIs with the same scheme

authority and path match However a path specification in the filter can contain wildcards to

require only a partial match of the path

The type attribute of a ltdatagt element specifies the MIME type of the data Its more common in

filters than a URI Both the Intent object and the filter can use a wildcard for the subtype field

mdash for example text or audio mdash indicating any subtype matches

The data test compares both the URI and the data type in the Intent object to a URI and data

type specified in the filter The rules are as follows

a An Intent object that contains neither a URI nor a data type passes the test only if the filter

likewise does not specify any URIs or data types

b An Intent object that contains a URI but no data type (and a type cannot be inferred from the

URI) passes the test only if its URI matches a URI in the filter and the filter likewise does not

specify a type This will be the case only for URIs like mailto and tel that do not refer to actual

data

c An Intent object that contains a data type but not a URI passes the test only if the filter lists the

same data type and similarly does not specify a URI

d An Intent object that contains both a URI and a data type (or a data type can be inferred from

the URI) passes the data type part of the test only if its type matches a type listed in the filter It

passes the URI part of the test either if its URI matches a URI in the filter or if it has a content

or file URI and the filter does not specify a URI In other words a component is presumed to

support content and file data if its filter lists only a data type

If an intent can pass through the filters of more than one activity or service the user may be asked

which component to activate An exception is raised if no target can be found

Common cases

The last rule shown above for the data test rule (d) reflects the expectation that components are able

to get local data from a file or content provider Therefore their filters can list just a data type and do

not need to explicitly name the content and file schemes This is a typical case A ltdatagt element like

the following for example tells Android that the component can get image data from a content

provider and display it

ltdata androidmimeType=image gt

Since most available data is dispensed by content providers filters that specify a data type but not a

URI are perhaps the most common

Another common configuration is filters with a scheme and a data type For example a ltdatagt

element like the following tells Android that the component can get video data from the network and

display it

ltdata androidscheme=http androidtype=video gt

Consider for example what the browser application does when the user follows a link on a web page

It first tries to display the data (as it could if the link was to an HTML page) If it cant display the data it

puts together an implicit intent with the scheme and data type and tries to start an activity that can do

the job If there are no takers it asks the download manager to download the data That puts it under

the control of a content provider so a potentially larger pool of activities (those with filters that just

name a data type) can respond

Most applications also have a way to start fresh without a reference to any particular data Activities

that can initiate applications have filters with androidintentactionMAIN specified as the action If

they are to be represented in the application launcher they also specify the

androidintentcategoryLAUNCHER category

ltintent-filter gt ltaction androidname=code androidintentactionMAIN gt ltcategory androidname=code androidintentcategoryLAUNCHER gt ltintent-filtergt

Using intent matching

Intents are matched against intent filters not only to discover a target component to activate but also

to discover something about the set of components on the device For example the Android system

populates the application launcher the top-level screen that shows the applications that are available

for the user to launch by finding all the activities with intent filters that specify the

androidintentactionMAIN action and androidintentcategoryLAUNCHER category (as illustrated

in the previous section) It then displays the icons and labels of those activities in the launcher

Similarly it discovers the home screen by looking for the activity with androidintentcategoryHOME

in its filter

Your application can use intent matching is a similar way The PackageManager has a set of query()

methods that return all components that can accept a particular intent and a similar series of

resolve() methods that determine the best component to respond to an intent For example

queryIntentActivities() returns a list of all activities that can perform the intent passed as an argument

and queryIntentServices() returns a similar list of services Neither method activates the components

they just list the ones that can respond Theres a similar method queryBroadcastReceivers() for

broadcast receivers

Note Pad Example

The Note Pad sample application enables users to browse through a list of notes view details about

individual items in the list edit the items and add a new item to the list This section looks at the intent

filters declared in its manifest file (If youre working offline in the SDK you can find all the source files

for this sample application including its manifest file at ltsdkgtsamplesNotePadindexhtml If youre

viewing the documentation online the source files are in the Tutorials and Sample Code section here)

In its manifest file the Note Pad application declares three activities each with at least one intent filter

It also declares a content provider that manages the note data Here is the manifest file in its entirety

ltmanifest xmlnsandroid=httpschemasandroidcomapkresandroid package=comexampleandroidnotepadgt ltapplication androidicon=drawableapp_notes androidlabel=stringapp_name gt ltprovider androidname=NotePadProvider androidauthorities=comgoogleproviderNotePad gt ltactivity androidname=NotesList androidlabel=stringtitle_notes_listgt ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltactivity androidname=NoteEditor androidtheme=androidstyleThemeLight androidlabel=stringtitle_note gt ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltactivitygt

ltactivity androidname=TitleEditor androidlabel=stringtitle_edit_title androidtheme=androidstyleThemeDialoggt ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltapplicationgt ltmanifestgt

The first activity NotesList is distinguished from the other activities by the fact that it operates on a

directory of notes (the note list) rather than on a single note It would generally serve as the initial user

interface into the application It can do three things as described by its three intent filters

1 ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt

This filter declares the main entry point into the Note Pad application The standard MAIN action is an

entry point that does not require any other information in the Intent (no data specification for example)

and the LAUNCHER category says that this entry point should be listed in the application launcher

2 ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

This filter declares the things that the activity can do on a directory of notes It can allow the user to

view or edit the directory (via the VIEW and EDIT actions) or to pick a particular note from the

directory (via the PICK action)

The mimeType attribute of the ltdatagt element specifies the kind of data that these actions operate on

It indicates that the activity can get a Cursor over zero or more items (vndandroidcursordir) from a

content provider that holds Note Pad data (vndgooglenote) The Intent object that launches the

activity would include a content URI specifying the exact data of this type that the activity should open

Note also the DEFAULT category supplied in this filter Its there because the ContextstartActivity()

and ActivitystartActivityForResult() methods treat all intents as if they contained the DEFAULT

category mdash with just two exceptions

o Intents that explicitly name the target activity

o Intents consisting of the MAIN action and LAUNCHER category

Therefore the DEFAULT category is required for all filters mdash except for those with the MAIN action

and LAUNCHER category (Intent filters are not consulted for explicit intents)

3 ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

This filter describes the activitys ability to return a note selected by the user without requiring any

specification of the directory the user should choose from The GET_CONTENT action is similar to the

PICK action In both cases the activity returns the URI for a note selected by the user (In each case

its returned to the activity that called startActivityForResult() to start the NoteList activity) Here

however the caller specifies the type of data desired instead of the directory of data the user will be

picking from

The data type vndandroidcursoritemvndgooglenote indicates the type of data the activity can

return mdash a URI for a single note From the returned URI the caller can get a Cursor for exactly one

item (vndandroidcursoritem) from the content provider that holds Note Pad data (vndgooglenote)

In other words for the PICK action in the previous filter the data type indicates the type of data the

activity could display to the user For the GET_CONTENT filter it indicates the type of data the activity

can return to the caller

Given these capabilities the following intents will resolve to the NotesList activity

action androidintentactionMAIN

Launches the activity with no data specified

action androidintentactionMAIN

category androidintentcategoryLAUNCHER

Launches the activity with no data selected specified This is the actual intent used by the

Launcher to populate its top-level list All activities with filters that match this action and

category are added to the list

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of all the notes under

contentcomgoogleproviderNotePadnotes The user can then browse through the list and

get information about the items in it

action androidintentactionPICK

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of the notes under

contentcomgoogleproviderNotePadnotes The user can then pick a note from the list and

the activity will return the URI for that item back to the activity that started the NoteList activity

action androidintentactionGET_CONTENT

data type vndandroidcursoritemvndgooglenote

Asks the activity to supply a single item of Note Pad data

The second activity NoteEditor shows users a single note entry and allows them to edit it It can do

two things as described by its two intent filters

1 ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The first primary purpose of this activity is to enable the user to interact with a single note ampmdash to

either VIEW the note or EDIT it (The EDIT_NOTE category is a synonym for EDIT) The intent would

contain the URI for data matching the MIME type vndandroidcursoritemvndgooglenote mdash that is

the URI for a single specific note It would typically be a URI that was returned by the PICK or

GET_CONTENT actions of the NoteList activity

As before this filter lists the DEFAULT category so that the activity can be launched by intents that

dont explicitly specify the NoteEditor class

2 ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

The secondary purpose of this activity is to enable the user to create a new note which it will INSERT

into an existing directory of notes The intent would contain the URI for data matching the MIME type

vndandroidcursordirvndgooglenote mdash that is the URI for the directory where the note should be

placed

Given these capabilities the following intents will resolve to the NoteEditor activity

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID (For details on how content

URIs specify individual members of a group see Content Providers)

action androidintentactionEDIT

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID and to let the user edit it If

the user saves the changes the activity updates the data for the note in the content provider

action androidintentactionINSERT

data contentcomgoogleproviderNotePadnotes

Asks the activity to create a new empty note in the notes list at

contentcomgoogleproviderNotePadnotes and allow the user to edit it If the user saves the

note its URI is returned to the caller

The last activity TitleEditor enables the user to edit the title of a note This could be implemented by

directly invoking the activity (by explicitly setting its component name in the Intent) without using an

intent filter But here we take the opportunity to show how to publish alternative operations on existing

data

ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The single intent filter for this activity uses a custom action called

comandroidnotepadactionEDIT_TITLE It must be invoked on a specific note (data type

vndandroidcursoritemvndgooglenote) like the previous VIEW and EDIT actions However here the

activity displays the title contained in the note data not the content of the note itself

In addition to supporting the usual DEFAULT category the title editor also supports two other standard

categories ALTERNATIVE and SELECTED_ALTERNATIVE These categories identify activities that

can be presented to users in a menu of options (much as the LAUNCHER category identifies activities

that should be presented to user in the application launcher) Note that the filter also supplies an

explicit label (via androidlabel=stringresolve_title) to better control what users see when

presented with this activity as an alternative action to the data they are currently viewing (For more

information on these categories and building options menus see the

PackageManagerqueryIntentActivityOptions() and MenuaddIntentOptions() methods)

Given these capabilities the following intent will resolve to the TitleEditor activity

action comandroidnotepadactionEDIT_TITLE

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the title associated with note ID and allow the user to edit the title

Processes and Threads

When an application component starts and the application does not have any other components

running the Android system starts a new Linux process for the application with a single thread of

execution By default all components of the same application run in the same process and thread

(called the main thread) If an application component starts and there already exists a process for

that application (because another component from the application exists) then the component is

started within that process and uses the same thread of execution However you can arrange for

different components in your application to run in separate processes and you can create additional

threads for any process

This document discusses how processes and threads work in an Android application

Processes

By default all components of the same application run in the same process and most applications

should not change this However if you find that you need to control which process a certain

component belongs to you can do so in the manifest file

The manifest entry for each type of component elementmdashltactivitygt ltservicegt ltreceivergt and

ltprovidergtmdashsupports an androidprocess attribute that can specify a process in which that component

should run You can set this attribute so that each component runs in its own process or so that some

components share a process while others do not You can also set androidprocess so that

components of different applications run in the same processmdashprovided that the applications share the

same Linux user ID and are signed with the same certificates

The ltapplicationgt element also supports an androidprocess attribute to set a default value that

applies to all components

Android might 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 thats killed are consequently destroyed A process is started again for those components

when theres again work for them to do

When deciding which processes to kill the Android system weighs their relative importance to the

user For example it more readily shuts down a process hosting activities that are no longer visible on

screen compared to a process hosting visible activities The decision whether to terminate a process

therefore depends on the state of the components running in that process The rules used to decide

which processes to terminate is discussed below

Process lifecycle

The Android system tries to maintain an application process for as long as possible but eventually

needs to remove old processes to reclaim memory for new or more important processes To determine

which processes to keep and which to kill the system places each process into an importance

hierarchy based on the components running in the process and the state of those components

Processes with the lowest importance are eliminated first then those with the next lowest importance

and so on as necessary to recover system resources

There are five levels in the importance hierarchy The following list presents the different types of

processes in order of importance (the first process is most important and is killed last)

1 Foreground process

A process that is required for what the user is currently doing A process is considered to be in the

foreground if any of the following conditions are true

o It hosts an Activity that the user is interacting with (the Activitys onResume() method has been called)

o It hosts a Service thats bound to the activity that the user is interacting with

o It hosts a Service thats running in the foregroundmdashthe service has called startForeground()

o It hosts a Service thats executing one of its lifecycle callbacks (onCreate() onStart() or onDestroy())

o It hosts a BroadcastReceiver thats executing its onReceive() method

Generally only a few foreground processes exist at any given time They are killed only as a last

resortmdashif memory is so low that they cannot all continue to run Generally at that point the device has

reached a memory paging state so killing some foreground processes is required to keep the user

interface responsive

2 Visible process

A process that doesnt have any foreground components but still can affect what the user sees on

screen A process is considered to be visible if either of the following conditions are true

o It hosts an Activity that is not in the foreground but is still visible to the user (its onPause() method has

been called) This might occur for example if the foreground activity started a dialog which allows the

previous activity to be seen behind it

o It hosts a Service thats bound to a visible (or foreground) activity

A visible process is considered extremely important and will not be killed unless doing so is required to

keep all foreground processes running

3 Service process

A process that is running a service that has been started with the startService() method and does not

fall into either of the two higher categories Although service processes are not directly tied to anything

the user sees they are generally doing things that the user cares about (such as playing music in the

background or downloading data on the network) so the system keeps them running unless theres

not enough memory to retain them along with all foreground and visible processes

4 Background process

A process holding an activity thats not currently visible to the user (the activitys onStop() method has

been called) These processes have no direct impact on the user experience and the system can kill

them at any time to reclaim memory for a foreground visible or service process Usually there are

many background processes running so they are kept in an LRU (least recently used) list to ensure

that the process with the activity that was most recently seen by the user is the last to be killed If an

activity implements its lifecycle methods correctly and saves its current state killing its process will not

have a visible effect on the user experience because when the user navigates back to the activity the

activity restores all of its visible state See the Activities document for information about saving and

restoring state

5 Empty process

A process that doesnt hold any active application components The only reason to keep this kind of

process alive is for caching purposes to improve startup time the next time a component needs to run

in it The system often kills these processes in order to balance overall system resources between

process caches and the underlying kernel caches

Android ranks a process at the highest level it can based upon the importance of the components

currently active in the process For example if a process hosts a service and a visible activity the

process is ranked as a visible process not a service process

In addition a processs ranking might be increased because other processes are dependent on itmdasha

process that is serving another process can never be ranked lower than the process it is serving For

example if a content provider in process A is serving a client in process B or if a service in process A

is bound to a component in process B process A is always considered at least as important as

process B

Because a process running a service is ranked higher than a process with background activities an

activity that initiates a long-running operation might do well to start a service for that operation rather

than simply create a worker threadmdashparticularly if the operation will likely outlast the activity For

example an activity thats uploading a picture to a web site should start a service to perform the

upload so that the upload can continue in the background even if the user leaves the activity Using a

service guarantees that the operation will have at least service process priority regardless of what

happens to the activity This is the same reason that broadcast receivers should employ services

rather than simply put time-consuming operations in a thread

Threads

When an application is launched the system creates a thread of execution for the application called

main This thread is very important because it is in charge of dispatching events to the appropriate

user interface widgets including drawing events It is also the thread in which your application interacts

with components from the Android UI toolkit (components from the androidwidget and androidview

packages) As such the main thread is also sometimes called the UI thread

The system does not create a separate thread for each instance of a component All components that

run in the same process are instantiated in the UI thread and system calls to each component are

dispatched from that thread Consequently methods that respond to system callbacks (such as

onKeyDown() to report user actions or a lifecycle callback method) always run in the UI thread of the

process

For instance when the user touches a button on the screen your apps UI thread dispatches the touch

event to the widget which in turn sets its pressed state and posts an invalidate request to the event

queue The UI thread dequeues the request and notifies the widget that it should redraw itself

When your app performs intensive work in response to user interaction this single thread model can

yield poor performance unless you implement your application properly Specifically if everything is

happening in the UI thread performing long operations such as network access or database queries

will block the whole UI When the thread is blocked no events can be dispatched including drawing

events From the users perspective the application appears to hang Even worse if the UI thread is

blocked for more than a few seconds (about 5 seconds currently) the user is presented with the

infamous application not responding (ANR) dialog The user might then decide to quit your

application and uninstall it if they are unhappy

Additionally the Andoid UI toolkit is not thread-safe So you must not manipulate your UI from a

worker threadmdashyou must do all manipulation to your user interface from the UI thread Thus there are

simply two rules to Androids single thread model

1 Do not block the UI thread

2 Do not access the Android UI toolkit from outside the UI thread

Worker threads

Because of the single thread model described above its vital to the responsiveness of your

applications UI that you do not block the UI thread If you have operations to perform that are not

instantaneous you should make sure to do them in separate threads (background or worker

threads)

For example below is some code for a click listener that downloads an image from a separate thread

and displays it in an ImageView

public void onClick(View v) new Thread(new Runnable() public void run() Bitmap b = loadImageFromNetwork(httpexamplecomimagepng) mImageViewsetImageBitmap(b) )start()

At first this seems to work fine because it creates a new thread to handle the network operation

However it violates the second rule of the single-threaded model do not access the Android UI toolkit

from outside the UI threadmdashthis sample modifies the ImageView from the worker thread instead of the

UI thread This can result in undefined and unexpected behavior which can be difficult and time-

consuming to track down

To fix this problem Android offers several ways to access the UI thread from other threads Here is a

list of methods that can help

ActivityrunOnUiThread(Runnable)

Viewpost(Runnable)

ViewpostDelayed(Runnable long)

For example you can fix the above code by using the Viewpost(Runnable) method

public void onClick(View v) new Thread(new Runnable() public void run() final Bitmap bitmap = loadImageFromNetwork(httpexamplecomimagepng) mImageViewpost(new Runnable() public void run() mImageViewsetImageBitmap(bitmap) ) )start()

Now this implementation is thread-safe the network operation is done from a separate thread while

the ImageView is manipulated from the UI thread

However as the complexity of the operation grows this kind of code can get complicated and difficult

to maintain To handle more complex interactions with a worker thread you might consider using a

Handler in your worker thread to process messages delivered from the UI thread Perhaps the best

solution though is to extend the AsyncTask class which simplifies the execution of worker thread

tasks that need to interact with the UI

Using AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface It performs the blocking

operations in a worker thread and then publishes the results on the UI thread without requiring you to

handle threads andor handlers yourself

To use it you must subclass AsyncTask and implement the doInBackground() callback method which

runs in a pool of background threads To update your UI you should implement onPostExecute()

which delivers the result from doInBackground() and runs in the UI thread so you can safely update

your UI You can then run the task by calling execute() from the UI thread

For example you can implement the previous example using AsyncTask this way

public void onClick(View v) new DownloadImageTask()execute(httpexamplecomimagepng) private class DownloadImageTask extends AsyncTaskltString Void Bitmapgt The system calls this to perform work in a worker thread and delivers it the parameters given to AsyncTaskexecute() protected Bitmap doInBackground(String urls) return loadImageFromNetwork(urls[0])

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 31: 03 services

If a query can return binary data such as an image or sound the data may be directly entered in the

table or the table entry for that data may be a string specifying a content URI that you can use to get

the data In general smaller amounts of data (say from 20 to 50K or less) are most often directly

entered in the table and can be read by calling CursorgetBlob() It returns a byte array

If the table entry is a content URI you should never try to open and read the file directly (for one thing

permissions problems can make this fail) Instead you should call ContentResolveropenInputStream()

to get an InputStream object that you can use to read the data

Modifying Data

Data kept by a content provider can be modified by

Adding new records

Adding new values to existing records

Batch updating existing records

Deleting records

All data modification is accomplished using ContentResolver methods Some content providers require

a more restrictive permission for writing data than they do for reading it If you dont have permission to

write to a content provider the ContentResolver methods will fail

Adding records

To add a new record to a content provider first set up a map of key-value pairs in a ContentValues

object where each key matches the name of a column in the content provider and the value is the

desired value for the new record in that column Then call ContentResolverinsert() and pass it the URI

of the provider and the ContentValues map This method returns the full URI of the new record mdash that

is the providers URI with the appended ID for the new record You can then use this URI to query and

get a Cursor over the new record and to further modify the record Heres an example

import androidproviderContactsPeople import androidcontentContentResolver import androidcontentContentValues ContentValues values = new ContentValues() Add Abraham Lincoln to contacts and make him a favorite valuesput(PeopleNAME Abraham Lincoln) 1 = the new contact is added to favorites 0 = the new contact is not added to favorites valuesput(PeopleSTARRED 1) Uri uri = getContentResolver()insert(PeopleCONTENT_URI values)

Adding new values

Once a record exists you can add new information to it or modify existing information For example

the next step in the example above would be to add contact information mdash like a phone number or an

IM or e-mail address mdash to the new entry

The best way to add to a record in the Contacts database is to append the name of the table where the

new data goes to the URI for the record then use the amended URI to add the new data values Each

Contacts table exposes a name for this purpose as a CONTENT_DIRECTORY constant The following

code continues the previous example by adding a phone number and e-mail address for the record

just created

Uri phoneUri = null Uri emailUri = null Add a phone number for Abraham Lincoln Begin with the URI for the new record just returned by insert() it ends with the _ID of the new record so we dont have to add the ID ourselves Then append the designation for the phone table to this URI and use the resulting URI to insert the phone number phoneUri = UriwithAppendedPath(uri PeoplePhonesCONTENT_DIRECTORY) valuesclear() valuesput(PeoplePhonesTYPE PeoplePhonesTYPE_MOBILE) valuesput(PeoplePhonesNUMBER 1233214567) getContentResolver()insert(phoneUri values) Now add an email address in the same way emailUri = UriwithAppendedPath(uri PeopleContactMethodsCONTENT_DIRECTORY) valuesclear() ContactMethodsKIND is used to distinguish different kinds of contact methods such as email IM etc valuesput(PeopleContactMethodsKIND ContactsKIND_EMAIL) valuesput(PeopleContactMethodsDATA testexamplecom) valuesput(PeopleContactMethodsTYPE PeopleContactMethodsTYPE_HOME) getContentResolver()insert(emailUri values)

You can place small amounts of binary data into a table by calling the version of ContentValuesput()

that takes a byte array That would work for a small icon-like image or a short audio clip for example

However if you have a large amount of binary data to add such as a photograph or a complete song

put a content URI for the data in the table and call ContentResolveropenOutputStream() with the files

URI (That causes the content provider to store the data in a file and record the file path in a hidden

field of the record)

In this regard the MediaStore content provider the main provider that dispenses image audio and

video data employs a special convention The same URI that is used with query() or managedQuery()

to get meta-information about the binary data (such as the caption of a photograph or the date it was

taken) is used with openInputStream() to get the data itself Similarly the same URI that is used with

insert() to put meta-information into a MediaStore record is used with openOutputStream() to place the

binary data there The following code snippet illustrates this convention

import androidproviderMediaStoreImagesMedia import androidcontentContentValues import javaioOutputStream Save the name and description of an image in a ContentValues map ContentValues values = new ContentValues(3) valuesput(MediaDISPLAY_NAME road_trip_1) valuesput(MediaDESCRIPTION Day 1 trip to Los Angeles) valuesput(MediaMIME_TYPE imagejpeg) Add a new record without the bitmap but with the values just set insert() returns the URI of the new record Uri uri = getContentResolver()insert(MediaEXTERNAL_CONTENT_URI values) Now get a handle to the file for that record and save the data into it Here sourceBitmap is a Bitmap object representing the file to save to the database try OutputStream outStream = getContentResolver()openOutputStream(uri) sourceBitmapcompress(BitmapCompressFormatJPEG 50 outStream) outStreamclose() catch (Exception e) Loge(TAG exception while writing image e)

Batch updating records

To batch update a group of records (for example to change NY to New York in all fields) call the

ContentResolverupdate() method with the columns and values to change

Deleting a record

To delete a single record call ContentResolverdelete() with the URI of a specific row

To delete multiple rows call ContentResolverdelete() with the URI of the type of record to delete (for

example androidproviderContactsPeopleCONTENT_URI) and an SQL WHERE clause defining

which rows to delete (Caution Be sure to include a valid WHERE clause if youre deleting a general

type or you risk deleting more records than you intended)

Creating a Content Provider

To create a content provider you must

Set up a system for storing the data Most content providers store their data using Androids file

storage methods or SQLite databases but you can store your data any way you want Android

provides the SQLiteOpenHelper class to help you create a database and SQLiteDatabase to manage

it

Extend the ContentProvider class to provide access to the data

Declare the content provider in the manifest file for your application (AndroidManifestxml)

The following sections have notes on the last two of these tasks

Extending the ContentProvider class

You define a ContentProvider subclass to expose your data to others using the conventions expected

by ContentResolver and Cursor objects Principally this means implementing six abstract methods

declared in the ContentProvider class

query()

insert()

update()

delete()

getType()

onCreate()

The query() method must return a Cursor object that can iterate over the requested data Cursor itself

is an interface but Android provides some ready-made Cursor objects that you can use For example

SQLiteCursor can iterate over data stored in an SQLite database You get the Cursor object by calling

any of the SQLiteDatabase classs query() methods There are other Cursor implementations mdash such

as MatrixCursor mdash for data not stored in a database

Because these ContentProvider methods can be called from various ContentResolver objects in

different processes and threads they must be implemented in a thread-safe manner

As a courtesy you might also want to call ContentResolvernotifyChange() to notify listeners when

there are modifications to the data

Beyond defining the subclass itself there are other steps you should take to simplify the work of clients

and make the class more accessible

Define a public static final Uri named CONTENT_URI This is the string that represents the full content

URI that your content provider handles You must define a unique string for this value The best

solution is to use the fully-qualified class name of the content provider (made lowercase) So for

example the URI for a TransportationProvider class could be defined as follows

public static final Uri CONTENT_URI = Uriparse(contentcomexamplecodelabtransportationprovider)

If the provider has subtables also define CONTENT_URI constants for each of the subtables These

URIs should all have the same authority (since that identifies the content provider) and be

distinguished only by their paths For example

contentcomexamplecodelabtransportationprovidertrain

contentcomexamplecodelabtransportationproviderairdomestic

contentcomexamplecodelabtransportationproviderairinternational

For an overview of content URIs see the Content URI Summary at the end of this document

Define the column names that the content provider will return to clients If you are using an underlying

database these column names are typically identical to the SQL database column names they

represent Also define public static String constants that clients can use to specify the columns in

queries and other instructions

Be sure to include an integer column named _id (with the constant _ID) for the IDs of the records

You should have this field whether or not you have another field (such as a URL) that is also unique

among all records If youre using the SQLite database the _ID field should be the following type

INTEGER PRIMARY KEY AUTOINCREMENT

The AUTOINCREMENT descriptor is optional But without it SQLite increments an ID counter field to

the next number above the largest existing number in the column If you delete the last row the next

row added will have the same ID as the deleted row AUTOINCREMENT avoids this by having SQLite

increment to the next largest value whether deleted or not

Carefully document the data type of each column Clients need this information to read the data

If you are handling a new data type you must define a new MIME type to return in your

implementation of ContentProvidergetType() The type depends in part on whether or not the content

URI submitted to getType() limits the request to a specific record Theres one form of the MIME type

for a single record and another for multiple records Use the Uri methods to help determine what is

being requested Here is the general format for each type

o For a single record vndandroidcursoritemvndyourcompanynamecontenttype

For example a request for train record 122 like this URI

contentcomexampletransportationprovidertrains122

might return this MIME type

vndandroidcursoritemvndexamplerail

o For multiple records vndandroidcursordirvndyourcompanynamecontenttype

For example a request for all train records like the following URI

contentcomexampletransportationprovidertrains

might return this MIME type

vndandroidcursordirvndexamplerail

If you are exposing byte data thats too big to put in the table itself mdash such as a large bitmap file mdash the

field that exposes the data to clients should actually contain a content URI string This is the field that

gives clients access to the data file The record should also have another field named _data that lists

the exact file path on the device for that file This field is not intended to be read by the client but by

the ContentResolver The client will call ContentResolveropenInputStream() on the user-facing field

holding the URI for the item The ContentResolver will request the _data field for that record and

because it has higher permissions than a client it should be able to access that file directly and return

a read wrapper for the file to the client

For an example of a private content provider implementation see the NodePadProvider class in the

Notepad sample application that ships with the SDK

Declaring the content provider

To let the Android system know about the content provider youve developed declare it with a

ltprovidergt element in the applications AndroidManifestxml file Content providers that are not

declared in the manifest are not visible to the Android system

The name attribute is the fully qualified name of the ContentProvider subclass The authorities attribute

is the authority part of the content URI that identifies the provider For example if the ContentProvider

subclass is AutoInfoProvider the ltprovidergt element might look like this

ltprovider androidname=comexampleautosAutoInfoProvider androidauthorities=comexampleautosautoinfoprovider gt ltprovidergt

Note that the authorities attribute omits the path part of a content URI For example if

AutoInfoProvider controlled subtables for different types of autos or different manufacturers

contentcomexampleautosautoinfoproviderhonda

contentcomexampleautosautoinfoprovidergmcompact

contentcomexampleautosautoinfoprovidergmsuv

those paths would not be declared in the manifest The authority is what identifies the provider not the

path your provider can interpret the path part of the URI in any way you choose

Other ltprovidergt attributes can set permissions to read and write data provide for an icon and text

that can be displayed to users enable and disable the provider and so on Set the multiprocess

attribute to true if data does not need to be synchronized between multiple running versions of the

content provider This permits an instance of the provider to be created in each client process

eliminating the need to perform IPC

Content URI Summary

Here is a recap of the important parts of a content URI

A Standard prefix indicating that the data is controlled by a content provider Its never modified

B The authority part of the URI it identifies the content provider For third-party applications this should

be a fully-qualified class name (reduced to lowercase) to ensure uniqueness The authority is declared

in the ltprovidergt elements authorities attribute

ltprovider androidname=TransportationProvider androidauthorities=comexampletransportationprovider gt

C The path that the content provider uses to determine what kind of data is being requested This can be

zero or more segments long If the content provider exposes only one type of data (only trains for

example) it can be absent If the provider exposes several types including subtypes it can be several

segments long mdash for example landbus landtrain seaship and seasubmarine to give four

possibilities

D The ID of the specific record being requested if any This is the _ID value of the requested record If

the request is not limited to a single record this segment and the trailing slash are omitted

contentcomexampletransportationprovidertrains

Intent and intent filters

Three of the core components of an application mdash activities services and broadcast receivers mdash 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 mdash 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 ContextstartActivity() or ActivitystartActivityForResult() to launch an

activity or get an existing activity to do something new (It can also be passed to ActivitysetResult() to

return information to the activity that called startActivityForResult())

An Intent object is passed to ContextstartService() to initiate a service or deliver new instructions to an

ongoing service Similarly an intent can be passed to ContextbindService() to establish a connection

between the calling component and a target service It can optionally initiate the service if its not

already running

Intent objects passed to any of the broadcast methods (such as ContextsendBroadcast()

ContextsendOrderedBroadcast() or ContextsendStickyBroadcast()) 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 mdash how it resolves which component should receive an intent message For

intents that dont explicitly name a target component this process involves testing the Intent object

against intent filters associated with potential targets

Intent Objects

An Intent object is a bundle of information It contains information of interest to the component that

receives the intent (such as the action to be taken and the data to act on) plus information of interest to

the Android system (such as the category of component that should handle the intent and instructions

on how to launch a target activity) Principally it can contain the following

Component name

The name of the component that should handle the intent This field is a ComponentName

object mdash a combination of the fully qualified class name of the target component (for example

comexampleprojectappFreneticActivity) and the package name set in the manifest file of the

application where the component resides (for example comexampleproject) The package

part of the component name and the package name set in the manifest do not necessarily have

to match

The component name is optional If it is set the Intent object is delivered to an instance of the

designated class If it is not set Android uses other information in the Intent object to locate a

suitable target mdash see Intent Resolution later in this document

The component name is set by setComponent() setClass() or setClassName() and read by

getComponent()

Action

A string naming the action to be performed mdash or in the case of broadcast intents the action

that took place and is being reported The Intent class defines a number of action constants

including these

Constant Target

component

Action

ACTION_CALL activity Initiate a phone call

ACTION_EDIT activity Display data for the user to edit

ACTION_MAIN activity Start up as the initial activity of a task

with no data input and no returned

output

ACTION_SYNC activity Synchronize data on a server with

data on the mobile device

ACTION_BATTERY_LOW broadcast

receiver

A warning that the battery is low

ACTION_HEADSET_PLUG broadcast

receiver

A headset has been plugged into the

device or unplugged from it

ACTION_SCREEN_ON broadcast

receiver

The screen has been turned on

ACTION_TIMEZONE_CHANGED broadcast

receiver

The setting for the time zone has

changed

See the Intent class description for a list of pre-defined constants for generic actions Other

actions are defined elsewhere in the Android API You can also define your own action strings

for activating the components in your application Those you invent should include the

application package as a prefix mdash for example comexampleprojectSHOW_COLOR

The action largely determines how the rest of the intent is structured mdash particularly the data and

extras fields mdash much as a method name determines a set of arguments and a return value For

this reason its a good idea to use action names that are as specific as possible and to couple

them tightly to the other fields of the intent In other words instead of defining an action in

isolation define an entire protocol for the Intent objects your components can handle

The action in an Intent object is set by the setAction() method and read by getAction()

Data

The URI of the data to be acted on and the MIME type of that data Different actions are paired

with different kinds of data specifications For example if the action field is ACTION_EDIT the

data field would contain the URI of the document to be displayed for editing If the action is

ACTION_CALL the data field would be a tel URI with the number to call Similarly if the action

is ACTION_VIEW and the data field is an http URI the receiving activity would be called upon

to download and display whatever data the URI refers to

When matching an intent to a component that is capable of handling the data its often

important to know the type of data (its MIME type) in addition to its URI For example a

component able to display image data should not be called upon to play an audio file

In many cases the data type can be inferred from the URI mdash particularly content URIs which

indicate that the data is located on the device and controlled by a content provider (see the

separate discussion on content providers) But the type can also be explicitly set in the Intent

object The setData() method specifies data only as a URI setType() specifies it only as a

MIME type and setDataAndType() specifies it as both a URI and a MIME type The URI is read

by getData() and the type by getType()

Category

A string containing additional information about the kind of component that should handle the

intent Any number of category descriptions can be placed in an Intent object As it does for

actions the Intent class defines several category constants including these

Constant Meaning

CATEGORY_BROWSABLE The target activity can be safely invoked by the browser to

display data referenced by a link mdash for example an image or

an e-mail message

CATEGORY_GADGET The activity can be embedded inside of another activity that

hosts gadgets

CATEGORY_HOME The activity displays the home screen the first screen the

user sees when the device is turned on or when the HOME

key is pressed

CATEGORY_LAUNCHER The activity can be the initial activity of a task and is listed in

the top-level application launcher

CATEGORY_PREFERENCE The target activity is a preference panel

See the Intent class description for the full list of categories

The addCategory() method places a category in an Intent object removeCategory() deletes a

category previously added and getCategories() gets the set of all categories currently in the

object

Extras

Key-value pairs for additional information that should be delivered to the component handling

the intent Just as some actions are paired with particular kinds of data URIs some are paired

with particular extras For example an ACTION_TIMEZONE_CHANGED intent has a time-

zone extra that identifies the new time zone and ACTION_HEADSET_PLUG has a state

extra indicating whether the headset is now plugged in or unplugged as well as a name extra

for the type of headset If you were to invent a SHOW_COLOR action the color value would be

set in an extra key-value pair

The Intent object has a series of put() methods for inserting various types of extra data and a

similar set of get() methods for reading the data These methods parallel those for Bundle

objects In fact the extras can be installed and read as a Bundle using the putExtras() and

getExtras() methods

Flags

Flags of various sorts Many instruct the Android system how to launch an activity (for example

which task the activity should belong to) and how to treat it after its launched (for example

whether it belongs in the list of recent activities) All these flags are defined in the Intent class

The Android system and the applications that come with the platform employ Intent objects both to

send out system-originated broadcasts and to activate system-defined components To see how to

structure an intent to activate a system component consult the list of intents in the reference

Intent Resolution

Intents can be divided into two groups

Explicit intents designate the target component by its name (the component name field mentioned

earlier has a value set) Since component names would generally not be known to developers of other

applications explicit intents are typically used for application-internal messages mdash such as an activity

starting a subordinate service or launching a sister activity

Implicit intents do not name a target (the field for the component name is blank) Implicit intents are

often used to activate components in other applications

Android delivers an explicit intent to an instance of the designated target class Nothing in the Intent

object other than the component name matters for determining which component should get the intent

A different strategy is needed for implicit intents In the absence of a designated target the Android

system must find the best component (or components) to handle the intent mdash a single activity or

service to perform the requested action or the set of broadcast receivers to respond to the broadcast

announcement It does so by comparing the contents of the Intent object to intent filters structures

associated with components that can potentially receive intents Filters advertise the capabilities of a

component and delimit the intents it can handle They open the component to the possibility of

receiving implicit intents of the advertised type If a component does not have any intent filters it can

receive only explicit intents A component with filters can receive both explicit and implicit intents

Only three aspects of an Intent object are consulted when the object is tested against an intent filter

action

data (both URI and data type)

category

The extras and flags play no part in resolving which component receives an intent

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 mdash but only unwanted implicit intents (those that dont 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

components 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 mdash 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 Pads filters are described in the Note Pad Example

section later)

Filters and security

An intent filter cannot be relied on for security While it opens a component to receiving only certain

kinds of implicit intents it does nothing to prevent explicit intents from targeting the component Even

though a filter restricts the intents a component will be asked to handle to certain actions and data

sources someone could always put together an explicit intent with a different action and data source

and name the component as the target

An intent filter is an instance of the IntentFilter class However since the Android system must know

about the capabilities of a component before it can launch that component intent filters are generally

not set up in Java code but in the applications manifest file (AndroidManifestxml) as ltintent-filtergt

elements (The one exception would be filters for broadcast receivers that are registered dynamically

by calling ContextregisterReceiver() they are directly created as IntentFilter objects)

A filter has fields that parallel the action data and category fields of an Intent object An implicit intent

is tested against the filter in all three areas To be delivered to the component that owns the filter it

must pass all three tests If it fails even one of them the Android system wont deliver it to the

component mdash at least not on the basis of that filter However since a component can have multiple

intent filters an intent that does not pass through one of a components filters might make it through on

another

Each of the three tests is described in detail below

Action test

An ltintent-filtergt element in the manifest file lists actions as ltactiongt subelements For

example

ltintent-filter gt ltaction androidname=comexampleprojectSHOW_CURRENT gt ltaction androidname=comexampleprojectSHOW_RECENT gt ltaction androidname=comexampleprojectSHOW_PENDING gt ltintent-filtergt

As the example shows while an Intent object names just a single action a filter may list more

than one The list cannot be empty a filter must contain at least one ltactiongt element or it will

block all intents

To pass this test the action specified in the Intent object must match one of the actions listed in

the filter If the object or the filter does not specify an action the results are as follows

If the filter fails to list any actions there is nothing for an intent to match so all intents fail the

test No intents can get through the filter

On the other hand an Intent object that doesnt specify an action automatically passes the test

mdash as long as the filter contains at least one action

Category test

An ltintent-filtergt element also lists categories as subelements For example

ltintent-filter gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryBROWSABLE gt ltintent-filtergt

Note that the constants described earlier for actions and categories are not used in the manifest

file The full string values are used instead For instance the

androidintentcategoryBROWSABLE string in the example above corresponds to the

CATEGORY_BROWSABLE constant mentioned earlier in this document Similarly the string

androidintentactionEDIT corresponds to the ACTION_EDIT constant

For an intent to pass the category test every category in the Intent object must match a

category in the filter The filter can list additional categories but it cannot omit any that are in the

intent

In principle therefore an Intent object with no categories should always pass this test

regardless of whats in the filter Thats mostly true However with one exception Android treats

all implicit intents passed to startActivity() as if they contained at least one category

androidintentcategoryDEFAULT (the CATEGORY_DEFAULT constant) Therefore activities

that are willing to receive implicit intents must include androidintentcategoryDEFAULT in

their intent filters (Filters with androidintentactionMAIN and

androidintentcategoryLAUNCHER settings are the exception They mark activities that begin

new tasks and that are represented on the launcher screen They can include

androidintentcategoryDEFAULT in the list of categories but dont need to) See Using intent

matching later for more on these filters)

Data test

Like the action and categories the data specification for an intent filter is contained in a

subelement And as in those cases the subelement can appear multiple times or not at all For

example

ltintent-filter gt ltdata androidmimeType=videompeg androidscheme=http gt ltdata androidmimeType=audiompeg androidscheme=http gt ltintent-filtergt

Each ltdatagt element can specify a URI and a data type (MIME media type) There are

separate attributes mdash scheme host port and path mdash for each part of the URI

schemehostportpath

For example in the following URI

contentcomexampleproject200foldersubfolderetc

the scheme is content the host is comexampleproject the port is 200 and the path is

foldersubfolderetc The host and port together constitute the URI authority if a host is not

specified the port is ignored

Each of these attributes is optional but they are not independent of each other For an authority

to be meaningful a scheme must also be specified For a path to be meaningful both a scheme

and an authority must be specified

When the URI in an Intent object is compared to a URI specification in a filter its compared

only to the parts of the URI actually mentioned in the filter For example if a filter specifies only

a scheme all URIs with that scheme match the filter If a filter specifies a scheme and an

authority but no path all URIs with the same scheme and authority match regardless of their

paths If a filter specifies a scheme an authority and a path only URIs with the same scheme

authority and path match However a path specification in the filter can contain wildcards to

require only a partial match of the path

The type attribute of a ltdatagt element specifies the MIME type of the data Its more common in

filters than a URI Both the Intent object and the filter can use a wildcard for the subtype field

mdash for example text or audio mdash indicating any subtype matches

The data test compares both the URI and the data type in the Intent object to a URI and data

type specified in the filter The rules are as follows

a An Intent object that contains neither a URI nor a data type passes the test only if the filter

likewise does not specify any URIs or data types

b An Intent object that contains a URI but no data type (and a type cannot be inferred from the

URI) passes the test only if its URI matches a URI in the filter and the filter likewise does not

specify a type This will be the case only for URIs like mailto and tel that do not refer to actual

data

c An Intent object that contains a data type but not a URI passes the test only if the filter lists the

same data type and similarly does not specify a URI

d An Intent object that contains both a URI and a data type (or a data type can be inferred from

the URI) passes the data type part of the test only if its type matches a type listed in the filter It

passes the URI part of the test either if its URI matches a URI in the filter or if it has a content

or file URI and the filter does not specify a URI In other words a component is presumed to

support content and file data if its filter lists only a data type

If an intent can pass through the filters of more than one activity or service the user may be asked

which component to activate An exception is raised if no target can be found

Common cases

The last rule shown above for the data test rule (d) reflects the expectation that components are able

to get local data from a file or content provider Therefore their filters can list just a data type and do

not need to explicitly name the content and file schemes This is a typical case A ltdatagt element like

the following for example tells Android that the component can get image data from a content

provider and display it

ltdata androidmimeType=image gt

Since most available data is dispensed by content providers filters that specify a data type but not a

URI are perhaps the most common

Another common configuration is filters with a scheme and a data type For example a ltdatagt

element like the following tells Android that the component can get video data from the network and

display it

ltdata androidscheme=http androidtype=video gt

Consider for example what the browser application does when the user follows a link on a web page

It first tries to display the data (as it could if the link was to an HTML page) If it cant display the data it

puts together an implicit intent with the scheme and data type and tries to start an activity that can do

the job If there are no takers it asks the download manager to download the data That puts it under

the control of a content provider so a potentially larger pool of activities (those with filters that just

name a data type) can respond

Most applications also have a way to start fresh without a reference to any particular data Activities

that can initiate applications have filters with androidintentactionMAIN specified as the action If

they are to be represented in the application launcher they also specify the

androidintentcategoryLAUNCHER category

ltintent-filter gt ltaction androidname=code androidintentactionMAIN gt ltcategory androidname=code androidintentcategoryLAUNCHER gt ltintent-filtergt

Using intent matching

Intents are matched against intent filters not only to discover a target component to activate but also

to discover something about the set of components on the device For example the Android system

populates the application launcher the top-level screen that shows the applications that are available

for the user to launch by finding all the activities with intent filters that specify the

androidintentactionMAIN action and androidintentcategoryLAUNCHER category (as illustrated

in the previous section) It then displays the icons and labels of those activities in the launcher

Similarly it discovers the home screen by looking for the activity with androidintentcategoryHOME

in its filter

Your application can use intent matching is a similar way The PackageManager has a set of query()

methods that return all components that can accept a particular intent and a similar series of

resolve() methods that determine the best component to respond to an intent For example

queryIntentActivities() returns a list of all activities that can perform the intent passed as an argument

and queryIntentServices() returns a similar list of services Neither method activates the components

they just list the ones that can respond Theres a similar method queryBroadcastReceivers() for

broadcast receivers

Note Pad Example

The Note Pad sample application enables users to browse through a list of notes view details about

individual items in the list edit the items and add a new item to the list This section looks at the intent

filters declared in its manifest file (If youre working offline in the SDK you can find all the source files

for this sample application including its manifest file at ltsdkgtsamplesNotePadindexhtml If youre

viewing the documentation online the source files are in the Tutorials and Sample Code section here)

In its manifest file the Note Pad application declares three activities each with at least one intent filter

It also declares a content provider that manages the note data Here is the manifest file in its entirety

ltmanifest xmlnsandroid=httpschemasandroidcomapkresandroid package=comexampleandroidnotepadgt ltapplication androidicon=drawableapp_notes androidlabel=stringapp_name gt ltprovider androidname=NotePadProvider androidauthorities=comgoogleproviderNotePad gt ltactivity androidname=NotesList androidlabel=stringtitle_notes_listgt ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltactivity androidname=NoteEditor androidtheme=androidstyleThemeLight androidlabel=stringtitle_note gt ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltactivitygt

ltactivity androidname=TitleEditor androidlabel=stringtitle_edit_title androidtheme=androidstyleThemeDialoggt ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltapplicationgt ltmanifestgt

The first activity NotesList is distinguished from the other activities by the fact that it operates on a

directory of notes (the note list) rather than on a single note It would generally serve as the initial user

interface into the application It can do three things as described by its three intent filters

1 ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt

This filter declares the main entry point into the Note Pad application The standard MAIN action is an

entry point that does not require any other information in the Intent (no data specification for example)

and the LAUNCHER category says that this entry point should be listed in the application launcher

2 ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

This filter declares the things that the activity can do on a directory of notes It can allow the user to

view or edit the directory (via the VIEW and EDIT actions) or to pick a particular note from the

directory (via the PICK action)

The mimeType attribute of the ltdatagt element specifies the kind of data that these actions operate on

It indicates that the activity can get a Cursor over zero or more items (vndandroidcursordir) from a

content provider that holds Note Pad data (vndgooglenote) The Intent object that launches the

activity would include a content URI specifying the exact data of this type that the activity should open

Note also the DEFAULT category supplied in this filter Its there because the ContextstartActivity()

and ActivitystartActivityForResult() methods treat all intents as if they contained the DEFAULT

category mdash with just two exceptions

o Intents that explicitly name the target activity

o Intents consisting of the MAIN action and LAUNCHER category

Therefore the DEFAULT category is required for all filters mdash except for those with the MAIN action

and LAUNCHER category (Intent filters are not consulted for explicit intents)

3 ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

This filter describes the activitys ability to return a note selected by the user without requiring any

specification of the directory the user should choose from The GET_CONTENT action is similar to the

PICK action In both cases the activity returns the URI for a note selected by the user (In each case

its returned to the activity that called startActivityForResult() to start the NoteList activity) Here

however the caller specifies the type of data desired instead of the directory of data the user will be

picking from

The data type vndandroidcursoritemvndgooglenote indicates the type of data the activity can

return mdash a URI for a single note From the returned URI the caller can get a Cursor for exactly one

item (vndandroidcursoritem) from the content provider that holds Note Pad data (vndgooglenote)

In other words for the PICK action in the previous filter the data type indicates the type of data the

activity could display to the user For the GET_CONTENT filter it indicates the type of data the activity

can return to the caller

Given these capabilities the following intents will resolve to the NotesList activity

action androidintentactionMAIN

Launches the activity with no data specified

action androidintentactionMAIN

category androidintentcategoryLAUNCHER

Launches the activity with no data selected specified This is the actual intent used by the

Launcher to populate its top-level list All activities with filters that match this action and

category are added to the list

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of all the notes under

contentcomgoogleproviderNotePadnotes The user can then browse through the list and

get information about the items in it

action androidintentactionPICK

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of the notes under

contentcomgoogleproviderNotePadnotes The user can then pick a note from the list and

the activity will return the URI for that item back to the activity that started the NoteList activity

action androidintentactionGET_CONTENT

data type vndandroidcursoritemvndgooglenote

Asks the activity to supply a single item of Note Pad data

The second activity NoteEditor shows users a single note entry and allows them to edit it It can do

two things as described by its two intent filters

1 ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The first primary purpose of this activity is to enable the user to interact with a single note ampmdash to

either VIEW the note or EDIT it (The EDIT_NOTE category is a synonym for EDIT) The intent would

contain the URI for data matching the MIME type vndandroidcursoritemvndgooglenote mdash that is

the URI for a single specific note It would typically be a URI that was returned by the PICK or

GET_CONTENT actions of the NoteList activity

As before this filter lists the DEFAULT category so that the activity can be launched by intents that

dont explicitly specify the NoteEditor class

2 ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

The secondary purpose of this activity is to enable the user to create a new note which it will INSERT

into an existing directory of notes The intent would contain the URI for data matching the MIME type

vndandroidcursordirvndgooglenote mdash that is the URI for the directory where the note should be

placed

Given these capabilities the following intents will resolve to the NoteEditor activity

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID (For details on how content

URIs specify individual members of a group see Content Providers)

action androidintentactionEDIT

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID and to let the user edit it If

the user saves the changes the activity updates the data for the note in the content provider

action androidintentactionINSERT

data contentcomgoogleproviderNotePadnotes

Asks the activity to create a new empty note in the notes list at

contentcomgoogleproviderNotePadnotes and allow the user to edit it If the user saves the

note its URI is returned to the caller

The last activity TitleEditor enables the user to edit the title of a note This could be implemented by

directly invoking the activity (by explicitly setting its component name in the Intent) without using an

intent filter But here we take the opportunity to show how to publish alternative operations on existing

data

ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The single intent filter for this activity uses a custom action called

comandroidnotepadactionEDIT_TITLE It must be invoked on a specific note (data type

vndandroidcursoritemvndgooglenote) like the previous VIEW and EDIT actions However here the

activity displays the title contained in the note data not the content of the note itself

In addition to supporting the usual DEFAULT category the title editor also supports two other standard

categories ALTERNATIVE and SELECTED_ALTERNATIVE These categories identify activities that

can be presented to users in a menu of options (much as the LAUNCHER category identifies activities

that should be presented to user in the application launcher) Note that the filter also supplies an

explicit label (via androidlabel=stringresolve_title) to better control what users see when

presented with this activity as an alternative action to the data they are currently viewing (For more

information on these categories and building options menus see the

PackageManagerqueryIntentActivityOptions() and MenuaddIntentOptions() methods)

Given these capabilities the following intent will resolve to the TitleEditor activity

action comandroidnotepadactionEDIT_TITLE

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the title associated with note ID and allow the user to edit the title

Processes and Threads

When an application component starts and the application does not have any other components

running the Android system starts a new Linux process for the application with a single thread of

execution By default all components of the same application run in the same process and thread

(called the main thread) If an application component starts and there already exists a process for

that application (because another component from the application exists) then the component is

started within that process and uses the same thread of execution However you can arrange for

different components in your application to run in separate processes and you can create additional

threads for any process

This document discusses how processes and threads work in an Android application

Processes

By default all components of the same application run in the same process and most applications

should not change this However if you find that you need to control which process a certain

component belongs to you can do so in the manifest file

The manifest entry for each type of component elementmdashltactivitygt ltservicegt ltreceivergt and

ltprovidergtmdashsupports an androidprocess attribute that can specify a process in which that component

should run You can set this attribute so that each component runs in its own process or so that some

components share a process while others do not You can also set androidprocess so that

components of different applications run in the same processmdashprovided that the applications share the

same Linux user ID and are signed with the same certificates

The ltapplicationgt element also supports an androidprocess attribute to set a default value that

applies to all components

Android might 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 thats killed are consequently destroyed A process is started again for those components

when theres again work for them to do

When deciding which processes to kill the Android system weighs their relative importance to the

user For example it more readily shuts down a process hosting activities that are no longer visible on

screen compared to a process hosting visible activities The decision whether to terminate a process

therefore depends on the state of the components running in that process The rules used to decide

which processes to terminate is discussed below

Process lifecycle

The Android system tries to maintain an application process for as long as possible but eventually

needs to remove old processes to reclaim memory for new or more important processes To determine

which processes to keep and which to kill the system places each process into an importance

hierarchy based on the components running in the process and the state of those components

Processes with the lowest importance are eliminated first then those with the next lowest importance

and so on as necessary to recover system resources

There are five levels in the importance hierarchy The following list presents the different types of

processes in order of importance (the first process is most important and is killed last)

1 Foreground process

A process that is required for what the user is currently doing A process is considered to be in the

foreground if any of the following conditions are true

o It hosts an Activity that the user is interacting with (the Activitys onResume() method has been called)

o It hosts a Service thats bound to the activity that the user is interacting with

o It hosts a Service thats running in the foregroundmdashthe service has called startForeground()

o It hosts a Service thats executing one of its lifecycle callbacks (onCreate() onStart() or onDestroy())

o It hosts a BroadcastReceiver thats executing its onReceive() method

Generally only a few foreground processes exist at any given time They are killed only as a last

resortmdashif memory is so low that they cannot all continue to run Generally at that point the device has

reached a memory paging state so killing some foreground processes is required to keep the user

interface responsive

2 Visible process

A process that doesnt have any foreground components but still can affect what the user sees on

screen A process is considered to be visible if either of the following conditions are true

o It hosts an Activity that is not in the foreground but is still visible to the user (its onPause() method has

been called) This might occur for example if the foreground activity started a dialog which allows the

previous activity to be seen behind it

o It hosts a Service thats bound to a visible (or foreground) activity

A visible process is considered extremely important and will not be killed unless doing so is required to

keep all foreground processes running

3 Service process

A process that is running a service that has been started with the startService() method and does not

fall into either of the two higher categories Although service processes are not directly tied to anything

the user sees they are generally doing things that the user cares about (such as playing music in the

background or downloading data on the network) so the system keeps them running unless theres

not enough memory to retain them along with all foreground and visible processes

4 Background process

A process holding an activity thats not currently visible to the user (the activitys onStop() method has

been called) These processes have no direct impact on the user experience and the system can kill

them at any time to reclaim memory for a foreground visible or service process Usually there are

many background processes running so they are kept in an LRU (least recently used) list to ensure

that the process with the activity that was most recently seen by the user is the last to be killed If an

activity implements its lifecycle methods correctly and saves its current state killing its process will not

have a visible effect on the user experience because when the user navigates back to the activity the

activity restores all of its visible state See the Activities document for information about saving and

restoring state

5 Empty process

A process that doesnt hold any active application components The only reason to keep this kind of

process alive is for caching purposes to improve startup time the next time a component needs to run

in it The system often kills these processes in order to balance overall system resources between

process caches and the underlying kernel caches

Android ranks a process at the highest level it can based upon the importance of the components

currently active in the process For example if a process hosts a service and a visible activity the

process is ranked as a visible process not a service process

In addition a processs ranking might be increased because other processes are dependent on itmdasha

process that is serving another process can never be ranked lower than the process it is serving For

example if a content provider in process A is serving a client in process B or if a service in process A

is bound to a component in process B process A is always considered at least as important as

process B

Because a process running a service is ranked higher than a process with background activities an

activity that initiates a long-running operation might do well to start a service for that operation rather

than simply create a worker threadmdashparticularly if the operation will likely outlast the activity For

example an activity thats uploading a picture to a web site should start a service to perform the

upload so that the upload can continue in the background even if the user leaves the activity Using a

service guarantees that the operation will have at least service process priority regardless of what

happens to the activity This is the same reason that broadcast receivers should employ services

rather than simply put time-consuming operations in a thread

Threads

When an application is launched the system creates a thread of execution for the application called

main This thread is very important because it is in charge of dispatching events to the appropriate

user interface widgets including drawing events It is also the thread in which your application interacts

with components from the Android UI toolkit (components from the androidwidget and androidview

packages) As such the main thread is also sometimes called the UI thread

The system does not create a separate thread for each instance of a component All components that

run in the same process are instantiated in the UI thread and system calls to each component are

dispatched from that thread Consequently methods that respond to system callbacks (such as

onKeyDown() to report user actions or a lifecycle callback method) always run in the UI thread of the

process

For instance when the user touches a button on the screen your apps UI thread dispatches the touch

event to the widget which in turn sets its pressed state and posts an invalidate request to the event

queue The UI thread dequeues the request and notifies the widget that it should redraw itself

When your app performs intensive work in response to user interaction this single thread model can

yield poor performance unless you implement your application properly Specifically if everything is

happening in the UI thread performing long operations such as network access or database queries

will block the whole UI When the thread is blocked no events can be dispatched including drawing

events From the users perspective the application appears to hang Even worse if the UI thread is

blocked for more than a few seconds (about 5 seconds currently) the user is presented with the

infamous application not responding (ANR) dialog The user might then decide to quit your

application and uninstall it if they are unhappy

Additionally the Andoid UI toolkit is not thread-safe So you must not manipulate your UI from a

worker threadmdashyou must do all manipulation to your user interface from the UI thread Thus there are

simply two rules to Androids single thread model

1 Do not block the UI thread

2 Do not access the Android UI toolkit from outside the UI thread

Worker threads

Because of the single thread model described above its vital to the responsiveness of your

applications UI that you do not block the UI thread If you have operations to perform that are not

instantaneous you should make sure to do them in separate threads (background or worker

threads)

For example below is some code for a click listener that downloads an image from a separate thread

and displays it in an ImageView

public void onClick(View v) new Thread(new Runnable() public void run() Bitmap b = loadImageFromNetwork(httpexamplecomimagepng) mImageViewsetImageBitmap(b) )start()

At first this seems to work fine because it creates a new thread to handle the network operation

However it violates the second rule of the single-threaded model do not access the Android UI toolkit

from outside the UI threadmdashthis sample modifies the ImageView from the worker thread instead of the

UI thread This can result in undefined and unexpected behavior which can be difficult and time-

consuming to track down

To fix this problem Android offers several ways to access the UI thread from other threads Here is a

list of methods that can help

ActivityrunOnUiThread(Runnable)

Viewpost(Runnable)

ViewpostDelayed(Runnable long)

For example you can fix the above code by using the Viewpost(Runnable) method

public void onClick(View v) new Thread(new Runnable() public void run() final Bitmap bitmap = loadImageFromNetwork(httpexamplecomimagepng) mImageViewpost(new Runnable() public void run() mImageViewsetImageBitmap(bitmap) ) )start()

Now this implementation is thread-safe the network operation is done from a separate thread while

the ImageView is manipulated from the UI thread

However as the complexity of the operation grows this kind of code can get complicated and difficult

to maintain To handle more complex interactions with a worker thread you might consider using a

Handler in your worker thread to process messages delivered from the UI thread Perhaps the best

solution though is to extend the AsyncTask class which simplifies the execution of worker thread

tasks that need to interact with the UI

Using AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface It performs the blocking

operations in a worker thread and then publishes the results on the UI thread without requiring you to

handle threads andor handlers yourself

To use it you must subclass AsyncTask and implement the doInBackground() callback method which

runs in a pool of background threads To update your UI you should implement onPostExecute()

which delivers the result from doInBackground() and runs in the UI thread so you can safely update

your UI You can then run the task by calling execute() from the UI thread

For example you can implement the previous example using AsyncTask this way

public void onClick(View v) new DownloadImageTask()execute(httpexamplecomimagepng) private class DownloadImageTask extends AsyncTaskltString Void Bitmapgt The system calls this to perform work in a worker thread and delivers it the parameters given to AsyncTaskexecute() protected Bitmap doInBackground(String urls) return loadImageFromNetwork(urls[0])

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 32: 03 services

Once a record exists you can add new information to it or modify existing information For example

the next step in the example above would be to add contact information mdash like a phone number or an

IM or e-mail address mdash to the new entry

The best way to add to a record in the Contacts database is to append the name of the table where the

new data goes to the URI for the record then use the amended URI to add the new data values Each

Contacts table exposes a name for this purpose as a CONTENT_DIRECTORY constant The following

code continues the previous example by adding a phone number and e-mail address for the record

just created

Uri phoneUri = null Uri emailUri = null Add a phone number for Abraham Lincoln Begin with the URI for the new record just returned by insert() it ends with the _ID of the new record so we dont have to add the ID ourselves Then append the designation for the phone table to this URI and use the resulting URI to insert the phone number phoneUri = UriwithAppendedPath(uri PeoplePhonesCONTENT_DIRECTORY) valuesclear() valuesput(PeoplePhonesTYPE PeoplePhonesTYPE_MOBILE) valuesput(PeoplePhonesNUMBER 1233214567) getContentResolver()insert(phoneUri values) Now add an email address in the same way emailUri = UriwithAppendedPath(uri PeopleContactMethodsCONTENT_DIRECTORY) valuesclear() ContactMethodsKIND is used to distinguish different kinds of contact methods such as email IM etc valuesput(PeopleContactMethodsKIND ContactsKIND_EMAIL) valuesput(PeopleContactMethodsDATA testexamplecom) valuesput(PeopleContactMethodsTYPE PeopleContactMethodsTYPE_HOME) getContentResolver()insert(emailUri values)

You can place small amounts of binary data into a table by calling the version of ContentValuesput()

that takes a byte array That would work for a small icon-like image or a short audio clip for example

However if you have a large amount of binary data to add such as a photograph or a complete song

put a content URI for the data in the table and call ContentResolveropenOutputStream() with the files

URI (That causes the content provider to store the data in a file and record the file path in a hidden

field of the record)

In this regard the MediaStore content provider the main provider that dispenses image audio and

video data employs a special convention The same URI that is used with query() or managedQuery()

to get meta-information about the binary data (such as the caption of a photograph or the date it was

taken) is used with openInputStream() to get the data itself Similarly the same URI that is used with

insert() to put meta-information into a MediaStore record is used with openOutputStream() to place the

binary data there The following code snippet illustrates this convention

import androidproviderMediaStoreImagesMedia import androidcontentContentValues import javaioOutputStream Save the name and description of an image in a ContentValues map ContentValues values = new ContentValues(3) valuesput(MediaDISPLAY_NAME road_trip_1) valuesput(MediaDESCRIPTION Day 1 trip to Los Angeles) valuesput(MediaMIME_TYPE imagejpeg) Add a new record without the bitmap but with the values just set insert() returns the URI of the new record Uri uri = getContentResolver()insert(MediaEXTERNAL_CONTENT_URI values) Now get a handle to the file for that record and save the data into it Here sourceBitmap is a Bitmap object representing the file to save to the database try OutputStream outStream = getContentResolver()openOutputStream(uri) sourceBitmapcompress(BitmapCompressFormatJPEG 50 outStream) outStreamclose() catch (Exception e) Loge(TAG exception while writing image e)

Batch updating records

To batch update a group of records (for example to change NY to New York in all fields) call the

ContentResolverupdate() method with the columns and values to change

Deleting a record

To delete a single record call ContentResolverdelete() with the URI of a specific row

To delete multiple rows call ContentResolverdelete() with the URI of the type of record to delete (for

example androidproviderContactsPeopleCONTENT_URI) and an SQL WHERE clause defining

which rows to delete (Caution Be sure to include a valid WHERE clause if youre deleting a general

type or you risk deleting more records than you intended)

Creating a Content Provider

To create a content provider you must

Set up a system for storing the data Most content providers store their data using Androids file

storage methods or SQLite databases but you can store your data any way you want Android

provides the SQLiteOpenHelper class to help you create a database and SQLiteDatabase to manage

it

Extend the ContentProvider class to provide access to the data

Declare the content provider in the manifest file for your application (AndroidManifestxml)

The following sections have notes on the last two of these tasks

Extending the ContentProvider class

You define a ContentProvider subclass to expose your data to others using the conventions expected

by ContentResolver and Cursor objects Principally this means implementing six abstract methods

declared in the ContentProvider class

query()

insert()

update()

delete()

getType()

onCreate()

The query() method must return a Cursor object that can iterate over the requested data Cursor itself

is an interface but Android provides some ready-made Cursor objects that you can use For example

SQLiteCursor can iterate over data stored in an SQLite database You get the Cursor object by calling

any of the SQLiteDatabase classs query() methods There are other Cursor implementations mdash such

as MatrixCursor mdash for data not stored in a database

Because these ContentProvider methods can be called from various ContentResolver objects in

different processes and threads they must be implemented in a thread-safe manner

As a courtesy you might also want to call ContentResolvernotifyChange() to notify listeners when

there are modifications to the data

Beyond defining the subclass itself there are other steps you should take to simplify the work of clients

and make the class more accessible

Define a public static final Uri named CONTENT_URI This is the string that represents the full content

URI that your content provider handles You must define a unique string for this value The best

solution is to use the fully-qualified class name of the content provider (made lowercase) So for

example the URI for a TransportationProvider class could be defined as follows

public static final Uri CONTENT_URI = Uriparse(contentcomexamplecodelabtransportationprovider)

If the provider has subtables also define CONTENT_URI constants for each of the subtables These

URIs should all have the same authority (since that identifies the content provider) and be

distinguished only by their paths For example

contentcomexamplecodelabtransportationprovidertrain

contentcomexamplecodelabtransportationproviderairdomestic

contentcomexamplecodelabtransportationproviderairinternational

For an overview of content URIs see the Content URI Summary at the end of this document

Define the column names that the content provider will return to clients If you are using an underlying

database these column names are typically identical to the SQL database column names they

represent Also define public static String constants that clients can use to specify the columns in

queries and other instructions

Be sure to include an integer column named _id (with the constant _ID) for the IDs of the records

You should have this field whether or not you have another field (such as a URL) that is also unique

among all records If youre using the SQLite database the _ID field should be the following type

INTEGER PRIMARY KEY AUTOINCREMENT

The AUTOINCREMENT descriptor is optional But without it SQLite increments an ID counter field to

the next number above the largest existing number in the column If you delete the last row the next

row added will have the same ID as the deleted row AUTOINCREMENT avoids this by having SQLite

increment to the next largest value whether deleted or not

Carefully document the data type of each column Clients need this information to read the data

If you are handling a new data type you must define a new MIME type to return in your

implementation of ContentProvidergetType() The type depends in part on whether or not the content

URI submitted to getType() limits the request to a specific record Theres one form of the MIME type

for a single record and another for multiple records Use the Uri methods to help determine what is

being requested Here is the general format for each type

o For a single record vndandroidcursoritemvndyourcompanynamecontenttype

For example a request for train record 122 like this URI

contentcomexampletransportationprovidertrains122

might return this MIME type

vndandroidcursoritemvndexamplerail

o For multiple records vndandroidcursordirvndyourcompanynamecontenttype

For example a request for all train records like the following URI

contentcomexampletransportationprovidertrains

might return this MIME type

vndandroidcursordirvndexamplerail

If you are exposing byte data thats too big to put in the table itself mdash such as a large bitmap file mdash the

field that exposes the data to clients should actually contain a content URI string This is the field that

gives clients access to the data file The record should also have another field named _data that lists

the exact file path on the device for that file This field is not intended to be read by the client but by

the ContentResolver The client will call ContentResolveropenInputStream() on the user-facing field

holding the URI for the item The ContentResolver will request the _data field for that record and

because it has higher permissions than a client it should be able to access that file directly and return

a read wrapper for the file to the client

For an example of a private content provider implementation see the NodePadProvider class in the

Notepad sample application that ships with the SDK

Declaring the content provider

To let the Android system know about the content provider youve developed declare it with a

ltprovidergt element in the applications AndroidManifestxml file Content providers that are not

declared in the manifest are not visible to the Android system

The name attribute is the fully qualified name of the ContentProvider subclass The authorities attribute

is the authority part of the content URI that identifies the provider For example if the ContentProvider

subclass is AutoInfoProvider the ltprovidergt element might look like this

ltprovider androidname=comexampleautosAutoInfoProvider androidauthorities=comexampleautosautoinfoprovider gt ltprovidergt

Note that the authorities attribute omits the path part of a content URI For example if

AutoInfoProvider controlled subtables for different types of autos or different manufacturers

contentcomexampleautosautoinfoproviderhonda

contentcomexampleautosautoinfoprovidergmcompact

contentcomexampleautosautoinfoprovidergmsuv

those paths would not be declared in the manifest The authority is what identifies the provider not the

path your provider can interpret the path part of the URI in any way you choose

Other ltprovidergt attributes can set permissions to read and write data provide for an icon and text

that can be displayed to users enable and disable the provider and so on Set the multiprocess

attribute to true if data does not need to be synchronized between multiple running versions of the

content provider This permits an instance of the provider to be created in each client process

eliminating the need to perform IPC

Content URI Summary

Here is a recap of the important parts of a content URI

A Standard prefix indicating that the data is controlled by a content provider Its never modified

B The authority part of the URI it identifies the content provider For third-party applications this should

be a fully-qualified class name (reduced to lowercase) to ensure uniqueness The authority is declared

in the ltprovidergt elements authorities attribute

ltprovider androidname=TransportationProvider androidauthorities=comexampletransportationprovider gt

C The path that the content provider uses to determine what kind of data is being requested This can be

zero or more segments long If the content provider exposes only one type of data (only trains for

example) it can be absent If the provider exposes several types including subtypes it can be several

segments long mdash for example landbus landtrain seaship and seasubmarine to give four

possibilities

D The ID of the specific record being requested if any This is the _ID value of the requested record If

the request is not limited to a single record this segment and the trailing slash are omitted

contentcomexampletransportationprovidertrains

Intent and intent filters

Three of the core components of an application mdash activities services and broadcast receivers mdash 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 mdash 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 ContextstartActivity() or ActivitystartActivityForResult() to launch an

activity or get an existing activity to do something new (It can also be passed to ActivitysetResult() to

return information to the activity that called startActivityForResult())

An Intent object is passed to ContextstartService() to initiate a service or deliver new instructions to an

ongoing service Similarly an intent can be passed to ContextbindService() to establish a connection

between the calling component and a target service It can optionally initiate the service if its not

already running

Intent objects passed to any of the broadcast methods (such as ContextsendBroadcast()

ContextsendOrderedBroadcast() or ContextsendStickyBroadcast()) 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 mdash how it resolves which component should receive an intent message For

intents that dont explicitly name a target component this process involves testing the Intent object

against intent filters associated with potential targets

Intent Objects

An Intent object is a bundle of information It contains information of interest to the component that

receives the intent (such as the action to be taken and the data to act on) plus information of interest to

the Android system (such as the category of component that should handle the intent and instructions

on how to launch a target activity) Principally it can contain the following

Component name

The name of the component that should handle the intent This field is a ComponentName

object mdash a combination of the fully qualified class name of the target component (for example

comexampleprojectappFreneticActivity) and the package name set in the manifest file of the

application where the component resides (for example comexampleproject) The package

part of the component name and the package name set in the manifest do not necessarily have

to match

The component name is optional If it is set the Intent object is delivered to an instance of the

designated class If it is not set Android uses other information in the Intent object to locate a

suitable target mdash see Intent Resolution later in this document

The component name is set by setComponent() setClass() or setClassName() and read by

getComponent()

Action

A string naming the action to be performed mdash or in the case of broadcast intents the action

that took place and is being reported The Intent class defines a number of action constants

including these

Constant Target

component

Action

ACTION_CALL activity Initiate a phone call

ACTION_EDIT activity Display data for the user to edit

ACTION_MAIN activity Start up as the initial activity of a task

with no data input and no returned

output

ACTION_SYNC activity Synchronize data on a server with

data on the mobile device

ACTION_BATTERY_LOW broadcast

receiver

A warning that the battery is low

ACTION_HEADSET_PLUG broadcast

receiver

A headset has been plugged into the

device or unplugged from it

ACTION_SCREEN_ON broadcast

receiver

The screen has been turned on

ACTION_TIMEZONE_CHANGED broadcast

receiver

The setting for the time zone has

changed

See the Intent class description for a list of pre-defined constants for generic actions Other

actions are defined elsewhere in the Android API You can also define your own action strings

for activating the components in your application Those you invent should include the

application package as a prefix mdash for example comexampleprojectSHOW_COLOR

The action largely determines how the rest of the intent is structured mdash particularly the data and

extras fields mdash much as a method name determines a set of arguments and a return value For

this reason its a good idea to use action names that are as specific as possible and to couple

them tightly to the other fields of the intent In other words instead of defining an action in

isolation define an entire protocol for the Intent objects your components can handle

The action in an Intent object is set by the setAction() method and read by getAction()

Data

The URI of the data to be acted on and the MIME type of that data Different actions are paired

with different kinds of data specifications For example if the action field is ACTION_EDIT the

data field would contain the URI of the document to be displayed for editing If the action is

ACTION_CALL the data field would be a tel URI with the number to call Similarly if the action

is ACTION_VIEW and the data field is an http URI the receiving activity would be called upon

to download and display whatever data the URI refers to

When matching an intent to a component that is capable of handling the data its often

important to know the type of data (its MIME type) in addition to its URI For example a

component able to display image data should not be called upon to play an audio file

In many cases the data type can be inferred from the URI mdash particularly content URIs which

indicate that the data is located on the device and controlled by a content provider (see the

separate discussion on content providers) But the type can also be explicitly set in the Intent

object The setData() method specifies data only as a URI setType() specifies it only as a

MIME type and setDataAndType() specifies it as both a URI and a MIME type The URI is read

by getData() and the type by getType()

Category

A string containing additional information about the kind of component that should handle the

intent Any number of category descriptions can be placed in an Intent object As it does for

actions the Intent class defines several category constants including these

Constant Meaning

CATEGORY_BROWSABLE The target activity can be safely invoked by the browser to

display data referenced by a link mdash for example an image or

an e-mail message

CATEGORY_GADGET The activity can be embedded inside of another activity that

hosts gadgets

CATEGORY_HOME The activity displays the home screen the first screen the

user sees when the device is turned on or when the HOME

key is pressed

CATEGORY_LAUNCHER The activity can be the initial activity of a task and is listed in

the top-level application launcher

CATEGORY_PREFERENCE The target activity is a preference panel

See the Intent class description for the full list of categories

The addCategory() method places a category in an Intent object removeCategory() deletes a

category previously added and getCategories() gets the set of all categories currently in the

object

Extras

Key-value pairs for additional information that should be delivered to the component handling

the intent Just as some actions are paired with particular kinds of data URIs some are paired

with particular extras For example an ACTION_TIMEZONE_CHANGED intent has a time-

zone extra that identifies the new time zone and ACTION_HEADSET_PLUG has a state

extra indicating whether the headset is now plugged in or unplugged as well as a name extra

for the type of headset If you were to invent a SHOW_COLOR action the color value would be

set in an extra key-value pair

The Intent object has a series of put() methods for inserting various types of extra data and a

similar set of get() methods for reading the data These methods parallel those for Bundle

objects In fact the extras can be installed and read as a Bundle using the putExtras() and

getExtras() methods

Flags

Flags of various sorts Many instruct the Android system how to launch an activity (for example

which task the activity should belong to) and how to treat it after its launched (for example

whether it belongs in the list of recent activities) All these flags are defined in the Intent class

The Android system and the applications that come with the platform employ Intent objects both to

send out system-originated broadcasts and to activate system-defined components To see how to

structure an intent to activate a system component consult the list of intents in the reference

Intent Resolution

Intents can be divided into two groups

Explicit intents designate the target component by its name (the component name field mentioned

earlier has a value set) Since component names would generally not be known to developers of other

applications explicit intents are typically used for application-internal messages mdash such as an activity

starting a subordinate service or launching a sister activity

Implicit intents do not name a target (the field for the component name is blank) Implicit intents are

often used to activate components in other applications

Android delivers an explicit intent to an instance of the designated target class Nothing in the Intent

object other than the component name matters for determining which component should get the intent

A different strategy is needed for implicit intents In the absence of a designated target the Android

system must find the best component (or components) to handle the intent mdash a single activity or

service to perform the requested action or the set of broadcast receivers to respond to the broadcast

announcement It does so by comparing the contents of the Intent object to intent filters structures

associated with components that can potentially receive intents Filters advertise the capabilities of a

component and delimit the intents it can handle They open the component to the possibility of

receiving implicit intents of the advertised type If a component does not have any intent filters it can

receive only explicit intents A component with filters can receive both explicit and implicit intents

Only three aspects of an Intent object are consulted when the object is tested against an intent filter

action

data (both URI and data type)

category

The extras and flags play no part in resolving which component receives an intent

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 mdash but only unwanted implicit intents (those that dont 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

components 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 mdash 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 Pads filters are described in the Note Pad Example

section later)

Filters and security

An intent filter cannot be relied on for security While it opens a component to receiving only certain

kinds of implicit intents it does nothing to prevent explicit intents from targeting the component Even

though a filter restricts the intents a component will be asked to handle to certain actions and data

sources someone could always put together an explicit intent with a different action and data source

and name the component as the target

An intent filter is an instance of the IntentFilter class However since the Android system must know

about the capabilities of a component before it can launch that component intent filters are generally

not set up in Java code but in the applications manifest file (AndroidManifestxml) as ltintent-filtergt

elements (The one exception would be filters for broadcast receivers that are registered dynamically

by calling ContextregisterReceiver() they are directly created as IntentFilter objects)

A filter has fields that parallel the action data and category fields of an Intent object An implicit intent

is tested against the filter in all three areas To be delivered to the component that owns the filter it

must pass all three tests If it fails even one of them the Android system wont deliver it to the

component mdash at least not on the basis of that filter However since a component can have multiple

intent filters an intent that does not pass through one of a components filters might make it through on

another

Each of the three tests is described in detail below

Action test

An ltintent-filtergt element in the manifest file lists actions as ltactiongt subelements For

example

ltintent-filter gt ltaction androidname=comexampleprojectSHOW_CURRENT gt ltaction androidname=comexampleprojectSHOW_RECENT gt ltaction androidname=comexampleprojectSHOW_PENDING gt ltintent-filtergt

As the example shows while an Intent object names just a single action a filter may list more

than one The list cannot be empty a filter must contain at least one ltactiongt element or it will

block all intents

To pass this test the action specified in the Intent object must match one of the actions listed in

the filter If the object or the filter does not specify an action the results are as follows

If the filter fails to list any actions there is nothing for an intent to match so all intents fail the

test No intents can get through the filter

On the other hand an Intent object that doesnt specify an action automatically passes the test

mdash as long as the filter contains at least one action

Category test

An ltintent-filtergt element also lists categories as subelements For example

ltintent-filter gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryBROWSABLE gt ltintent-filtergt

Note that the constants described earlier for actions and categories are not used in the manifest

file The full string values are used instead For instance the

androidintentcategoryBROWSABLE string in the example above corresponds to the

CATEGORY_BROWSABLE constant mentioned earlier in this document Similarly the string

androidintentactionEDIT corresponds to the ACTION_EDIT constant

For an intent to pass the category test every category in the Intent object must match a

category in the filter The filter can list additional categories but it cannot omit any that are in the

intent

In principle therefore an Intent object with no categories should always pass this test

regardless of whats in the filter Thats mostly true However with one exception Android treats

all implicit intents passed to startActivity() as if they contained at least one category

androidintentcategoryDEFAULT (the CATEGORY_DEFAULT constant) Therefore activities

that are willing to receive implicit intents must include androidintentcategoryDEFAULT in

their intent filters (Filters with androidintentactionMAIN and

androidintentcategoryLAUNCHER settings are the exception They mark activities that begin

new tasks and that are represented on the launcher screen They can include

androidintentcategoryDEFAULT in the list of categories but dont need to) See Using intent

matching later for more on these filters)

Data test

Like the action and categories the data specification for an intent filter is contained in a

subelement And as in those cases the subelement can appear multiple times or not at all For

example

ltintent-filter gt ltdata androidmimeType=videompeg androidscheme=http gt ltdata androidmimeType=audiompeg androidscheme=http gt ltintent-filtergt

Each ltdatagt element can specify a URI and a data type (MIME media type) There are

separate attributes mdash scheme host port and path mdash for each part of the URI

schemehostportpath

For example in the following URI

contentcomexampleproject200foldersubfolderetc

the scheme is content the host is comexampleproject the port is 200 and the path is

foldersubfolderetc The host and port together constitute the URI authority if a host is not

specified the port is ignored

Each of these attributes is optional but they are not independent of each other For an authority

to be meaningful a scheme must also be specified For a path to be meaningful both a scheme

and an authority must be specified

When the URI in an Intent object is compared to a URI specification in a filter its compared

only to the parts of the URI actually mentioned in the filter For example if a filter specifies only

a scheme all URIs with that scheme match the filter If a filter specifies a scheme and an

authority but no path all URIs with the same scheme and authority match regardless of their

paths If a filter specifies a scheme an authority and a path only URIs with the same scheme

authority and path match However a path specification in the filter can contain wildcards to

require only a partial match of the path

The type attribute of a ltdatagt element specifies the MIME type of the data Its more common in

filters than a URI Both the Intent object and the filter can use a wildcard for the subtype field

mdash for example text or audio mdash indicating any subtype matches

The data test compares both the URI and the data type in the Intent object to a URI and data

type specified in the filter The rules are as follows

a An Intent object that contains neither a URI nor a data type passes the test only if the filter

likewise does not specify any URIs or data types

b An Intent object that contains a URI but no data type (and a type cannot be inferred from the

URI) passes the test only if its URI matches a URI in the filter and the filter likewise does not

specify a type This will be the case only for URIs like mailto and tel that do not refer to actual

data

c An Intent object that contains a data type but not a URI passes the test only if the filter lists the

same data type and similarly does not specify a URI

d An Intent object that contains both a URI and a data type (or a data type can be inferred from

the URI) passes the data type part of the test only if its type matches a type listed in the filter It

passes the URI part of the test either if its URI matches a URI in the filter or if it has a content

or file URI and the filter does not specify a URI In other words a component is presumed to

support content and file data if its filter lists only a data type

If an intent can pass through the filters of more than one activity or service the user may be asked

which component to activate An exception is raised if no target can be found

Common cases

The last rule shown above for the data test rule (d) reflects the expectation that components are able

to get local data from a file or content provider Therefore their filters can list just a data type and do

not need to explicitly name the content and file schemes This is a typical case A ltdatagt element like

the following for example tells Android that the component can get image data from a content

provider and display it

ltdata androidmimeType=image gt

Since most available data is dispensed by content providers filters that specify a data type but not a

URI are perhaps the most common

Another common configuration is filters with a scheme and a data type For example a ltdatagt

element like the following tells Android that the component can get video data from the network and

display it

ltdata androidscheme=http androidtype=video gt

Consider for example what the browser application does when the user follows a link on a web page

It first tries to display the data (as it could if the link was to an HTML page) If it cant display the data it

puts together an implicit intent with the scheme and data type and tries to start an activity that can do

the job If there are no takers it asks the download manager to download the data That puts it under

the control of a content provider so a potentially larger pool of activities (those with filters that just

name a data type) can respond

Most applications also have a way to start fresh without a reference to any particular data Activities

that can initiate applications have filters with androidintentactionMAIN specified as the action If

they are to be represented in the application launcher they also specify the

androidintentcategoryLAUNCHER category

ltintent-filter gt ltaction androidname=code androidintentactionMAIN gt ltcategory androidname=code androidintentcategoryLAUNCHER gt ltintent-filtergt

Using intent matching

Intents are matched against intent filters not only to discover a target component to activate but also

to discover something about the set of components on the device For example the Android system

populates the application launcher the top-level screen that shows the applications that are available

for the user to launch by finding all the activities with intent filters that specify the

androidintentactionMAIN action and androidintentcategoryLAUNCHER category (as illustrated

in the previous section) It then displays the icons and labels of those activities in the launcher

Similarly it discovers the home screen by looking for the activity with androidintentcategoryHOME

in its filter

Your application can use intent matching is a similar way The PackageManager has a set of query()

methods that return all components that can accept a particular intent and a similar series of

resolve() methods that determine the best component to respond to an intent For example

queryIntentActivities() returns a list of all activities that can perform the intent passed as an argument

and queryIntentServices() returns a similar list of services Neither method activates the components

they just list the ones that can respond Theres a similar method queryBroadcastReceivers() for

broadcast receivers

Note Pad Example

The Note Pad sample application enables users to browse through a list of notes view details about

individual items in the list edit the items and add a new item to the list This section looks at the intent

filters declared in its manifest file (If youre working offline in the SDK you can find all the source files

for this sample application including its manifest file at ltsdkgtsamplesNotePadindexhtml If youre

viewing the documentation online the source files are in the Tutorials and Sample Code section here)

In its manifest file the Note Pad application declares three activities each with at least one intent filter

It also declares a content provider that manages the note data Here is the manifest file in its entirety

ltmanifest xmlnsandroid=httpschemasandroidcomapkresandroid package=comexampleandroidnotepadgt ltapplication androidicon=drawableapp_notes androidlabel=stringapp_name gt ltprovider androidname=NotePadProvider androidauthorities=comgoogleproviderNotePad gt ltactivity androidname=NotesList androidlabel=stringtitle_notes_listgt ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltactivity androidname=NoteEditor androidtheme=androidstyleThemeLight androidlabel=stringtitle_note gt ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltactivitygt

ltactivity androidname=TitleEditor androidlabel=stringtitle_edit_title androidtheme=androidstyleThemeDialoggt ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltapplicationgt ltmanifestgt

The first activity NotesList is distinguished from the other activities by the fact that it operates on a

directory of notes (the note list) rather than on a single note It would generally serve as the initial user

interface into the application It can do three things as described by its three intent filters

1 ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt

This filter declares the main entry point into the Note Pad application The standard MAIN action is an

entry point that does not require any other information in the Intent (no data specification for example)

and the LAUNCHER category says that this entry point should be listed in the application launcher

2 ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

This filter declares the things that the activity can do on a directory of notes It can allow the user to

view or edit the directory (via the VIEW and EDIT actions) or to pick a particular note from the

directory (via the PICK action)

The mimeType attribute of the ltdatagt element specifies the kind of data that these actions operate on

It indicates that the activity can get a Cursor over zero or more items (vndandroidcursordir) from a

content provider that holds Note Pad data (vndgooglenote) The Intent object that launches the

activity would include a content URI specifying the exact data of this type that the activity should open

Note also the DEFAULT category supplied in this filter Its there because the ContextstartActivity()

and ActivitystartActivityForResult() methods treat all intents as if they contained the DEFAULT

category mdash with just two exceptions

o Intents that explicitly name the target activity

o Intents consisting of the MAIN action and LAUNCHER category

Therefore the DEFAULT category is required for all filters mdash except for those with the MAIN action

and LAUNCHER category (Intent filters are not consulted for explicit intents)

3 ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

This filter describes the activitys ability to return a note selected by the user without requiring any

specification of the directory the user should choose from The GET_CONTENT action is similar to the

PICK action In both cases the activity returns the URI for a note selected by the user (In each case

its returned to the activity that called startActivityForResult() to start the NoteList activity) Here

however the caller specifies the type of data desired instead of the directory of data the user will be

picking from

The data type vndandroidcursoritemvndgooglenote indicates the type of data the activity can

return mdash a URI for a single note From the returned URI the caller can get a Cursor for exactly one

item (vndandroidcursoritem) from the content provider that holds Note Pad data (vndgooglenote)

In other words for the PICK action in the previous filter the data type indicates the type of data the

activity could display to the user For the GET_CONTENT filter it indicates the type of data the activity

can return to the caller

Given these capabilities the following intents will resolve to the NotesList activity

action androidintentactionMAIN

Launches the activity with no data specified

action androidintentactionMAIN

category androidintentcategoryLAUNCHER

Launches the activity with no data selected specified This is the actual intent used by the

Launcher to populate its top-level list All activities with filters that match this action and

category are added to the list

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of all the notes under

contentcomgoogleproviderNotePadnotes The user can then browse through the list and

get information about the items in it

action androidintentactionPICK

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of the notes under

contentcomgoogleproviderNotePadnotes The user can then pick a note from the list and

the activity will return the URI for that item back to the activity that started the NoteList activity

action androidintentactionGET_CONTENT

data type vndandroidcursoritemvndgooglenote

Asks the activity to supply a single item of Note Pad data

The second activity NoteEditor shows users a single note entry and allows them to edit it It can do

two things as described by its two intent filters

1 ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The first primary purpose of this activity is to enable the user to interact with a single note ampmdash to

either VIEW the note or EDIT it (The EDIT_NOTE category is a synonym for EDIT) The intent would

contain the URI for data matching the MIME type vndandroidcursoritemvndgooglenote mdash that is

the URI for a single specific note It would typically be a URI that was returned by the PICK or

GET_CONTENT actions of the NoteList activity

As before this filter lists the DEFAULT category so that the activity can be launched by intents that

dont explicitly specify the NoteEditor class

2 ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

The secondary purpose of this activity is to enable the user to create a new note which it will INSERT

into an existing directory of notes The intent would contain the URI for data matching the MIME type

vndandroidcursordirvndgooglenote mdash that is the URI for the directory where the note should be

placed

Given these capabilities the following intents will resolve to the NoteEditor activity

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID (For details on how content

URIs specify individual members of a group see Content Providers)

action androidintentactionEDIT

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID and to let the user edit it If

the user saves the changes the activity updates the data for the note in the content provider

action androidintentactionINSERT

data contentcomgoogleproviderNotePadnotes

Asks the activity to create a new empty note in the notes list at

contentcomgoogleproviderNotePadnotes and allow the user to edit it If the user saves the

note its URI is returned to the caller

The last activity TitleEditor enables the user to edit the title of a note This could be implemented by

directly invoking the activity (by explicitly setting its component name in the Intent) without using an

intent filter But here we take the opportunity to show how to publish alternative operations on existing

data

ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The single intent filter for this activity uses a custom action called

comandroidnotepadactionEDIT_TITLE It must be invoked on a specific note (data type

vndandroidcursoritemvndgooglenote) like the previous VIEW and EDIT actions However here the

activity displays the title contained in the note data not the content of the note itself

In addition to supporting the usual DEFAULT category the title editor also supports two other standard

categories ALTERNATIVE and SELECTED_ALTERNATIVE These categories identify activities that

can be presented to users in a menu of options (much as the LAUNCHER category identifies activities

that should be presented to user in the application launcher) Note that the filter also supplies an

explicit label (via androidlabel=stringresolve_title) to better control what users see when

presented with this activity as an alternative action to the data they are currently viewing (For more

information on these categories and building options menus see the

PackageManagerqueryIntentActivityOptions() and MenuaddIntentOptions() methods)

Given these capabilities the following intent will resolve to the TitleEditor activity

action comandroidnotepadactionEDIT_TITLE

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the title associated with note ID and allow the user to edit the title

Processes and Threads

When an application component starts and the application does not have any other components

running the Android system starts a new Linux process for the application with a single thread of

execution By default all components of the same application run in the same process and thread

(called the main thread) If an application component starts and there already exists a process for

that application (because another component from the application exists) then the component is

started within that process and uses the same thread of execution However you can arrange for

different components in your application to run in separate processes and you can create additional

threads for any process

This document discusses how processes and threads work in an Android application

Processes

By default all components of the same application run in the same process and most applications

should not change this However if you find that you need to control which process a certain

component belongs to you can do so in the manifest file

The manifest entry for each type of component elementmdashltactivitygt ltservicegt ltreceivergt and

ltprovidergtmdashsupports an androidprocess attribute that can specify a process in which that component

should run You can set this attribute so that each component runs in its own process or so that some

components share a process while others do not You can also set androidprocess so that

components of different applications run in the same processmdashprovided that the applications share the

same Linux user ID and are signed with the same certificates

The ltapplicationgt element also supports an androidprocess attribute to set a default value that

applies to all components

Android might 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 thats killed are consequently destroyed A process is started again for those components

when theres again work for them to do

When deciding which processes to kill the Android system weighs their relative importance to the

user For example it more readily shuts down a process hosting activities that are no longer visible on

screen compared to a process hosting visible activities The decision whether to terminate a process

therefore depends on the state of the components running in that process The rules used to decide

which processes to terminate is discussed below

Process lifecycle

The Android system tries to maintain an application process for as long as possible but eventually

needs to remove old processes to reclaim memory for new or more important processes To determine

which processes to keep and which to kill the system places each process into an importance

hierarchy based on the components running in the process and the state of those components

Processes with the lowest importance are eliminated first then those with the next lowest importance

and so on as necessary to recover system resources

There are five levels in the importance hierarchy The following list presents the different types of

processes in order of importance (the first process is most important and is killed last)

1 Foreground process

A process that is required for what the user is currently doing A process is considered to be in the

foreground if any of the following conditions are true

o It hosts an Activity that the user is interacting with (the Activitys onResume() method has been called)

o It hosts a Service thats bound to the activity that the user is interacting with

o It hosts a Service thats running in the foregroundmdashthe service has called startForeground()

o It hosts a Service thats executing one of its lifecycle callbacks (onCreate() onStart() or onDestroy())

o It hosts a BroadcastReceiver thats executing its onReceive() method

Generally only a few foreground processes exist at any given time They are killed only as a last

resortmdashif memory is so low that they cannot all continue to run Generally at that point the device has

reached a memory paging state so killing some foreground processes is required to keep the user

interface responsive

2 Visible process

A process that doesnt have any foreground components but still can affect what the user sees on

screen A process is considered to be visible if either of the following conditions are true

o It hosts an Activity that is not in the foreground but is still visible to the user (its onPause() method has

been called) This might occur for example if the foreground activity started a dialog which allows the

previous activity to be seen behind it

o It hosts a Service thats bound to a visible (or foreground) activity

A visible process is considered extremely important and will not be killed unless doing so is required to

keep all foreground processes running

3 Service process

A process that is running a service that has been started with the startService() method and does not

fall into either of the two higher categories Although service processes are not directly tied to anything

the user sees they are generally doing things that the user cares about (such as playing music in the

background or downloading data on the network) so the system keeps them running unless theres

not enough memory to retain them along with all foreground and visible processes

4 Background process

A process holding an activity thats not currently visible to the user (the activitys onStop() method has

been called) These processes have no direct impact on the user experience and the system can kill

them at any time to reclaim memory for a foreground visible or service process Usually there are

many background processes running so they are kept in an LRU (least recently used) list to ensure

that the process with the activity that was most recently seen by the user is the last to be killed If an

activity implements its lifecycle methods correctly and saves its current state killing its process will not

have a visible effect on the user experience because when the user navigates back to the activity the

activity restores all of its visible state See the Activities document for information about saving and

restoring state

5 Empty process

A process that doesnt hold any active application components The only reason to keep this kind of

process alive is for caching purposes to improve startup time the next time a component needs to run

in it The system often kills these processes in order to balance overall system resources between

process caches and the underlying kernel caches

Android ranks a process at the highest level it can based upon the importance of the components

currently active in the process For example if a process hosts a service and a visible activity the

process is ranked as a visible process not a service process

In addition a processs ranking might be increased because other processes are dependent on itmdasha

process that is serving another process can never be ranked lower than the process it is serving For

example if a content provider in process A is serving a client in process B or if a service in process A

is bound to a component in process B process A is always considered at least as important as

process B

Because a process running a service is ranked higher than a process with background activities an

activity that initiates a long-running operation might do well to start a service for that operation rather

than simply create a worker threadmdashparticularly if the operation will likely outlast the activity For

example an activity thats uploading a picture to a web site should start a service to perform the

upload so that the upload can continue in the background even if the user leaves the activity Using a

service guarantees that the operation will have at least service process priority regardless of what

happens to the activity This is the same reason that broadcast receivers should employ services

rather than simply put time-consuming operations in a thread

Threads

When an application is launched the system creates a thread of execution for the application called

main This thread is very important because it is in charge of dispatching events to the appropriate

user interface widgets including drawing events It is also the thread in which your application interacts

with components from the Android UI toolkit (components from the androidwidget and androidview

packages) As such the main thread is also sometimes called the UI thread

The system does not create a separate thread for each instance of a component All components that

run in the same process are instantiated in the UI thread and system calls to each component are

dispatched from that thread Consequently methods that respond to system callbacks (such as

onKeyDown() to report user actions or a lifecycle callback method) always run in the UI thread of the

process

For instance when the user touches a button on the screen your apps UI thread dispatches the touch

event to the widget which in turn sets its pressed state and posts an invalidate request to the event

queue The UI thread dequeues the request and notifies the widget that it should redraw itself

When your app performs intensive work in response to user interaction this single thread model can

yield poor performance unless you implement your application properly Specifically if everything is

happening in the UI thread performing long operations such as network access or database queries

will block the whole UI When the thread is blocked no events can be dispatched including drawing

events From the users perspective the application appears to hang Even worse if the UI thread is

blocked for more than a few seconds (about 5 seconds currently) the user is presented with the

infamous application not responding (ANR) dialog The user might then decide to quit your

application and uninstall it if they are unhappy

Additionally the Andoid UI toolkit is not thread-safe So you must not manipulate your UI from a

worker threadmdashyou must do all manipulation to your user interface from the UI thread Thus there are

simply two rules to Androids single thread model

1 Do not block the UI thread

2 Do not access the Android UI toolkit from outside the UI thread

Worker threads

Because of the single thread model described above its vital to the responsiveness of your

applications UI that you do not block the UI thread If you have operations to perform that are not

instantaneous you should make sure to do them in separate threads (background or worker

threads)

For example below is some code for a click listener that downloads an image from a separate thread

and displays it in an ImageView

public void onClick(View v) new Thread(new Runnable() public void run() Bitmap b = loadImageFromNetwork(httpexamplecomimagepng) mImageViewsetImageBitmap(b) )start()

At first this seems to work fine because it creates a new thread to handle the network operation

However it violates the second rule of the single-threaded model do not access the Android UI toolkit

from outside the UI threadmdashthis sample modifies the ImageView from the worker thread instead of the

UI thread This can result in undefined and unexpected behavior which can be difficult and time-

consuming to track down

To fix this problem Android offers several ways to access the UI thread from other threads Here is a

list of methods that can help

ActivityrunOnUiThread(Runnable)

Viewpost(Runnable)

ViewpostDelayed(Runnable long)

For example you can fix the above code by using the Viewpost(Runnable) method

public void onClick(View v) new Thread(new Runnable() public void run() final Bitmap bitmap = loadImageFromNetwork(httpexamplecomimagepng) mImageViewpost(new Runnable() public void run() mImageViewsetImageBitmap(bitmap) ) )start()

Now this implementation is thread-safe the network operation is done from a separate thread while

the ImageView is manipulated from the UI thread

However as the complexity of the operation grows this kind of code can get complicated and difficult

to maintain To handle more complex interactions with a worker thread you might consider using a

Handler in your worker thread to process messages delivered from the UI thread Perhaps the best

solution though is to extend the AsyncTask class which simplifies the execution of worker thread

tasks that need to interact with the UI

Using AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface It performs the blocking

operations in a worker thread and then publishes the results on the UI thread without requiring you to

handle threads andor handlers yourself

To use it you must subclass AsyncTask and implement the doInBackground() callback method which

runs in a pool of background threads To update your UI you should implement onPostExecute()

which delivers the result from doInBackground() and runs in the UI thread so you can safely update

your UI You can then run the task by calling execute() from the UI thread

For example you can implement the previous example using AsyncTask this way

public void onClick(View v) new DownloadImageTask()execute(httpexamplecomimagepng) private class DownloadImageTask extends AsyncTaskltString Void Bitmapgt The system calls this to perform work in a worker thread and delivers it the parameters given to AsyncTaskexecute() protected Bitmap doInBackground(String urls) return loadImageFromNetwork(urls[0])

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 33: 03 services

insert() to put meta-information into a MediaStore record is used with openOutputStream() to place the

binary data there The following code snippet illustrates this convention

import androidproviderMediaStoreImagesMedia import androidcontentContentValues import javaioOutputStream Save the name and description of an image in a ContentValues map ContentValues values = new ContentValues(3) valuesput(MediaDISPLAY_NAME road_trip_1) valuesput(MediaDESCRIPTION Day 1 trip to Los Angeles) valuesput(MediaMIME_TYPE imagejpeg) Add a new record without the bitmap but with the values just set insert() returns the URI of the new record Uri uri = getContentResolver()insert(MediaEXTERNAL_CONTENT_URI values) Now get a handle to the file for that record and save the data into it Here sourceBitmap is a Bitmap object representing the file to save to the database try OutputStream outStream = getContentResolver()openOutputStream(uri) sourceBitmapcompress(BitmapCompressFormatJPEG 50 outStream) outStreamclose() catch (Exception e) Loge(TAG exception while writing image e)

Batch updating records

To batch update a group of records (for example to change NY to New York in all fields) call the

ContentResolverupdate() method with the columns and values to change

Deleting a record

To delete a single record call ContentResolverdelete() with the URI of a specific row

To delete multiple rows call ContentResolverdelete() with the URI of the type of record to delete (for

example androidproviderContactsPeopleCONTENT_URI) and an SQL WHERE clause defining

which rows to delete (Caution Be sure to include a valid WHERE clause if youre deleting a general

type or you risk deleting more records than you intended)

Creating a Content Provider

To create a content provider you must

Set up a system for storing the data Most content providers store their data using Androids file

storage methods or SQLite databases but you can store your data any way you want Android

provides the SQLiteOpenHelper class to help you create a database and SQLiteDatabase to manage

it

Extend the ContentProvider class to provide access to the data

Declare the content provider in the manifest file for your application (AndroidManifestxml)

The following sections have notes on the last two of these tasks

Extending the ContentProvider class

You define a ContentProvider subclass to expose your data to others using the conventions expected

by ContentResolver and Cursor objects Principally this means implementing six abstract methods

declared in the ContentProvider class

query()

insert()

update()

delete()

getType()

onCreate()

The query() method must return a Cursor object that can iterate over the requested data Cursor itself

is an interface but Android provides some ready-made Cursor objects that you can use For example

SQLiteCursor can iterate over data stored in an SQLite database You get the Cursor object by calling

any of the SQLiteDatabase classs query() methods There are other Cursor implementations mdash such

as MatrixCursor mdash for data not stored in a database

Because these ContentProvider methods can be called from various ContentResolver objects in

different processes and threads they must be implemented in a thread-safe manner

As a courtesy you might also want to call ContentResolvernotifyChange() to notify listeners when

there are modifications to the data

Beyond defining the subclass itself there are other steps you should take to simplify the work of clients

and make the class more accessible

Define a public static final Uri named CONTENT_URI This is the string that represents the full content

URI that your content provider handles You must define a unique string for this value The best

solution is to use the fully-qualified class name of the content provider (made lowercase) So for

example the URI for a TransportationProvider class could be defined as follows

public static final Uri CONTENT_URI = Uriparse(contentcomexamplecodelabtransportationprovider)

If the provider has subtables also define CONTENT_URI constants for each of the subtables These

URIs should all have the same authority (since that identifies the content provider) and be

distinguished only by their paths For example

contentcomexamplecodelabtransportationprovidertrain

contentcomexamplecodelabtransportationproviderairdomestic

contentcomexamplecodelabtransportationproviderairinternational

For an overview of content URIs see the Content URI Summary at the end of this document

Define the column names that the content provider will return to clients If you are using an underlying

database these column names are typically identical to the SQL database column names they

represent Also define public static String constants that clients can use to specify the columns in

queries and other instructions

Be sure to include an integer column named _id (with the constant _ID) for the IDs of the records

You should have this field whether or not you have another field (such as a URL) that is also unique

among all records If youre using the SQLite database the _ID field should be the following type

INTEGER PRIMARY KEY AUTOINCREMENT

The AUTOINCREMENT descriptor is optional But without it SQLite increments an ID counter field to

the next number above the largest existing number in the column If you delete the last row the next

row added will have the same ID as the deleted row AUTOINCREMENT avoids this by having SQLite

increment to the next largest value whether deleted or not

Carefully document the data type of each column Clients need this information to read the data

If you are handling a new data type you must define a new MIME type to return in your

implementation of ContentProvidergetType() The type depends in part on whether or not the content

URI submitted to getType() limits the request to a specific record Theres one form of the MIME type

for a single record and another for multiple records Use the Uri methods to help determine what is

being requested Here is the general format for each type

o For a single record vndandroidcursoritemvndyourcompanynamecontenttype

For example a request for train record 122 like this URI

contentcomexampletransportationprovidertrains122

might return this MIME type

vndandroidcursoritemvndexamplerail

o For multiple records vndandroidcursordirvndyourcompanynamecontenttype

For example a request for all train records like the following URI

contentcomexampletransportationprovidertrains

might return this MIME type

vndandroidcursordirvndexamplerail

If you are exposing byte data thats too big to put in the table itself mdash such as a large bitmap file mdash the

field that exposes the data to clients should actually contain a content URI string This is the field that

gives clients access to the data file The record should also have another field named _data that lists

the exact file path on the device for that file This field is not intended to be read by the client but by

the ContentResolver The client will call ContentResolveropenInputStream() on the user-facing field

holding the URI for the item The ContentResolver will request the _data field for that record and

because it has higher permissions than a client it should be able to access that file directly and return

a read wrapper for the file to the client

For an example of a private content provider implementation see the NodePadProvider class in the

Notepad sample application that ships with the SDK

Declaring the content provider

To let the Android system know about the content provider youve developed declare it with a

ltprovidergt element in the applications AndroidManifestxml file Content providers that are not

declared in the manifest are not visible to the Android system

The name attribute is the fully qualified name of the ContentProvider subclass The authorities attribute

is the authority part of the content URI that identifies the provider For example if the ContentProvider

subclass is AutoInfoProvider the ltprovidergt element might look like this

ltprovider androidname=comexampleautosAutoInfoProvider androidauthorities=comexampleautosautoinfoprovider gt ltprovidergt

Note that the authorities attribute omits the path part of a content URI For example if

AutoInfoProvider controlled subtables for different types of autos or different manufacturers

contentcomexampleautosautoinfoproviderhonda

contentcomexampleautosautoinfoprovidergmcompact

contentcomexampleautosautoinfoprovidergmsuv

those paths would not be declared in the manifest The authority is what identifies the provider not the

path your provider can interpret the path part of the URI in any way you choose

Other ltprovidergt attributes can set permissions to read and write data provide for an icon and text

that can be displayed to users enable and disable the provider and so on Set the multiprocess

attribute to true if data does not need to be synchronized between multiple running versions of the

content provider This permits an instance of the provider to be created in each client process

eliminating the need to perform IPC

Content URI Summary

Here is a recap of the important parts of a content URI

A Standard prefix indicating that the data is controlled by a content provider Its never modified

B The authority part of the URI it identifies the content provider For third-party applications this should

be a fully-qualified class name (reduced to lowercase) to ensure uniqueness The authority is declared

in the ltprovidergt elements authorities attribute

ltprovider androidname=TransportationProvider androidauthorities=comexampletransportationprovider gt

C The path that the content provider uses to determine what kind of data is being requested This can be

zero or more segments long If the content provider exposes only one type of data (only trains for

example) it can be absent If the provider exposes several types including subtypes it can be several

segments long mdash for example landbus landtrain seaship and seasubmarine to give four

possibilities

D The ID of the specific record being requested if any This is the _ID value of the requested record If

the request is not limited to a single record this segment and the trailing slash are omitted

contentcomexampletransportationprovidertrains

Intent and intent filters

Three of the core components of an application mdash activities services and broadcast receivers mdash 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 mdash 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 ContextstartActivity() or ActivitystartActivityForResult() to launch an

activity or get an existing activity to do something new (It can also be passed to ActivitysetResult() to

return information to the activity that called startActivityForResult())

An Intent object is passed to ContextstartService() to initiate a service or deliver new instructions to an

ongoing service Similarly an intent can be passed to ContextbindService() to establish a connection

between the calling component and a target service It can optionally initiate the service if its not

already running

Intent objects passed to any of the broadcast methods (such as ContextsendBroadcast()

ContextsendOrderedBroadcast() or ContextsendStickyBroadcast()) 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 mdash how it resolves which component should receive an intent message For

intents that dont explicitly name a target component this process involves testing the Intent object

against intent filters associated with potential targets

Intent Objects

An Intent object is a bundle of information It contains information of interest to the component that

receives the intent (such as the action to be taken and the data to act on) plus information of interest to

the Android system (such as the category of component that should handle the intent and instructions

on how to launch a target activity) Principally it can contain the following

Component name

The name of the component that should handle the intent This field is a ComponentName

object mdash a combination of the fully qualified class name of the target component (for example

comexampleprojectappFreneticActivity) and the package name set in the manifest file of the

application where the component resides (for example comexampleproject) The package

part of the component name and the package name set in the manifest do not necessarily have

to match

The component name is optional If it is set the Intent object is delivered to an instance of the

designated class If it is not set Android uses other information in the Intent object to locate a

suitable target mdash see Intent Resolution later in this document

The component name is set by setComponent() setClass() or setClassName() and read by

getComponent()

Action

A string naming the action to be performed mdash or in the case of broadcast intents the action

that took place and is being reported The Intent class defines a number of action constants

including these

Constant Target

component

Action

ACTION_CALL activity Initiate a phone call

ACTION_EDIT activity Display data for the user to edit

ACTION_MAIN activity Start up as the initial activity of a task

with no data input and no returned

output

ACTION_SYNC activity Synchronize data on a server with

data on the mobile device

ACTION_BATTERY_LOW broadcast

receiver

A warning that the battery is low

ACTION_HEADSET_PLUG broadcast

receiver

A headset has been plugged into the

device or unplugged from it

ACTION_SCREEN_ON broadcast

receiver

The screen has been turned on

ACTION_TIMEZONE_CHANGED broadcast

receiver

The setting for the time zone has

changed

See the Intent class description for a list of pre-defined constants for generic actions Other

actions are defined elsewhere in the Android API You can also define your own action strings

for activating the components in your application Those you invent should include the

application package as a prefix mdash for example comexampleprojectSHOW_COLOR

The action largely determines how the rest of the intent is structured mdash particularly the data and

extras fields mdash much as a method name determines a set of arguments and a return value For

this reason its a good idea to use action names that are as specific as possible and to couple

them tightly to the other fields of the intent In other words instead of defining an action in

isolation define an entire protocol for the Intent objects your components can handle

The action in an Intent object is set by the setAction() method and read by getAction()

Data

The URI of the data to be acted on and the MIME type of that data Different actions are paired

with different kinds of data specifications For example if the action field is ACTION_EDIT the

data field would contain the URI of the document to be displayed for editing If the action is

ACTION_CALL the data field would be a tel URI with the number to call Similarly if the action

is ACTION_VIEW and the data field is an http URI the receiving activity would be called upon

to download and display whatever data the URI refers to

When matching an intent to a component that is capable of handling the data its often

important to know the type of data (its MIME type) in addition to its URI For example a

component able to display image data should not be called upon to play an audio file

In many cases the data type can be inferred from the URI mdash particularly content URIs which

indicate that the data is located on the device and controlled by a content provider (see the

separate discussion on content providers) But the type can also be explicitly set in the Intent

object The setData() method specifies data only as a URI setType() specifies it only as a

MIME type and setDataAndType() specifies it as both a URI and a MIME type The URI is read

by getData() and the type by getType()

Category

A string containing additional information about the kind of component that should handle the

intent Any number of category descriptions can be placed in an Intent object As it does for

actions the Intent class defines several category constants including these

Constant Meaning

CATEGORY_BROWSABLE The target activity can be safely invoked by the browser to

display data referenced by a link mdash for example an image or

an e-mail message

CATEGORY_GADGET The activity can be embedded inside of another activity that

hosts gadgets

CATEGORY_HOME The activity displays the home screen the first screen the

user sees when the device is turned on or when the HOME

key is pressed

CATEGORY_LAUNCHER The activity can be the initial activity of a task and is listed in

the top-level application launcher

CATEGORY_PREFERENCE The target activity is a preference panel

See the Intent class description for the full list of categories

The addCategory() method places a category in an Intent object removeCategory() deletes a

category previously added and getCategories() gets the set of all categories currently in the

object

Extras

Key-value pairs for additional information that should be delivered to the component handling

the intent Just as some actions are paired with particular kinds of data URIs some are paired

with particular extras For example an ACTION_TIMEZONE_CHANGED intent has a time-

zone extra that identifies the new time zone and ACTION_HEADSET_PLUG has a state

extra indicating whether the headset is now plugged in or unplugged as well as a name extra

for the type of headset If you were to invent a SHOW_COLOR action the color value would be

set in an extra key-value pair

The Intent object has a series of put() methods for inserting various types of extra data and a

similar set of get() methods for reading the data These methods parallel those for Bundle

objects In fact the extras can be installed and read as a Bundle using the putExtras() and

getExtras() methods

Flags

Flags of various sorts Many instruct the Android system how to launch an activity (for example

which task the activity should belong to) and how to treat it after its launched (for example

whether it belongs in the list of recent activities) All these flags are defined in the Intent class

The Android system and the applications that come with the platform employ Intent objects both to

send out system-originated broadcasts and to activate system-defined components To see how to

structure an intent to activate a system component consult the list of intents in the reference

Intent Resolution

Intents can be divided into two groups

Explicit intents designate the target component by its name (the component name field mentioned

earlier has a value set) Since component names would generally not be known to developers of other

applications explicit intents are typically used for application-internal messages mdash such as an activity

starting a subordinate service or launching a sister activity

Implicit intents do not name a target (the field for the component name is blank) Implicit intents are

often used to activate components in other applications

Android delivers an explicit intent to an instance of the designated target class Nothing in the Intent

object other than the component name matters for determining which component should get the intent

A different strategy is needed for implicit intents In the absence of a designated target the Android

system must find the best component (or components) to handle the intent mdash a single activity or

service to perform the requested action or the set of broadcast receivers to respond to the broadcast

announcement It does so by comparing the contents of the Intent object to intent filters structures

associated with components that can potentially receive intents Filters advertise the capabilities of a

component and delimit the intents it can handle They open the component to the possibility of

receiving implicit intents of the advertised type If a component does not have any intent filters it can

receive only explicit intents A component with filters can receive both explicit and implicit intents

Only three aspects of an Intent object are consulted when the object is tested against an intent filter

action

data (both URI and data type)

category

The extras and flags play no part in resolving which component receives an intent

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 mdash but only unwanted implicit intents (those that dont 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

components 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 mdash 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 Pads filters are described in the Note Pad Example

section later)

Filters and security

An intent filter cannot be relied on for security While it opens a component to receiving only certain

kinds of implicit intents it does nothing to prevent explicit intents from targeting the component Even

though a filter restricts the intents a component will be asked to handle to certain actions and data

sources someone could always put together an explicit intent with a different action and data source

and name the component as the target

An intent filter is an instance of the IntentFilter class However since the Android system must know

about the capabilities of a component before it can launch that component intent filters are generally

not set up in Java code but in the applications manifest file (AndroidManifestxml) as ltintent-filtergt

elements (The one exception would be filters for broadcast receivers that are registered dynamically

by calling ContextregisterReceiver() they are directly created as IntentFilter objects)

A filter has fields that parallel the action data and category fields of an Intent object An implicit intent

is tested against the filter in all three areas To be delivered to the component that owns the filter it

must pass all three tests If it fails even one of them the Android system wont deliver it to the

component mdash at least not on the basis of that filter However since a component can have multiple

intent filters an intent that does not pass through one of a components filters might make it through on

another

Each of the three tests is described in detail below

Action test

An ltintent-filtergt element in the manifest file lists actions as ltactiongt subelements For

example

ltintent-filter gt ltaction androidname=comexampleprojectSHOW_CURRENT gt ltaction androidname=comexampleprojectSHOW_RECENT gt ltaction androidname=comexampleprojectSHOW_PENDING gt ltintent-filtergt

As the example shows while an Intent object names just a single action a filter may list more

than one The list cannot be empty a filter must contain at least one ltactiongt element or it will

block all intents

To pass this test the action specified in the Intent object must match one of the actions listed in

the filter If the object or the filter does not specify an action the results are as follows

If the filter fails to list any actions there is nothing for an intent to match so all intents fail the

test No intents can get through the filter

On the other hand an Intent object that doesnt specify an action automatically passes the test

mdash as long as the filter contains at least one action

Category test

An ltintent-filtergt element also lists categories as subelements For example

ltintent-filter gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryBROWSABLE gt ltintent-filtergt

Note that the constants described earlier for actions and categories are not used in the manifest

file The full string values are used instead For instance the

androidintentcategoryBROWSABLE string in the example above corresponds to the

CATEGORY_BROWSABLE constant mentioned earlier in this document Similarly the string

androidintentactionEDIT corresponds to the ACTION_EDIT constant

For an intent to pass the category test every category in the Intent object must match a

category in the filter The filter can list additional categories but it cannot omit any that are in the

intent

In principle therefore an Intent object with no categories should always pass this test

regardless of whats in the filter Thats mostly true However with one exception Android treats

all implicit intents passed to startActivity() as if they contained at least one category

androidintentcategoryDEFAULT (the CATEGORY_DEFAULT constant) Therefore activities

that are willing to receive implicit intents must include androidintentcategoryDEFAULT in

their intent filters (Filters with androidintentactionMAIN and

androidintentcategoryLAUNCHER settings are the exception They mark activities that begin

new tasks and that are represented on the launcher screen They can include

androidintentcategoryDEFAULT in the list of categories but dont need to) See Using intent

matching later for more on these filters)

Data test

Like the action and categories the data specification for an intent filter is contained in a

subelement And as in those cases the subelement can appear multiple times or not at all For

example

ltintent-filter gt ltdata androidmimeType=videompeg androidscheme=http gt ltdata androidmimeType=audiompeg androidscheme=http gt ltintent-filtergt

Each ltdatagt element can specify a URI and a data type (MIME media type) There are

separate attributes mdash scheme host port and path mdash for each part of the URI

schemehostportpath

For example in the following URI

contentcomexampleproject200foldersubfolderetc

the scheme is content the host is comexampleproject the port is 200 and the path is

foldersubfolderetc The host and port together constitute the URI authority if a host is not

specified the port is ignored

Each of these attributes is optional but they are not independent of each other For an authority

to be meaningful a scheme must also be specified For a path to be meaningful both a scheme

and an authority must be specified

When the URI in an Intent object is compared to a URI specification in a filter its compared

only to the parts of the URI actually mentioned in the filter For example if a filter specifies only

a scheme all URIs with that scheme match the filter If a filter specifies a scheme and an

authority but no path all URIs with the same scheme and authority match regardless of their

paths If a filter specifies a scheme an authority and a path only URIs with the same scheme

authority and path match However a path specification in the filter can contain wildcards to

require only a partial match of the path

The type attribute of a ltdatagt element specifies the MIME type of the data Its more common in

filters than a URI Both the Intent object and the filter can use a wildcard for the subtype field

mdash for example text or audio mdash indicating any subtype matches

The data test compares both the URI and the data type in the Intent object to a URI and data

type specified in the filter The rules are as follows

a An Intent object that contains neither a URI nor a data type passes the test only if the filter

likewise does not specify any URIs or data types

b An Intent object that contains a URI but no data type (and a type cannot be inferred from the

URI) passes the test only if its URI matches a URI in the filter and the filter likewise does not

specify a type This will be the case only for URIs like mailto and tel that do not refer to actual

data

c An Intent object that contains a data type but not a URI passes the test only if the filter lists the

same data type and similarly does not specify a URI

d An Intent object that contains both a URI and a data type (or a data type can be inferred from

the URI) passes the data type part of the test only if its type matches a type listed in the filter It

passes the URI part of the test either if its URI matches a URI in the filter or if it has a content

or file URI and the filter does not specify a URI In other words a component is presumed to

support content and file data if its filter lists only a data type

If an intent can pass through the filters of more than one activity or service the user may be asked

which component to activate An exception is raised if no target can be found

Common cases

The last rule shown above for the data test rule (d) reflects the expectation that components are able

to get local data from a file or content provider Therefore their filters can list just a data type and do

not need to explicitly name the content and file schemes This is a typical case A ltdatagt element like

the following for example tells Android that the component can get image data from a content

provider and display it

ltdata androidmimeType=image gt

Since most available data is dispensed by content providers filters that specify a data type but not a

URI are perhaps the most common

Another common configuration is filters with a scheme and a data type For example a ltdatagt

element like the following tells Android that the component can get video data from the network and

display it

ltdata androidscheme=http androidtype=video gt

Consider for example what the browser application does when the user follows a link on a web page

It first tries to display the data (as it could if the link was to an HTML page) If it cant display the data it

puts together an implicit intent with the scheme and data type and tries to start an activity that can do

the job If there are no takers it asks the download manager to download the data That puts it under

the control of a content provider so a potentially larger pool of activities (those with filters that just

name a data type) can respond

Most applications also have a way to start fresh without a reference to any particular data Activities

that can initiate applications have filters with androidintentactionMAIN specified as the action If

they are to be represented in the application launcher they also specify the

androidintentcategoryLAUNCHER category

ltintent-filter gt ltaction androidname=code androidintentactionMAIN gt ltcategory androidname=code androidintentcategoryLAUNCHER gt ltintent-filtergt

Using intent matching

Intents are matched against intent filters not only to discover a target component to activate but also

to discover something about the set of components on the device For example the Android system

populates the application launcher the top-level screen that shows the applications that are available

for the user to launch by finding all the activities with intent filters that specify the

androidintentactionMAIN action and androidintentcategoryLAUNCHER category (as illustrated

in the previous section) It then displays the icons and labels of those activities in the launcher

Similarly it discovers the home screen by looking for the activity with androidintentcategoryHOME

in its filter

Your application can use intent matching is a similar way The PackageManager has a set of query()

methods that return all components that can accept a particular intent and a similar series of

resolve() methods that determine the best component to respond to an intent For example

queryIntentActivities() returns a list of all activities that can perform the intent passed as an argument

and queryIntentServices() returns a similar list of services Neither method activates the components

they just list the ones that can respond Theres a similar method queryBroadcastReceivers() for

broadcast receivers

Note Pad Example

The Note Pad sample application enables users to browse through a list of notes view details about

individual items in the list edit the items and add a new item to the list This section looks at the intent

filters declared in its manifest file (If youre working offline in the SDK you can find all the source files

for this sample application including its manifest file at ltsdkgtsamplesNotePadindexhtml If youre

viewing the documentation online the source files are in the Tutorials and Sample Code section here)

In its manifest file the Note Pad application declares three activities each with at least one intent filter

It also declares a content provider that manages the note data Here is the manifest file in its entirety

ltmanifest xmlnsandroid=httpschemasandroidcomapkresandroid package=comexampleandroidnotepadgt ltapplication androidicon=drawableapp_notes androidlabel=stringapp_name gt ltprovider androidname=NotePadProvider androidauthorities=comgoogleproviderNotePad gt ltactivity androidname=NotesList androidlabel=stringtitle_notes_listgt ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltactivity androidname=NoteEditor androidtheme=androidstyleThemeLight androidlabel=stringtitle_note gt ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltactivitygt

ltactivity androidname=TitleEditor androidlabel=stringtitle_edit_title androidtheme=androidstyleThemeDialoggt ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltapplicationgt ltmanifestgt

The first activity NotesList is distinguished from the other activities by the fact that it operates on a

directory of notes (the note list) rather than on a single note It would generally serve as the initial user

interface into the application It can do three things as described by its three intent filters

1 ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt

This filter declares the main entry point into the Note Pad application The standard MAIN action is an

entry point that does not require any other information in the Intent (no data specification for example)

and the LAUNCHER category says that this entry point should be listed in the application launcher

2 ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

This filter declares the things that the activity can do on a directory of notes It can allow the user to

view or edit the directory (via the VIEW and EDIT actions) or to pick a particular note from the

directory (via the PICK action)

The mimeType attribute of the ltdatagt element specifies the kind of data that these actions operate on

It indicates that the activity can get a Cursor over zero or more items (vndandroidcursordir) from a

content provider that holds Note Pad data (vndgooglenote) The Intent object that launches the

activity would include a content URI specifying the exact data of this type that the activity should open

Note also the DEFAULT category supplied in this filter Its there because the ContextstartActivity()

and ActivitystartActivityForResult() methods treat all intents as if they contained the DEFAULT

category mdash with just two exceptions

o Intents that explicitly name the target activity

o Intents consisting of the MAIN action and LAUNCHER category

Therefore the DEFAULT category is required for all filters mdash except for those with the MAIN action

and LAUNCHER category (Intent filters are not consulted for explicit intents)

3 ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

This filter describes the activitys ability to return a note selected by the user without requiring any

specification of the directory the user should choose from The GET_CONTENT action is similar to the

PICK action In both cases the activity returns the URI for a note selected by the user (In each case

its returned to the activity that called startActivityForResult() to start the NoteList activity) Here

however the caller specifies the type of data desired instead of the directory of data the user will be

picking from

The data type vndandroidcursoritemvndgooglenote indicates the type of data the activity can

return mdash a URI for a single note From the returned URI the caller can get a Cursor for exactly one

item (vndandroidcursoritem) from the content provider that holds Note Pad data (vndgooglenote)

In other words for the PICK action in the previous filter the data type indicates the type of data the

activity could display to the user For the GET_CONTENT filter it indicates the type of data the activity

can return to the caller

Given these capabilities the following intents will resolve to the NotesList activity

action androidintentactionMAIN

Launches the activity with no data specified

action androidintentactionMAIN

category androidintentcategoryLAUNCHER

Launches the activity with no data selected specified This is the actual intent used by the

Launcher to populate its top-level list All activities with filters that match this action and

category are added to the list

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of all the notes under

contentcomgoogleproviderNotePadnotes The user can then browse through the list and

get information about the items in it

action androidintentactionPICK

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of the notes under

contentcomgoogleproviderNotePadnotes The user can then pick a note from the list and

the activity will return the URI for that item back to the activity that started the NoteList activity

action androidintentactionGET_CONTENT

data type vndandroidcursoritemvndgooglenote

Asks the activity to supply a single item of Note Pad data

The second activity NoteEditor shows users a single note entry and allows them to edit it It can do

two things as described by its two intent filters

1 ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The first primary purpose of this activity is to enable the user to interact with a single note ampmdash to

either VIEW the note or EDIT it (The EDIT_NOTE category is a synonym for EDIT) The intent would

contain the URI for data matching the MIME type vndandroidcursoritemvndgooglenote mdash that is

the URI for a single specific note It would typically be a URI that was returned by the PICK or

GET_CONTENT actions of the NoteList activity

As before this filter lists the DEFAULT category so that the activity can be launched by intents that

dont explicitly specify the NoteEditor class

2 ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

The secondary purpose of this activity is to enable the user to create a new note which it will INSERT

into an existing directory of notes The intent would contain the URI for data matching the MIME type

vndandroidcursordirvndgooglenote mdash that is the URI for the directory where the note should be

placed

Given these capabilities the following intents will resolve to the NoteEditor activity

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID (For details on how content

URIs specify individual members of a group see Content Providers)

action androidintentactionEDIT

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID and to let the user edit it If

the user saves the changes the activity updates the data for the note in the content provider

action androidintentactionINSERT

data contentcomgoogleproviderNotePadnotes

Asks the activity to create a new empty note in the notes list at

contentcomgoogleproviderNotePadnotes and allow the user to edit it If the user saves the

note its URI is returned to the caller

The last activity TitleEditor enables the user to edit the title of a note This could be implemented by

directly invoking the activity (by explicitly setting its component name in the Intent) without using an

intent filter But here we take the opportunity to show how to publish alternative operations on existing

data

ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The single intent filter for this activity uses a custom action called

comandroidnotepadactionEDIT_TITLE It must be invoked on a specific note (data type

vndandroidcursoritemvndgooglenote) like the previous VIEW and EDIT actions However here the

activity displays the title contained in the note data not the content of the note itself

In addition to supporting the usual DEFAULT category the title editor also supports two other standard

categories ALTERNATIVE and SELECTED_ALTERNATIVE These categories identify activities that

can be presented to users in a menu of options (much as the LAUNCHER category identifies activities

that should be presented to user in the application launcher) Note that the filter also supplies an

explicit label (via androidlabel=stringresolve_title) to better control what users see when

presented with this activity as an alternative action to the data they are currently viewing (For more

information on these categories and building options menus see the

PackageManagerqueryIntentActivityOptions() and MenuaddIntentOptions() methods)

Given these capabilities the following intent will resolve to the TitleEditor activity

action comandroidnotepadactionEDIT_TITLE

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the title associated with note ID and allow the user to edit the title

Processes and Threads

When an application component starts and the application does not have any other components

running the Android system starts a new Linux process for the application with a single thread of

execution By default all components of the same application run in the same process and thread

(called the main thread) If an application component starts and there already exists a process for

that application (because another component from the application exists) then the component is

started within that process and uses the same thread of execution However you can arrange for

different components in your application to run in separate processes and you can create additional

threads for any process

This document discusses how processes and threads work in an Android application

Processes

By default all components of the same application run in the same process and most applications

should not change this However if you find that you need to control which process a certain

component belongs to you can do so in the manifest file

The manifest entry for each type of component elementmdashltactivitygt ltservicegt ltreceivergt and

ltprovidergtmdashsupports an androidprocess attribute that can specify a process in which that component

should run You can set this attribute so that each component runs in its own process or so that some

components share a process while others do not You can also set androidprocess so that

components of different applications run in the same processmdashprovided that the applications share the

same Linux user ID and are signed with the same certificates

The ltapplicationgt element also supports an androidprocess attribute to set a default value that

applies to all components

Android might 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 thats killed are consequently destroyed A process is started again for those components

when theres again work for them to do

When deciding which processes to kill the Android system weighs their relative importance to the

user For example it more readily shuts down a process hosting activities that are no longer visible on

screen compared to a process hosting visible activities The decision whether to terminate a process

therefore depends on the state of the components running in that process The rules used to decide

which processes to terminate is discussed below

Process lifecycle

The Android system tries to maintain an application process for as long as possible but eventually

needs to remove old processes to reclaim memory for new or more important processes To determine

which processes to keep and which to kill the system places each process into an importance

hierarchy based on the components running in the process and the state of those components

Processes with the lowest importance are eliminated first then those with the next lowest importance

and so on as necessary to recover system resources

There are five levels in the importance hierarchy The following list presents the different types of

processes in order of importance (the first process is most important and is killed last)

1 Foreground process

A process that is required for what the user is currently doing A process is considered to be in the

foreground if any of the following conditions are true

o It hosts an Activity that the user is interacting with (the Activitys onResume() method has been called)

o It hosts a Service thats bound to the activity that the user is interacting with

o It hosts a Service thats running in the foregroundmdashthe service has called startForeground()

o It hosts a Service thats executing one of its lifecycle callbacks (onCreate() onStart() or onDestroy())

o It hosts a BroadcastReceiver thats executing its onReceive() method

Generally only a few foreground processes exist at any given time They are killed only as a last

resortmdashif memory is so low that they cannot all continue to run Generally at that point the device has

reached a memory paging state so killing some foreground processes is required to keep the user

interface responsive

2 Visible process

A process that doesnt have any foreground components but still can affect what the user sees on

screen A process is considered to be visible if either of the following conditions are true

o It hosts an Activity that is not in the foreground but is still visible to the user (its onPause() method has

been called) This might occur for example if the foreground activity started a dialog which allows the

previous activity to be seen behind it

o It hosts a Service thats bound to a visible (or foreground) activity

A visible process is considered extremely important and will not be killed unless doing so is required to

keep all foreground processes running

3 Service process

A process that is running a service that has been started with the startService() method and does not

fall into either of the two higher categories Although service processes are not directly tied to anything

the user sees they are generally doing things that the user cares about (such as playing music in the

background or downloading data on the network) so the system keeps them running unless theres

not enough memory to retain them along with all foreground and visible processes

4 Background process

A process holding an activity thats not currently visible to the user (the activitys onStop() method has

been called) These processes have no direct impact on the user experience and the system can kill

them at any time to reclaim memory for a foreground visible or service process Usually there are

many background processes running so they are kept in an LRU (least recently used) list to ensure

that the process with the activity that was most recently seen by the user is the last to be killed If an

activity implements its lifecycle methods correctly and saves its current state killing its process will not

have a visible effect on the user experience because when the user navigates back to the activity the

activity restores all of its visible state See the Activities document for information about saving and

restoring state

5 Empty process

A process that doesnt hold any active application components The only reason to keep this kind of

process alive is for caching purposes to improve startup time the next time a component needs to run

in it The system often kills these processes in order to balance overall system resources between

process caches and the underlying kernel caches

Android ranks a process at the highest level it can based upon the importance of the components

currently active in the process For example if a process hosts a service and a visible activity the

process is ranked as a visible process not a service process

In addition a processs ranking might be increased because other processes are dependent on itmdasha

process that is serving another process can never be ranked lower than the process it is serving For

example if a content provider in process A is serving a client in process B or if a service in process A

is bound to a component in process B process A is always considered at least as important as

process B

Because a process running a service is ranked higher than a process with background activities an

activity that initiates a long-running operation might do well to start a service for that operation rather

than simply create a worker threadmdashparticularly if the operation will likely outlast the activity For

example an activity thats uploading a picture to a web site should start a service to perform the

upload so that the upload can continue in the background even if the user leaves the activity Using a

service guarantees that the operation will have at least service process priority regardless of what

happens to the activity This is the same reason that broadcast receivers should employ services

rather than simply put time-consuming operations in a thread

Threads

When an application is launched the system creates a thread of execution for the application called

main This thread is very important because it is in charge of dispatching events to the appropriate

user interface widgets including drawing events It is also the thread in which your application interacts

with components from the Android UI toolkit (components from the androidwidget and androidview

packages) As such the main thread is also sometimes called the UI thread

The system does not create a separate thread for each instance of a component All components that

run in the same process are instantiated in the UI thread and system calls to each component are

dispatched from that thread Consequently methods that respond to system callbacks (such as

onKeyDown() to report user actions or a lifecycle callback method) always run in the UI thread of the

process

For instance when the user touches a button on the screen your apps UI thread dispatches the touch

event to the widget which in turn sets its pressed state and posts an invalidate request to the event

queue The UI thread dequeues the request and notifies the widget that it should redraw itself

When your app performs intensive work in response to user interaction this single thread model can

yield poor performance unless you implement your application properly Specifically if everything is

happening in the UI thread performing long operations such as network access or database queries

will block the whole UI When the thread is blocked no events can be dispatched including drawing

events From the users perspective the application appears to hang Even worse if the UI thread is

blocked for more than a few seconds (about 5 seconds currently) the user is presented with the

infamous application not responding (ANR) dialog The user might then decide to quit your

application and uninstall it if they are unhappy

Additionally the Andoid UI toolkit is not thread-safe So you must not manipulate your UI from a

worker threadmdashyou must do all manipulation to your user interface from the UI thread Thus there are

simply two rules to Androids single thread model

1 Do not block the UI thread

2 Do not access the Android UI toolkit from outside the UI thread

Worker threads

Because of the single thread model described above its vital to the responsiveness of your

applications UI that you do not block the UI thread If you have operations to perform that are not

instantaneous you should make sure to do them in separate threads (background or worker

threads)

For example below is some code for a click listener that downloads an image from a separate thread

and displays it in an ImageView

public void onClick(View v) new Thread(new Runnable() public void run() Bitmap b = loadImageFromNetwork(httpexamplecomimagepng) mImageViewsetImageBitmap(b) )start()

At first this seems to work fine because it creates a new thread to handle the network operation

However it violates the second rule of the single-threaded model do not access the Android UI toolkit

from outside the UI threadmdashthis sample modifies the ImageView from the worker thread instead of the

UI thread This can result in undefined and unexpected behavior which can be difficult and time-

consuming to track down

To fix this problem Android offers several ways to access the UI thread from other threads Here is a

list of methods that can help

ActivityrunOnUiThread(Runnable)

Viewpost(Runnable)

ViewpostDelayed(Runnable long)

For example you can fix the above code by using the Viewpost(Runnable) method

public void onClick(View v) new Thread(new Runnable() public void run() final Bitmap bitmap = loadImageFromNetwork(httpexamplecomimagepng) mImageViewpost(new Runnable() public void run() mImageViewsetImageBitmap(bitmap) ) )start()

Now this implementation is thread-safe the network operation is done from a separate thread while

the ImageView is manipulated from the UI thread

However as the complexity of the operation grows this kind of code can get complicated and difficult

to maintain To handle more complex interactions with a worker thread you might consider using a

Handler in your worker thread to process messages delivered from the UI thread Perhaps the best

solution though is to extend the AsyncTask class which simplifies the execution of worker thread

tasks that need to interact with the UI

Using AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface It performs the blocking

operations in a worker thread and then publishes the results on the UI thread without requiring you to

handle threads andor handlers yourself

To use it you must subclass AsyncTask and implement the doInBackground() callback method which

runs in a pool of background threads To update your UI you should implement onPostExecute()

which delivers the result from doInBackground() and runs in the UI thread so you can safely update

your UI You can then run the task by calling execute() from the UI thread

For example you can implement the previous example using AsyncTask this way

public void onClick(View v) new DownloadImageTask()execute(httpexamplecomimagepng) private class DownloadImageTask extends AsyncTaskltString Void Bitmapgt The system calls this to perform work in a worker thread and delivers it the parameters given to AsyncTaskexecute() protected Bitmap doInBackground(String urls) return loadImageFromNetwork(urls[0])

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 34: 03 services

provides the SQLiteOpenHelper class to help you create a database and SQLiteDatabase to manage

it

Extend the ContentProvider class to provide access to the data

Declare the content provider in the manifest file for your application (AndroidManifestxml)

The following sections have notes on the last two of these tasks

Extending the ContentProvider class

You define a ContentProvider subclass to expose your data to others using the conventions expected

by ContentResolver and Cursor objects Principally this means implementing six abstract methods

declared in the ContentProvider class

query()

insert()

update()

delete()

getType()

onCreate()

The query() method must return a Cursor object that can iterate over the requested data Cursor itself

is an interface but Android provides some ready-made Cursor objects that you can use For example

SQLiteCursor can iterate over data stored in an SQLite database You get the Cursor object by calling

any of the SQLiteDatabase classs query() methods There are other Cursor implementations mdash such

as MatrixCursor mdash for data not stored in a database

Because these ContentProvider methods can be called from various ContentResolver objects in

different processes and threads they must be implemented in a thread-safe manner

As a courtesy you might also want to call ContentResolvernotifyChange() to notify listeners when

there are modifications to the data

Beyond defining the subclass itself there are other steps you should take to simplify the work of clients

and make the class more accessible

Define a public static final Uri named CONTENT_URI This is the string that represents the full content

URI that your content provider handles You must define a unique string for this value The best

solution is to use the fully-qualified class name of the content provider (made lowercase) So for

example the URI for a TransportationProvider class could be defined as follows

public static final Uri CONTENT_URI = Uriparse(contentcomexamplecodelabtransportationprovider)

If the provider has subtables also define CONTENT_URI constants for each of the subtables These

URIs should all have the same authority (since that identifies the content provider) and be

distinguished only by their paths For example

contentcomexamplecodelabtransportationprovidertrain

contentcomexamplecodelabtransportationproviderairdomestic

contentcomexamplecodelabtransportationproviderairinternational

For an overview of content URIs see the Content URI Summary at the end of this document

Define the column names that the content provider will return to clients If you are using an underlying

database these column names are typically identical to the SQL database column names they

represent Also define public static String constants that clients can use to specify the columns in

queries and other instructions

Be sure to include an integer column named _id (with the constant _ID) for the IDs of the records

You should have this field whether or not you have another field (such as a URL) that is also unique

among all records If youre using the SQLite database the _ID field should be the following type

INTEGER PRIMARY KEY AUTOINCREMENT

The AUTOINCREMENT descriptor is optional But without it SQLite increments an ID counter field to

the next number above the largest existing number in the column If you delete the last row the next

row added will have the same ID as the deleted row AUTOINCREMENT avoids this by having SQLite

increment to the next largest value whether deleted or not

Carefully document the data type of each column Clients need this information to read the data

If you are handling a new data type you must define a new MIME type to return in your

implementation of ContentProvidergetType() The type depends in part on whether or not the content

URI submitted to getType() limits the request to a specific record Theres one form of the MIME type

for a single record and another for multiple records Use the Uri methods to help determine what is

being requested Here is the general format for each type

o For a single record vndandroidcursoritemvndyourcompanynamecontenttype

For example a request for train record 122 like this URI

contentcomexampletransportationprovidertrains122

might return this MIME type

vndandroidcursoritemvndexamplerail

o For multiple records vndandroidcursordirvndyourcompanynamecontenttype

For example a request for all train records like the following URI

contentcomexampletransportationprovidertrains

might return this MIME type

vndandroidcursordirvndexamplerail

If you are exposing byte data thats too big to put in the table itself mdash such as a large bitmap file mdash the

field that exposes the data to clients should actually contain a content URI string This is the field that

gives clients access to the data file The record should also have another field named _data that lists

the exact file path on the device for that file This field is not intended to be read by the client but by

the ContentResolver The client will call ContentResolveropenInputStream() on the user-facing field

holding the URI for the item The ContentResolver will request the _data field for that record and

because it has higher permissions than a client it should be able to access that file directly and return

a read wrapper for the file to the client

For an example of a private content provider implementation see the NodePadProvider class in the

Notepad sample application that ships with the SDK

Declaring the content provider

To let the Android system know about the content provider youve developed declare it with a

ltprovidergt element in the applications AndroidManifestxml file Content providers that are not

declared in the manifest are not visible to the Android system

The name attribute is the fully qualified name of the ContentProvider subclass The authorities attribute

is the authority part of the content URI that identifies the provider For example if the ContentProvider

subclass is AutoInfoProvider the ltprovidergt element might look like this

ltprovider androidname=comexampleautosAutoInfoProvider androidauthorities=comexampleautosautoinfoprovider gt ltprovidergt

Note that the authorities attribute omits the path part of a content URI For example if

AutoInfoProvider controlled subtables for different types of autos or different manufacturers

contentcomexampleautosautoinfoproviderhonda

contentcomexampleautosautoinfoprovidergmcompact

contentcomexampleautosautoinfoprovidergmsuv

those paths would not be declared in the manifest The authority is what identifies the provider not the

path your provider can interpret the path part of the URI in any way you choose

Other ltprovidergt attributes can set permissions to read and write data provide for an icon and text

that can be displayed to users enable and disable the provider and so on Set the multiprocess

attribute to true if data does not need to be synchronized between multiple running versions of the

content provider This permits an instance of the provider to be created in each client process

eliminating the need to perform IPC

Content URI Summary

Here is a recap of the important parts of a content URI

A Standard prefix indicating that the data is controlled by a content provider Its never modified

B The authority part of the URI it identifies the content provider For third-party applications this should

be a fully-qualified class name (reduced to lowercase) to ensure uniqueness The authority is declared

in the ltprovidergt elements authorities attribute

ltprovider androidname=TransportationProvider androidauthorities=comexampletransportationprovider gt

C The path that the content provider uses to determine what kind of data is being requested This can be

zero or more segments long If the content provider exposes only one type of data (only trains for

example) it can be absent If the provider exposes several types including subtypes it can be several

segments long mdash for example landbus landtrain seaship and seasubmarine to give four

possibilities

D The ID of the specific record being requested if any This is the _ID value of the requested record If

the request is not limited to a single record this segment and the trailing slash are omitted

contentcomexampletransportationprovidertrains

Intent and intent filters

Three of the core components of an application mdash activities services and broadcast receivers mdash 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 mdash 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 ContextstartActivity() or ActivitystartActivityForResult() to launch an

activity or get an existing activity to do something new (It can also be passed to ActivitysetResult() to

return information to the activity that called startActivityForResult())

An Intent object is passed to ContextstartService() to initiate a service or deliver new instructions to an

ongoing service Similarly an intent can be passed to ContextbindService() to establish a connection

between the calling component and a target service It can optionally initiate the service if its not

already running

Intent objects passed to any of the broadcast methods (such as ContextsendBroadcast()

ContextsendOrderedBroadcast() or ContextsendStickyBroadcast()) 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 mdash how it resolves which component should receive an intent message For

intents that dont explicitly name a target component this process involves testing the Intent object

against intent filters associated with potential targets

Intent Objects

An Intent object is a bundle of information It contains information of interest to the component that

receives the intent (such as the action to be taken and the data to act on) plus information of interest to

the Android system (such as the category of component that should handle the intent and instructions

on how to launch a target activity) Principally it can contain the following

Component name

The name of the component that should handle the intent This field is a ComponentName

object mdash a combination of the fully qualified class name of the target component (for example

comexampleprojectappFreneticActivity) and the package name set in the manifest file of the

application where the component resides (for example comexampleproject) The package

part of the component name and the package name set in the manifest do not necessarily have

to match

The component name is optional If it is set the Intent object is delivered to an instance of the

designated class If it is not set Android uses other information in the Intent object to locate a

suitable target mdash see Intent Resolution later in this document

The component name is set by setComponent() setClass() or setClassName() and read by

getComponent()

Action

A string naming the action to be performed mdash or in the case of broadcast intents the action

that took place and is being reported The Intent class defines a number of action constants

including these

Constant Target

component

Action

ACTION_CALL activity Initiate a phone call

ACTION_EDIT activity Display data for the user to edit

ACTION_MAIN activity Start up as the initial activity of a task

with no data input and no returned

output

ACTION_SYNC activity Synchronize data on a server with

data on the mobile device

ACTION_BATTERY_LOW broadcast

receiver

A warning that the battery is low

ACTION_HEADSET_PLUG broadcast

receiver

A headset has been plugged into the

device or unplugged from it

ACTION_SCREEN_ON broadcast

receiver

The screen has been turned on

ACTION_TIMEZONE_CHANGED broadcast

receiver

The setting for the time zone has

changed

See the Intent class description for a list of pre-defined constants for generic actions Other

actions are defined elsewhere in the Android API You can also define your own action strings

for activating the components in your application Those you invent should include the

application package as a prefix mdash for example comexampleprojectSHOW_COLOR

The action largely determines how the rest of the intent is structured mdash particularly the data and

extras fields mdash much as a method name determines a set of arguments and a return value For

this reason its a good idea to use action names that are as specific as possible and to couple

them tightly to the other fields of the intent In other words instead of defining an action in

isolation define an entire protocol for the Intent objects your components can handle

The action in an Intent object is set by the setAction() method and read by getAction()

Data

The URI of the data to be acted on and the MIME type of that data Different actions are paired

with different kinds of data specifications For example if the action field is ACTION_EDIT the

data field would contain the URI of the document to be displayed for editing If the action is

ACTION_CALL the data field would be a tel URI with the number to call Similarly if the action

is ACTION_VIEW and the data field is an http URI the receiving activity would be called upon

to download and display whatever data the URI refers to

When matching an intent to a component that is capable of handling the data its often

important to know the type of data (its MIME type) in addition to its URI For example a

component able to display image data should not be called upon to play an audio file

In many cases the data type can be inferred from the URI mdash particularly content URIs which

indicate that the data is located on the device and controlled by a content provider (see the

separate discussion on content providers) But the type can also be explicitly set in the Intent

object The setData() method specifies data only as a URI setType() specifies it only as a

MIME type and setDataAndType() specifies it as both a URI and a MIME type The URI is read

by getData() and the type by getType()

Category

A string containing additional information about the kind of component that should handle the

intent Any number of category descriptions can be placed in an Intent object As it does for

actions the Intent class defines several category constants including these

Constant Meaning

CATEGORY_BROWSABLE The target activity can be safely invoked by the browser to

display data referenced by a link mdash for example an image or

an e-mail message

CATEGORY_GADGET The activity can be embedded inside of another activity that

hosts gadgets

CATEGORY_HOME The activity displays the home screen the first screen the

user sees when the device is turned on or when the HOME

key is pressed

CATEGORY_LAUNCHER The activity can be the initial activity of a task and is listed in

the top-level application launcher

CATEGORY_PREFERENCE The target activity is a preference panel

See the Intent class description for the full list of categories

The addCategory() method places a category in an Intent object removeCategory() deletes a

category previously added and getCategories() gets the set of all categories currently in the

object

Extras

Key-value pairs for additional information that should be delivered to the component handling

the intent Just as some actions are paired with particular kinds of data URIs some are paired

with particular extras For example an ACTION_TIMEZONE_CHANGED intent has a time-

zone extra that identifies the new time zone and ACTION_HEADSET_PLUG has a state

extra indicating whether the headset is now plugged in or unplugged as well as a name extra

for the type of headset If you were to invent a SHOW_COLOR action the color value would be

set in an extra key-value pair

The Intent object has a series of put() methods for inserting various types of extra data and a

similar set of get() methods for reading the data These methods parallel those for Bundle

objects In fact the extras can be installed and read as a Bundle using the putExtras() and

getExtras() methods

Flags

Flags of various sorts Many instruct the Android system how to launch an activity (for example

which task the activity should belong to) and how to treat it after its launched (for example

whether it belongs in the list of recent activities) All these flags are defined in the Intent class

The Android system and the applications that come with the platform employ Intent objects both to

send out system-originated broadcasts and to activate system-defined components To see how to

structure an intent to activate a system component consult the list of intents in the reference

Intent Resolution

Intents can be divided into two groups

Explicit intents designate the target component by its name (the component name field mentioned

earlier has a value set) Since component names would generally not be known to developers of other

applications explicit intents are typically used for application-internal messages mdash such as an activity

starting a subordinate service or launching a sister activity

Implicit intents do not name a target (the field for the component name is blank) Implicit intents are

often used to activate components in other applications

Android delivers an explicit intent to an instance of the designated target class Nothing in the Intent

object other than the component name matters for determining which component should get the intent

A different strategy is needed for implicit intents In the absence of a designated target the Android

system must find the best component (or components) to handle the intent mdash a single activity or

service to perform the requested action or the set of broadcast receivers to respond to the broadcast

announcement It does so by comparing the contents of the Intent object to intent filters structures

associated with components that can potentially receive intents Filters advertise the capabilities of a

component and delimit the intents it can handle They open the component to the possibility of

receiving implicit intents of the advertised type If a component does not have any intent filters it can

receive only explicit intents A component with filters can receive both explicit and implicit intents

Only three aspects of an Intent object are consulted when the object is tested against an intent filter

action

data (both URI and data type)

category

The extras and flags play no part in resolving which component receives an intent

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 mdash but only unwanted implicit intents (those that dont 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

components 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 mdash 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 Pads filters are described in the Note Pad Example

section later)

Filters and security

An intent filter cannot be relied on for security While it opens a component to receiving only certain

kinds of implicit intents it does nothing to prevent explicit intents from targeting the component Even

though a filter restricts the intents a component will be asked to handle to certain actions and data

sources someone could always put together an explicit intent with a different action and data source

and name the component as the target

An intent filter is an instance of the IntentFilter class However since the Android system must know

about the capabilities of a component before it can launch that component intent filters are generally

not set up in Java code but in the applications manifest file (AndroidManifestxml) as ltintent-filtergt

elements (The one exception would be filters for broadcast receivers that are registered dynamically

by calling ContextregisterReceiver() they are directly created as IntentFilter objects)

A filter has fields that parallel the action data and category fields of an Intent object An implicit intent

is tested against the filter in all three areas To be delivered to the component that owns the filter it

must pass all three tests If it fails even one of them the Android system wont deliver it to the

component mdash at least not on the basis of that filter However since a component can have multiple

intent filters an intent that does not pass through one of a components filters might make it through on

another

Each of the three tests is described in detail below

Action test

An ltintent-filtergt element in the manifest file lists actions as ltactiongt subelements For

example

ltintent-filter gt ltaction androidname=comexampleprojectSHOW_CURRENT gt ltaction androidname=comexampleprojectSHOW_RECENT gt ltaction androidname=comexampleprojectSHOW_PENDING gt ltintent-filtergt

As the example shows while an Intent object names just a single action a filter may list more

than one The list cannot be empty a filter must contain at least one ltactiongt element or it will

block all intents

To pass this test the action specified in the Intent object must match one of the actions listed in

the filter If the object or the filter does not specify an action the results are as follows

If the filter fails to list any actions there is nothing for an intent to match so all intents fail the

test No intents can get through the filter

On the other hand an Intent object that doesnt specify an action automatically passes the test

mdash as long as the filter contains at least one action

Category test

An ltintent-filtergt element also lists categories as subelements For example

ltintent-filter gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryBROWSABLE gt ltintent-filtergt

Note that the constants described earlier for actions and categories are not used in the manifest

file The full string values are used instead For instance the

androidintentcategoryBROWSABLE string in the example above corresponds to the

CATEGORY_BROWSABLE constant mentioned earlier in this document Similarly the string

androidintentactionEDIT corresponds to the ACTION_EDIT constant

For an intent to pass the category test every category in the Intent object must match a

category in the filter The filter can list additional categories but it cannot omit any that are in the

intent

In principle therefore an Intent object with no categories should always pass this test

regardless of whats in the filter Thats mostly true However with one exception Android treats

all implicit intents passed to startActivity() as if they contained at least one category

androidintentcategoryDEFAULT (the CATEGORY_DEFAULT constant) Therefore activities

that are willing to receive implicit intents must include androidintentcategoryDEFAULT in

their intent filters (Filters with androidintentactionMAIN and

androidintentcategoryLAUNCHER settings are the exception They mark activities that begin

new tasks and that are represented on the launcher screen They can include

androidintentcategoryDEFAULT in the list of categories but dont need to) See Using intent

matching later for more on these filters)

Data test

Like the action and categories the data specification for an intent filter is contained in a

subelement And as in those cases the subelement can appear multiple times or not at all For

example

ltintent-filter gt ltdata androidmimeType=videompeg androidscheme=http gt ltdata androidmimeType=audiompeg androidscheme=http gt ltintent-filtergt

Each ltdatagt element can specify a URI and a data type (MIME media type) There are

separate attributes mdash scheme host port and path mdash for each part of the URI

schemehostportpath

For example in the following URI

contentcomexampleproject200foldersubfolderetc

the scheme is content the host is comexampleproject the port is 200 and the path is

foldersubfolderetc The host and port together constitute the URI authority if a host is not

specified the port is ignored

Each of these attributes is optional but they are not independent of each other For an authority

to be meaningful a scheme must also be specified For a path to be meaningful both a scheme

and an authority must be specified

When the URI in an Intent object is compared to a URI specification in a filter its compared

only to the parts of the URI actually mentioned in the filter For example if a filter specifies only

a scheme all URIs with that scheme match the filter If a filter specifies a scheme and an

authority but no path all URIs with the same scheme and authority match regardless of their

paths If a filter specifies a scheme an authority and a path only URIs with the same scheme

authority and path match However a path specification in the filter can contain wildcards to

require only a partial match of the path

The type attribute of a ltdatagt element specifies the MIME type of the data Its more common in

filters than a URI Both the Intent object and the filter can use a wildcard for the subtype field

mdash for example text or audio mdash indicating any subtype matches

The data test compares both the URI and the data type in the Intent object to a URI and data

type specified in the filter The rules are as follows

a An Intent object that contains neither a URI nor a data type passes the test only if the filter

likewise does not specify any URIs or data types

b An Intent object that contains a URI but no data type (and a type cannot be inferred from the

URI) passes the test only if its URI matches a URI in the filter and the filter likewise does not

specify a type This will be the case only for URIs like mailto and tel that do not refer to actual

data

c An Intent object that contains a data type but not a URI passes the test only if the filter lists the

same data type and similarly does not specify a URI

d An Intent object that contains both a URI and a data type (or a data type can be inferred from

the URI) passes the data type part of the test only if its type matches a type listed in the filter It

passes the URI part of the test either if its URI matches a URI in the filter or if it has a content

or file URI and the filter does not specify a URI In other words a component is presumed to

support content and file data if its filter lists only a data type

If an intent can pass through the filters of more than one activity or service the user may be asked

which component to activate An exception is raised if no target can be found

Common cases

The last rule shown above for the data test rule (d) reflects the expectation that components are able

to get local data from a file or content provider Therefore their filters can list just a data type and do

not need to explicitly name the content and file schemes This is a typical case A ltdatagt element like

the following for example tells Android that the component can get image data from a content

provider and display it

ltdata androidmimeType=image gt

Since most available data is dispensed by content providers filters that specify a data type but not a

URI are perhaps the most common

Another common configuration is filters with a scheme and a data type For example a ltdatagt

element like the following tells Android that the component can get video data from the network and

display it

ltdata androidscheme=http androidtype=video gt

Consider for example what the browser application does when the user follows a link on a web page

It first tries to display the data (as it could if the link was to an HTML page) If it cant display the data it

puts together an implicit intent with the scheme and data type and tries to start an activity that can do

the job If there are no takers it asks the download manager to download the data That puts it under

the control of a content provider so a potentially larger pool of activities (those with filters that just

name a data type) can respond

Most applications also have a way to start fresh without a reference to any particular data Activities

that can initiate applications have filters with androidintentactionMAIN specified as the action If

they are to be represented in the application launcher they also specify the

androidintentcategoryLAUNCHER category

ltintent-filter gt ltaction androidname=code androidintentactionMAIN gt ltcategory androidname=code androidintentcategoryLAUNCHER gt ltintent-filtergt

Using intent matching

Intents are matched against intent filters not only to discover a target component to activate but also

to discover something about the set of components on the device For example the Android system

populates the application launcher the top-level screen that shows the applications that are available

for the user to launch by finding all the activities with intent filters that specify the

androidintentactionMAIN action and androidintentcategoryLAUNCHER category (as illustrated

in the previous section) It then displays the icons and labels of those activities in the launcher

Similarly it discovers the home screen by looking for the activity with androidintentcategoryHOME

in its filter

Your application can use intent matching is a similar way The PackageManager has a set of query()

methods that return all components that can accept a particular intent and a similar series of

resolve() methods that determine the best component to respond to an intent For example

queryIntentActivities() returns a list of all activities that can perform the intent passed as an argument

and queryIntentServices() returns a similar list of services Neither method activates the components

they just list the ones that can respond Theres a similar method queryBroadcastReceivers() for

broadcast receivers

Note Pad Example

The Note Pad sample application enables users to browse through a list of notes view details about

individual items in the list edit the items and add a new item to the list This section looks at the intent

filters declared in its manifest file (If youre working offline in the SDK you can find all the source files

for this sample application including its manifest file at ltsdkgtsamplesNotePadindexhtml If youre

viewing the documentation online the source files are in the Tutorials and Sample Code section here)

In its manifest file the Note Pad application declares three activities each with at least one intent filter

It also declares a content provider that manages the note data Here is the manifest file in its entirety

ltmanifest xmlnsandroid=httpschemasandroidcomapkresandroid package=comexampleandroidnotepadgt ltapplication androidicon=drawableapp_notes androidlabel=stringapp_name gt ltprovider androidname=NotePadProvider androidauthorities=comgoogleproviderNotePad gt ltactivity androidname=NotesList androidlabel=stringtitle_notes_listgt ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltactivity androidname=NoteEditor androidtheme=androidstyleThemeLight androidlabel=stringtitle_note gt ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltactivitygt

ltactivity androidname=TitleEditor androidlabel=stringtitle_edit_title androidtheme=androidstyleThemeDialoggt ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltapplicationgt ltmanifestgt

The first activity NotesList is distinguished from the other activities by the fact that it operates on a

directory of notes (the note list) rather than on a single note It would generally serve as the initial user

interface into the application It can do three things as described by its three intent filters

1 ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt

This filter declares the main entry point into the Note Pad application The standard MAIN action is an

entry point that does not require any other information in the Intent (no data specification for example)

and the LAUNCHER category says that this entry point should be listed in the application launcher

2 ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

This filter declares the things that the activity can do on a directory of notes It can allow the user to

view or edit the directory (via the VIEW and EDIT actions) or to pick a particular note from the

directory (via the PICK action)

The mimeType attribute of the ltdatagt element specifies the kind of data that these actions operate on

It indicates that the activity can get a Cursor over zero or more items (vndandroidcursordir) from a

content provider that holds Note Pad data (vndgooglenote) The Intent object that launches the

activity would include a content URI specifying the exact data of this type that the activity should open

Note also the DEFAULT category supplied in this filter Its there because the ContextstartActivity()

and ActivitystartActivityForResult() methods treat all intents as if they contained the DEFAULT

category mdash with just two exceptions

o Intents that explicitly name the target activity

o Intents consisting of the MAIN action and LAUNCHER category

Therefore the DEFAULT category is required for all filters mdash except for those with the MAIN action

and LAUNCHER category (Intent filters are not consulted for explicit intents)

3 ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

This filter describes the activitys ability to return a note selected by the user without requiring any

specification of the directory the user should choose from The GET_CONTENT action is similar to the

PICK action In both cases the activity returns the URI for a note selected by the user (In each case

its returned to the activity that called startActivityForResult() to start the NoteList activity) Here

however the caller specifies the type of data desired instead of the directory of data the user will be

picking from

The data type vndandroidcursoritemvndgooglenote indicates the type of data the activity can

return mdash a URI for a single note From the returned URI the caller can get a Cursor for exactly one

item (vndandroidcursoritem) from the content provider that holds Note Pad data (vndgooglenote)

In other words for the PICK action in the previous filter the data type indicates the type of data the

activity could display to the user For the GET_CONTENT filter it indicates the type of data the activity

can return to the caller

Given these capabilities the following intents will resolve to the NotesList activity

action androidintentactionMAIN

Launches the activity with no data specified

action androidintentactionMAIN

category androidintentcategoryLAUNCHER

Launches the activity with no data selected specified This is the actual intent used by the

Launcher to populate its top-level list All activities with filters that match this action and

category are added to the list

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of all the notes under

contentcomgoogleproviderNotePadnotes The user can then browse through the list and

get information about the items in it

action androidintentactionPICK

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of the notes under

contentcomgoogleproviderNotePadnotes The user can then pick a note from the list and

the activity will return the URI for that item back to the activity that started the NoteList activity

action androidintentactionGET_CONTENT

data type vndandroidcursoritemvndgooglenote

Asks the activity to supply a single item of Note Pad data

The second activity NoteEditor shows users a single note entry and allows them to edit it It can do

two things as described by its two intent filters

1 ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The first primary purpose of this activity is to enable the user to interact with a single note ampmdash to

either VIEW the note or EDIT it (The EDIT_NOTE category is a synonym for EDIT) The intent would

contain the URI for data matching the MIME type vndandroidcursoritemvndgooglenote mdash that is

the URI for a single specific note It would typically be a URI that was returned by the PICK or

GET_CONTENT actions of the NoteList activity

As before this filter lists the DEFAULT category so that the activity can be launched by intents that

dont explicitly specify the NoteEditor class

2 ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

The secondary purpose of this activity is to enable the user to create a new note which it will INSERT

into an existing directory of notes The intent would contain the URI for data matching the MIME type

vndandroidcursordirvndgooglenote mdash that is the URI for the directory where the note should be

placed

Given these capabilities the following intents will resolve to the NoteEditor activity

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID (For details on how content

URIs specify individual members of a group see Content Providers)

action androidintentactionEDIT

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID and to let the user edit it If

the user saves the changes the activity updates the data for the note in the content provider

action androidintentactionINSERT

data contentcomgoogleproviderNotePadnotes

Asks the activity to create a new empty note in the notes list at

contentcomgoogleproviderNotePadnotes and allow the user to edit it If the user saves the

note its URI is returned to the caller

The last activity TitleEditor enables the user to edit the title of a note This could be implemented by

directly invoking the activity (by explicitly setting its component name in the Intent) without using an

intent filter But here we take the opportunity to show how to publish alternative operations on existing

data

ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The single intent filter for this activity uses a custom action called

comandroidnotepadactionEDIT_TITLE It must be invoked on a specific note (data type

vndandroidcursoritemvndgooglenote) like the previous VIEW and EDIT actions However here the

activity displays the title contained in the note data not the content of the note itself

In addition to supporting the usual DEFAULT category the title editor also supports two other standard

categories ALTERNATIVE and SELECTED_ALTERNATIVE These categories identify activities that

can be presented to users in a menu of options (much as the LAUNCHER category identifies activities

that should be presented to user in the application launcher) Note that the filter also supplies an

explicit label (via androidlabel=stringresolve_title) to better control what users see when

presented with this activity as an alternative action to the data they are currently viewing (For more

information on these categories and building options menus see the

PackageManagerqueryIntentActivityOptions() and MenuaddIntentOptions() methods)

Given these capabilities the following intent will resolve to the TitleEditor activity

action comandroidnotepadactionEDIT_TITLE

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the title associated with note ID and allow the user to edit the title

Processes and Threads

When an application component starts and the application does not have any other components

running the Android system starts a new Linux process for the application with a single thread of

execution By default all components of the same application run in the same process and thread

(called the main thread) If an application component starts and there already exists a process for

that application (because another component from the application exists) then the component is

started within that process and uses the same thread of execution However you can arrange for

different components in your application to run in separate processes and you can create additional

threads for any process

This document discusses how processes and threads work in an Android application

Processes

By default all components of the same application run in the same process and most applications

should not change this However if you find that you need to control which process a certain

component belongs to you can do so in the manifest file

The manifest entry for each type of component elementmdashltactivitygt ltservicegt ltreceivergt and

ltprovidergtmdashsupports an androidprocess attribute that can specify a process in which that component

should run You can set this attribute so that each component runs in its own process or so that some

components share a process while others do not You can also set androidprocess so that

components of different applications run in the same processmdashprovided that the applications share the

same Linux user ID and are signed with the same certificates

The ltapplicationgt element also supports an androidprocess attribute to set a default value that

applies to all components

Android might 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 thats killed are consequently destroyed A process is started again for those components

when theres again work for them to do

When deciding which processes to kill the Android system weighs their relative importance to the

user For example it more readily shuts down a process hosting activities that are no longer visible on

screen compared to a process hosting visible activities The decision whether to terminate a process

therefore depends on the state of the components running in that process The rules used to decide

which processes to terminate is discussed below

Process lifecycle

The Android system tries to maintain an application process for as long as possible but eventually

needs to remove old processes to reclaim memory for new or more important processes To determine

which processes to keep and which to kill the system places each process into an importance

hierarchy based on the components running in the process and the state of those components

Processes with the lowest importance are eliminated first then those with the next lowest importance

and so on as necessary to recover system resources

There are five levels in the importance hierarchy The following list presents the different types of

processes in order of importance (the first process is most important and is killed last)

1 Foreground process

A process that is required for what the user is currently doing A process is considered to be in the

foreground if any of the following conditions are true

o It hosts an Activity that the user is interacting with (the Activitys onResume() method has been called)

o It hosts a Service thats bound to the activity that the user is interacting with

o It hosts a Service thats running in the foregroundmdashthe service has called startForeground()

o It hosts a Service thats executing one of its lifecycle callbacks (onCreate() onStart() or onDestroy())

o It hosts a BroadcastReceiver thats executing its onReceive() method

Generally only a few foreground processes exist at any given time They are killed only as a last

resortmdashif memory is so low that they cannot all continue to run Generally at that point the device has

reached a memory paging state so killing some foreground processes is required to keep the user

interface responsive

2 Visible process

A process that doesnt have any foreground components but still can affect what the user sees on

screen A process is considered to be visible if either of the following conditions are true

o It hosts an Activity that is not in the foreground but is still visible to the user (its onPause() method has

been called) This might occur for example if the foreground activity started a dialog which allows the

previous activity to be seen behind it

o It hosts a Service thats bound to a visible (or foreground) activity

A visible process is considered extremely important and will not be killed unless doing so is required to

keep all foreground processes running

3 Service process

A process that is running a service that has been started with the startService() method and does not

fall into either of the two higher categories Although service processes are not directly tied to anything

the user sees they are generally doing things that the user cares about (such as playing music in the

background or downloading data on the network) so the system keeps them running unless theres

not enough memory to retain them along with all foreground and visible processes

4 Background process

A process holding an activity thats not currently visible to the user (the activitys onStop() method has

been called) These processes have no direct impact on the user experience and the system can kill

them at any time to reclaim memory for a foreground visible or service process Usually there are

many background processes running so they are kept in an LRU (least recently used) list to ensure

that the process with the activity that was most recently seen by the user is the last to be killed If an

activity implements its lifecycle methods correctly and saves its current state killing its process will not

have a visible effect on the user experience because when the user navigates back to the activity the

activity restores all of its visible state See the Activities document for information about saving and

restoring state

5 Empty process

A process that doesnt hold any active application components The only reason to keep this kind of

process alive is for caching purposes to improve startup time the next time a component needs to run

in it The system often kills these processes in order to balance overall system resources between

process caches and the underlying kernel caches

Android ranks a process at the highest level it can based upon the importance of the components

currently active in the process For example if a process hosts a service and a visible activity the

process is ranked as a visible process not a service process

In addition a processs ranking might be increased because other processes are dependent on itmdasha

process that is serving another process can never be ranked lower than the process it is serving For

example if a content provider in process A is serving a client in process B or if a service in process A

is bound to a component in process B process A is always considered at least as important as

process B

Because a process running a service is ranked higher than a process with background activities an

activity that initiates a long-running operation might do well to start a service for that operation rather

than simply create a worker threadmdashparticularly if the operation will likely outlast the activity For

example an activity thats uploading a picture to a web site should start a service to perform the

upload so that the upload can continue in the background even if the user leaves the activity Using a

service guarantees that the operation will have at least service process priority regardless of what

happens to the activity This is the same reason that broadcast receivers should employ services

rather than simply put time-consuming operations in a thread

Threads

When an application is launched the system creates a thread of execution for the application called

main This thread is very important because it is in charge of dispatching events to the appropriate

user interface widgets including drawing events It is also the thread in which your application interacts

with components from the Android UI toolkit (components from the androidwidget and androidview

packages) As such the main thread is also sometimes called the UI thread

The system does not create a separate thread for each instance of a component All components that

run in the same process are instantiated in the UI thread and system calls to each component are

dispatched from that thread Consequently methods that respond to system callbacks (such as

onKeyDown() to report user actions or a lifecycle callback method) always run in the UI thread of the

process

For instance when the user touches a button on the screen your apps UI thread dispatches the touch

event to the widget which in turn sets its pressed state and posts an invalidate request to the event

queue The UI thread dequeues the request and notifies the widget that it should redraw itself

When your app performs intensive work in response to user interaction this single thread model can

yield poor performance unless you implement your application properly Specifically if everything is

happening in the UI thread performing long operations such as network access or database queries

will block the whole UI When the thread is blocked no events can be dispatched including drawing

events From the users perspective the application appears to hang Even worse if the UI thread is

blocked for more than a few seconds (about 5 seconds currently) the user is presented with the

infamous application not responding (ANR) dialog The user might then decide to quit your

application and uninstall it if they are unhappy

Additionally the Andoid UI toolkit is not thread-safe So you must not manipulate your UI from a

worker threadmdashyou must do all manipulation to your user interface from the UI thread Thus there are

simply two rules to Androids single thread model

1 Do not block the UI thread

2 Do not access the Android UI toolkit from outside the UI thread

Worker threads

Because of the single thread model described above its vital to the responsiveness of your

applications UI that you do not block the UI thread If you have operations to perform that are not

instantaneous you should make sure to do them in separate threads (background or worker

threads)

For example below is some code for a click listener that downloads an image from a separate thread

and displays it in an ImageView

public void onClick(View v) new Thread(new Runnable() public void run() Bitmap b = loadImageFromNetwork(httpexamplecomimagepng) mImageViewsetImageBitmap(b) )start()

At first this seems to work fine because it creates a new thread to handle the network operation

However it violates the second rule of the single-threaded model do not access the Android UI toolkit

from outside the UI threadmdashthis sample modifies the ImageView from the worker thread instead of the

UI thread This can result in undefined and unexpected behavior which can be difficult and time-

consuming to track down

To fix this problem Android offers several ways to access the UI thread from other threads Here is a

list of methods that can help

ActivityrunOnUiThread(Runnable)

Viewpost(Runnable)

ViewpostDelayed(Runnable long)

For example you can fix the above code by using the Viewpost(Runnable) method

public void onClick(View v) new Thread(new Runnable() public void run() final Bitmap bitmap = loadImageFromNetwork(httpexamplecomimagepng) mImageViewpost(new Runnable() public void run() mImageViewsetImageBitmap(bitmap) ) )start()

Now this implementation is thread-safe the network operation is done from a separate thread while

the ImageView is manipulated from the UI thread

However as the complexity of the operation grows this kind of code can get complicated and difficult

to maintain To handle more complex interactions with a worker thread you might consider using a

Handler in your worker thread to process messages delivered from the UI thread Perhaps the best

solution though is to extend the AsyncTask class which simplifies the execution of worker thread

tasks that need to interact with the UI

Using AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface It performs the blocking

operations in a worker thread and then publishes the results on the UI thread without requiring you to

handle threads andor handlers yourself

To use it you must subclass AsyncTask and implement the doInBackground() callback method which

runs in a pool of background threads To update your UI you should implement onPostExecute()

which delivers the result from doInBackground() and runs in the UI thread so you can safely update

your UI You can then run the task by calling execute() from the UI thread

For example you can implement the previous example using AsyncTask this way

public void onClick(View v) new DownloadImageTask()execute(httpexamplecomimagepng) private class DownloadImageTask extends AsyncTaskltString Void Bitmapgt The system calls this to perform work in a worker thread and delivers it the parameters given to AsyncTaskexecute() protected Bitmap doInBackground(String urls) return loadImageFromNetwork(urls[0])

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 35: 03 services

contentcomexamplecodelabtransportationprovidertrain

contentcomexamplecodelabtransportationproviderairdomestic

contentcomexamplecodelabtransportationproviderairinternational

For an overview of content URIs see the Content URI Summary at the end of this document

Define the column names that the content provider will return to clients If you are using an underlying

database these column names are typically identical to the SQL database column names they

represent Also define public static String constants that clients can use to specify the columns in

queries and other instructions

Be sure to include an integer column named _id (with the constant _ID) for the IDs of the records

You should have this field whether or not you have another field (such as a URL) that is also unique

among all records If youre using the SQLite database the _ID field should be the following type

INTEGER PRIMARY KEY AUTOINCREMENT

The AUTOINCREMENT descriptor is optional But without it SQLite increments an ID counter field to

the next number above the largest existing number in the column If you delete the last row the next

row added will have the same ID as the deleted row AUTOINCREMENT avoids this by having SQLite

increment to the next largest value whether deleted or not

Carefully document the data type of each column Clients need this information to read the data

If you are handling a new data type you must define a new MIME type to return in your

implementation of ContentProvidergetType() The type depends in part on whether or not the content

URI submitted to getType() limits the request to a specific record Theres one form of the MIME type

for a single record and another for multiple records Use the Uri methods to help determine what is

being requested Here is the general format for each type

o For a single record vndandroidcursoritemvndyourcompanynamecontenttype

For example a request for train record 122 like this URI

contentcomexampletransportationprovidertrains122

might return this MIME type

vndandroidcursoritemvndexamplerail

o For multiple records vndandroidcursordirvndyourcompanynamecontenttype

For example a request for all train records like the following URI

contentcomexampletransportationprovidertrains

might return this MIME type

vndandroidcursordirvndexamplerail

If you are exposing byte data thats too big to put in the table itself mdash such as a large bitmap file mdash the

field that exposes the data to clients should actually contain a content URI string This is the field that

gives clients access to the data file The record should also have another field named _data that lists

the exact file path on the device for that file This field is not intended to be read by the client but by

the ContentResolver The client will call ContentResolveropenInputStream() on the user-facing field

holding the URI for the item The ContentResolver will request the _data field for that record and

because it has higher permissions than a client it should be able to access that file directly and return

a read wrapper for the file to the client

For an example of a private content provider implementation see the NodePadProvider class in the

Notepad sample application that ships with the SDK

Declaring the content provider

To let the Android system know about the content provider youve developed declare it with a

ltprovidergt element in the applications AndroidManifestxml file Content providers that are not

declared in the manifest are not visible to the Android system

The name attribute is the fully qualified name of the ContentProvider subclass The authorities attribute

is the authority part of the content URI that identifies the provider For example if the ContentProvider

subclass is AutoInfoProvider the ltprovidergt element might look like this

ltprovider androidname=comexampleautosAutoInfoProvider androidauthorities=comexampleautosautoinfoprovider gt ltprovidergt

Note that the authorities attribute omits the path part of a content URI For example if

AutoInfoProvider controlled subtables for different types of autos or different manufacturers

contentcomexampleautosautoinfoproviderhonda

contentcomexampleautosautoinfoprovidergmcompact

contentcomexampleautosautoinfoprovidergmsuv

those paths would not be declared in the manifest The authority is what identifies the provider not the

path your provider can interpret the path part of the URI in any way you choose

Other ltprovidergt attributes can set permissions to read and write data provide for an icon and text

that can be displayed to users enable and disable the provider and so on Set the multiprocess

attribute to true if data does not need to be synchronized between multiple running versions of the

content provider This permits an instance of the provider to be created in each client process

eliminating the need to perform IPC

Content URI Summary

Here is a recap of the important parts of a content URI

A Standard prefix indicating that the data is controlled by a content provider Its never modified

B The authority part of the URI it identifies the content provider For third-party applications this should

be a fully-qualified class name (reduced to lowercase) to ensure uniqueness The authority is declared

in the ltprovidergt elements authorities attribute

ltprovider androidname=TransportationProvider androidauthorities=comexampletransportationprovider gt

C The path that the content provider uses to determine what kind of data is being requested This can be

zero or more segments long If the content provider exposes only one type of data (only trains for

example) it can be absent If the provider exposes several types including subtypes it can be several

segments long mdash for example landbus landtrain seaship and seasubmarine to give four

possibilities

D The ID of the specific record being requested if any This is the _ID value of the requested record If

the request is not limited to a single record this segment and the trailing slash are omitted

contentcomexampletransportationprovidertrains

Intent and intent filters

Three of the core components of an application mdash activities services and broadcast receivers mdash 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 mdash 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 ContextstartActivity() or ActivitystartActivityForResult() to launch an

activity or get an existing activity to do something new (It can also be passed to ActivitysetResult() to

return information to the activity that called startActivityForResult())

An Intent object is passed to ContextstartService() to initiate a service or deliver new instructions to an

ongoing service Similarly an intent can be passed to ContextbindService() to establish a connection

between the calling component and a target service It can optionally initiate the service if its not

already running

Intent objects passed to any of the broadcast methods (such as ContextsendBroadcast()

ContextsendOrderedBroadcast() or ContextsendStickyBroadcast()) 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 mdash how it resolves which component should receive an intent message For

intents that dont explicitly name a target component this process involves testing the Intent object

against intent filters associated with potential targets

Intent Objects

An Intent object is a bundle of information It contains information of interest to the component that

receives the intent (such as the action to be taken and the data to act on) plus information of interest to

the Android system (such as the category of component that should handle the intent and instructions

on how to launch a target activity) Principally it can contain the following

Component name

The name of the component that should handle the intent This field is a ComponentName

object mdash a combination of the fully qualified class name of the target component (for example

comexampleprojectappFreneticActivity) and the package name set in the manifest file of the

application where the component resides (for example comexampleproject) The package

part of the component name and the package name set in the manifest do not necessarily have

to match

The component name is optional If it is set the Intent object is delivered to an instance of the

designated class If it is not set Android uses other information in the Intent object to locate a

suitable target mdash see Intent Resolution later in this document

The component name is set by setComponent() setClass() or setClassName() and read by

getComponent()

Action

A string naming the action to be performed mdash or in the case of broadcast intents the action

that took place and is being reported The Intent class defines a number of action constants

including these

Constant Target

component

Action

ACTION_CALL activity Initiate a phone call

ACTION_EDIT activity Display data for the user to edit

ACTION_MAIN activity Start up as the initial activity of a task

with no data input and no returned

output

ACTION_SYNC activity Synchronize data on a server with

data on the mobile device

ACTION_BATTERY_LOW broadcast

receiver

A warning that the battery is low

ACTION_HEADSET_PLUG broadcast

receiver

A headset has been plugged into the

device or unplugged from it

ACTION_SCREEN_ON broadcast

receiver

The screen has been turned on

ACTION_TIMEZONE_CHANGED broadcast

receiver

The setting for the time zone has

changed

See the Intent class description for a list of pre-defined constants for generic actions Other

actions are defined elsewhere in the Android API You can also define your own action strings

for activating the components in your application Those you invent should include the

application package as a prefix mdash for example comexampleprojectSHOW_COLOR

The action largely determines how the rest of the intent is structured mdash particularly the data and

extras fields mdash much as a method name determines a set of arguments and a return value For

this reason its a good idea to use action names that are as specific as possible and to couple

them tightly to the other fields of the intent In other words instead of defining an action in

isolation define an entire protocol for the Intent objects your components can handle

The action in an Intent object is set by the setAction() method and read by getAction()

Data

The URI of the data to be acted on and the MIME type of that data Different actions are paired

with different kinds of data specifications For example if the action field is ACTION_EDIT the

data field would contain the URI of the document to be displayed for editing If the action is

ACTION_CALL the data field would be a tel URI with the number to call Similarly if the action

is ACTION_VIEW and the data field is an http URI the receiving activity would be called upon

to download and display whatever data the URI refers to

When matching an intent to a component that is capable of handling the data its often

important to know the type of data (its MIME type) in addition to its URI For example a

component able to display image data should not be called upon to play an audio file

In many cases the data type can be inferred from the URI mdash particularly content URIs which

indicate that the data is located on the device and controlled by a content provider (see the

separate discussion on content providers) But the type can also be explicitly set in the Intent

object The setData() method specifies data only as a URI setType() specifies it only as a

MIME type and setDataAndType() specifies it as both a URI and a MIME type The URI is read

by getData() and the type by getType()

Category

A string containing additional information about the kind of component that should handle the

intent Any number of category descriptions can be placed in an Intent object As it does for

actions the Intent class defines several category constants including these

Constant Meaning

CATEGORY_BROWSABLE The target activity can be safely invoked by the browser to

display data referenced by a link mdash for example an image or

an e-mail message

CATEGORY_GADGET The activity can be embedded inside of another activity that

hosts gadgets

CATEGORY_HOME The activity displays the home screen the first screen the

user sees when the device is turned on or when the HOME

key is pressed

CATEGORY_LAUNCHER The activity can be the initial activity of a task and is listed in

the top-level application launcher

CATEGORY_PREFERENCE The target activity is a preference panel

See the Intent class description for the full list of categories

The addCategory() method places a category in an Intent object removeCategory() deletes a

category previously added and getCategories() gets the set of all categories currently in the

object

Extras

Key-value pairs for additional information that should be delivered to the component handling

the intent Just as some actions are paired with particular kinds of data URIs some are paired

with particular extras For example an ACTION_TIMEZONE_CHANGED intent has a time-

zone extra that identifies the new time zone and ACTION_HEADSET_PLUG has a state

extra indicating whether the headset is now plugged in or unplugged as well as a name extra

for the type of headset If you were to invent a SHOW_COLOR action the color value would be

set in an extra key-value pair

The Intent object has a series of put() methods for inserting various types of extra data and a

similar set of get() methods for reading the data These methods parallel those for Bundle

objects In fact the extras can be installed and read as a Bundle using the putExtras() and

getExtras() methods

Flags

Flags of various sorts Many instruct the Android system how to launch an activity (for example

which task the activity should belong to) and how to treat it after its launched (for example

whether it belongs in the list of recent activities) All these flags are defined in the Intent class

The Android system and the applications that come with the platform employ Intent objects both to

send out system-originated broadcasts and to activate system-defined components To see how to

structure an intent to activate a system component consult the list of intents in the reference

Intent Resolution

Intents can be divided into two groups

Explicit intents designate the target component by its name (the component name field mentioned

earlier has a value set) Since component names would generally not be known to developers of other

applications explicit intents are typically used for application-internal messages mdash such as an activity

starting a subordinate service or launching a sister activity

Implicit intents do not name a target (the field for the component name is blank) Implicit intents are

often used to activate components in other applications

Android delivers an explicit intent to an instance of the designated target class Nothing in the Intent

object other than the component name matters for determining which component should get the intent

A different strategy is needed for implicit intents In the absence of a designated target the Android

system must find the best component (or components) to handle the intent mdash a single activity or

service to perform the requested action or the set of broadcast receivers to respond to the broadcast

announcement It does so by comparing the contents of the Intent object to intent filters structures

associated with components that can potentially receive intents Filters advertise the capabilities of a

component and delimit the intents it can handle They open the component to the possibility of

receiving implicit intents of the advertised type If a component does not have any intent filters it can

receive only explicit intents A component with filters can receive both explicit and implicit intents

Only three aspects of an Intent object are consulted when the object is tested against an intent filter

action

data (both URI and data type)

category

The extras and flags play no part in resolving which component receives an intent

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 mdash but only unwanted implicit intents (those that dont 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

components 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 mdash 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 Pads filters are described in the Note Pad Example

section later)

Filters and security

An intent filter cannot be relied on for security While it opens a component to receiving only certain

kinds of implicit intents it does nothing to prevent explicit intents from targeting the component Even

though a filter restricts the intents a component will be asked to handle to certain actions and data

sources someone could always put together an explicit intent with a different action and data source

and name the component as the target

An intent filter is an instance of the IntentFilter class However since the Android system must know

about the capabilities of a component before it can launch that component intent filters are generally

not set up in Java code but in the applications manifest file (AndroidManifestxml) as ltintent-filtergt

elements (The one exception would be filters for broadcast receivers that are registered dynamically

by calling ContextregisterReceiver() they are directly created as IntentFilter objects)

A filter has fields that parallel the action data and category fields of an Intent object An implicit intent

is tested against the filter in all three areas To be delivered to the component that owns the filter it

must pass all three tests If it fails even one of them the Android system wont deliver it to the

component mdash at least not on the basis of that filter However since a component can have multiple

intent filters an intent that does not pass through one of a components filters might make it through on

another

Each of the three tests is described in detail below

Action test

An ltintent-filtergt element in the manifest file lists actions as ltactiongt subelements For

example

ltintent-filter gt ltaction androidname=comexampleprojectSHOW_CURRENT gt ltaction androidname=comexampleprojectSHOW_RECENT gt ltaction androidname=comexampleprojectSHOW_PENDING gt ltintent-filtergt

As the example shows while an Intent object names just a single action a filter may list more

than one The list cannot be empty a filter must contain at least one ltactiongt element or it will

block all intents

To pass this test the action specified in the Intent object must match one of the actions listed in

the filter If the object or the filter does not specify an action the results are as follows

If the filter fails to list any actions there is nothing for an intent to match so all intents fail the

test No intents can get through the filter

On the other hand an Intent object that doesnt specify an action automatically passes the test

mdash as long as the filter contains at least one action

Category test

An ltintent-filtergt element also lists categories as subelements For example

ltintent-filter gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryBROWSABLE gt ltintent-filtergt

Note that the constants described earlier for actions and categories are not used in the manifest

file The full string values are used instead For instance the

androidintentcategoryBROWSABLE string in the example above corresponds to the

CATEGORY_BROWSABLE constant mentioned earlier in this document Similarly the string

androidintentactionEDIT corresponds to the ACTION_EDIT constant

For an intent to pass the category test every category in the Intent object must match a

category in the filter The filter can list additional categories but it cannot omit any that are in the

intent

In principle therefore an Intent object with no categories should always pass this test

regardless of whats in the filter Thats mostly true However with one exception Android treats

all implicit intents passed to startActivity() as if they contained at least one category

androidintentcategoryDEFAULT (the CATEGORY_DEFAULT constant) Therefore activities

that are willing to receive implicit intents must include androidintentcategoryDEFAULT in

their intent filters (Filters with androidintentactionMAIN and

androidintentcategoryLAUNCHER settings are the exception They mark activities that begin

new tasks and that are represented on the launcher screen They can include

androidintentcategoryDEFAULT in the list of categories but dont need to) See Using intent

matching later for more on these filters)

Data test

Like the action and categories the data specification for an intent filter is contained in a

subelement And as in those cases the subelement can appear multiple times or not at all For

example

ltintent-filter gt ltdata androidmimeType=videompeg androidscheme=http gt ltdata androidmimeType=audiompeg androidscheme=http gt ltintent-filtergt

Each ltdatagt element can specify a URI and a data type (MIME media type) There are

separate attributes mdash scheme host port and path mdash for each part of the URI

schemehostportpath

For example in the following URI

contentcomexampleproject200foldersubfolderetc

the scheme is content the host is comexampleproject the port is 200 and the path is

foldersubfolderetc The host and port together constitute the URI authority if a host is not

specified the port is ignored

Each of these attributes is optional but they are not independent of each other For an authority

to be meaningful a scheme must also be specified For a path to be meaningful both a scheme

and an authority must be specified

When the URI in an Intent object is compared to a URI specification in a filter its compared

only to the parts of the URI actually mentioned in the filter For example if a filter specifies only

a scheme all URIs with that scheme match the filter If a filter specifies a scheme and an

authority but no path all URIs with the same scheme and authority match regardless of their

paths If a filter specifies a scheme an authority and a path only URIs with the same scheme

authority and path match However a path specification in the filter can contain wildcards to

require only a partial match of the path

The type attribute of a ltdatagt element specifies the MIME type of the data Its more common in

filters than a URI Both the Intent object and the filter can use a wildcard for the subtype field

mdash for example text or audio mdash indicating any subtype matches

The data test compares both the URI and the data type in the Intent object to a URI and data

type specified in the filter The rules are as follows

a An Intent object that contains neither a URI nor a data type passes the test only if the filter

likewise does not specify any URIs or data types

b An Intent object that contains a URI but no data type (and a type cannot be inferred from the

URI) passes the test only if its URI matches a URI in the filter and the filter likewise does not

specify a type This will be the case only for URIs like mailto and tel that do not refer to actual

data

c An Intent object that contains a data type but not a URI passes the test only if the filter lists the

same data type and similarly does not specify a URI

d An Intent object that contains both a URI and a data type (or a data type can be inferred from

the URI) passes the data type part of the test only if its type matches a type listed in the filter It

passes the URI part of the test either if its URI matches a URI in the filter or if it has a content

or file URI and the filter does not specify a URI In other words a component is presumed to

support content and file data if its filter lists only a data type

If an intent can pass through the filters of more than one activity or service the user may be asked

which component to activate An exception is raised if no target can be found

Common cases

The last rule shown above for the data test rule (d) reflects the expectation that components are able

to get local data from a file or content provider Therefore their filters can list just a data type and do

not need to explicitly name the content and file schemes This is a typical case A ltdatagt element like

the following for example tells Android that the component can get image data from a content

provider and display it

ltdata androidmimeType=image gt

Since most available data is dispensed by content providers filters that specify a data type but not a

URI are perhaps the most common

Another common configuration is filters with a scheme and a data type For example a ltdatagt

element like the following tells Android that the component can get video data from the network and

display it

ltdata androidscheme=http androidtype=video gt

Consider for example what the browser application does when the user follows a link on a web page

It first tries to display the data (as it could if the link was to an HTML page) If it cant display the data it

puts together an implicit intent with the scheme and data type and tries to start an activity that can do

the job If there are no takers it asks the download manager to download the data That puts it under

the control of a content provider so a potentially larger pool of activities (those with filters that just

name a data type) can respond

Most applications also have a way to start fresh without a reference to any particular data Activities

that can initiate applications have filters with androidintentactionMAIN specified as the action If

they are to be represented in the application launcher they also specify the

androidintentcategoryLAUNCHER category

ltintent-filter gt ltaction androidname=code androidintentactionMAIN gt ltcategory androidname=code androidintentcategoryLAUNCHER gt ltintent-filtergt

Using intent matching

Intents are matched against intent filters not only to discover a target component to activate but also

to discover something about the set of components on the device For example the Android system

populates the application launcher the top-level screen that shows the applications that are available

for the user to launch by finding all the activities with intent filters that specify the

androidintentactionMAIN action and androidintentcategoryLAUNCHER category (as illustrated

in the previous section) It then displays the icons and labels of those activities in the launcher

Similarly it discovers the home screen by looking for the activity with androidintentcategoryHOME

in its filter

Your application can use intent matching is a similar way The PackageManager has a set of query()

methods that return all components that can accept a particular intent and a similar series of

resolve() methods that determine the best component to respond to an intent For example

queryIntentActivities() returns a list of all activities that can perform the intent passed as an argument

and queryIntentServices() returns a similar list of services Neither method activates the components

they just list the ones that can respond Theres a similar method queryBroadcastReceivers() for

broadcast receivers

Note Pad Example

The Note Pad sample application enables users to browse through a list of notes view details about

individual items in the list edit the items and add a new item to the list This section looks at the intent

filters declared in its manifest file (If youre working offline in the SDK you can find all the source files

for this sample application including its manifest file at ltsdkgtsamplesNotePadindexhtml If youre

viewing the documentation online the source files are in the Tutorials and Sample Code section here)

In its manifest file the Note Pad application declares three activities each with at least one intent filter

It also declares a content provider that manages the note data Here is the manifest file in its entirety

ltmanifest xmlnsandroid=httpschemasandroidcomapkresandroid package=comexampleandroidnotepadgt ltapplication androidicon=drawableapp_notes androidlabel=stringapp_name gt ltprovider androidname=NotePadProvider androidauthorities=comgoogleproviderNotePad gt ltactivity androidname=NotesList androidlabel=stringtitle_notes_listgt ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltactivity androidname=NoteEditor androidtheme=androidstyleThemeLight androidlabel=stringtitle_note gt ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltactivitygt

ltactivity androidname=TitleEditor androidlabel=stringtitle_edit_title androidtheme=androidstyleThemeDialoggt ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltapplicationgt ltmanifestgt

The first activity NotesList is distinguished from the other activities by the fact that it operates on a

directory of notes (the note list) rather than on a single note It would generally serve as the initial user

interface into the application It can do three things as described by its three intent filters

1 ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt

This filter declares the main entry point into the Note Pad application The standard MAIN action is an

entry point that does not require any other information in the Intent (no data specification for example)

and the LAUNCHER category says that this entry point should be listed in the application launcher

2 ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

This filter declares the things that the activity can do on a directory of notes It can allow the user to

view or edit the directory (via the VIEW and EDIT actions) or to pick a particular note from the

directory (via the PICK action)

The mimeType attribute of the ltdatagt element specifies the kind of data that these actions operate on

It indicates that the activity can get a Cursor over zero or more items (vndandroidcursordir) from a

content provider that holds Note Pad data (vndgooglenote) The Intent object that launches the

activity would include a content URI specifying the exact data of this type that the activity should open

Note also the DEFAULT category supplied in this filter Its there because the ContextstartActivity()

and ActivitystartActivityForResult() methods treat all intents as if they contained the DEFAULT

category mdash with just two exceptions

o Intents that explicitly name the target activity

o Intents consisting of the MAIN action and LAUNCHER category

Therefore the DEFAULT category is required for all filters mdash except for those with the MAIN action

and LAUNCHER category (Intent filters are not consulted for explicit intents)

3 ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

This filter describes the activitys ability to return a note selected by the user without requiring any

specification of the directory the user should choose from The GET_CONTENT action is similar to the

PICK action In both cases the activity returns the URI for a note selected by the user (In each case

its returned to the activity that called startActivityForResult() to start the NoteList activity) Here

however the caller specifies the type of data desired instead of the directory of data the user will be

picking from

The data type vndandroidcursoritemvndgooglenote indicates the type of data the activity can

return mdash a URI for a single note From the returned URI the caller can get a Cursor for exactly one

item (vndandroidcursoritem) from the content provider that holds Note Pad data (vndgooglenote)

In other words for the PICK action in the previous filter the data type indicates the type of data the

activity could display to the user For the GET_CONTENT filter it indicates the type of data the activity

can return to the caller

Given these capabilities the following intents will resolve to the NotesList activity

action androidintentactionMAIN

Launches the activity with no data specified

action androidintentactionMAIN

category androidintentcategoryLAUNCHER

Launches the activity with no data selected specified This is the actual intent used by the

Launcher to populate its top-level list All activities with filters that match this action and

category are added to the list

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of all the notes under

contentcomgoogleproviderNotePadnotes The user can then browse through the list and

get information about the items in it

action androidintentactionPICK

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of the notes under

contentcomgoogleproviderNotePadnotes The user can then pick a note from the list and

the activity will return the URI for that item back to the activity that started the NoteList activity

action androidintentactionGET_CONTENT

data type vndandroidcursoritemvndgooglenote

Asks the activity to supply a single item of Note Pad data

The second activity NoteEditor shows users a single note entry and allows them to edit it It can do

two things as described by its two intent filters

1 ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The first primary purpose of this activity is to enable the user to interact with a single note ampmdash to

either VIEW the note or EDIT it (The EDIT_NOTE category is a synonym for EDIT) The intent would

contain the URI for data matching the MIME type vndandroidcursoritemvndgooglenote mdash that is

the URI for a single specific note It would typically be a URI that was returned by the PICK or

GET_CONTENT actions of the NoteList activity

As before this filter lists the DEFAULT category so that the activity can be launched by intents that

dont explicitly specify the NoteEditor class

2 ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

The secondary purpose of this activity is to enable the user to create a new note which it will INSERT

into an existing directory of notes The intent would contain the URI for data matching the MIME type

vndandroidcursordirvndgooglenote mdash that is the URI for the directory where the note should be

placed

Given these capabilities the following intents will resolve to the NoteEditor activity

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID (For details on how content

URIs specify individual members of a group see Content Providers)

action androidintentactionEDIT

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID and to let the user edit it If

the user saves the changes the activity updates the data for the note in the content provider

action androidintentactionINSERT

data contentcomgoogleproviderNotePadnotes

Asks the activity to create a new empty note in the notes list at

contentcomgoogleproviderNotePadnotes and allow the user to edit it If the user saves the

note its URI is returned to the caller

The last activity TitleEditor enables the user to edit the title of a note This could be implemented by

directly invoking the activity (by explicitly setting its component name in the Intent) without using an

intent filter But here we take the opportunity to show how to publish alternative operations on existing

data

ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The single intent filter for this activity uses a custom action called

comandroidnotepadactionEDIT_TITLE It must be invoked on a specific note (data type

vndandroidcursoritemvndgooglenote) like the previous VIEW and EDIT actions However here the

activity displays the title contained in the note data not the content of the note itself

In addition to supporting the usual DEFAULT category the title editor also supports two other standard

categories ALTERNATIVE and SELECTED_ALTERNATIVE These categories identify activities that

can be presented to users in a menu of options (much as the LAUNCHER category identifies activities

that should be presented to user in the application launcher) Note that the filter also supplies an

explicit label (via androidlabel=stringresolve_title) to better control what users see when

presented with this activity as an alternative action to the data they are currently viewing (For more

information on these categories and building options menus see the

PackageManagerqueryIntentActivityOptions() and MenuaddIntentOptions() methods)

Given these capabilities the following intent will resolve to the TitleEditor activity

action comandroidnotepadactionEDIT_TITLE

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the title associated with note ID and allow the user to edit the title

Processes and Threads

When an application component starts and the application does not have any other components

running the Android system starts a new Linux process for the application with a single thread of

execution By default all components of the same application run in the same process and thread

(called the main thread) If an application component starts and there already exists a process for

that application (because another component from the application exists) then the component is

started within that process and uses the same thread of execution However you can arrange for

different components in your application to run in separate processes and you can create additional

threads for any process

This document discusses how processes and threads work in an Android application

Processes

By default all components of the same application run in the same process and most applications

should not change this However if you find that you need to control which process a certain

component belongs to you can do so in the manifest file

The manifest entry for each type of component elementmdashltactivitygt ltservicegt ltreceivergt and

ltprovidergtmdashsupports an androidprocess attribute that can specify a process in which that component

should run You can set this attribute so that each component runs in its own process or so that some

components share a process while others do not You can also set androidprocess so that

components of different applications run in the same processmdashprovided that the applications share the

same Linux user ID and are signed with the same certificates

The ltapplicationgt element also supports an androidprocess attribute to set a default value that

applies to all components

Android might 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 thats killed are consequently destroyed A process is started again for those components

when theres again work for them to do

When deciding which processes to kill the Android system weighs their relative importance to the

user For example it more readily shuts down a process hosting activities that are no longer visible on

screen compared to a process hosting visible activities The decision whether to terminate a process

therefore depends on the state of the components running in that process The rules used to decide

which processes to terminate is discussed below

Process lifecycle

The Android system tries to maintain an application process for as long as possible but eventually

needs to remove old processes to reclaim memory for new or more important processes To determine

which processes to keep and which to kill the system places each process into an importance

hierarchy based on the components running in the process and the state of those components

Processes with the lowest importance are eliminated first then those with the next lowest importance

and so on as necessary to recover system resources

There are five levels in the importance hierarchy The following list presents the different types of

processes in order of importance (the first process is most important and is killed last)

1 Foreground process

A process that is required for what the user is currently doing A process is considered to be in the

foreground if any of the following conditions are true

o It hosts an Activity that the user is interacting with (the Activitys onResume() method has been called)

o It hosts a Service thats bound to the activity that the user is interacting with

o It hosts a Service thats running in the foregroundmdashthe service has called startForeground()

o It hosts a Service thats executing one of its lifecycle callbacks (onCreate() onStart() or onDestroy())

o It hosts a BroadcastReceiver thats executing its onReceive() method

Generally only a few foreground processes exist at any given time They are killed only as a last

resortmdashif memory is so low that they cannot all continue to run Generally at that point the device has

reached a memory paging state so killing some foreground processes is required to keep the user

interface responsive

2 Visible process

A process that doesnt have any foreground components but still can affect what the user sees on

screen A process is considered to be visible if either of the following conditions are true

o It hosts an Activity that is not in the foreground but is still visible to the user (its onPause() method has

been called) This might occur for example if the foreground activity started a dialog which allows the

previous activity to be seen behind it

o It hosts a Service thats bound to a visible (or foreground) activity

A visible process is considered extremely important and will not be killed unless doing so is required to

keep all foreground processes running

3 Service process

A process that is running a service that has been started with the startService() method and does not

fall into either of the two higher categories Although service processes are not directly tied to anything

the user sees they are generally doing things that the user cares about (such as playing music in the

background or downloading data on the network) so the system keeps them running unless theres

not enough memory to retain them along with all foreground and visible processes

4 Background process

A process holding an activity thats not currently visible to the user (the activitys onStop() method has

been called) These processes have no direct impact on the user experience and the system can kill

them at any time to reclaim memory for a foreground visible or service process Usually there are

many background processes running so they are kept in an LRU (least recently used) list to ensure

that the process with the activity that was most recently seen by the user is the last to be killed If an

activity implements its lifecycle methods correctly and saves its current state killing its process will not

have a visible effect on the user experience because when the user navigates back to the activity the

activity restores all of its visible state See the Activities document for information about saving and

restoring state

5 Empty process

A process that doesnt hold any active application components The only reason to keep this kind of

process alive is for caching purposes to improve startup time the next time a component needs to run

in it The system often kills these processes in order to balance overall system resources between

process caches and the underlying kernel caches

Android ranks a process at the highest level it can based upon the importance of the components

currently active in the process For example if a process hosts a service and a visible activity the

process is ranked as a visible process not a service process

In addition a processs ranking might be increased because other processes are dependent on itmdasha

process that is serving another process can never be ranked lower than the process it is serving For

example if a content provider in process A is serving a client in process B or if a service in process A

is bound to a component in process B process A is always considered at least as important as

process B

Because a process running a service is ranked higher than a process with background activities an

activity that initiates a long-running operation might do well to start a service for that operation rather

than simply create a worker threadmdashparticularly if the operation will likely outlast the activity For

example an activity thats uploading a picture to a web site should start a service to perform the

upload so that the upload can continue in the background even if the user leaves the activity Using a

service guarantees that the operation will have at least service process priority regardless of what

happens to the activity This is the same reason that broadcast receivers should employ services

rather than simply put time-consuming operations in a thread

Threads

When an application is launched the system creates a thread of execution for the application called

main This thread is very important because it is in charge of dispatching events to the appropriate

user interface widgets including drawing events It is also the thread in which your application interacts

with components from the Android UI toolkit (components from the androidwidget and androidview

packages) As such the main thread is also sometimes called the UI thread

The system does not create a separate thread for each instance of a component All components that

run in the same process are instantiated in the UI thread and system calls to each component are

dispatched from that thread Consequently methods that respond to system callbacks (such as

onKeyDown() to report user actions or a lifecycle callback method) always run in the UI thread of the

process

For instance when the user touches a button on the screen your apps UI thread dispatches the touch

event to the widget which in turn sets its pressed state and posts an invalidate request to the event

queue The UI thread dequeues the request and notifies the widget that it should redraw itself

When your app performs intensive work in response to user interaction this single thread model can

yield poor performance unless you implement your application properly Specifically if everything is

happening in the UI thread performing long operations such as network access or database queries

will block the whole UI When the thread is blocked no events can be dispatched including drawing

events From the users perspective the application appears to hang Even worse if the UI thread is

blocked for more than a few seconds (about 5 seconds currently) the user is presented with the

infamous application not responding (ANR) dialog The user might then decide to quit your

application and uninstall it if they are unhappy

Additionally the Andoid UI toolkit is not thread-safe So you must not manipulate your UI from a

worker threadmdashyou must do all manipulation to your user interface from the UI thread Thus there are

simply two rules to Androids single thread model

1 Do not block the UI thread

2 Do not access the Android UI toolkit from outside the UI thread

Worker threads

Because of the single thread model described above its vital to the responsiveness of your

applications UI that you do not block the UI thread If you have operations to perform that are not

instantaneous you should make sure to do them in separate threads (background or worker

threads)

For example below is some code for a click listener that downloads an image from a separate thread

and displays it in an ImageView

public void onClick(View v) new Thread(new Runnable() public void run() Bitmap b = loadImageFromNetwork(httpexamplecomimagepng) mImageViewsetImageBitmap(b) )start()

At first this seems to work fine because it creates a new thread to handle the network operation

However it violates the second rule of the single-threaded model do not access the Android UI toolkit

from outside the UI threadmdashthis sample modifies the ImageView from the worker thread instead of the

UI thread This can result in undefined and unexpected behavior which can be difficult and time-

consuming to track down

To fix this problem Android offers several ways to access the UI thread from other threads Here is a

list of methods that can help

ActivityrunOnUiThread(Runnable)

Viewpost(Runnable)

ViewpostDelayed(Runnable long)

For example you can fix the above code by using the Viewpost(Runnable) method

public void onClick(View v) new Thread(new Runnable() public void run() final Bitmap bitmap = loadImageFromNetwork(httpexamplecomimagepng) mImageViewpost(new Runnable() public void run() mImageViewsetImageBitmap(bitmap) ) )start()

Now this implementation is thread-safe the network operation is done from a separate thread while

the ImageView is manipulated from the UI thread

However as the complexity of the operation grows this kind of code can get complicated and difficult

to maintain To handle more complex interactions with a worker thread you might consider using a

Handler in your worker thread to process messages delivered from the UI thread Perhaps the best

solution though is to extend the AsyncTask class which simplifies the execution of worker thread

tasks that need to interact with the UI

Using AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface It performs the blocking

operations in a worker thread and then publishes the results on the UI thread without requiring you to

handle threads andor handlers yourself

To use it you must subclass AsyncTask and implement the doInBackground() callback method which

runs in a pool of background threads To update your UI you should implement onPostExecute()

which delivers the result from doInBackground() and runs in the UI thread so you can safely update

your UI You can then run the task by calling execute() from the UI thread

For example you can implement the previous example using AsyncTask this way

public void onClick(View v) new DownloadImageTask()execute(httpexamplecomimagepng) private class DownloadImageTask extends AsyncTaskltString Void Bitmapgt The system calls this to perform work in a worker thread and delivers it the parameters given to AsyncTaskexecute() protected Bitmap doInBackground(String urls) return loadImageFromNetwork(urls[0])

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 36: 03 services

the exact file path on the device for that file This field is not intended to be read by the client but by

the ContentResolver The client will call ContentResolveropenInputStream() on the user-facing field

holding the URI for the item The ContentResolver will request the _data field for that record and

because it has higher permissions than a client it should be able to access that file directly and return

a read wrapper for the file to the client

For an example of a private content provider implementation see the NodePadProvider class in the

Notepad sample application that ships with the SDK

Declaring the content provider

To let the Android system know about the content provider youve developed declare it with a

ltprovidergt element in the applications AndroidManifestxml file Content providers that are not

declared in the manifest are not visible to the Android system

The name attribute is the fully qualified name of the ContentProvider subclass The authorities attribute

is the authority part of the content URI that identifies the provider For example if the ContentProvider

subclass is AutoInfoProvider the ltprovidergt element might look like this

ltprovider androidname=comexampleautosAutoInfoProvider androidauthorities=comexampleautosautoinfoprovider gt ltprovidergt

Note that the authorities attribute omits the path part of a content URI For example if

AutoInfoProvider controlled subtables for different types of autos or different manufacturers

contentcomexampleautosautoinfoproviderhonda

contentcomexampleautosautoinfoprovidergmcompact

contentcomexampleautosautoinfoprovidergmsuv

those paths would not be declared in the manifest The authority is what identifies the provider not the

path your provider can interpret the path part of the URI in any way you choose

Other ltprovidergt attributes can set permissions to read and write data provide for an icon and text

that can be displayed to users enable and disable the provider and so on Set the multiprocess

attribute to true if data does not need to be synchronized between multiple running versions of the

content provider This permits an instance of the provider to be created in each client process

eliminating the need to perform IPC

Content URI Summary

Here is a recap of the important parts of a content URI

A Standard prefix indicating that the data is controlled by a content provider Its never modified

B The authority part of the URI it identifies the content provider For third-party applications this should

be a fully-qualified class name (reduced to lowercase) to ensure uniqueness The authority is declared

in the ltprovidergt elements authorities attribute

ltprovider androidname=TransportationProvider androidauthorities=comexampletransportationprovider gt

C The path that the content provider uses to determine what kind of data is being requested This can be

zero or more segments long If the content provider exposes only one type of data (only trains for

example) it can be absent If the provider exposes several types including subtypes it can be several

segments long mdash for example landbus landtrain seaship and seasubmarine to give four

possibilities

D The ID of the specific record being requested if any This is the _ID value of the requested record If

the request is not limited to a single record this segment and the trailing slash are omitted

contentcomexampletransportationprovidertrains

Intent and intent filters

Three of the core components of an application mdash activities services and broadcast receivers mdash 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 mdash 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 ContextstartActivity() or ActivitystartActivityForResult() to launch an

activity or get an existing activity to do something new (It can also be passed to ActivitysetResult() to

return information to the activity that called startActivityForResult())

An Intent object is passed to ContextstartService() to initiate a service or deliver new instructions to an

ongoing service Similarly an intent can be passed to ContextbindService() to establish a connection

between the calling component and a target service It can optionally initiate the service if its not

already running

Intent objects passed to any of the broadcast methods (such as ContextsendBroadcast()

ContextsendOrderedBroadcast() or ContextsendStickyBroadcast()) 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 mdash how it resolves which component should receive an intent message For

intents that dont explicitly name a target component this process involves testing the Intent object

against intent filters associated with potential targets

Intent Objects

An Intent object is a bundle of information It contains information of interest to the component that

receives the intent (such as the action to be taken and the data to act on) plus information of interest to

the Android system (such as the category of component that should handle the intent and instructions

on how to launch a target activity) Principally it can contain the following

Component name

The name of the component that should handle the intent This field is a ComponentName

object mdash a combination of the fully qualified class name of the target component (for example

comexampleprojectappFreneticActivity) and the package name set in the manifest file of the

application where the component resides (for example comexampleproject) The package

part of the component name and the package name set in the manifest do not necessarily have

to match

The component name is optional If it is set the Intent object is delivered to an instance of the

designated class If it is not set Android uses other information in the Intent object to locate a

suitable target mdash see Intent Resolution later in this document

The component name is set by setComponent() setClass() or setClassName() and read by

getComponent()

Action

A string naming the action to be performed mdash or in the case of broadcast intents the action

that took place and is being reported The Intent class defines a number of action constants

including these

Constant Target

component

Action

ACTION_CALL activity Initiate a phone call

ACTION_EDIT activity Display data for the user to edit

ACTION_MAIN activity Start up as the initial activity of a task

with no data input and no returned

output

ACTION_SYNC activity Synchronize data on a server with

data on the mobile device

ACTION_BATTERY_LOW broadcast

receiver

A warning that the battery is low

ACTION_HEADSET_PLUG broadcast

receiver

A headset has been plugged into the

device or unplugged from it

ACTION_SCREEN_ON broadcast

receiver

The screen has been turned on

ACTION_TIMEZONE_CHANGED broadcast

receiver

The setting for the time zone has

changed

See the Intent class description for a list of pre-defined constants for generic actions Other

actions are defined elsewhere in the Android API You can also define your own action strings

for activating the components in your application Those you invent should include the

application package as a prefix mdash for example comexampleprojectSHOW_COLOR

The action largely determines how the rest of the intent is structured mdash particularly the data and

extras fields mdash much as a method name determines a set of arguments and a return value For

this reason its a good idea to use action names that are as specific as possible and to couple

them tightly to the other fields of the intent In other words instead of defining an action in

isolation define an entire protocol for the Intent objects your components can handle

The action in an Intent object is set by the setAction() method and read by getAction()

Data

The URI of the data to be acted on and the MIME type of that data Different actions are paired

with different kinds of data specifications For example if the action field is ACTION_EDIT the

data field would contain the URI of the document to be displayed for editing If the action is

ACTION_CALL the data field would be a tel URI with the number to call Similarly if the action

is ACTION_VIEW and the data field is an http URI the receiving activity would be called upon

to download and display whatever data the URI refers to

When matching an intent to a component that is capable of handling the data its often

important to know the type of data (its MIME type) in addition to its URI For example a

component able to display image data should not be called upon to play an audio file

In many cases the data type can be inferred from the URI mdash particularly content URIs which

indicate that the data is located on the device and controlled by a content provider (see the

separate discussion on content providers) But the type can also be explicitly set in the Intent

object The setData() method specifies data only as a URI setType() specifies it only as a

MIME type and setDataAndType() specifies it as both a URI and a MIME type The URI is read

by getData() and the type by getType()

Category

A string containing additional information about the kind of component that should handle the

intent Any number of category descriptions can be placed in an Intent object As it does for

actions the Intent class defines several category constants including these

Constant Meaning

CATEGORY_BROWSABLE The target activity can be safely invoked by the browser to

display data referenced by a link mdash for example an image or

an e-mail message

CATEGORY_GADGET The activity can be embedded inside of another activity that

hosts gadgets

CATEGORY_HOME The activity displays the home screen the first screen the

user sees when the device is turned on or when the HOME

key is pressed

CATEGORY_LAUNCHER The activity can be the initial activity of a task and is listed in

the top-level application launcher

CATEGORY_PREFERENCE The target activity is a preference panel

See the Intent class description for the full list of categories

The addCategory() method places a category in an Intent object removeCategory() deletes a

category previously added and getCategories() gets the set of all categories currently in the

object

Extras

Key-value pairs for additional information that should be delivered to the component handling

the intent Just as some actions are paired with particular kinds of data URIs some are paired

with particular extras For example an ACTION_TIMEZONE_CHANGED intent has a time-

zone extra that identifies the new time zone and ACTION_HEADSET_PLUG has a state

extra indicating whether the headset is now plugged in or unplugged as well as a name extra

for the type of headset If you were to invent a SHOW_COLOR action the color value would be

set in an extra key-value pair

The Intent object has a series of put() methods for inserting various types of extra data and a

similar set of get() methods for reading the data These methods parallel those for Bundle

objects In fact the extras can be installed and read as a Bundle using the putExtras() and

getExtras() methods

Flags

Flags of various sorts Many instruct the Android system how to launch an activity (for example

which task the activity should belong to) and how to treat it after its launched (for example

whether it belongs in the list of recent activities) All these flags are defined in the Intent class

The Android system and the applications that come with the platform employ Intent objects both to

send out system-originated broadcasts and to activate system-defined components To see how to

structure an intent to activate a system component consult the list of intents in the reference

Intent Resolution

Intents can be divided into two groups

Explicit intents designate the target component by its name (the component name field mentioned

earlier has a value set) Since component names would generally not be known to developers of other

applications explicit intents are typically used for application-internal messages mdash such as an activity

starting a subordinate service or launching a sister activity

Implicit intents do not name a target (the field for the component name is blank) Implicit intents are

often used to activate components in other applications

Android delivers an explicit intent to an instance of the designated target class Nothing in the Intent

object other than the component name matters for determining which component should get the intent

A different strategy is needed for implicit intents In the absence of a designated target the Android

system must find the best component (or components) to handle the intent mdash a single activity or

service to perform the requested action or the set of broadcast receivers to respond to the broadcast

announcement It does so by comparing the contents of the Intent object to intent filters structures

associated with components that can potentially receive intents Filters advertise the capabilities of a

component and delimit the intents it can handle They open the component to the possibility of

receiving implicit intents of the advertised type If a component does not have any intent filters it can

receive only explicit intents A component with filters can receive both explicit and implicit intents

Only three aspects of an Intent object are consulted when the object is tested against an intent filter

action

data (both URI and data type)

category

The extras and flags play no part in resolving which component receives an intent

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 mdash but only unwanted implicit intents (those that dont 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

components 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 mdash 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 Pads filters are described in the Note Pad Example

section later)

Filters and security

An intent filter cannot be relied on for security While it opens a component to receiving only certain

kinds of implicit intents it does nothing to prevent explicit intents from targeting the component Even

though a filter restricts the intents a component will be asked to handle to certain actions and data

sources someone could always put together an explicit intent with a different action and data source

and name the component as the target

An intent filter is an instance of the IntentFilter class However since the Android system must know

about the capabilities of a component before it can launch that component intent filters are generally

not set up in Java code but in the applications manifest file (AndroidManifestxml) as ltintent-filtergt

elements (The one exception would be filters for broadcast receivers that are registered dynamically

by calling ContextregisterReceiver() they are directly created as IntentFilter objects)

A filter has fields that parallel the action data and category fields of an Intent object An implicit intent

is tested against the filter in all three areas To be delivered to the component that owns the filter it

must pass all three tests If it fails even one of them the Android system wont deliver it to the

component mdash at least not on the basis of that filter However since a component can have multiple

intent filters an intent that does not pass through one of a components filters might make it through on

another

Each of the three tests is described in detail below

Action test

An ltintent-filtergt element in the manifest file lists actions as ltactiongt subelements For

example

ltintent-filter gt ltaction androidname=comexampleprojectSHOW_CURRENT gt ltaction androidname=comexampleprojectSHOW_RECENT gt ltaction androidname=comexampleprojectSHOW_PENDING gt ltintent-filtergt

As the example shows while an Intent object names just a single action a filter may list more

than one The list cannot be empty a filter must contain at least one ltactiongt element or it will

block all intents

To pass this test the action specified in the Intent object must match one of the actions listed in

the filter If the object or the filter does not specify an action the results are as follows

If the filter fails to list any actions there is nothing for an intent to match so all intents fail the

test No intents can get through the filter

On the other hand an Intent object that doesnt specify an action automatically passes the test

mdash as long as the filter contains at least one action

Category test

An ltintent-filtergt element also lists categories as subelements For example

ltintent-filter gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryBROWSABLE gt ltintent-filtergt

Note that the constants described earlier for actions and categories are not used in the manifest

file The full string values are used instead For instance the

androidintentcategoryBROWSABLE string in the example above corresponds to the

CATEGORY_BROWSABLE constant mentioned earlier in this document Similarly the string

androidintentactionEDIT corresponds to the ACTION_EDIT constant

For an intent to pass the category test every category in the Intent object must match a

category in the filter The filter can list additional categories but it cannot omit any that are in the

intent

In principle therefore an Intent object with no categories should always pass this test

regardless of whats in the filter Thats mostly true However with one exception Android treats

all implicit intents passed to startActivity() as if they contained at least one category

androidintentcategoryDEFAULT (the CATEGORY_DEFAULT constant) Therefore activities

that are willing to receive implicit intents must include androidintentcategoryDEFAULT in

their intent filters (Filters with androidintentactionMAIN and

androidintentcategoryLAUNCHER settings are the exception They mark activities that begin

new tasks and that are represented on the launcher screen They can include

androidintentcategoryDEFAULT in the list of categories but dont need to) See Using intent

matching later for more on these filters)

Data test

Like the action and categories the data specification for an intent filter is contained in a

subelement And as in those cases the subelement can appear multiple times or not at all For

example

ltintent-filter gt ltdata androidmimeType=videompeg androidscheme=http gt ltdata androidmimeType=audiompeg androidscheme=http gt ltintent-filtergt

Each ltdatagt element can specify a URI and a data type (MIME media type) There are

separate attributes mdash scheme host port and path mdash for each part of the URI

schemehostportpath

For example in the following URI

contentcomexampleproject200foldersubfolderetc

the scheme is content the host is comexampleproject the port is 200 and the path is

foldersubfolderetc The host and port together constitute the URI authority if a host is not

specified the port is ignored

Each of these attributes is optional but they are not independent of each other For an authority

to be meaningful a scheme must also be specified For a path to be meaningful both a scheme

and an authority must be specified

When the URI in an Intent object is compared to a URI specification in a filter its compared

only to the parts of the URI actually mentioned in the filter For example if a filter specifies only

a scheme all URIs with that scheme match the filter If a filter specifies a scheme and an

authority but no path all URIs with the same scheme and authority match regardless of their

paths If a filter specifies a scheme an authority and a path only URIs with the same scheme

authority and path match However a path specification in the filter can contain wildcards to

require only a partial match of the path

The type attribute of a ltdatagt element specifies the MIME type of the data Its more common in

filters than a URI Both the Intent object and the filter can use a wildcard for the subtype field

mdash for example text or audio mdash indicating any subtype matches

The data test compares both the URI and the data type in the Intent object to a URI and data

type specified in the filter The rules are as follows

a An Intent object that contains neither a URI nor a data type passes the test only if the filter

likewise does not specify any URIs or data types

b An Intent object that contains a URI but no data type (and a type cannot be inferred from the

URI) passes the test only if its URI matches a URI in the filter and the filter likewise does not

specify a type This will be the case only for URIs like mailto and tel that do not refer to actual

data

c An Intent object that contains a data type but not a URI passes the test only if the filter lists the

same data type and similarly does not specify a URI

d An Intent object that contains both a URI and a data type (or a data type can be inferred from

the URI) passes the data type part of the test only if its type matches a type listed in the filter It

passes the URI part of the test either if its URI matches a URI in the filter or if it has a content

or file URI and the filter does not specify a URI In other words a component is presumed to

support content and file data if its filter lists only a data type

If an intent can pass through the filters of more than one activity or service the user may be asked

which component to activate An exception is raised if no target can be found

Common cases

The last rule shown above for the data test rule (d) reflects the expectation that components are able

to get local data from a file or content provider Therefore their filters can list just a data type and do

not need to explicitly name the content and file schemes This is a typical case A ltdatagt element like

the following for example tells Android that the component can get image data from a content

provider and display it

ltdata androidmimeType=image gt

Since most available data is dispensed by content providers filters that specify a data type but not a

URI are perhaps the most common

Another common configuration is filters with a scheme and a data type For example a ltdatagt

element like the following tells Android that the component can get video data from the network and

display it

ltdata androidscheme=http androidtype=video gt

Consider for example what the browser application does when the user follows a link on a web page

It first tries to display the data (as it could if the link was to an HTML page) If it cant display the data it

puts together an implicit intent with the scheme and data type and tries to start an activity that can do

the job If there are no takers it asks the download manager to download the data That puts it under

the control of a content provider so a potentially larger pool of activities (those with filters that just

name a data type) can respond

Most applications also have a way to start fresh without a reference to any particular data Activities

that can initiate applications have filters with androidintentactionMAIN specified as the action If

they are to be represented in the application launcher they also specify the

androidintentcategoryLAUNCHER category

ltintent-filter gt ltaction androidname=code androidintentactionMAIN gt ltcategory androidname=code androidintentcategoryLAUNCHER gt ltintent-filtergt

Using intent matching

Intents are matched against intent filters not only to discover a target component to activate but also

to discover something about the set of components on the device For example the Android system

populates the application launcher the top-level screen that shows the applications that are available

for the user to launch by finding all the activities with intent filters that specify the

androidintentactionMAIN action and androidintentcategoryLAUNCHER category (as illustrated

in the previous section) It then displays the icons and labels of those activities in the launcher

Similarly it discovers the home screen by looking for the activity with androidintentcategoryHOME

in its filter

Your application can use intent matching is a similar way The PackageManager has a set of query()

methods that return all components that can accept a particular intent and a similar series of

resolve() methods that determine the best component to respond to an intent For example

queryIntentActivities() returns a list of all activities that can perform the intent passed as an argument

and queryIntentServices() returns a similar list of services Neither method activates the components

they just list the ones that can respond Theres a similar method queryBroadcastReceivers() for

broadcast receivers

Note Pad Example

The Note Pad sample application enables users to browse through a list of notes view details about

individual items in the list edit the items and add a new item to the list This section looks at the intent

filters declared in its manifest file (If youre working offline in the SDK you can find all the source files

for this sample application including its manifest file at ltsdkgtsamplesNotePadindexhtml If youre

viewing the documentation online the source files are in the Tutorials and Sample Code section here)

In its manifest file the Note Pad application declares three activities each with at least one intent filter

It also declares a content provider that manages the note data Here is the manifest file in its entirety

ltmanifest xmlnsandroid=httpschemasandroidcomapkresandroid package=comexampleandroidnotepadgt ltapplication androidicon=drawableapp_notes androidlabel=stringapp_name gt ltprovider androidname=NotePadProvider androidauthorities=comgoogleproviderNotePad gt ltactivity androidname=NotesList androidlabel=stringtitle_notes_listgt ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltactivity androidname=NoteEditor androidtheme=androidstyleThemeLight androidlabel=stringtitle_note gt ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltactivitygt

ltactivity androidname=TitleEditor androidlabel=stringtitle_edit_title androidtheme=androidstyleThemeDialoggt ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltapplicationgt ltmanifestgt

The first activity NotesList is distinguished from the other activities by the fact that it operates on a

directory of notes (the note list) rather than on a single note It would generally serve as the initial user

interface into the application It can do three things as described by its three intent filters

1 ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt

This filter declares the main entry point into the Note Pad application The standard MAIN action is an

entry point that does not require any other information in the Intent (no data specification for example)

and the LAUNCHER category says that this entry point should be listed in the application launcher

2 ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

This filter declares the things that the activity can do on a directory of notes It can allow the user to

view or edit the directory (via the VIEW and EDIT actions) or to pick a particular note from the

directory (via the PICK action)

The mimeType attribute of the ltdatagt element specifies the kind of data that these actions operate on

It indicates that the activity can get a Cursor over zero or more items (vndandroidcursordir) from a

content provider that holds Note Pad data (vndgooglenote) The Intent object that launches the

activity would include a content URI specifying the exact data of this type that the activity should open

Note also the DEFAULT category supplied in this filter Its there because the ContextstartActivity()

and ActivitystartActivityForResult() methods treat all intents as if they contained the DEFAULT

category mdash with just two exceptions

o Intents that explicitly name the target activity

o Intents consisting of the MAIN action and LAUNCHER category

Therefore the DEFAULT category is required for all filters mdash except for those with the MAIN action

and LAUNCHER category (Intent filters are not consulted for explicit intents)

3 ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

This filter describes the activitys ability to return a note selected by the user without requiring any

specification of the directory the user should choose from The GET_CONTENT action is similar to the

PICK action In both cases the activity returns the URI for a note selected by the user (In each case

its returned to the activity that called startActivityForResult() to start the NoteList activity) Here

however the caller specifies the type of data desired instead of the directory of data the user will be

picking from

The data type vndandroidcursoritemvndgooglenote indicates the type of data the activity can

return mdash a URI for a single note From the returned URI the caller can get a Cursor for exactly one

item (vndandroidcursoritem) from the content provider that holds Note Pad data (vndgooglenote)

In other words for the PICK action in the previous filter the data type indicates the type of data the

activity could display to the user For the GET_CONTENT filter it indicates the type of data the activity

can return to the caller

Given these capabilities the following intents will resolve to the NotesList activity

action androidintentactionMAIN

Launches the activity with no data specified

action androidintentactionMAIN

category androidintentcategoryLAUNCHER

Launches the activity with no data selected specified This is the actual intent used by the

Launcher to populate its top-level list All activities with filters that match this action and

category are added to the list

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of all the notes under

contentcomgoogleproviderNotePadnotes The user can then browse through the list and

get information about the items in it

action androidintentactionPICK

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of the notes under

contentcomgoogleproviderNotePadnotes The user can then pick a note from the list and

the activity will return the URI for that item back to the activity that started the NoteList activity

action androidintentactionGET_CONTENT

data type vndandroidcursoritemvndgooglenote

Asks the activity to supply a single item of Note Pad data

The second activity NoteEditor shows users a single note entry and allows them to edit it It can do

two things as described by its two intent filters

1 ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The first primary purpose of this activity is to enable the user to interact with a single note ampmdash to

either VIEW the note or EDIT it (The EDIT_NOTE category is a synonym for EDIT) The intent would

contain the URI for data matching the MIME type vndandroidcursoritemvndgooglenote mdash that is

the URI for a single specific note It would typically be a URI that was returned by the PICK or

GET_CONTENT actions of the NoteList activity

As before this filter lists the DEFAULT category so that the activity can be launched by intents that

dont explicitly specify the NoteEditor class

2 ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

The secondary purpose of this activity is to enable the user to create a new note which it will INSERT

into an existing directory of notes The intent would contain the URI for data matching the MIME type

vndandroidcursordirvndgooglenote mdash that is the URI for the directory where the note should be

placed

Given these capabilities the following intents will resolve to the NoteEditor activity

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID (For details on how content

URIs specify individual members of a group see Content Providers)

action androidintentactionEDIT

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID and to let the user edit it If

the user saves the changes the activity updates the data for the note in the content provider

action androidintentactionINSERT

data contentcomgoogleproviderNotePadnotes

Asks the activity to create a new empty note in the notes list at

contentcomgoogleproviderNotePadnotes and allow the user to edit it If the user saves the

note its URI is returned to the caller

The last activity TitleEditor enables the user to edit the title of a note This could be implemented by

directly invoking the activity (by explicitly setting its component name in the Intent) without using an

intent filter But here we take the opportunity to show how to publish alternative operations on existing

data

ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The single intent filter for this activity uses a custom action called

comandroidnotepadactionEDIT_TITLE It must be invoked on a specific note (data type

vndandroidcursoritemvndgooglenote) like the previous VIEW and EDIT actions However here the

activity displays the title contained in the note data not the content of the note itself

In addition to supporting the usual DEFAULT category the title editor also supports two other standard

categories ALTERNATIVE and SELECTED_ALTERNATIVE These categories identify activities that

can be presented to users in a menu of options (much as the LAUNCHER category identifies activities

that should be presented to user in the application launcher) Note that the filter also supplies an

explicit label (via androidlabel=stringresolve_title) to better control what users see when

presented with this activity as an alternative action to the data they are currently viewing (For more

information on these categories and building options menus see the

PackageManagerqueryIntentActivityOptions() and MenuaddIntentOptions() methods)

Given these capabilities the following intent will resolve to the TitleEditor activity

action comandroidnotepadactionEDIT_TITLE

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the title associated with note ID and allow the user to edit the title

Processes and Threads

When an application component starts and the application does not have any other components

running the Android system starts a new Linux process for the application with a single thread of

execution By default all components of the same application run in the same process and thread

(called the main thread) If an application component starts and there already exists a process for

that application (because another component from the application exists) then the component is

started within that process and uses the same thread of execution However you can arrange for

different components in your application to run in separate processes and you can create additional

threads for any process

This document discusses how processes and threads work in an Android application

Processes

By default all components of the same application run in the same process and most applications

should not change this However if you find that you need to control which process a certain

component belongs to you can do so in the manifest file

The manifest entry for each type of component elementmdashltactivitygt ltservicegt ltreceivergt and

ltprovidergtmdashsupports an androidprocess attribute that can specify a process in which that component

should run You can set this attribute so that each component runs in its own process or so that some

components share a process while others do not You can also set androidprocess so that

components of different applications run in the same processmdashprovided that the applications share the

same Linux user ID and are signed with the same certificates

The ltapplicationgt element also supports an androidprocess attribute to set a default value that

applies to all components

Android might 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 thats killed are consequently destroyed A process is started again for those components

when theres again work for them to do

When deciding which processes to kill the Android system weighs their relative importance to the

user For example it more readily shuts down a process hosting activities that are no longer visible on

screen compared to a process hosting visible activities The decision whether to terminate a process

therefore depends on the state of the components running in that process The rules used to decide

which processes to terminate is discussed below

Process lifecycle

The Android system tries to maintain an application process for as long as possible but eventually

needs to remove old processes to reclaim memory for new or more important processes To determine

which processes to keep and which to kill the system places each process into an importance

hierarchy based on the components running in the process and the state of those components

Processes with the lowest importance are eliminated first then those with the next lowest importance

and so on as necessary to recover system resources

There are five levels in the importance hierarchy The following list presents the different types of

processes in order of importance (the first process is most important and is killed last)

1 Foreground process

A process that is required for what the user is currently doing A process is considered to be in the

foreground if any of the following conditions are true

o It hosts an Activity that the user is interacting with (the Activitys onResume() method has been called)

o It hosts a Service thats bound to the activity that the user is interacting with

o It hosts a Service thats running in the foregroundmdashthe service has called startForeground()

o It hosts a Service thats executing one of its lifecycle callbacks (onCreate() onStart() or onDestroy())

o It hosts a BroadcastReceiver thats executing its onReceive() method

Generally only a few foreground processes exist at any given time They are killed only as a last

resortmdashif memory is so low that they cannot all continue to run Generally at that point the device has

reached a memory paging state so killing some foreground processes is required to keep the user

interface responsive

2 Visible process

A process that doesnt have any foreground components but still can affect what the user sees on

screen A process is considered to be visible if either of the following conditions are true

o It hosts an Activity that is not in the foreground but is still visible to the user (its onPause() method has

been called) This might occur for example if the foreground activity started a dialog which allows the

previous activity to be seen behind it

o It hosts a Service thats bound to a visible (or foreground) activity

A visible process is considered extremely important and will not be killed unless doing so is required to

keep all foreground processes running

3 Service process

A process that is running a service that has been started with the startService() method and does not

fall into either of the two higher categories Although service processes are not directly tied to anything

the user sees they are generally doing things that the user cares about (such as playing music in the

background or downloading data on the network) so the system keeps them running unless theres

not enough memory to retain them along with all foreground and visible processes

4 Background process

A process holding an activity thats not currently visible to the user (the activitys onStop() method has

been called) These processes have no direct impact on the user experience and the system can kill

them at any time to reclaim memory for a foreground visible or service process Usually there are

many background processes running so they are kept in an LRU (least recently used) list to ensure

that the process with the activity that was most recently seen by the user is the last to be killed If an

activity implements its lifecycle methods correctly and saves its current state killing its process will not

have a visible effect on the user experience because when the user navigates back to the activity the

activity restores all of its visible state See the Activities document for information about saving and

restoring state

5 Empty process

A process that doesnt hold any active application components The only reason to keep this kind of

process alive is for caching purposes to improve startup time the next time a component needs to run

in it The system often kills these processes in order to balance overall system resources between

process caches and the underlying kernel caches

Android ranks a process at the highest level it can based upon the importance of the components

currently active in the process For example if a process hosts a service and a visible activity the

process is ranked as a visible process not a service process

In addition a processs ranking might be increased because other processes are dependent on itmdasha

process that is serving another process can never be ranked lower than the process it is serving For

example if a content provider in process A is serving a client in process B or if a service in process A

is bound to a component in process B process A is always considered at least as important as

process B

Because a process running a service is ranked higher than a process with background activities an

activity that initiates a long-running operation might do well to start a service for that operation rather

than simply create a worker threadmdashparticularly if the operation will likely outlast the activity For

example an activity thats uploading a picture to a web site should start a service to perform the

upload so that the upload can continue in the background even if the user leaves the activity Using a

service guarantees that the operation will have at least service process priority regardless of what

happens to the activity This is the same reason that broadcast receivers should employ services

rather than simply put time-consuming operations in a thread

Threads

When an application is launched the system creates a thread of execution for the application called

main This thread is very important because it is in charge of dispatching events to the appropriate

user interface widgets including drawing events It is also the thread in which your application interacts

with components from the Android UI toolkit (components from the androidwidget and androidview

packages) As such the main thread is also sometimes called the UI thread

The system does not create a separate thread for each instance of a component All components that

run in the same process are instantiated in the UI thread and system calls to each component are

dispatched from that thread Consequently methods that respond to system callbacks (such as

onKeyDown() to report user actions or a lifecycle callback method) always run in the UI thread of the

process

For instance when the user touches a button on the screen your apps UI thread dispatches the touch

event to the widget which in turn sets its pressed state and posts an invalidate request to the event

queue The UI thread dequeues the request and notifies the widget that it should redraw itself

When your app performs intensive work in response to user interaction this single thread model can

yield poor performance unless you implement your application properly Specifically if everything is

happening in the UI thread performing long operations such as network access or database queries

will block the whole UI When the thread is blocked no events can be dispatched including drawing

events From the users perspective the application appears to hang Even worse if the UI thread is

blocked for more than a few seconds (about 5 seconds currently) the user is presented with the

infamous application not responding (ANR) dialog The user might then decide to quit your

application and uninstall it if they are unhappy

Additionally the Andoid UI toolkit is not thread-safe So you must not manipulate your UI from a

worker threadmdashyou must do all manipulation to your user interface from the UI thread Thus there are

simply two rules to Androids single thread model

1 Do not block the UI thread

2 Do not access the Android UI toolkit from outside the UI thread

Worker threads

Because of the single thread model described above its vital to the responsiveness of your

applications UI that you do not block the UI thread If you have operations to perform that are not

instantaneous you should make sure to do them in separate threads (background or worker

threads)

For example below is some code for a click listener that downloads an image from a separate thread

and displays it in an ImageView

public void onClick(View v) new Thread(new Runnable() public void run() Bitmap b = loadImageFromNetwork(httpexamplecomimagepng) mImageViewsetImageBitmap(b) )start()

At first this seems to work fine because it creates a new thread to handle the network operation

However it violates the second rule of the single-threaded model do not access the Android UI toolkit

from outside the UI threadmdashthis sample modifies the ImageView from the worker thread instead of the

UI thread This can result in undefined and unexpected behavior which can be difficult and time-

consuming to track down

To fix this problem Android offers several ways to access the UI thread from other threads Here is a

list of methods that can help

ActivityrunOnUiThread(Runnable)

Viewpost(Runnable)

ViewpostDelayed(Runnable long)

For example you can fix the above code by using the Viewpost(Runnable) method

public void onClick(View v) new Thread(new Runnable() public void run() final Bitmap bitmap = loadImageFromNetwork(httpexamplecomimagepng) mImageViewpost(new Runnable() public void run() mImageViewsetImageBitmap(bitmap) ) )start()

Now this implementation is thread-safe the network operation is done from a separate thread while

the ImageView is manipulated from the UI thread

However as the complexity of the operation grows this kind of code can get complicated and difficult

to maintain To handle more complex interactions with a worker thread you might consider using a

Handler in your worker thread to process messages delivered from the UI thread Perhaps the best

solution though is to extend the AsyncTask class which simplifies the execution of worker thread

tasks that need to interact with the UI

Using AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface It performs the blocking

operations in a worker thread and then publishes the results on the UI thread without requiring you to

handle threads andor handlers yourself

To use it you must subclass AsyncTask and implement the doInBackground() callback method which

runs in a pool of background threads To update your UI you should implement onPostExecute()

which delivers the result from doInBackground() and runs in the UI thread so you can safely update

your UI You can then run the task by calling execute() from the UI thread

For example you can implement the previous example using AsyncTask this way

public void onClick(View v) new DownloadImageTask()execute(httpexamplecomimagepng) private class DownloadImageTask extends AsyncTaskltString Void Bitmapgt The system calls this to perform work in a worker thread and delivers it the parameters given to AsyncTaskexecute() protected Bitmap doInBackground(String urls) return loadImageFromNetwork(urls[0])

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 37: 03 services

A Standard prefix indicating that the data is controlled by a content provider Its never modified

B The authority part of the URI it identifies the content provider For third-party applications this should

be a fully-qualified class name (reduced to lowercase) to ensure uniqueness The authority is declared

in the ltprovidergt elements authorities attribute

ltprovider androidname=TransportationProvider androidauthorities=comexampletransportationprovider gt

C The path that the content provider uses to determine what kind of data is being requested This can be

zero or more segments long If the content provider exposes only one type of data (only trains for

example) it can be absent If the provider exposes several types including subtypes it can be several

segments long mdash for example landbus landtrain seaship and seasubmarine to give four

possibilities

D The ID of the specific record being requested if any This is the _ID value of the requested record If

the request is not limited to a single record this segment and the trailing slash are omitted

contentcomexampletransportationprovidertrains

Intent and intent filters

Three of the core components of an application mdash activities services and broadcast receivers mdash 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 mdash 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 ContextstartActivity() or ActivitystartActivityForResult() to launch an

activity or get an existing activity to do something new (It can also be passed to ActivitysetResult() to

return information to the activity that called startActivityForResult())

An Intent object is passed to ContextstartService() to initiate a service or deliver new instructions to an

ongoing service Similarly an intent can be passed to ContextbindService() to establish a connection

between the calling component and a target service It can optionally initiate the service if its not

already running

Intent objects passed to any of the broadcast methods (such as ContextsendBroadcast()

ContextsendOrderedBroadcast() or ContextsendStickyBroadcast()) 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 mdash how it resolves which component should receive an intent message For

intents that dont explicitly name a target component this process involves testing the Intent object

against intent filters associated with potential targets

Intent Objects

An Intent object is a bundle of information It contains information of interest to the component that

receives the intent (such as the action to be taken and the data to act on) plus information of interest to

the Android system (such as the category of component that should handle the intent and instructions

on how to launch a target activity) Principally it can contain the following

Component name

The name of the component that should handle the intent This field is a ComponentName

object mdash a combination of the fully qualified class name of the target component (for example

comexampleprojectappFreneticActivity) and the package name set in the manifest file of the

application where the component resides (for example comexampleproject) The package

part of the component name and the package name set in the manifest do not necessarily have

to match

The component name is optional If it is set the Intent object is delivered to an instance of the

designated class If it is not set Android uses other information in the Intent object to locate a

suitable target mdash see Intent Resolution later in this document

The component name is set by setComponent() setClass() or setClassName() and read by

getComponent()

Action

A string naming the action to be performed mdash or in the case of broadcast intents the action

that took place and is being reported The Intent class defines a number of action constants

including these

Constant Target

component

Action

ACTION_CALL activity Initiate a phone call

ACTION_EDIT activity Display data for the user to edit

ACTION_MAIN activity Start up as the initial activity of a task

with no data input and no returned

output

ACTION_SYNC activity Synchronize data on a server with

data on the mobile device

ACTION_BATTERY_LOW broadcast

receiver

A warning that the battery is low

ACTION_HEADSET_PLUG broadcast

receiver

A headset has been plugged into the

device or unplugged from it

ACTION_SCREEN_ON broadcast

receiver

The screen has been turned on

ACTION_TIMEZONE_CHANGED broadcast

receiver

The setting for the time zone has

changed

See the Intent class description for a list of pre-defined constants for generic actions Other

actions are defined elsewhere in the Android API You can also define your own action strings

for activating the components in your application Those you invent should include the

application package as a prefix mdash for example comexampleprojectSHOW_COLOR

The action largely determines how the rest of the intent is structured mdash particularly the data and

extras fields mdash much as a method name determines a set of arguments and a return value For

this reason its a good idea to use action names that are as specific as possible and to couple

them tightly to the other fields of the intent In other words instead of defining an action in

isolation define an entire protocol for the Intent objects your components can handle

The action in an Intent object is set by the setAction() method and read by getAction()

Data

The URI of the data to be acted on and the MIME type of that data Different actions are paired

with different kinds of data specifications For example if the action field is ACTION_EDIT the

data field would contain the URI of the document to be displayed for editing If the action is

ACTION_CALL the data field would be a tel URI with the number to call Similarly if the action

is ACTION_VIEW and the data field is an http URI the receiving activity would be called upon

to download and display whatever data the URI refers to

When matching an intent to a component that is capable of handling the data its often

important to know the type of data (its MIME type) in addition to its URI For example a

component able to display image data should not be called upon to play an audio file

In many cases the data type can be inferred from the URI mdash particularly content URIs which

indicate that the data is located on the device and controlled by a content provider (see the

separate discussion on content providers) But the type can also be explicitly set in the Intent

object The setData() method specifies data only as a URI setType() specifies it only as a

MIME type and setDataAndType() specifies it as both a URI and a MIME type The URI is read

by getData() and the type by getType()

Category

A string containing additional information about the kind of component that should handle the

intent Any number of category descriptions can be placed in an Intent object As it does for

actions the Intent class defines several category constants including these

Constant Meaning

CATEGORY_BROWSABLE The target activity can be safely invoked by the browser to

display data referenced by a link mdash for example an image or

an e-mail message

CATEGORY_GADGET The activity can be embedded inside of another activity that

hosts gadgets

CATEGORY_HOME The activity displays the home screen the first screen the

user sees when the device is turned on or when the HOME

key is pressed

CATEGORY_LAUNCHER The activity can be the initial activity of a task and is listed in

the top-level application launcher

CATEGORY_PREFERENCE The target activity is a preference panel

See the Intent class description for the full list of categories

The addCategory() method places a category in an Intent object removeCategory() deletes a

category previously added and getCategories() gets the set of all categories currently in the

object

Extras

Key-value pairs for additional information that should be delivered to the component handling

the intent Just as some actions are paired with particular kinds of data URIs some are paired

with particular extras For example an ACTION_TIMEZONE_CHANGED intent has a time-

zone extra that identifies the new time zone and ACTION_HEADSET_PLUG has a state

extra indicating whether the headset is now plugged in or unplugged as well as a name extra

for the type of headset If you were to invent a SHOW_COLOR action the color value would be

set in an extra key-value pair

The Intent object has a series of put() methods for inserting various types of extra data and a

similar set of get() methods for reading the data These methods parallel those for Bundle

objects In fact the extras can be installed and read as a Bundle using the putExtras() and

getExtras() methods

Flags

Flags of various sorts Many instruct the Android system how to launch an activity (for example

which task the activity should belong to) and how to treat it after its launched (for example

whether it belongs in the list of recent activities) All these flags are defined in the Intent class

The Android system and the applications that come with the platform employ Intent objects both to

send out system-originated broadcasts and to activate system-defined components To see how to

structure an intent to activate a system component consult the list of intents in the reference

Intent Resolution

Intents can be divided into two groups

Explicit intents designate the target component by its name (the component name field mentioned

earlier has a value set) Since component names would generally not be known to developers of other

applications explicit intents are typically used for application-internal messages mdash such as an activity

starting a subordinate service or launching a sister activity

Implicit intents do not name a target (the field for the component name is blank) Implicit intents are

often used to activate components in other applications

Android delivers an explicit intent to an instance of the designated target class Nothing in the Intent

object other than the component name matters for determining which component should get the intent

A different strategy is needed for implicit intents In the absence of a designated target the Android

system must find the best component (or components) to handle the intent mdash a single activity or

service to perform the requested action or the set of broadcast receivers to respond to the broadcast

announcement It does so by comparing the contents of the Intent object to intent filters structures

associated with components that can potentially receive intents Filters advertise the capabilities of a

component and delimit the intents it can handle They open the component to the possibility of

receiving implicit intents of the advertised type If a component does not have any intent filters it can

receive only explicit intents A component with filters can receive both explicit and implicit intents

Only three aspects of an Intent object are consulted when the object is tested against an intent filter

action

data (both URI and data type)

category

The extras and flags play no part in resolving which component receives an intent

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 mdash but only unwanted implicit intents (those that dont 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

components 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 mdash 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 Pads filters are described in the Note Pad Example

section later)

Filters and security

An intent filter cannot be relied on for security While it opens a component to receiving only certain

kinds of implicit intents it does nothing to prevent explicit intents from targeting the component Even

though a filter restricts the intents a component will be asked to handle to certain actions and data

sources someone could always put together an explicit intent with a different action and data source

and name the component as the target

An intent filter is an instance of the IntentFilter class However since the Android system must know

about the capabilities of a component before it can launch that component intent filters are generally

not set up in Java code but in the applications manifest file (AndroidManifestxml) as ltintent-filtergt

elements (The one exception would be filters for broadcast receivers that are registered dynamically

by calling ContextregisterReceiver() they are directly created as IntentFilter objects)

A filter has fields that parallel the action data and category fields of an Intent object An implicit intent

is tested against the filter in all three areas To be delivered to the component that owns the filter it

must pass all three tests If it fails even one of them the Android system wont deliver it to the

component mdash at least not on the basis of that filter However since a component can have multiple

intent filters an intent that does not pass through one of a components filters might make it through on

another

Each of the three tests is described in detail below

Action test

An ltintent-filtergt element in the manifest file lists actions as ltactiongt subelements For

example

ltintent-filter gt ltaction androidname=comexampleprojectSHOW_CURRENT gt ltaction androidname=comexampleprojectSHOW_RECENT gt ltaction androidname=comexampleprojectSHOW_PENDING gt ltintent-filtergt

As the example shows while an Intent object names just a single action a filter may list more

than one The list cannot be empty a filter must contain at least one ltactiongt element or it will

block all intents

To pass this test the action specified in the Intent object must match one of the actions listed in

the filter If the object or the filter does not specify an action the results are as follows

If the filter fails to list any actions there is nothing for an intent to match so all intents fail the

test No intents can get through the filter

On the other hand an Intent object that doesnt specify an action automatically passes the test

mdash as long as the filter contains at least one action

Category test

An ltintent-filtergt element also lists categories as subelements For example

ltintent-filter gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryBROWSABLE gt ltintent-filtergt

Note that the constants described earlier for actions and categories are not used in the manifest

file The full string values are used instead For instance the

androidintentcategoryBROWSABLE string in the example above corresponds to the

CATEGORY_BROWSABLE constant mentioned earlier in this document Similarly the string

androidintentactionEDIT corresponds to the ACTION_EDIT constant

For an intent to pass the category test every category in the Intent object must match a

category in the filter The filter can list additional categories but it cannot omit any that are in the

intent

In principle therefore an Intent object with no categories should always pass this test

regardless of whats in the filter Thats mostly true However with one exception Android treats

all implicit intents passed to startActivity() as if they contained at least one category

androidintentcategoryDEFAULT (the CATEGORY_DEFAULT constant) Therefore activities

that are willing to receive implicit intents must include androidintentcategoryDEFAULT in

their intent filters (Filters with androidintentactionMAIN and

androidintentcategoryLAUNCHER settings are the exception They mark activities that begin

new tasks and that are represented on the launcher screen They can include

androidintentcategoryDEFAULT in the list of categories but dont need to) See Using intent

matching later for more on these filters)

Data test

Like the action and categories the data specification for an intent filter is contained in a

subelement And as in those cases the subelement can appear multiple times or not at all For

example

ltintent-filter gt ltdata androidmimeType=videompeg androidscheme=http gt ltdata androidmimeType=audiompeg androidscheme=http gt ltintent-filtergt

Each ltdatagt element can specify a URI and a data type (MIME media type) There are

separate attributes mdash scheme host port and path mdash for each part of the URI

schemehostportpath

For example in the following URI

contentcomexampleproject200foldersubfolderetc

the scheme is content the host is comexampleproject the port is 200 and the path is

foldersubfolderetc The host and port together constitute the URI authority if a host is not

specified the port is ignored

Each of these attributes is optional but they are not independent of each other For an authority

to be meaningful a scheme must also be specified For a path to be meaningful both a scheme

and an authority must be specified

When the URI in an Intent object is compared to a URI specification in a filter its compared

only to the parts of the URI actually mentioned in the filter For example if a filter specifies only

a scheme all URIs with that scheme match the filter If a filter specifies a scheme and an

authority but no path all URIs with the same scheme and authority match regardless of their

paths If a filter specifies a scheme an authority and a path only URIs with the same scheme

authority and path match However a path specification in the filter can contain wildcards to

require only a partial match of the path

The type attribute of a ltdatagt element specifies the MIME type of the data Its more common in

filters than a URI Both the Intent object and the filter can use a wildcard for the subtype field

mdash for example text or audio mdash indicating any subtype matches

The data test compares both the URI and the data type in the Intent object to a URI and data

type specified in the filter The rules are as follows

a An Intent object that contains neither a URI nor a data type passes the test only if the filter

likewise does not specify any URIs or data types

b An Intent object that contains a URI but no data type (and a type cannot be inferred from the

URI) passes the test only if its URI matches a URI in the filter and the filter likewise does not

specify a type This will be the case only for URIs like mailto and tel that do not refer to actual

data

c An Intent object that contains a data type but not a URI passes the test only if the filter lists the

same data type and similarly does not specify a URI

d An Intent object that contains both a URI and a data type (or a data type can be inferred from

the URI) passes the data type part of the test only if its type matches a type listed in the filter It

passes the URI part of the test either if its URI matches a URI in the filter or if it has a content

or file URI and the filter does not specify a URI In other words a component is presumed to

support content and file data if its filter lists only a data type

If an intent can pass through the filters of more than one activity or service the user may be asked

which component to activate An exception is raised if no target can be found

Common cases

The last rule shown above for the data test rule (d) reflects the expectation that components are able

to get local data from a file or content provider Therefore their filters can list just a data type and do

not need to explicitly name the content and file schemes This is a typical case A ltdatagt element like

the following for example tells Android that the component can get image data from a content

provider and display it

ltdata androidmimeType=image gt

Since most available data is dispensed by content providers filters that specify a data type but not a

URI are perhaps the most common

Another common configuration is filters with a scheme and a data type For example a ltdatagt

element like the following tells Android that the component can get video data from the network and

display it

ltdata androidscheme=http androidtype=video gt

Consider for example what the browser application does when the user follows a link on a web page

It first tries to display the data (as it could if the link was to an HTML page) If it cant display the data it

puts together an implicit intent with the scheme and data type and tries to start an activity that can do

the job If there are no takers it asks the download manager to download the data That puts it under

the control of a content provider so a potentially larger pool of activities (those with filters that just

name a data type) can respond

Most applications also have a way to start fresh without a reference to any particular data Activities

that can initiate applications have filters with androidintentactionMAIN specified as the action If

they are to be represented in the application launcher they also specify the

androidintentcategoryLAUNCHER category

ltintent-filter gt ltaction androidname=code androidintentactionMAIN gt ltcategory androidname=code androidintentcategoryLAUNCHER gt ltintent-filtergt

Using intent matching

Intents are matched against intent filters not only to discover a target component to activate but also

to discover something about the set of components on the device For example the Android system

populates the application launcher the top-level screen that shows the applications that are available

for the user to launch by finding all the activities with intent filters that specify the

androidintentactionMAIN action and androidintentcategoryLAUNCHER category (as illustrated

in the previous section) It then displays the icons and labels of those activities in the launcher

Similarly it discovers the home screen by looking for the activity with androidintentcategoryHOME

in its filter

Your application can use intent matching is a similar way The PackageManager has a set of query()

methods that return all components that can accept a particular intent and a similar series of

resolve() methods that determine the best component to respond to an intent For example

queryIntentActivities() returns a list of all activities that can perform the intent passed as an argument

and queryIntentServices() returns a similar list of services Neither method activates the components

they just list the ones that can respond Theres a similar method queryBroadcastReceivers() for

broadcast receivers

Note Pad Example

The Note Pad sample application enables users to browse through a list of notes view details about

individual items in the list edit the items and add a new item to the list This section looks at the intent

filters declared in its manifest file (If youre working offline in the SDK you can find all the source files

for this sample application including its manifest file at ltsdkgtsamplesNotePadindexhtml If youre

viewing the documentation online the source files are in the Tutorials and Sample Code section here)

In its manifest file the Note Pad application declares three activities each with at least one intent filter

It also declares a content provider that manages the note data Here is the manifest file in its entirety

ltmanifest xmlnsandroid=httpschemasandroidcomapkresandroid package=comexampleandroidnotepadgt ltapplication androidicon=drawableapp_notes androidlabel=stringapp_name gt ltprovider androidname=NotePadProvider androidauthorities=comgoogleproviderNotePad gt ltactivity androidname=NotesList androidlabel=stringtitle_notes_listgt ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltactivity androidname=NoteEditor androidtheme=androidstyleThemeLight androidlabel=stringtitle_note gt ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltactivitygt

ltactivity androidname=TitleEditor androidlabel=stringtitle_edit_title androidtheme=androidstyleThemeDialoggt ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltapplicationgt ltmanifestgt

The first activity NotesList is distinguished from the other activities by the fact that it operates on a

directory of notes (the note list) rather than on a single note It would generally serve as the initial user

interface into the application It can do three things as described by its three intent filters

1 ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt

This filter declares the main entry point into the Note Pad application The standard MAIN action is an

entry point that does not require any other information in the Intent (no data specification for example)

and the LAUNCHER category says that this entry point should be listed in the application launcher

2 ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

This filter declares the things that the activity can do on a directory of notes It can allow the user to

view or edit the directory (via the VIEW and EDIT actions) or to pick a particular note from the

directory (via the PICK action)

The mimeType attribute of the ltdatagt element specifies the kind of data that these actions operate on

It indicates that the activity can get a Cursor over zero or more items (vndandroidcursordir) from a

content provider that holds Note Pad data (vndgooglenote) The Intent object that launches the

activity would include a content URI specifying the exact data of this type that the activity should open

Note also the DEFAULT category supplied in this filter Its there because the ContextstartActivity()

and ActivitystartActivityForResult() methods treat all intents as if they contained the DEFAULT

category mdash with just two exceptions

o Intents that explicitly name the target activity

o Intents consisting of the MAIN action and LAUNCHER category

Therefore the DEFAULT category is required for all filters mdash except for those with the MAIN action

and LAUNCHER category (Intent filters are not consulted for explicit intents)

3 ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

This filter describes the activitys ability to return a note selected by the user without requiring any

specification of the directory the user should choose from The GET_CONTENT action is similar to the

PICK action In both cases the activity returns the URI for a note selected by the user (In each case

its returned to the activity that called startActivityForResult() to start the NoteList activity) Here

however the caller specifies the type of data desired instead of the directory of data the user will be

picking from

The data type vndandroidcursoritemvndgooglenote indicates the type of data the activity can

return mdash a URI for a single note From the returned URI the caller can get a Cursor for exactly one

item (vndandroidcursoritem) from the content provider that holds Note Pad data (vndgooglenote)

In other words for the PICK action in the previous filter the data type indicates the type of data the

activity could display to the user For the GET_CONTENT filter it indicates the type of data the activity

can return to the caller

Given these capabilities the following intents will resolve to the NotesList activity

action androidintentactionMAIN

Launches the activity with no data specified

action androidintentactionMAIN

category androidintentcategoryLAUNCHER

Launches the activity with no data selected specified This is the actual intent used by the

Launcher to populate its top-level list All activities with filters that match this action and

category are added to the list

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of all the notes under

contentcomgoogleproviderNotePadnotes The user can then browse through the list and

get information about the items in it

action androidintentactionPICK

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of the notes under

contentcomgoogleproviderNotePadnotes The user can then pick a note from the list and

the activity will return the URI for that item back to the activity that started the NoteList activity

action androidintentactionGET_CONTENT

data type vndandroidcursoritemvndgooglenote

Asks the activity to supply a single item of Note Pad data

The second activity NoteEditor shows users a single note entry and allows them to edit it It can do

two things as described by its two intent filters

1 ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The first primary purpose of this activity is to enable the user to interact with a single note ampmdash to

either VIEW the note or EDIT it (The EDIT_NOTE category is a synonym for EDIT) The intent would

contain the URI for data matching the MIME type vndandroidcursoritemvndgooglenote mdash that is

the URI for a single specific note It would typically be a URI that was returned by the PICK or

GET_CONTENT actions of the NoteList activity

As before this filter lists the DEFAULT category so that the activity can be launched by intents that

dont explicitly specify the NoteEditor class

2 ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

The secondary purpose of this activity is to enable the user to create a new note which it will INSERT

into an existing directory of notes The intent would contain the URI for data matching the MIME type

vndandroidcursordirvndgooglenote mdash that is the URI for the directory where the note should be

placed

Given these capabilities the following intents will resolve to the NoteEditor activity

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID (For details on how content

URIs specify individual members of a group see Content Providers)

action androidintentactionEDIT

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID and to let the user edit it If

the user saves the changes the activity updates the data for the note in the content provider

action androidintentactionINSERT

data contentcomgoogleproviderNotePadnotes

Asks the activity to create a new empty note in the notes list at

contentcomgoogleproviderNotePadnotes and allow the user to edit it If the user saves the

note its URI is returned to the caller

The last activity TitleEditor enables the user to edit the title of a note This could be implemented by

directly invoking the activity (by explicitly setting its component name in the Intent) without using an

intent filter But here we take the opportunity to show how to publish alternative operations on existing

data

ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The single intent filter for this activity uses a custom action called

comandroidnotepadactionEDIT_TITLE It must be invoked on a specific note (data type

vndandroidcursoritemvndgooglenote) like the previous VIEW and EDIT actions However here the

activity displays the title contained in the note data not the content of the note itself

In addition to supporting the usual DEFAULT category the title editor also supports two other standard

categories ALTERNATIVE and SELECTED_ALTERNATIVE These categories identify activities that

can be presented to users in a menu of options (much as the LAUNCHER category identifies activities

that should be presented to user in the application launcher) Note that the filter also supplies an

explicit label (via androidlabel=stringresolve_title) to better control what users see when

presented with this activity as an alternative action to the data they are currently viewing (For more

information on these categories and building options menus see the

PackageManagerqueryIntentActivityOptions() and MenuaddIntentOptions() methods)

Given these capabilities the following intent will resolve to the TitleEditor activity

action comandroidnotepadactionEDIT_TITLE

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the title associated with note ID and allow the user to edit the title

Processes and Threads

When an application component starts and the application does not have any other components

running the Android system starts a new Linux process for the application with a single thread of

execution By default all components of the same application run in the same process and thread

(called the main thread) If an application component starts and there already exists a process for

that application (because another component from the application exists) then the component is

started within that process and uses the same thread of execution However you can arrange for

different components in your application to run in separate processes and you can create additional

threads for any process

This document discusses how processes and threads work in an Android application

Processes

By default all components of the same application run in the same process and most applications

should not change this However if you find that you need to control which process a certain

component belongs to you can do so in the manifest file

The manifest entry for each type of component elementmdashltactivitygt ltservicegt ltreceivergt and

ltprovidergtmdashsupports an androidprocess attribute that can specify a process in which that component

should run You can set this attribute so that each component runs in its own process or so that some

components share a process while others do not You can also set androidprocess so that

components of different applications run in the same processmdashprovided that the applications share the

same Linux user ID and are signed with the same certificates

The ltapplicationgt element also supports an androidprocess attribute to set a default value that

applies to all components

Android might 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 thats killed are consequently destroyed A process is started again for those components

when theres again work for them to do

When deciding which processes to kill the Android system weighs their relative importance to the

user For example it more readily shuts down a process hosting activities that are no longer visible on

screen compared to a process hosting visible activities The decision whether to terminate a process

therefore depends on the state of the components running in that process The rules used to decide

which processes to terminate is discussed below

Process lifecycle

The Android system tries to maintain an application process for as long as possible but eventually

needs to remove old processes to reclaim memory for new or more important processes To determine

which processes to keep and which to kill the system places each process into an importance

hierarchy based on the components running in the process and the state of those components

Processes with the lowest importance are eliminated first then those with the next lowest importance

and so on as necessary to recover system resources

There are five levels in the importance hierarchy The following list presents the different types of

processes in order of importance (the first process is most important and is killed last)

1 Foreground process

A process that is required for what the user is currently doing A process is considered to be in the

foreground if any of the following conditions are true

o It hosts an Activity that the user is interacting with (the Activitys onResume() method has been called)

o It hosts a Service thats bound to the activity that the user is interacting with

o It hosts a Service thats running in the foregroundmdashthe service has called startForeground()

o It hosts a Service thats executing one of its lifecycle callbacks (onCreate() onStart() or onDestroy())

o It hosts a BroadcastReceiver thats executing its onReceive() method

Generally only a few foreground processes exist at any given time They are killed only as a last

resortmdashif memory is so low that they cannot all continue to run Generally at that point the device has

reached a memory paging state so killing some foreground processes is required to keep the user

interface responsive

2 Visible process

A process that doesnt have any foreground components but still can affect what the user sees on

screen A process is considered to be visible if either of the following conditions are true

o It hosts an Activity that is not in the foreground but is still visible to the user (its onPause() method has

been called) This might occur for example if the foreground activity started a dialog which allows the

previous activity to be seen behind it

o It hosts a Service thats bound to a visible (or foreground) activity

A visible process is considered extremely important and will not be killed unless doing so is required to

keep all foreground processes running

3 Service process

A process that is running a service that has been started with the startService() method and does not

fall into either of the two higher categories Although service processes are not directly tied to anything

the user sees they are generally doing things that the user cares about (such as playing music in the

background or downloading data on the network) so the system keeps them running unless theres

not enough memory to retain them along with all foreground and visible processes

4 Background process

A process holding an activity thats not currently visible to the user (the activitys onStop() method has

been called) These processes have no direct impact on the user experience and the system can kill

them at any time to reclaim memory for a foreground visible or service process Usually there are

many background processes running so they are kept in an LRU (least recently used) list to ensure

that the process with the activity that was most recently seen by the user is the last to be killed If an

activity implements its lifecycle methods correctly and saves its current state killing its process will not

have a visible effect on the user experience because when the user navigates back to the activity the

activity restores all of its visible state See the Activities document for information about saving and

restoring state

5 Empty process

A process that doesnt hold any active application components The only reason to keep this kind of

process alive is for caching purposes to improve startup time the next time a component needs to run

in it The system often kills these processes in order to balance overall system resources between

process caches and the underlying kernel caches

Android ranks a process at the highest level it can based upon the importance of the components

currently active in the process For example if a process hosts a service and a visible activity the

process is ranked as a visible process not a service process

In addition a processs ranking might be increased because other processes are dependent on itmdasha

process that is serving another process can never be ranked lower than the process it is serving For

example if a content provider in process A is serving a client in process B or if a service in process A

is bound to a component in process B process A is always considered at least as important as

process B

Because a process running a service is ranked higher than a process with background activities an

activity that initiates a long-running operation might do well to start a service for that operation rather

than simply create a worker threadmdashparticularly if the operation will likely outlast the activity For

example an activity thats uploading a picture to a web site should start a service to perform the

upload so that the upload can continue in the background even if the user leaves the activity Using a

service guarantees that the operation will have at least service process priority regardless of what

happens to the activity This is the same reason that broadcast receivers should employ services

rather than simply put time-consuming operations in a thread

Threads

When an application is launched the system creates a thread of execution for the application called

main This thread is very important because it is in charge of dispatching events to the appropriate

user interface widgets including drawing events It is also the thread in which your application interacts

with components from the Android UI toolkit (components from the androidwidget and androidview

packages) As such the main thread is also sometimes called the UI thread

The system does not create a separate thread for each instance of a component All components that

run in the same process are instantiated in the UI thread and system calls to each component are

dispatched from that thread Consequently methods that respond to system callbacks (such as

onKeyDown() to report user actions or a lifecycle callback method) always run in the UI thread of the

process

For instance when the user touches a button on the screen your apps UI thread dispatches the touch

event to the widget which in turn sets its pressed state and posts an invalidate request to the event

queue The UI thread dequeues the request and notifies the widget that it should redraw itself

When your app performs intensive work in response to user interaction this single thread model can

yield poor performance unless you implement your application properly Specifically if everything is

happening in the UI thread performing long operations such as network access or database queries

will block the whole UI When the thread is blocked no events can be dispatched including drawing

events From the users perspective the application appears to hang Even worse if the UI thread is

blocked for more than a few seconds (about 5 seconds currently) the user is presented with the

infamous application not responding (ANR) dialog The user might then decide to quit your

application and uninstall it if they are unhappy

Additionally the Andoid UI toolkit is not thread-safe So you must not manipulate your UI from a

worker threadmdashyou must do all manipulation to your user interface from the UI thread Thus there are

simply two rules to Androids single thread model

1 Do not block the UI thread

2 Do not access the Android UI toolkit from outside the UI thread

Worker threads

Because of the single thread model described above its vital to the responsiveness of your

applications UI that you do not block the UI thread If you have operations to perform that are not

instantaneous you should make sure to do them in separate threads (background or worker

threads)

For example below is some code for a click listener that downloads an image from a separate thread

and displays it in an ImageView

public void onClick(View v) new Thread(new Runnable() public void run() Bitmap b = loadImageFromNetwork(httpexamplecomimagepng) mImageViewsetImageBitmap(b) )start()

At first this seems to work fine because it creates a new thread to handle the network operation

However it violates the second rule of the single-threaded model do not access the Android UI toolkit

from outside the UI threadmdashthis sample modifies the ImageView from the worker thread instead of the

UI thread This can result in undefined and unexpected behavior which can be difficult and time-

consuming to track down

To fix this problem Android offers several ways to access the UI thread from other threads Here is a

list of methods that can help

ActivityrunOnUiThread(Runnable)

Viewpost(Runnable)

ViewpostDelayed(Runnable long)

For example you can fix the above code by using the Viewpost(Runnable) method

public void onClick(View v) new Thread(new Runnable() public void run() final Bitmap bitmap = loadImageFromNetwork(httpexamplecomimagepng) mImageViewpost(new Runnable() public void run() mImageViewsetImageBitmap(bitmap) ) )start()

Now this implementation is thread-safe the network operation is done from a separate thread while

the ImageView is manipulated from the UI thread

However as the complexity of the operation grows this kind of code can get complicated and difficult

to maintain To handle more complex interactions with a worker thread you might consider using a

Handler in your worker thread to process messages delivered from the UI thread Perhaps the best

solution though is to extend the AsyncTask class which simplifies the execution of worker thread

tasks that need to interact with the UI

Using AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface It performs the blocking

operations in a worker thread and then publishes the results on the UI thread without requiring you to

handle threads andor handlers yourself

To use it you must subclass AsyncTask and implement the doInBackground() callback method which

runs in a pool of background threads To update your UI you should implement onPostExecute()

which delivers the result from doInBackground() and runs in the UI thread so you can safely update

your UI You can then run the task by calling execute() from the UI thread

For example you can implement the previous example using AsyncTask this way

public void onClick(View v) new DownloadImageTask()execute(httpexamplecomimagepng) private class DownloadImageTask extends AsyncTaskltString Void Bitmapgt The system calls this to perform work in a worker thread and delivers it the parameters given to AsyncTaskexecute() protected Bitmap doInBackground(String urls) return loadImageFromNetwork(urls[0])

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 38: 03 services

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 mdash how it resolves which component should receive an intent message For

intents that dont explicitly name a target component this process involves testing the Intent object

against intent filters associated with potential targets

Intent Objects

An Intent object is a bundle of information It contains information of interest to the component that

receives the intent (such as the action to be taken and the data to act on) plus information of interest to

the Android system (such as the category of component that should handle the intent and instructions

on how to launch a target activity) Principally it can contain the following

Component name

The name of the component that should handle the intent This field is a ComponentName

object mdash a combination of the fully qualified class name of the target component (for example

comexampleprojectappFreneticActivity) and the package name set in the manifest file of the

application where the component resides (for example comexampleproject) The package

part of the component name and the package name set in the manifest do not necessarily have

to match

The component name is optional If it is set the Intent object is delivered to an instance of the

designated class If it is not set Android uses other information in the Intent object to locate a

suitable target mdash see Intent Resolution later in this document

The component name is set by setComponent() setClass() or setClassName() and read by

getComponent()

Action

A string naming the action to be performed mdash or in the case of broadcast intents the action

that took place and is being reported The Intent class defines a number of action constants

including these

Constant Target

component

Action

ACTION_CALL activity Initiate a phone call

ACTION_EDIT activity Display data for the user to edit

ACTION_MAIN activity Start up as the initial activity of a task

with no data input and no returned

output

ACTION_SYNC activity Synchronize data on a server with

data on the mobile device

ACTION_BATTERY_LOW broadcast

receiver

A warning that the battery is low

ACTION_HEADSET_PLUG broadcast

receiver

A headset has been plugged into the

device or unplugged from it

ACTION_SCREEN_ON broadcast

receiver

The screen has been turned on

ACTION_TIMEZONE_CHANGED broadcast

receiver

The setting for the time zone has

changed

See the Intent class description for a list of pre-defined constants for generic actions Other

actions are defined elsewhere in the Android API You can also define your own action strings

for activating the components in your application Those you invent should include the

application package as a prefix mdash for example comexampleprojectSHOW_COLOR

The action largely determines how the rest of the intent is structured mdash particularly the data and

extras fields mdash much as a method name determines a set of arguments and a return value For

this reason its a good idea to use action names that are as specific as possible and to couple

them tightly to the other fields of the intent In other words instead of defining an action in

isolation define an entire protocol for the Intent objects your components can handle

The action in an Intent object is set by the setAction() method and read by getAction()

Data

The URI of the data to be acted on and the MIME type of that data Different actions are paired

with different kinds of data specifications For example if the action field is ACTION_EDIT the

data field would contain the URI of the document to be displayed for editing If the action is

ACTION_CALL the data field would be a tel URI with the number to call Similarly if the action

is ACTION_VIEW and the data field is an http URI the receiving activity would be called upon

to download and display whatever data the URI refers to

When matching an intent to a component that is capable of handling the data its often

important to know the type of data (its MIME type) in addition to its URI For example a

component able to display image data should not be called upon to play an audio file

In many cases the data type can be inferred from the URI mdash particularly content URIs which

indicate that the data is located on the device and controlled by a content provider (see the

separate discussion on content providers) But the type can also be explicitly set in the Intent

object The setData() method specifies data only as a URI setType() specifies it only as a

MIME type and setDataAndType() specifies it as both a URI and a MIME type The URI is read

by getData() and the type by getType()

Category

A string containing additional information about the kind of component that should handle the

intent Any number of category descriptions can be placed in an Intent object As it does for

actions the Intent class defines several category constants including these

Constant Meaning

CATEGORY_BROWSABLE The target activity can be safely invoked by the browser to

display data referenced by a link mdash for example an image or

an e-mail message

CATEGORY_GADGET The activity can be embedded inside of another activity that

hosts gadgets

CATEGORY_HOME The activity displays the home screen the first screen the

user sees when the device is turned on or when the HOME

key is pressed

CATEGORY_LAUNCHER The activity can be the initial activity of a task and is listed in

the top-level application launcher

CATEGORY_PREFERENCE The target activity is a preference panel

See the Intent class description for the full list of categories

The addCategory() method places a category in an Intent object removeCategory() deletes a

category previously added and getCategories() gets the set of all categories currently in the

object

Extras

Key-value pairs for additional information that should be delivered to the component handling

the intent Just as some actions are paired with particular kinds of data URIs some are paired

with particular extras For example an ACTION_TIMEZONE_CHANGED intent has a time-

zone extra that identifies the new time zone and ACTION_HEADSET_PLUG has a state

extra indicating whether the headset is now plugged in or unplugged as well as a name extra

for the type of headset If you were to invent a SHOW_COLOR action the color value would be

set in an extra key-value pair

The Intent object has a series of put() methods for inserting various types of extra data and a

similar set of get() methods for reading the data These methods parallel those for Bundle

objects In fact the extras can be installed and read as a Bundle using the putExtras() and

getExtras() methods

Flags

Flags of various sorts Many instruct the Android system how to launch an activity (for example

which task the activity should belong to) and how to treat it after its launched (for example

whether it belongs in the list of recent activities) All these flags are defined in the Intent class

The Android system and the applications that come with the platform employ Intent objects both to

send out system-originated broadcasts and to activate system-defined components To see how to

structure an intent to activate a system component consult the list of intents in the reference

Intent Resolution

Intents can be divided into two groups

Explicit intents designate the target component by its name (the component name field mentioned

earlier has a value set) Since component names would generally not be known to developers of other

applications explicit intents are typically used for application-internal messages mdash such as an activity

starting a subordinate service or launching a sister activity

Implicit intents do not name a target (the field for the component name is blank) Implicit intents are

often used to activate components in other applications

Android delivers an explicit intent to an instance of the designated target class Nothing in the Intent

object other than the component name matters for determining which component should get the intent

A different strategy is needed for implicit intents In the absence of a designated target the Android

system must find the best component (or components) to handle the intent mdash a single activity or

service to perform the requested action or the set of broadcast receivers to respond to the broadcast

announcement It does so by comparing the contents of the Intent object to intent filters structures

associated with components that can potentially receive intents Filters advertise the capabilities of a

component and delimit the intents it can handle They open the component to the possibility of

receiving implicit intents of the advertised type If a component does not have any intent filters it can

receive only explicit intents A component with filters can receive both explicit and implicit intents

Only three aspects of an Intent object are consulted when the object is tested against an intent filter

action

data (both URI and data type)

category

The extras and flags play no part in resolving which component receives an intent

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 mdash but only unwanted implicit intents (those that dont 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

components 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 mdash 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 Pads filters are described in the Note Pad Example

section later)

Filters and security

An intent filter cannot be relied on for security While it opens a component to receiving only certain

kinds of implicit intents it does nothing to prevent explicit intents from targeting the component Even

though a filter restricts the intents a component will be asked to handle to certain actions and data

sources someone could always put together an explicit intent with a different action and data source

and name the component as the target

An intent filter is an instance of the IntentFilter class However since the Android system must know

about the capabilities of a component before it can launch that component intent filters are generally

not set up in Java code but in the applications manifest file (AndroidManifestxml) as ltintent-filtergt

elements (The one exception would be filters for broadcast receivers that are registered dynamically

by calling ContextregisterReceiver() they are directly created as IntentFilter objects)

A filter has fields that parallel the action data and category fields of an Intent object An implicit intent

is tested against the filter in all three areas To be delivered to the component that owns the filter it

must pass all three tests If it fails even one of them the Android system wont deliver it to the

component mdash at least not on the basis of that filter However since a component can have multiple

intent filters an intent that does not pass through one of a components filters might make it through on

another

Each of the three tests is described in detail below

Action test

An ltintent-filtergt element in the manifest file lists actions as ltactiongt subelements For

example

ltintent-filter gt ltaction androidname=comexampleprojectSHOW_CURRENT gt ltaction androidname=comexampleprojectSHOW_RECENT gt ltaction androidname=comexampleprojectSHOW_PENDING gt ltintent-filtergt

As the example shows while an Intent object names just a single action a filter may list more

than one The list cannot be empty a filter must contain at least one ltactiongt element or it will

block all intents

To pass this test the action specified in the Intent object must match one of the actions listed in

the filter If the object or the filter does not specify an action the results are as follows

If the filter fails to list any actions there is nothing for an intent to match so all intents fail the

test No intents can get through the filter

On the other hand an Intent object that doesnt specify an action automatically passes the test

mdash as long as the filter contains at least one action

Category test

An ltintent-filtergt element also lists categories as subelements For example

ltintent-filter gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryBROWSABLE gt ltintent-filtergt

Note that the constants described earlier for actions and categories are not used in the manifest

file The full string values are used instead For instance the

androidintentcategoryBROWSABLE string in the example above corresponds to the

CATEGORY_BROWSABLE constant mentioned earlier in this document Similarly the string

androidintentactionEDIT corresponds to the ACTION_EDIT constant

For an intent to pass the category test every category in the Intent object must match a

category in the filter The filter can list additional categories but it cannot omit any that are in the

intent

In principle therefore an Intent object with no categories should always pass this test

regardless of whats in the filter Thats mostly true However with one exception Android treats

all implicit intents passed to startActivity() as if they contained at least one category

androidintentcategoryDEFAULT (the CATEGORY_DEFAULT constant) Therefore activities

that are willing to receive implicit intents must include androidintentcategoryDEFAULT in

their intent filters (Filters with androidintentactionMAIN and

androidintentcategoryLAUNCHER settings are the exception They mark activities that begin

new tasks and that are represented on the launcher screen They can include

androidintentcategoryDEFAULT in the list of categories but dont need to) See Using intent

matching later for more on these filters)

Data test

Like the action and categories the data specification for an intent filter is contained in a

subelement And as in those cases the subelement can appear multiple times or not at all For

example

ltintent-filter gt ltdata androidmimeType=videompeg androidscheme=http gt ltdata androidmimeType=audiompeg androidscheme=http gt ltintent-filtergt

Each ltdatagt element can specify a URI and a data type (MIME media type) There are

separate attributes mdash scheme host port and path mdash for each part of the URI

schemehostportpath

For example in the following URI

contentcomexampleproject200foldersubfolderetc

the scheme is content the host is comexampleproject the port is 200 and the path is

foldersubfolderetc The host and port together constitute the URI authority if a host is not

specified the port is ignored

Each of these attributes is optional but they are not independent of each other For an authority

to be meaningful a scheme must also be specified For a path to be meaningful both a scheme

and an authority must be specified

When the URI in an Intent object is compared to a URI specification in a filter its compared

only to the parts of the URI actually mentioned in the filter For example if a filter specifies only

a scheme all URIs with that scheme match the filter If a filter specifies a scheme and an

authority but no path all URIs with the same scheme and authority match regardless of their

paths If a filter specifies a scheme an authority and a path only URIs with the same scheme

authority and path match However a path specification in the filter can contain wildcards to

require only a partial match of the path

The type attribute of a ltdatagt element specifies the MIME type of the data Its more common in

filters than a URI Both the Intent object and the filter can use a wildcard for the subtype field

mdash for example text or audio mdash indicating any subtype matches

The data test compares both the URI and the data type in the Intent object to a URI and data

type specified in the filter The rules are as follows

a An Intent object that contains neither a URI nor a data type passes the test only if the filter

likewise does not specify any URIs or data types

b An Intent object that contains a URI but no data type (and a type cannot be inferred from the

URI) passes the test only if its URI matches a URI in the filter and the filter likewise does not

specify a type This will be the case only for URIs like mailto and tel that do not refer to actual

data

c An Intent object that contains a data type but not a URI passes the test only if the filter lists the

same data type and similarly does not specify a URI

d An Intent object that contains both a URI and a data type (or a data type can be inferred from

the URI) passes the data type part of the test only if its type matches a type listed in the filter It

passes the URI part of the test either if its URI matches a URI in the filter or if it has a content

or file URI and the filter does not specify a URI In other words a component is presumed to

support content and file data if its filter lists only a data type

If an intent can pass through the filters of more than one activity or service the user may be asked

which component to activate An exception is raised if no target can be found

Common cases

The last rule shown above for the data test rule (d) reflects the expectation that components are able

to get local data from a file or content provider Therefore their filters can list just a data type and do

not need to explicitly name the content and file schemes This is a typical case A ltdatagt element like

the following for example tells Android that the component can get image data from a content

provider and display it

ltdata androidmimeType=image gt

Since most available data is dispensed by content providers filters that specify a data type but not a

URI are perhaps the most common

Another common configuration is filters with a scheme and a data type For example a ltdatagt

element like the following tells Android that the component can get video data from the network and

display it

ltdata androidscheme=http androidtype=video gt

Consider for example what the browser application does when the user follows a link on a web page

It first tries to display the data (as it could if the link was to an HTML page) If it cant display the data it

puts together an implicit intent with the scheme and data type and tries to start an activity that can do

the job If there are no takers it asks the download manager to download the data That puts it under

the control of a content provider so a potentially larger pool of activities (those with filters that just

name a data type) can respond

Most applications also have a way to start fresh without a reference to any particular data Activities

that can initiate applications have filters with androidintentactionMAIN specified as the action If

they are to be represented in the application launcher they also specify the

androidintentcategoryLAUNCHER category

ltintent-filter gt ltaction androidname=code androidintentactionMAIN gt ltcategory androidname=code androidintentcategoryLAUNCHER gt ltintent-filtergt

Using intent matching

Intents are matched against intent filters not only to discover a target component to activate but also

to discover something about the set of components on the device For example the Android system

populates the application launcher the top-level screen that shows the applications that are available

for the user to launch by finding all the activities with intent filters that specify the

androidintentactionMAIN action and androidintentcategoryLAUNCHER category (as illustrated

in the previous section) It then displays the icons and labels of those activities in the launcher

Similarly it discovers the home screen by looking for the activity with androidintentcategoryHOME

in its filter

Your application can use intent matching is a similar way The PackageManager has a set of query()

methods that return all components that can accept a particular intent and a similar series of

resolve() methods that determine the best component to respond to an intent For example

queryIntentActivities() returns a list of all activities that can perform the intent passed as an argument

and queryIntentServices() returns a similar list of services Neither method activates the components

they just list the ones that can respond Theres a similar method queryBroadcastReceivers() for

broadcast receivers

Note Pad Example

The Note Pad sample application enables users to browse through a list of notes view details about

individual items in the list edit the items and add a new item to the list This section looks at the intent

filters declared in its manifest file (If youre working offline in the SDK you can find all the source files

for this sample application including its manifest file at ltsdkgtsamplesNotePadindexhtml If youre

viewing the documentation online the source files are in the Tutorials and Sample Code section here)

In its manifest file the Note Pad application declares three activities each with at least one intent filter

It also declares a content provider that manages the note data Here is the manifest file in its entirety

ltmanifest xmlnsandroid=httpschemasandroidcomapkresandroid package=comexampleandroidnotepadgt ltapplication androidicon=drawableapp_notes androidlabel=stringapp_name gt ltprovider androidname=NotePadProvider androidauthorities=comgoogleproviderNotePad gt ltactivity androidname=NotesList androidlabel=stringtitle_notes_listgt ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltactivity androidname=NoteEditor androidtheme=androidstyleThemeLight androidlabel=stringtitle_note gt ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltactivitygt

ltactivity androidname=TitleEditor androidlabel=stringtitle_edit_title androidtheme=androidstyleThemeDialoggt ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltapplicationgt ltmanifestgt

The first activity NotesList is distinguished from the other activities by the fact that it operates on a

directory of notes (the note list) rather than on a single note It would generally serve as the initial user

interface into the application It can do three things as described by its three intent filters

1 ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt

This filter declares the main entry point into the Note Pad application The standard MAIN action is an

entry point that does not require any other information in the Intent (no data specification for example)

and the LAUNCHER category says that this entry point should be listed in the application launcher

2 ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

This filter declares the things that the activity can do on a directory of notes It can allow the user to

view or edit the directory (via the VIEW and EDIT actions) or to pick a particular note from the

directory (via the PICK action)

The mimeType attribute of the ltdatagt element specifies the kind of data that these actions operate on

It indicates that the activity can get a Cursor over zero or more items (vndandroidcursordir) from a

content provider that holds Note Pad data (vndgooglenote) The Intent object that launches the

activity would include a content URI specifying the exact data of this type that the activity should open

Note also the DEFAULT category supplied in this filter Its there because the ContextstartActivity()

and ActivitystartActivityForResult() methods treat all intents as if they contained the DEFAULT

category mdash with just two exceptions

o Intents that explicitly name the target activity

o Intents consisting of the MAIN action and LAUNCHER category

Therefore the DEFAULT category is required for all filters mdash except for those with the MAIN action

and LAUNCHER category (Intent filters are not consulted for explicit intents)

3 ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

This filter describes the activitys ability to return a note selected by the user without requiring any

specification of the directory the user should choose from The GET_CONTENT action is similar to the

PICK action In both cases the activity returns the URI for a note selected by the user (In each case

its returned to the activity that called startActivityForResult() to start the NoteList activity) Here

however the caller specifies the type of data desired instead of the directory of data the user will be

picking from

The data type vndandroidcursoritemvndgooglenote indicates the type of data the activity can

return mdash a URI for a single note From the returned URI the caller can get a Cursor for exactly one

item (vndandroidcursoritem) from the content provider that holds Note Pad data (vndgooglenote)

In other words for the PICK action in the previous filter the data type indicates the type of data the

activity could display to the user For the GET_CONTENT filter it indicates the type of data the activity

can return to the caller

Given these capabilities the following intents will resolve to the NotesList activity

action androidintentactionMAIN

Launches the activity with no data specified

action androidintentactionMAIN

category androidintentcategoryLAUNCHER

Launches the activity with no data selected specified This is the actual intent used by the

Launcher to populate its top-level list All activities with filters that match this action and

category are added to the list

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of all the notes under

contentcomgoogleproviderNotePadnotes The user can then browse through the list and

get information about the items in it

action androidintentactionPICK

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of the notes under

contentcomgoogleproviderNotePadnotes The user can then pick a note from the list and

the activity will return the URI for that item back to the activity that started the NoteList activity

action androidintentactionGET_CONTENT

data type vndandroidcursoritemvndgooglenote

Asks the activity to supply a single item of Note Pad data

The second activity NoteEditor shows users a single note entry and allows them to edit it It can do

two things as described by its two intent filters

1 ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The first primary purpose of this activity is to enable the user to interact with a single note ampmdash to

either VIEW the note or EDIT it (The EDIT_NOTE category is a synonym for EDIT) The intent would

contain the URI for data matching the MIME type vndandroidcursoritemvndgooglenote mdash that is

the URI for a single specific note It would typically be a URI that was returned by the PICK or

GET_CONTENT actions of the NoteList activity

As before this filter lists the DEFAULT category so that the activity can be launched by intents that

dont explicitly specify the NoteEditor class

2 ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

The secondary purpose of this activity is to enable the user to create a new note which it will INSERT

into an existing directory of notes The intent would contain the URI for data matching the MIME type

vndandroidcursordirvndgooglenote mdash that is the URI for the directory where the note should be

placed

Given these capabilities the following intents will resolve to the NoteEditor activity

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID (For details on how content

URIs specify individual members of a group see Content Providers)

action androidintentactionEDIT

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID and to let the user edit it If

the user saves the changes the activity updates the data for the note in the content provider

action androidintentactionINSERT

data contentcomgoogleproviderNotePadnotes

Asks the activity to create a new empty note in the notes list at

contentcomgoogleproviderNotePadnotes and allow the user to edit it If the user saves the

note its URI is returned to the caller

The last activity TitleEditor enables the user to edit the title of a note This could be implemented by

directly invoking the activity (by explicitly setting its component name in the Intent) without using an

intent filter But here we take the opportunity to show how to publish alternative operations on existing

data

ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The single intent filter for this activity uses a custom action called

comandroidnotepadactionEDIT_TITLE It must be invoked on a specific note (data type

vndandroidcursoritemvndgooglenote) like the previous VIEW and EDIT actions However here the

activity displays the title contained in the note data not the content of the note itself

In addition to supporting the usual DEFAULT category the title editor also supports two other standard

categories ALTERNATIVE and SELECTED_ALTERNATIVE These categories identify activities that

can be presented to users in a menu of options (much as the LAUNCHER category identifies activities

that should be presented to user in the application launcher) Note that the filter also supplies an

explicit label (via androidlabel=stringresolve_title) to better control what users see when

presented with this activity as an alternative action to the data they are currently viewing (For more

information on these categories and building options menus see the

PackageManagerqueryIntentActivityOptions() and MenuaddIntentOptions() methods)

Given these capabilities the following intent will resolve to the TitleEditor activity

action comandroidnotepadactionEDIT_TITLE

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the title associated with note ID and allow the user to edit the title

Processes and Threads

When an application component starts and the application does not have any other components

running the Android system starts a new Linux process for the application with a single thread of

execution By default all components of the same application run in the same process and thread

(called the main thread) If an application component starts and there already exists a process for

that application (because another component from the application exists) then the component is

started within that process and uses the same thread of execution However you can arrange for

different components in your application to run in separate processes and you can create additional

threads for any process

This document discusses how processes and threads work in an Android application

Processes

By default all components of the same application run in the same process and most applications

should not change this However if you find that you need to control which process a certain

component belongs to you can do so in the manifest file

The manifest entry for each type of component elementmdashltactivitygt ltservicegt ltreceivergt and

ltprovidergtmdashsupports an androidprocess attribute that can specify a process in which that component

should run You can set this attribute so that each component runs in its own process or so that some

components share a process while others do not You can also set androidprocess so that

components of different applications run in the same processmdashprovided that the applications share the

same Linux user ID and are signed with the same certificates

The ltapplicationgt element also supports an androidprocess attribute to set a default value that

applies to all components

Android might 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 thats killed are consequently destroyed A process is started again for those components

when theres again work for them to do

When deciding which processes to kill the Android system weighs their relative importance to the

user For example it more readily shuts down a process hosting activities that are no longer visible on

screen compared to a process hosting visible activities The decision whether to terminate a process

therefore depends on the state of the components running in that process The rules used to decide

which processes to terminate is discussed below

Process lifecycle

The Android system tries to maintain an application process for as long as possible but eventually

needs to remove old processes to reclaim memory for new or more important processes To determine

which processes to keep and which to kill the system places each process into an importance

hierarchy based on the components running in the process and the state of those components

Processes with the lowest importance are eliminated first then those with the next lowest importance

and so on as necessary to recover system resources

There are five levels in the importance hierarchy The following list presents the different types of

processes in order of importance (the first process is most important and is killed last)

1 Foreground process

A process that is required for what the user is currently doing A process is considered to be in the

foreground if any of the following conditions are true

o It hosts an Activity that the user is interacting with (the Activitys onResume() method has been called)

o It hosts a Service thats bound to the activity that the user is interacting with

o It hosts a Service thats running in the foregroundmdashthe service has called startForeground()

o It hosts a Service thats executing one of its lifecycle callbacks (onCreate() onStart() or onDestroy())

o It hosts a BroadcastReceiver thats executing its onReceive() method

Generally only a few foreground processes exist at any given time They are killed only as a last

resortmdashif memory is so low that they cannot all continue to run Generally at that point the device has

reached a memory paging state so killing some foreground processes is required to keep the user

interface responsive

2 Visible process

A process that doesnt have any foreground components but still can affect what the user sees on

screen A process is considered to be visible if either of the following conditions are true

o It hosts an Activity that is not in the foreground but is still visible to the user (its onPause() method has

been called) This might occur for example if the foreground activity started a dialog which allows the

previous activity to be seen behind it

o It hosts a Service thats bound to a visible (or foreground) activity

A visible process is considered extremely important and will not be killed unless doing so is required to

keep all foreground processes running

3 Service process

A process that is running a service that has been started with the startService() method and does not

fall into either of the two higher categories Although service processes are not directly tied to anything

the user sees they are generally doing things that the user cares about (such as playing music in the

background or downloading data on the network) so the system keeps them running unless theres

not enough memory to retain them along with all foreground and visible processes

4 Background process

A process holding an activity thats not currently visible to the user (the activitys onStop() method has

been called) These processes have no direct impact on the user experience and the system can kill

them at any time to reclaim memory for a foreground visible or service process Usually there are

many background processes running so they are kept in an LRU (least recently used) list to ensure

that the process with the activity that was most recently seen by the user is the last to be killed If an

activity implements its lifecycle methods correctly and saves its current state killing its process will not

have a visible effect on the user experience because when the user navigates back to the activity the

activity restores all of its visible state See the Activities document for information about saving and

restoring state

5 Empty process

A process that doesnt hold any active application components The only reason to keep this kind of

process alive is for caching purposes to improve startup time the next time a component needs to run

in it The system often kills these processes in order to balance overall system resources between

process caches and the underlying kernel caches

Android ranks a process at the highest level it can based upon the importance of the components

currently active in the process For example if a process hosts a service and a visible activity the

process is ranked as a visible process not a service process

In addition a processs ranking might be increased because other processes are dependent on itmdasha

process that is serving another process can never be ranked lower than the process it is serving For

example if a content provider in process A is serving a client in process B or if a service in process A

is bound to a component in process B process A is always considered at least as important as

process B

Because a process running a service is ranked higher than a process with background activities an

activity that initiates a long-running operation might do well to start a service for that operation rather

than simply create a worker threadmdashparticularly if the operation will likely outlast the activity For

example an activity thats uploading a picture to a web site should start a service to perform the

upload so that the upload can continue in the background even if the user leaves the activity Using a

service guarantees that the operation will have at least service process priority regardless of what

happens to the activity This is the same reason that broadcast receivers should employ services

rather than simply put time-consuming operations in a thread

Threads

When an application is launched the system creates a thread of execution for the application called

main This thread is very important because it is in charge of dispatching events to the appropriate

user interface widgets including drawing events It is also the thread in which your application interacts

with components from the Android UI toolkit (components from the androidwidget and androidview

packages) As such the main thread is also sometimes called the UI thread

The system does not create a separate thread for each instance of a component All components that

run in the same process are instantiated in the UI thread and system calls to each component are

dispatched from that thread Consequently methods that respond to system callbacks (such as

onKeyDown() to report user actions or a lifecycle callback method) always run in the UI thread of the

process

For instance when the user touches a button on the screen your apps UI thread dispatches the touch

event to the widget which in turn sets its pressed state and posts an invalidate request to the event

queue The UI thread dequeues the request and notifies the widget that it should redraw itself

When your app performs intensive work in response to user interaction this single thread model can

yield poor performance unless you implement your application properly Specifically if everything is

happening in the UI thread performing long operations such as network access or database queries

will block the whole UI When the thread is blocked no events can be dispatched including drawing

events From the users perspective the application appears to hang Even worse if the UI thread is

blocked for more than a few seconds (about 5 seconds currently) the user is presented with the

infamous application not responding (ANR) dialog The user might then decide to quit your

application and uninstall it if they are unhappy

Additionally the Andoid UI toolkit is not thread-safe So you must not manipulate your UI from a

worker threadmdashyou must do all manipulation to your user interface from the UI thread Thus there are

simply two rules to Androids single thread model

1 Do not block the UI thread

2 Do not access the Android UI toolkit from outside the UI thread

Worker threads

Because of the single thread model described above its vital to the responsiveness of your

applications UI that you do not block the UI thread If you have operations to perform that are not

instantaneous you should make sure to do them in separate threads (background or worker

threads)

For example below is some code for a click listener that downloads an image from a separate thread

and displays it in an ImageView

public void onClick(View v) new Thread(new Runnable() public void run() Bitmap b = loadImageFromNetwork(httpexamplecomimagepng) mImageViewsetImageBitmap(b) )start()

At first this seems to work fine because it creates a new thread to handle the network operation

However it violates the second rule of the single-threaded model do not access the Android UI toolkit

from outside the UI threadmdashthis sample modifies the ImageView from the worker thread instead of the

UI thread This can result in undefined and unexpected behavior which can be difficult and time-

consuming to track down

To fix this problem Android offers several ways to access the UI thread from other threads Here is a

list of methods that can help

ActivityrunOnUiThread(Runnable)

Viewpost(Runnable)

ViewpostDelayed(Runnable long)

For example you can fix the above code by using the Viewpost(Runnable) method

public void onClick(View v) new Thread(new Runnable() public void run() final Bitmap bitmap = loadImageFromNetwork(httpexamplecomimagepng) mImageViewpost(new Runnable() public void run() mImageViewsetImageBitmap(bitmap) ) )start()

Now this implementation is thread-safe the network operation is done from a separate thread while

the ImageView is manipulated from the UI thread

However as the complexity of the operation grows this kind of code can get complicated and difficult

to maintain To handle more complex interactions with a worker thread you might consider using a

Handler in your worker thread to process messages delivered from the UI thread Perhaps the best

solution though is to extend the AsyncTask class which simplifies the execution of worker thread

tasks that need to interact with the UI

Using AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface It performs the blocking

operations in a worker thread and then publishes the results on the UI thread without requiring you to

handle threads andor handlers yourself

To use it you must subclass AsyncTask and implement the doInBackground() callback method which

runs in a pool of background threads To update your UI you should implement onPostExecute()

which delivers the result from doInBackground() and runs in the UI thread so you can safely update

your UI You can then run the task by calling execute() from the UI thread

For example you can implement the previous example using AsyncTask this way

public void onClick(View v) new DownloadImageTask()execute(httpexamplecomimagepng) private class DownloadImageTask extends AsyncTaskltString Void Bitmapgt The system calls this to perform work in a worker thread and delivers it the parameters given to AsyncTaskexecute() protected Bitmap doInBackground(String urls) return loadImageFromNetwork(urls[0])

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 39: 03 services

ACTION_EDIT activity Display data for the user to edit

ACTION_MAIN activity Start up as the initial activity of a task

with no data input and no returned

output

ACTION_SYNC activity Synchronize data on a server with

data on the mobile device

ACTION_BATTERY_LOW broadcast

receiver

A warning that the battery is low

ACTION_HEADSET_PLUG broadcast

receiver

A headset has been plugged into the

device or unplugged from it

ACTION_SCREEN_ON broadcast

receiver

The screen has been turned on

ACTION_TIMEZONE_CHANGED broadcast

receiver

The setting for the time zone has

changed

See the Intent class description for a list of pre-defined constants for generic actions Other

actions are defined elsewhere in the Android API You can also define your own action strings

for activating the components in your application Those you invent should include the

application package as a prefix mdash for example comexampleprojectSHOW_COLOR

The action largely determines how the rest of the intent is structured mdash particularly the data and

extras fields mdash much as a method name determines a set of arguments and a return value For

this reason its a good idea to use action names that are as specific as possible and to couple

them tightly to the other fields of the intent In other words instead of defining an action in

isolation define an entire protocol for the Intent objects your components can handle

The action in an Intent object is set by the setAction() method and read by getAction()

Data

The URI of the data to be acted on and the MIME type of that data Different actions are paired

with different kinds of data specifications For example if the action field is ACTION_EDIT the

data field would contain the URI of the document to be displayed for editing If the action is

ACTION_CALL the data field would be a tel URI with the number to call Similarly if the action

is ACTION_VIEW and the data field is an http URI the receiving activity would be called upon

to download and display whatever data the URI refers to

When matching an intent to a component that is capable of handling the data its often

important to know the type of data (its MIME type) in addition to its URI For example a

component able to display image data should not be called upon to play an audio file

In many cases the data type can be inferred from the URI mdash particularly content URIs which

indicate that the data is located on the device and controlled by a content provider (see the

separate discussion on content providers) But the type can also be explicitly set in the Intent

object The setData() method specifies data only as a URI setType() specifies it only as a

MIME type and setDataAndType() specifies it as both a URI and a MIME type The URI is read

by getData() and the type by getType()

Category

A string containing additional information about the kind of component that should handle the

intent Any number of category descriptions can be placed in an Intent object As it does for

actions the Intent class defines several category constants including these

Constant Meaning

CATEGORY_BROWSABLE The target activity can be safely invoked by the browser to

display data referenced by a link mdash for example an image or

an e-mail message

CATEGORY_GADGET The activity can be embedded inside of another activity that

hosts gadgets

CATEGORY_HOME The activity displays the home screen the first screen the

user sees when the device is turned on or when the HOME

key is pressed

CATEGORY_LAUNCHER The activity can be the initial activity of a task and is listed in

the top-level application launcher

CATEGORY_PREFERENCE The target activity is a preference panel

See the Intent class description for the full list of categories

The addCategory() method places a category in an Intent object removeCategory() deletes a

category previously added and getCategories() gets the set of all categories currently in the

object

Extras

Key-value pairs for additional information that should be delivered to the component handling

the intent Just as some actions are paired with particular kinds of data URIs some are paired

with particular extras For example an ACTION_TIMEZONE_CHANGED intent has a time-

zone extra that identifies the new time zone and ACTION_HEADSET_PLUG has a state

extra indicating whether the headset is now plugged in or unplugged as well as a name extra

for the type of headset If you were to invent a SHOW_COLOR action the color value would be

set in an extra key-value pair

The Intent object has a series of put() methods for inserting various types of extra data and a

similar set of get() methods for reading the data These methods parallel those for Bundle

objects In fact the extras can be installed and read as a Bundle using the putExtras() and

getExtras() methods

Flags

Flags of various sorts Many instruct the Android system how to launch an activity (for example

which task the activity should belong to) and how to treat it after its launched (for example

whether it belongs in the list of recent activities) All these flags are defined in the Intent class

The Android system and the applications that come with the platform employ Intent objects both to

send out system-originated broadcasts and to activate system-defined components To see how to

structure an intent to activate a system component consult the list of intents in the reference

Intent Resolution

Intents can be divided into two groups

Explicit intents designate the target component by its name (the component name field mentioned

earlier has a value set) Since component names would generally not be known to developers of other

applications explicit intents are typically used for application-internal messages mdash such as an activity

starting a subordinate service or launching a sister activity

Implicit intents do not name a target (the field for the component name is blank) Implicit intents are

often used to activate components in other applications

Android delivers an explicit intent to an instance of the designated target class Nothing in the Intent

object other than the component name matters for determining which component should get the intent

A different strategy is needed for implicit intents In the absence of a designated target the Android

system must find the best component (or components) to handle the intent mdash a single activity or

service to perform the requested action or the set of broadcast receivers to respond to the broadcast

announcement It does so by comparing the contents of the Intent object to intent filters structures

associated with components that can potentially receive intents Filters advertise the capabilities of a

component and delimit the intents it can handle They open the component to the possibility of

receiving implicit intents of the advertised type If a component does not have any intent filters it can

receive only explicit intents A component with filters can receive both explicit and implicit intents

Only three aspects of an Intent object are consulted when the object is tested against an intent filter

action

data (both URI and data type)

category

The extras and flags play no part in resolving which component receives an intent

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 mdash but only unwanted implicit intents (those that dont 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

components 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 mdash 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 Pads filters are described in the Note Pad Example

section later)

Filters and security

An intent filter cannot be relied on for security While it opens a component to receiving only certain

kinds of implicit intents it does nothing to prevent explicit intents from targeting the component Even

though a filter restricts the intents a component will be asked to handle to certain actions and data

sources someone could always put together an explicit intent with a different action and data source

and name the component as the target

An intent filter is an instance of the IntentFilter class However since the Android system must know

about the capabilities of a component before it can launch that component intent filters are generally

not set up in Java code but in the applications manifest file (AndroidManifestxml) as ltintent-filtergt

elements (The one exception would be filters for broadcast receivers that are registered dynamically

by calling ContextregisterReceiver() they are directly created as IntentFilter objects)

A filter has fields that parallel the action data and category fields of an Intent object An implicit intent

is tested against the filter in all three areas To be delivered to the component that owns the filter it

must pass all three tests If it fails even one of them the Android system wont deliver it to the

component mdash at least not on the basis of that filter However since a component can have multiple

intent filters an intent that does not pass through one of a components filters might make it through on

another

Each of the three tests is described in detail below

Action test

An ltintent-filtergt element in the manifest file lists actions as ltactiongt subelements For

example

ltintent-filter gt ltaction androidname=comexampleprojectSHOW_CURRENT gt ltaction androidname=comexampleprojectSHOW_RECENT gt ltaction androidname=comexampleprojectSHOW_PENDING gt ltintent-filtergt

As the example shows while an Intent object names just a single action a filter may list more

than one The list cannot be empty a filter must contain at least one ltactiongt element or it will

block all intents

To pass this test the action specified in the Intent object must match one of the actions listed in

the filter If the object or the filter does not specify an action the results are as follows

If the filter fails to list any actions there is nothing for an intent to match so all intents fail the

test No intents can get through the filter

On the other hand an Intent object that doesnt specify an action automatically passes the test

mdash as long as the filter contains at least one action

Category test

An ltintent-filtergt element also lists categories as subelements For example

ltintent-filter gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryBROWSABLE gt ltintent-filtergt

Note that the constants described earlier for actions and categories are not used in the manifest

file The full string values are used instead For instance the

androidintentcategoryBROWSABLE string in the example above corresponds to the

CATEGORY_BROWSABLE constant mentioned earlier in this document Similarly the string

androidintentactionEDIT corresponds to the ACTION_EDIT constant

For an intent to pass the category test every category in the Intent object must match a

category in the filter The filter can list additional categories but it cannot omit any that are in the

intent

In principle therefore an Intent object with no categories should always pass this test

regardless of whats in the filter Thats mostly true However with one exception Android treats

all implicit intents passed to startActivity() as if they contained at least one category

androidintentcategoryDEFAULT (the CATEGORY_DEFAULT constant) Therefore activities

that are willing to receive implicit intents must include androidintentcategoryDEFAULT in

their intent filters (Filters with androidintentactionMAIN and

androidintentcategoryLAUNCHER settings are the exception They mark activities that begin

new tasks and that are represented on the launcher screen They can include

androidintentcategoryDEFAULT in the list of categories but dont need to) See Using intent

matching later for more on these filters)

Data test

Like the action and categories the data specification for an intent filter is contained in a

subelement And as in those cases the subelement can appear multiple times or not at all For

example

ltintent-filter gt ltdata androidmimeType=videompeg androidscheme=http gt ltdata androidmimeType=audiompeg androidscheme=http gt ltintent-filtergt

Each ltdatagt element can specify a URI and a data type (MIME media type) There are

separate attributes mdash scheme host port and path mdash for each part of the URI

schemehostportpath

For example in the following URI

contentcomexampleproject200foldersubfolderetc

the scheme is content the host is comexampleproject the port is 200 and the path is

foldersubfolderetc The host and port together constitute the URI authority if a host is not

specified the port is ignored

Each of these attributes is optional but they are not independent of each other For an authority

to be meaningful a scheme must also be specified For a path to be meaningful both a scheme

and an authority must be specified

When the URI in an Intent object is compared to a URI specification in a filter its compared

only to the parts of the URI actually mentioned in the filter For example if a filter specifies only

a scheme all URIs with that scheme match the filter If a filter specifies a scheme and an

authority but no path all URIs with the same scheme and authority match regardless of their

paths If a filter specifies a scheme an authority and a path only URIs with the same scheme

authority and path match However a path specification in the filter can contain wildcards to

require only a partial match of the path

The type attribute of a ltdatagt element specifies the MIME type of the data Its more common in

filters than a URI Both the Intent object and the filter can use a wildcard for the subtype field

mdash for example text or audio mdash indicating any subtype matches

The data test compares both the URI and the data type in the Intent object to a URI and data

type specified in the filter The rules are as follows

a An Intent object that contains neither a URI nor a data type passes the test only if the filter

likewise does not specify any URIs or data types

b An Intent object that contains a URI but no data type (and a type cannot be inferred from the

URI) passes the test only if its URI matches a URI in the filter and the filter likewise does not

specify a type This will be the case only for URIs like mailto and tel that do not refer to actual

data

c An Intent object that contains a data type but not a URI passes the test only if the filter lists the

same data type and similarly does not specify a URI

d An Intent object that contains both a URI and a data type (or a data type can be inferred from

the URI) passes the data type part of the test only if its type matches a type listed in the filter It

passes the URI part of the test either if its URI matches a URI in the filter or if it has a content

or file URI and the filter does not specify a URI In other words a component is presumed to

support content and file data if its filter lists only a data type

If an intent can pass through the filters of more than one activity or service the user may be asked

which component to activate An exception is raised if no target can be found

Common cases

The last rule shown above for the data test rule (d) reflects the expectation that components are able

to get local data from a file or content provider Therefore their filters can list just a data type and do

not need to explicitly name the content and file schemes This is a typical case A ltdatagt element like

the following for example tells Android that the component can get image data from a content

provider and display it

ltdata androidmimeType=image gt

Since most available data is dispensed by content providers filters that specify a data type but not a

URI are perhaps the most common

Another common configuration is filters with a scheme and a data type For example a ltdatagt

element like the following tells Android that the component can get video data from the network and

display it

ltdata androidscheme=http androidtype=video gt

Consider for example what the browser application does when the user follows a link on a web page

It first tries to display the data (as it could if the link was to an HTML page) If it cant display the data it

puts together an implicit intent with the scheme and data type and tries to start an activity that can do

the job If there are no takers it asks the download manager to download the data That puts it under

the control of a content provider so a potentially larger pool of activities (those with filters that just

name a data type) can respond

Most applications also have a way to start fresh without a reference to any particular data Activities

that can initiate applications have filters with androidintentactionMAIN specified as the action If

they are to be represented in the application launcher they also specify the

androidintentcategoryLAUNCHER category

ltintent-filter gt ltaction androidname=code androidintentactionMAIN gt ltcategory androidname=code androidintentcategoryLAUNCHER gt ltintent-filtergt

Using intent matching

Intents are matched against intent filters not only to discover a target component to activate but also

to discover something about the set of components on the device For example the Android system

populates the application launcher the top-level screen that shows the applications that are available

for the user to launch by finding all the activities with intent filters that specify the

androidintentactionMAIN action and androidintentcategoryLAUNCHER category (as illustrated

in the previous section) It then displays the icons and labels of those activities in the launcher

Similarly it discovers the home screen by looking for the activity with androidintentcategoryHOME

in its filter

Your application can use intent matching is a similar way The PackageManager has a set of query()

methods that return all components that can accept a particular intent and a similar series of

resolve() methods that determine the best component to respond to an intent For example

queryIntentActivities() returns a list of all activities that can perform the intent passed as an argument

and queryIntentServices() returns a similar list of services Neither method activates the components

they just list the ones that can respond Theres a similar method queryBroadcastReceivers() for

broadcast receivers

Note Pad Example

The Note Pad sample application enables users to browse through a list of notes view details about

individual items in the list edit the items and add a new item to the list This section looks at the intent

filters declared in its manifest file (If youre working offline in the SDK you can find all the source files

for this sample application including its manifest file at ltsdkgtsamplesNotePadindexhtml If youre

viewing the documentation online the source files are in the Tutorials and Sample Code section here)

In its manifest file the Note Pad application declares three activities each with at least one intent filter

It also declares a content provider that manages the note data Here is the manifest file in its entirety

ltmanifest xmlnsandroid=httpschemasandroidcomapkresandroid package=comexampleandroidnotepadgt ltapplication androidicon=drawableapp_notes androidlabel=stringapp_name gt ltprovider androidname=NotePadProvider androidauthorities=comgoogleproviderNotePad gt ltactivity androidname=NotesList androidlabel=stringtitle_notes_listgt ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltactivity androidname=NoteEditor androidtheme=androidstyleThemeLight androidlabel=stringtitle_note gt ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltactivitygt

ltactivity androidname=TitleEditor androidlabel=stringtitle_edit_title androidtheme=androidstyleThemeDialoggt ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltapplicationgt ltmanifestgt

The first activity NotesList is distinguished from the other activities by the fact that it operates on a

directory of notes (the note list) rather than on a single note It would generally serve as the initial user

interface into the application It can do three things as described by its three intent filters

1 ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt

This filter declares the main entry point into the Note Pad application The standard MAIN action is an

entry point that does not require any other information in the Intent (no data specification for example)

and the LAUNCHER category says that this entry point should be listed in the application launcher

2 ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

This filter declares the things that the activity can do on a directory of notes It can allow the user to

view or edit the directory (via the VIEW and EDIT actions) or to pick a particular note from the

directory (via the PICK action)

The mimeType attribute of the ltdatagt element specifies the kind of data that these actions operate on

It indicates that the activity can get a Cursor over zero or more items (vndandroidcursordir) from a

content provider that holds Note Pad data (vndgooglenote) The Intent object that launches the

activity would include a content URI specifying the exact data of this type that the activity should open

Note also the DEFAULT category supplied in this filter Its there because the ContextstartActivity()

and ActivitystartActivityForResult() methods treat all intents as if they contained the DEFAULT

category mdash with just two exceptions

o Intents that explicitly name the target activity

o Intents consisting of the MAIN action and LAUNCHER category

Therefore the DEFAULT category is required for all filters mdash except for those with the MAIN action

and LAUNCHER category (Intent filters are not consulted for explicit intents)

3 ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

This filter describes the activitys ability to return a note selected by the user without requiring any

specification of the directory the user should choose from The GET_CONTENT action is similar to the

PICK action In both cases the activity returns the URI for a note selected by the user (In each case

its returned to the activity that called startActivityForResult() to start the NoteList activity) Here

however the caller specifies the type of data desired instead of the directory of data the user will be

picking from

The data type vndandroidcursoritemvndgooglenote indicates the type of data the activity can

return mdash a URI for a single note From the returned URI the caller can get a Cursor for exactly one

item (vndandroidcursoritem) from the content provider that holds Note Pad data (vndgooglenote)

In other words for the PICK action in the previous filter the data type indicates the type of data the

activity could display to the user For the GET_CONTENT filter it indicates the type of data the activity

can return to the caller

Given these capabilities the following intents will resolve to the NotesList activity

action androidintentactionMAIN

Launches the activity with no data specified

action androidintentactionMAIN

category androidintentcategoryLAUNCHER

Launches the activity with no data selected specified This is the actual intent used by the

Launcher to populate its top-level list All activities with filters that match this action and

category are added to the list

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of all the notes under

contentcomgoogleproviderNotePadnotes The user can then browse through the list and

get information about the items in it

action androidintentactionPICK

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of the notes under

contentcomgoogleproviderNotePadnotes The user can then pick a note from the list and

the activity will return the URI for that item back to the activity that started the NoteList activity

action androidintentactionGET_CONTENT

data type vndandroidcursoritemvndgooglenote

Asks the activity to supply a single item of Note Pad data

The second activity NoteEditor shows users a single note entry and allows them to edit it It can do

two things as described by its two intent filters

1 ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The first primary purpose of this activity is to enable the user to interact with a single note ampmdash to

either VIEW the note or EDIT it (The EDIT_NOTE category is a synonym for EDIT) The intent would

contain the URI for data matching the MIME type vndandroidcursoritemvndgooglenote mdash that is

the URI for a single specific note It would typically be a URI that was returned by the PICK or

GET_CONTENT actions of the NoteList activity

As before this filter lists the DEFAULT category so that the activity can be launched by intents that

dont explicitly specify the NoteEditor class

2 ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

The secondary purpose of this activity is to enable the user to create a new note which it will INSERT

into an existing directory of notes The intent would contain the URI for data matching the MIME type

vndandroidcursordirvndgooglenote mdash that is the URI for the directory where the note should be

placed

Given these capabilities the following intents will resolve to the NoteEditor activity

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID (For details on how content

URIs specify individual members of a group see Content Providers)

action androidintentactionEDIT

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID and to let the user edit it If

the user saves the changes the activity updates the data for the note in the content provider

action androidintentactionINSERT

data contentcomgoogleproviderNotePadnotes

Asks the activity to create a new empty note in the notes list at

contentcomgoogleproviderNotePadnotes and allow the user to edit it If the user saves the

note its URI is returned to the caller

The last activity TitleEditor enables the user to edit the title of a note This could be implemented by

directly invoking the activity (by explicitly setting its component name in the Intent) without using an

intent filter But here we take the opportunity to show how to publish alternative operations on existing

data

ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The single intent filter for this activity uses a custom action called

comandroidnotepadactionEDIT_TITLE It must be invoked on a specific note (data type

vndandroidcursoritemvndgooglenote) like the previous VIEW and EDIT actions However here the

activity displays the title contained in the note data not the content of the note itself

In addition to supporting the usual DEFAULT category the title editor also supports two other standard

categories ALTERNATIVE and SELECTED_ALTERNATIVE These categories identify activities that

can be presented to users in a menu of options (much as the LAUNCHER category identifies activities

that should be presented to user in the application launcher) Note that the filter also supplies an

explicit label (via androidlabel=stringresolve_title) to better control what users see when

presented with this activity as an alternative action to the data they are currently viewing (For more

information on these categories and building options menus see the

PackageManagerqueryIntentActivityOptions() and MenuaddIntentOptions() methods)

Given these capabilities the following intent will resolve to the TitleEditor activity

action comandroidnotepadactionEDIT_TITLE

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the title associated with note ID and allow the user to edit the title

Processes and Threads

When an application component starts and the application does not have any other components

running the Android system starts a new Linux process for the application with a single thread of

execution By default all components of the same application run in the same process and thread

(called the main thread) If an application component starts and there already exists a process for

that application (because another component from the application exists) then the component is

started within that process and uses the same thread of execution However you can arrange for

different components in your application to run in separate processes and you can create additional

threads for any process

This document discusses how processes and threads work in an Android application

Processes

By default all components of the same application run in the same process and most applications

should not change this However if you find that you need to control which process a certain

component belongs to you can do so in the manifest file

The manifest entry for each type of component elementmdashltactivitygt ltservicegt ltreceivergt and

ltprovidergtmdashsupports an androidprocess attribute that can specify a process in which that component

should run You can set this attribute so that each component runs in its own process or so that some

components share a process while others do not You can also set androidprocess so that

components of different applications run in the same processmdashprovided that the applications share the

same Linux user ID and are signed with the same certificates

The ltapplicationgt element also supports an androidprocess attribute to set a default value that

applies to all components

Android might 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 thats killed are consequently destroyed A process is started again for those components

when theres again work for them to do

When deciding which processes to kill the Android system weighs their relative importance to the

user For example it more readily shuts down a process hosting activities that are no longer visible on

screen compared to a process hosting visible activities The decision whether to terminate a process

therefore depends on the state of the components running in that process The rules used to decide

which processes to terminate is discussed below

Process lifecycle

The Android system tries to maintain an application process for as long as possible but eventually

needs to remove old processes to reclaim memory for new or more important processes To determine

which processes to keep and which to kill the system places each process into an importance

hierarchy based on the components running in the process and the state of those components

Processes with the lowest importance are eliminated first then those with the next lowest importance

and so on as necessary to recover system resources

There are five levels in the importance hierarchy The following list presents the different types of

processes in order of importance (the first process is most important and is killed last)

1 Foreground process

A process that is required for what the user is currently doing A process is considered to be in the

foreground if any of the following conditions are true

o It hosts an Activity that the user is interacting with (the Activitys onResume() method has been called)

o It hosts a Service thats bound to the activity that the user is interacting with

o It hosts a Service thats running in the foregroundmdashthe service has called startForeground()

o It hosts a Service thats executing one of its lifecycle callbacks (onCreate() onStart() or onDestroy())

o It hosts a BroadcastReceiver thats executing its onReceive() method

Generally only a few foreground processes exist at any given time They are killed only as a last

resortmdashif memory is so low that they cannot all continue to run Generally at that point the device has

reached a memory paging state so killing some foreground processes is required to keep the user

interface responsive

2 Visible process

A process that doesnt have any foreground components but still can affect what the user sees on

screen A process is considered to be visible if either of the following conditions are true

o It hosts an Activity that is not in the foreground but is still visible to the user (its onPause() method has

been called) This might occur for example if the foreground activity started a dialog which allows the

previous activity to be seen behind it

o It hosts a Service thats bound to a visible (or foreground) activity

A visible process is considered extremely important and will not be killed unless doing so is required to

keep all foreground processes running

3 Service process

A process that is running a service that has been started with the startService() method and does not

fall into either of the two higher categories Although service processes are not directly tied to anything

the user sees they are generally doing things that the user cares about (such as playing music in the

background or downloading data on the network) so the system keeps them running unless theres

not enough memory to retain them along with all foreground and visible processes

4 Background process

A process holding an activity thats not currently visible to the user (the activitys onStop() method has

been called) These processes have no direct impact on the user experience and the system can kill

them at any time to reclaim memory for a foreground visible or service process Usually there are

many background processes running so they are kept in an LRU (least recently used) list to ensure

that the process with the activity that was most recently seen by the user is the last to be killed If an

activity implements its lifecycle methods correctly and saves its current state killing its process will not

have a visible effect on the user experience because when the user navigates back to the activity the

activity restores all of its visible state See the Activities document for information about saving and

restoring state

5 Empty process

A process that doesnt hold any active application components The only reason to keep this kind of

process alive is for caching purposes to improve startup time the next time a component needs to run

in it The system often kills these processes in order to balance overall system resources between

process caches and the underlying kernel caches

Android ranks a process at the highest level it can based upon the importance of the components

currently active in the process For example if a process hosts a service and a visible activity the

process is ranked as a visible process not a service process

In addition a processs ranking might be increased because other processes are dependent on itmdasha

process that is serving another process can never be ranked lower than the process it is serving For

example if a content provider in process A is serving a client in process B or if a service in process A

is bound to a component in process B process A is always considered at least as important as

process B

Because a process running a service is ranked higher than a process with background activities an

activity that initiates a long-running operation might do well to start a service for that operation rather

than simply create a worker threadmdashparticularly if the operation will likely outlast the activity For

example an activity thats uploading a picture to a web site should start a service to perform the

upload so that the upload can continue in the background even if the user leaves the activity Using a

service guarantees that the operation will have at least service process priority regardless of what

happens to the activity This is the same reason that broadcast receivers should employ services

rather than simply put time-consuming operations in a thread

Threads

When an application is launched the system creates a thread of execution for the application called

main This thread is very important because it is in charge of dispatching events to the appropriate

user interface widgets including drawing events It is also the thread in which your application interacts

with components from the Android UI toolkit (components from the androidwidget and androidview

packages) As such the main thread is also sometimes called the UI thread

The system does not create a separate thread for each instance of a component All components that

run in the same process are instantiated in the UI thread and system calls to each component are

dispatched from that thread Consequently methods that respond to system callbacks (such as

onKeyDown() to report user actions or a lifecycle callback method) always run in the UI thread of the

process

For instance when the user touches a button on the screen your apps UI thread dispatches the touch

event to the widget which in turn sets its pressed state and posts an invalidate request to the event

queue The UI thread dequeues the request and notifies the widget that it should redraw itself

When your app performs intensive work in response to user interaction this single thread model can

yield poor performance unless you implement your application properly Specifically if everything is

happening in the UI thread performing long operations such as network access or database queries

will block the whole UI When the thread is blocked no events can be dispatched including drawing

events From the users perspective the application appears to hang Even worse if the UI thread is

blocked for more than a few seconds (about 5 seconds currently) the user is presented with the

infamous application not responding (ANR) dialog The user might then decide to quit your

application and uninstall it if they are unhappy

Additionally the Andoid UI toolkit is not thread-safe So you must not manipulate your UI from a

worker threadmdashyou must do all manipulation to your user interface from the UI thread Thus there are

simply two rules to Androids single thread model

1 Do not block the UI thread

2 Do not access the Android UI toolkit from outside the UI thread

Worker threads

Because of the single thread model described above its vital to the responsiveness of your

applications UI that you do not block the UI thread If you have operations to perform that are not

instantaneous you should make sure to do them in separate threads (background or worker

threads)

For example below is some code for a click listener that downloads an image from a separate thread

and displays it in an ImageView

public void onClick(View v) new Thread(new Runnable() public void run() Bitmap b = loadImageFromNetwork(httpexamplecomimagepng) mImageViewsetImageBitmap(b) )start()

At first this seems to work fine because it creates a new thread to handle the network operation

However it violates the second rule of the single-threaded model do not access the Android UI toolkit

from outside the UI threadmdashthis sample modifies the ImageView from the worker thread instead of the

UI thread This can result in undefined and unexpected behavior which can be difficult and time-

consuming to track down

To fix this problem Android offers several ways to access the UI thread from other threads Here is a

list of methods that can help

ActivityrunOnUiThread(Runnable)

Viewpost(Runnable)

ViewpostDelayed(Runnable long)

For example you can fix the above code by using the Viewpost(Runnable) method

public void onClick(View v) new Thread(new Runnable() public void run() final Bitmap bitmap = loadImageFromNetwork(httpexamplecomimagepng) mImageViewpost(new Runnable() public void run() mImageViewsetImageBitmap(bitmap) ) )start()

Now this implementation is thread-safe the network operation is done from a separate thread while

the ImageView is manipulated from the UI thread

However as the complexity of the operation grows this kind of code can get complicated and difficult

to maintain To handle more complex interactions with a worker thread you might consider using a

Handler in your worker thread to process messages delivered from the UI thread Perhaps the best

solution though is to extend the AsyncTask class which simplifies the execution of worker thread

tasks that need to interact with the UI

Using AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface It performs the blocking

operations in a worker thread and then publishes the results on the UI thread without requiring you to

handle threads andor handlers yourself

To use it you must subclass AsyncTask and implement the doInBackground() callback method which

runs in a pool of background threads To update your UI you should implement onPostExecute()

which delivers the result from doInBackground() and runs in the UI thread so you can safely update

your UI You can then run the task by calling execute() from the UI thread

For example you can implement the previous example using AsyncTask this way

public void onClick(View v) new DownloadImageTask()execute(httpexamplecomimagepng) private class DownloadImageTask extends AsyncTaskltString Void Bitmapgt The system calls this to perform work in a worker thread and delivers it the parameters given to AsyncTaskexecute() protected Bitmap doInBackground(String urls) return loadImageFromNetwork(urls[0])

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 40: 03 services

data field would contain the URI of the document to be displayed for editing If the action is

ACTION_CALL the data field would be a tel URI with the number to call Similarly if the action

is ACTION_VIEW and the data field is an http URI the receiving activity would be called upon

to download and display whatever data the URI refers to

When matching an intent to a component that is capable of handling the data its often

important to know the type of data (its MIME type) in addition to its URI For example a

component able to display image data should not be called upon to play an audio file

In many cases the data type can be inferred from the URI mdash particularly content URIs which

indicate that the data is located on the device and controlled by a content provider (see the

separate discussion on content providers) But the type can also be explicitly set in the Intent

object The setData() method specifies data only as a URI setType() specifies it only as a

MIME type and setDataAndType() specifies it as both a URI and a MIME type The URI is read

by getData() and the type by getType()

Category

A string containing additional information about the kind of component that should handle the

intent Any number of category descriptions can be placed in an Intent object As it does for

actions the Intent class defines several category constants including these

Constant Meaning

CATEGORY_BROWSABLE The target activity can be safely invoked by the browser to

display data referenced by a link mdash for example an image or

an e-mail message

CATEGORY_GADGET The activity can be embedded inside of another activity that

hosts gadgets

CATEGORY_HOME The activity displays the home screen the first screen the

user sees when the device is turned on or when the HOME

key is pressed

CATEGORY_LAUNCHER The activity can be the initial activity of a task and is listed in

the top-level application launcher

CATEGORY_PREFERENCE The target activity is a preference panel

See the Intent class description for the full list of categories

The addCategory() method places a category in an Intent object removeCategory() deletes a

category previously added and getCategories() gets the set of all categories currently in the

object

Extras

Key-value pairs for additional information that should be delivered to the component handling

the intent Just as some actions are paired with particular kinds of data URIs some are paired

with particular extras For example an ACTION_TIMEZONE_CHANGED intent has a time-

zone extra that identifies the new time zone and ACTION_HEADSET_PLUG has a state

extra indicating whether the headset is now plugged in or unplugged as well as a name extra

for the type of headset If you were to invent a SHOW_COLOR action the color value would be

set in an extra key-value pair

The Intent object has a series of put() methods for inserting various types of extra data and a

similar set of get() methods for reading the data These methods parallel those for Bundle

objects In fact the extras can be installed and read as a Bundle using the putExtras() and

getExtras() methods

Flags

Flags of various sorts Many instruct the Android system how to launch an activity (for example

which task the activity should belong to) and how to treat it after its launched (for example

whether it belongs in the list of recent activities) All these flags are defined in the Intent class

The Android system and the applications that come with the platform employ Intent objects both to

send out system-originated broadcasts and to activate system-defined components To see how to

structure an intent to activate a system component consult the list of intents in the reference

Intent Resolution

Intents can be divided into two groups

Explicit intents designate the target component by its name (the component name field mentioned

earlier has a value set) Since component names would generally not be known to developers of other

applications explicit intents are typically used for application-internal messages mdash such as an activity

starting a subordinate service or launching a sister activity

Implicit intents do not name a target (the field for the component name is blank) Implicit intents are

often used to activate components in other applications

Android delivers an explicit intent to an instance of the designated target class Nothing in the Intent

object other than the component name matters for determining which component should get the intent

A different strategy is needed for implicit intents In the absence of a designated target the Android

system must find the best component (or components) to handle the intent mdash a single activity or

service to perform the requested action or the set of broadcast receivers to respond to the broadcast

announcement It does so by comparing the contents of the Intent object to intent filters structures

associated with components that can potentially receive intents Filters advertise the capabilities of a

component and delimit the intents it can handle They open the component to the possibility of

receiving implicit intents of the advertised type If a component does not have any intent filters it can

receive only explicit intents A component with filters can receive both explicit and implicit intents

Only three aspects of an Intent object are consulted when the object is tested against an intent filter

action

data (both URI and data type)

category

The extras and flags play no part in resolving which component receives an intent

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 mdash but only unwanted implicit intents (those that dont 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

components 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 mdash 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 Pads filters are described in the Note Pad Example

section later)

Filters and security

An intent filter cannot be relied on for security While it opens a component to receiving only certain

kinds of implicit intents it does nothing to prevent explicit intents from targeting the component Even

though a filter restricts the intents a component will be asked to handle to certain actions and data

sources someone could always put together an explicit intent with a different action and data source

and name the component as the target

An intent filter is an instance of the IntentFilter class However since the Android system must know

about the capabilities of a component before it can launch that component intent filters are generally

not set up in Java code but in the applications manifest file (AndroidManifestxml) as ltintent-filtergt

elements (The one exception would be filters for broadcast receivers that are registered dynamically

by calling ContextregisterReceiver() they are directly created as IntentFilter objects)

A filter has fields that parallel the action data and category fields of an Intent object An implicit intent

is tested against the filter in all three areas To be delivered to the component that owns the filter it

must pass all three tests If it fails even one of them the Android system wont deliver it to the

component mdash at least not on the basis of that filter However since a component can have multiple

intent filters an intent that does not pass through one of a components filters might make it through on

another

Each of the three tests is described in detail below

Action test

An ltintent-filtergt element in the manifest file lists actions as ltactiongt subelements For

example

ltintent-filter gt ltaction androidname=comexampleprojectSHOW_CURRENT gt ltaction androidname=comexampleprojectSHOW_RECENT gt ltaction androidname=comexampleprojectSHOW_PENDING gt ltintent-filtergt

As the example shows while an Intent object names just a single action a filter may list more

than one The list cannot be empty a filter must contain at least one ltactiongt element or it will

block all intents

To pass this test the action specified in the Intent object must match one of the actions listed in

the filter If the object or the filter does not specify an action the results are as follows

If the filter fails to list any actions there is nothing for an intent to match so all intents fail the

test No intents can get through the filter

On the other hand an Intent object that doesnt specify an action automatically passes the test

mdash as long as the filter contains at least one action

Category test

An ltintent-filtergt element also lists categories as subelements For example

ltintent-filter gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryBROWSABLE gt ltintent-filtergt

Note that the constants described earlier for actions and categories are not used in the manifest

file The full string values are used instead For instance the

androidintentcategoryBROWSABLE string in the example above corresponds to the

CATEGORY_BROWSABLE constant mentioned earlier in this document Similarly the string

androidintentactionEDIT corresponds to the ACTION_EDIT constant

For an intent to pass the category test every category in the Intent object must match a

category in the filter The filter can list additional categories but it cannot omit any that are in the

intent

In principle therefore an Intent object with no categories should always pass this test

regardless of whats in the filter Thats mostly true However with one exception Android treats

all implicit intents passed to startActivity() as if they contained at least one category

androidintentcategoryDEFAULT (the CATEGORY_DEFAULT constant) Therefore activities

that are willing to receive implicit intents must include androidintentcategoryDEFAULT in

their intent filters (Filters with androidintentactionMAIN and

androidintentcategoryLAUNCHER settings are the exception They mark activities that begin

new tasks and that are represented on the launcher screen They can include

androidintentcategoryDEFAULT in the list of categories but dont need to) See Using intent

matching later for more on these filters)

Data test

Like the action and categories the data specification for an intent filter is contained in a

subelement And as in those cases the subelement can appear multiple times or not at all For

example

ltintent-filter gt ltdata androidmimeType=videompeg androidscheme=http gt ltdata androidmimeType=audiompeg androidscheme=http gt ltintent-filtergt

Each ltdatagt element can specify a URI and a data type (MIME media type) There are

separate attributes mdash scheme host port and path mdash for each part of the URI

schemehostportpath

For example in the following URI

contentcomexampleproject200foldersubfolderetc

the scheme is content the host is comexampleproject the port is 200 and the path is

foldersubfolderetc The host and port together constitute the URI authority if a host is not

specified the port is ignored

Each of these attributes is optional but they are not independent of each other For an authority

to be meaningful a scheme must also be specified For a path to be meaningful both a scheme

and an authority must be specified

When the URI in an Intent object is compared to a URI specification in a filter its compared

only to the parts of the URI actually mentioned in the filter For example if a filter specifies only

a scheme all URIs with that scheme match the filter If a filter specifies a scheme and an

authority but no path all URIs with the same scheme and authority match regardless of their

paths If a filter specifies a scheme an authority and a path only URIs with the same scheme

authority and path match However a path specification in the filter can contain wildcards to

require only a partial match of the path

The type attribute of a ltdatagt element specifies the MIME type of the data Its more common in

filters than a URI Both the Intent object and the filter can use a wildcard for the subtype field

mdash for example text or audio mdash indicating any subtype matches

The data test compares both the URI and the data type in the Intent object to a URI and data

type specified in the filter The rules are as follows

a An Intent object that contains neither a URI nor a data type passes the test only if the filter

likewise does not specify any URIs or data types

b An Intent object that contains a URI but no data type (and a type cannot be inferred from the

URI) passes the test only if its URI matches a URI in the filter and the filter likewise does not

specify a type This will be the case only for URIs like mailto and tel that do not refer to actual

data

c An Intent object that contains a data type but not a URI passes the test only if the filter lists the

same data type and similarly does not specify a URI

d An Intent object that contains both a URI and a data type (or a data type can be inferred from

the URI) passes the data type part of the test only if its type matches a type listed in the filter It

passes the URI part of the test either if its URI matches a URI in the filter or if it has a content

or file URI and the filter does not specify a URI In other words a component is presumed to

support content and file data if its filter lists only a data type

If an intent can pass through the filters of more than one activity or service the user may be asked

which component to activate An exception is raised if no target can be found

Common cases

The last rule shown above for the data test rule (d) reflects the expectation that components are able

to get local data from a file or content provider Therefore their filters can list just a data type and do

not need to explicitly name the content and file schemes This is a typical case A ltdatagt element like

the following for example tells Android that the component can get image data from a content

provider and display it

ltdata androidmimeType=image gt

Since most available data is dispensed by content providers filters that specify a data type but not a

URI are perhaps the most common

Another common configuration is filters with a scheme and a data type For example a ltdatagt

element like the following tells Android that the component can get video data from the network and

display it

ltdata androidscheme=http androidtype=video gt

Consider for example what the browser application does when the user follows a link on a web page

It first tries to display the data (as it could if the link was to an HTML page) If it cant display the data it

puts together an implicit intent with the scheme and data type and tries to start an activity that can do

the job If there are no takers it asks the download manager to download the data That puts it under

the control of a content provider so a potentially larger pool of activities (those with filters that just

name a data type) can respond

Most applications also have a way to start fresh without a reference to any particular data Activities

that can initiate applications have filters with androidintentactionMAIN specified as the action If

they are to be represented in the application launcher they also specify the

androidintentcategoryLAUNCHER category

ltintent-filter gt ltaction androidname=code androidintentactionMAIN gt ltcategory androidname=code androidintentcategoryLAUNCHER gt ltintent-filtergt

Using intent matching

Intents are matched against intent filters not only to discover a target component to activate but also

to discover something about the set of components on the device For example the Android system

populates the application launcher the top-level screen that shows the applications that are available

for the user to launch by finding all the activities with intent filters that specify the

androidintentactionMAIN action and androidintentcategoryLAUNCHER category (as illustrated

in the previous section) It then displays the icons and labels of those activities in the launcher

Similarly it discovers the home screen by looking for the activity with androidintentcategoryHOME

in its filter

Your application can use intent matching is a similar way The PackageManager has a set of query()

methods that return all components that can accept a particular intent and a similar series of

resolve() methods that determine the best component to respond to an intent For example

queryIntentActivities() returns a list of all activities that can perform the intent passed as an argument

and queryIntentServices() returns a similar list of services Neither method activates the components

they just list the ones that can respond Theres a similar method queryBroadcastReceivers() for

broadcast receivers

Note Pad Example

The Note Pad sample application enables users to browse through a list of notes view details about

individual items in the list edit the items and add a new item to the list This section looks at the intent

filters declared in its manifest file (If youre working offline in the SDK you can find all the source files

for this sample application including its manifest file at ltsdkgtsamplesNotePadindexhtml If youre

viewing the documentation online the source files are in the Tutorials and Sample Code section here)

In its manifest file the Note Pad application declares three activities each with at least one intent filter

It also declares a content provider that manages the note data Here is the manifest file in its entirety

ltmanifest xmlnsandroid=httpschemasandroidcomapkresandroid package=comexampleandroidnotepadgt ltapplication androidicon=drawableapp_notes androidlabel=stringapp_name gt ltprovider androidname=NotePadProvider androidauthorities=comgoogleproviderNotePad gt ltactivity androidname=NotesList androidlabel=stringtitle_notes_listgt ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltactivity androidname=NoteEditor androidtheme=androidstyleThemeLight androidlabel=stringtitle_note gt ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltactivitygt

ltactivity androidname=TitleEditor androidlabel=stringtitle_edit_title androidtheme=androidstyleThemeDialoggt ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltapplicationgt ltmanifestgt

The first activity NotesList is distinguished from the other activities by the fact that it operates on a

directory of notes (the note list) rather than on a single note It would generally serve as the initial user

interface into the application It can do three things as described by its three intent filters

1 ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt

This filter declares the main entry point into the Note Pad application The standard MAIN action is an

entry point that does not require any other information in the Intent (no data specification for example)

and the LAUNCHER category says that this entry point should be listed in the application launcher

2 ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

This filter declares the things that the activity can do on a directory of notes It can allow the user to

view or edit the directory (via the VIEW and EDIT actions) or to pick a particular note from the

directory (via the PICK action)

The mimeType attribute of the ltdatagt element specifies the kind of data that these actions operate on

It indicates that the activity can get a Cursor over zero or more items (vndandroidcursordir) from a

content provider that holds Note Pad data (vndgooglenote) The Intent object that launches the

activity would include a content URI specifying the exact data of this type that the activity should open

Note also the DEFAULT category supplied in this filter Its there because the ContextstartActivity()

and ActivitystartActivityForResult() methods treat all intents as if they contained the DEFAULT

category mdash with just two exceptions

o Intents that explicitly name the target activity

o Intents consisting of the MAIN action and LAUNCHER category

Therefore the DEFAULT category is required for all filters mdash except for those with the MAIN action

and LAUNCHER category (Intent filters are not consulted for explicit intents)

3 ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

This filter describes the activitys ability to return a note selected by the user without requiring any

specification of the directory the user should choose from The GET_CONTENT action is similar to the

PICK action In both cases the activity returns the URI for a note selected by the user (In each case

its returned to the activity that called startActivityForResult() to start the NoteList activity) Here

however the caller specifies the type of data desired instead of the directory of data the user will be

picking from

The data type vndandroidcursoritemvndgooglenote indicates the type of data the activity can

return mdash a URI for a single note From the returned URI the caller can get a Cursor for exactly one

item (vndandroidcursoritem) from the content provider that holds Note Pad data (vndgooglenote)

In other words for the PICK action in the previous filter the data type indicates the type of data the

activity could display to the user For the GET_CONTENT filter it indicates the type of data the activity

can return to the caller

Given these capabilities the following intents will resolve to the NotesList activity

action androidintentactionMAIN

Launches the activity with no data specified

action androidintentactionMAIN

category androidintentcategoryLAUNCHER

Launches the activity with no data selected specified This is the actual intent used by the

Launcher to populate its top-level list All activities with filters that match this action and

category are added to the list

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of all the notes under

contentcomgoogleproviderNotePadnotes The user can then browse through the list and

get information about the items in it

action androidintentactionPICK

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of the notes under

contentcomgoogleproviderNotePadnotes The user can then pick a note from the list and

the activity will return the URI for that item back to the activity that started the NoteList activity

action androidintentactionGET_CONTENT

data type vndandroidcursoritemvndgooglenote

Asks the activity to supply a single item of Note Pad data

The second activity NoteEditor shows users a single note entry and allows them to edit it It can do

two things as described by its two intent filters

1 ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The first primary purpose of this activity is to enable the user to interact with a single note ampmdash to

either VIEW the note or EDIT it (The EDIT_NOTE category is a synonym for EDIT) The intent would

contain the URI for data matching the MIME type vndandroidcursoritemvndgooglenote mdash that is

the URI for a single specific note It would typically be a URI that was returned by the PICK or

GET_CONTENT actions of the NoteList activity

As before this filter lists the DEFAULT category so that the activity can be launched by intents that

dont explicitly specify the NoteEditor class

2 ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

The secondary purpose of this activity is to enable the user to create a new note which it will INSERT

into an existing directory of notes The intent would contain the URI for data matching the MIME type

vndandroidcursordirvndgooglenote mdash that is the URI for the directory where the note should be

placed

Given these capabilities the following intents will resolve to the NoteEditor activity

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID (For details on how content

URIs specify individual members of a group see Content Providers)

action androidintentactionEDIT

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID and to let the user edit it If

the user saves the changes the activity updates the data for the note in the content provider

action androidintentactionINSERT

data contentcomgoogleproviderNotePadnotes

Asks the activity to create a new empty note in the notes list at

contentcomgoogleproviderNotePadnotes and allow the user to edit it If the user saves the

note its URI is returned to the caller

The last activity TitleEditor enables the user to edit the title of a note This could be implemented by

directly invoking the activity (by explicitly setting its component name in the Intent) without using an

intent filter But here we take the opportunity to show how to publish alternative operations on existing

data

ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The single intent filter for this activity uses a custom action called

comandroidnotepadactionEDIT_TITLE It must be invoked on a specific note (data type

vndandroidcursoritemvndgooglenote) like the previous VIEW and EDIT actions However here the

activity displays the title contained in the note data not the content of the note itself

In addition to supporting the usual DEFAULT category the title editor also supports two other standard

categories ALTERNATIVE and SELECTED_ALTERNATIVE These categories identify activities that

can be presented to users in a menu of options (much as the LAUNCHER category identifies activities

that should be presented to user in the application launcher) Note that the filter also supplies an

explicit label (via androidlabel=stringresolve_title) to better control what users see when

presented with this activity as an alternative action to the data they are currently viewing (For more

information on these categories and building options menus see the

PackageManagerqueryIntentActivityOptions() and MenuaddIntentOptions() methods)

Given these capabilities the following intent will resolve to the TitleEditor activity

action comandroidnotepadactionEDIT_TITLE

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the title associated with note ID and allow the user to edit the title

Processes and Threads

When an application component starts and the application does not have any other components

running the Android system starts a new Linux process for the application with a single thread of

execution By default all components of the same application run in the same process and thread

(called the main thread) If an application component starts and there already exists a process for

that application (because another component from the application exists) then the component is

started within that process and uses the same thread of execution However you can arrange for

different components in your application to run in separate processes and you can create additional

threads for any process

This document discusses how processes and threads work in an Android application

Processes

By default all components of the same application run in the same process and most applications

should not change this However if you find that you need to control which process a certain

component belongs to you can do so in the manifest file

The manifest entry for each type of component elementmdashltactivitygt ltservicegt ltreceivergt and

ltprovidergtmdashsupports an androidprocess attribute that can specify a process in which that component

should run You can set this attribute so that each component runs in its own process or so that some

components share a process while others do not You can also set androidprocess so that

components of different applications run in the same processmdashprovided that the applications share the

same Linux user ID and are signed with the same certificates

The ltapplicationgt element also supports an androidprocess attribute to set a default value that

applies to all components

Android might 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 thats killed are consequently destroyed A process is started again for those components

when theres again work for them to do

When deciding which processes to kill the Android system weighs their relative importance to the

user For example it more readily shuts down a process hosting activities that are no longer visible on

screen compared to a process hosting visible activities The decision whether to terminate a process

therefore depends on the state of the components running in that process The rules used to decide

which processes to terminate is discussed below

Process lifecycle

The Android system tries to maintain an application process for as long as possible but eventually

needs to remove old processes to reclaim memory for new or more important processes To determine

which processes to keep and which to kill the system places each process into an importance

hierarchy based on the components running in the process and the state of those components

Processes with the lowest importance are eliminated first then those with the next lowest importance

and so on as necessary to recover system resources

There are five levels in the importance hierarchy The following list presents the different types of

processes in order of importance (the first process is most important and is killed last)

1 Foreground process

A process that is required for what the user is currently doing A process is considered to be in the

foreground if any of the following conditions are true

o It hosts an Activity that the user is interacting with (the Activitys onResume() method has been called)

o It hosts a Service thats bound to the activity that the user is interacting with

o It hosts a Service thats running in the foregroundmdashthe service has called startForeground()

o It hosts a Service thats executing one of its lifecycle callbacks (onCreate() onStart() or onDestroy())

o It hosts a BroadcastReceiver thats executing its onReceive() method

Generally only a few foreground processes exist at any given time They are killed only as a last

resortmdashif memory is so low that they cannot all continue to run Generally at that point the device has

reached a memory paging state so killing some foreground processes is required to keep the user

interface responsive

2 Visible process

A process that doesnt have any foreground components but still can affect what the user sees on

screen A process is considered to be visible if either of the following conditions are true

o It hosts an Activity that is not in the foreground but is still visible to the user (its onPause() method has

been called) This might occur for example if the foreground activity started a dialog which allows the

previous activity to be seen behind it

o It hosts a Service thats bound to a visible (or foreground) activity

A visible process is considered extremely important and will not be killed unless doing so is required to

keep all foreground processes running

3 Service process

A process that is running a service that has been started with the startService() method and does not

fall into either of the two higher categories Although service processes are not directly tied to anything

the user sees they are generally doing things that the user cares about (such as playing music in the

background or downloading data on the network) so the system keeps them running unless theres

not enough memory to retain them along with all foreground and visible processes

4 Background process

A process holding an activity thats not currently visible to the user (the activitys onStop() method has

been called) These processes have no direct impact on the user experience and the system can kill

them at any time to reclaim memory for a foreground visible or service process Usually there are

many background processes running so they are kept in an LRU (least recently used) list to ensure

that the process with the activity that was most recently seen by the user is the last to be killed If an

activity implements its lifecycle methods correctly and saves its current state killing its process will not

have a visible effect on the user experience because when the user navigates back to the activity the

activity restores all of its visible state See the Activities document for information about saving and

restoring state

5 Empty process

A process that doesnt hold any active application components The only reason to keep this kind of

process alive is for caching purposes to improve startup time the next time a component needs to run

in it The system often kills these processes in order to balance overall system resources between

process caches and the underlying kernel caches

Android ranks a process at the highest level it can based upon the importance of the components

currently active in the process For example if a process hosts a service and a visible activity the

process is ranked as a visible process not a service process

In addition a processs ranking might be increased because other processes are dependent on itmdasha

process that is serving another process can never be ranked lower than the process it is serving For

example if a content provider in process A is serving a client in process B or if a service in process A

is bound to a component in process B process A is always considered at least as important as

process B

Because a process running a service is ranked higher than a process with background activities an

activity that initiates a long-running operation might do well to start a service for that operation rather

than simply create a worker threadmdashparticularly if the operation will likely outlast the activity For

example an activity thats uploading a picture to a web site should start a service to perform the

upload so that the upload can continue in the background even if the user leaves the activity Using a

service guarantees that the operation will have at least service process priority regardless of what

happens to the activity This is the same reason that broadcast receivers should employ services

rather than simply put time-consuming operations in a thread

Threads

When an application is launched the system creates a thread of execution for the application called

main This thread is very important because it is in charge of dispatching events to the appropriate

user interface widgets including drawing events It is also the thread in which your application interacts

with components from the Android UI toolkit (components from the androidwidget and androidview

packages) As such the main thread is also sometimes called the UI thread

The system does not create a separate thread for each instance of a component All components that

run in the same process are instantiated in the UI thread and system calls to each component are

dispatched from that thread Consequently methods that respond to system callbacks (such as

onKeyDown() to report user actions or a lifecycle callback method) always run in the UI thread of the

process

For instance when the user touches a button on the screen your apps UI thread dispatches the touch

event to the widget which in turn sets its pressed state and posts an invalidate request to the event

queue The UI thread dequeues the request and notifies the widget that it should redraw itself

When your app performs intensive work in response to user interaction this single thread model can

yield poor performance unless you implement your application properly Specifically if everything is

happening in the UI thread performing long operations such as network access or database queries

will block the whole UI When the thread is blocked no events can be dispatched including drawing

events From the users perspective the application appears to hang Even worse if the UI thread is

blocked for more than a few seconds (about 5 seconds currently) the user is presented with the

infamous application not responding (ANR) dialog The user might then decide to quit your

application and uninstall it if they are unhappy

Additionally the Andoid UI toolkit is not thread-safe So you must not manipulate your UI from a

worker threadmdashyou must do all manipulation to your user interface from the UI thread Thus there are

simply two rules to Androids single thread model

1 Do not block the UI thread

2 Do not access the Android UI toolkit from outside the UI thread

Worker threads

Because of the single thread model described above its vital to the responsiveness of your

applications UI that you do not block the UI thread If you have operations to perform that are not

instantaneous you should make sure to do them in separate threads (background or worker

threads)

For example below is some code for a click listener that downloads an image from a separate thread

and displays it in an ImageView

public void onClick(View v) new Thread(new Runnable() public void run() Bitmap b = loadImageFromNetwork(httpexamplecomimagepng) mImageViewsetImageBitmap(b) )start()

At first this seems to work fine because it creates a new thread to handle the network operation

However it violates the second rule of the single-threaded model do not access the Android UI toolkit

from outside the UI threadmdashthis sample modifies the ImageView from the worker thread instead of the

UI thread This can result in undefined and unexpected behavior which can be difficult and time-

consuming to track down

To fix this problem Android offers several ways to access the UI thread from other threads Here is a

list of methods that can help

ActivityrunOnUiThread(Runnable)

Viewpost(Runnable)

ViewpostDelayed(Runnable long)

For example you can fix the above code by using the Viewpost(Runnable) method

public void onClick(View v) new Thread(new Runnable() public void run() final Bitmap bitmap = loadImageFromNetwork(httpexamplecomimagepng) mImageViewpost(new Runnable() public void run() mImageViewsetImageBitmap(bitmap) ) )start()

Now this implementation is thread-safe the network operation is done from a separate thread while

the ImageView is manipulated from the UI thread

However as the complexity of the operation grows this kind of code can get complicated and difficult

to maintain To handle more complex interactions with a worker thread you might consider using a

Handler in your worker thread to process messages delivered from the UI thread Perhaps the best

solution though is to extend the AsyncTask class which simplifies the execution of worker thread

tasks that need to interact with the UI

Using AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface It performs the blocking

operations in a worker thread and then publishes the results on the UI thread without requiring you to

handle threads andor handlers yourself

To use it you must subclass AsyncTask and implement the doInBackground() callback method which

runs in a pool of background threads To update your UI you should implement onPostExecute()

which delivers the result from doInBackground() and runs in the UI thread so you can safely update

your UI You can then run the task by calling execute() from the UI thread

For example you can implement the previous example using AsyncTask this way

public void onClick(View v) new DownloadImageTask()execute(httpexamplecomimagepng) private class DownloadImageTask extends AsyncTaskltString Void Bitmapgt The system calls this to perform work in a worker thread and delivers it the parameters given to AsyncTaskexecute() protected Bitmap doInBackground(String urls) return loadImageFromNetwork(urls[0])

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 41: 03 services

See the Intent class description for the full list of categories

The addCategory() method places a category in an Intent object removeCategory() deletes a

category previously added and getCategories() gets the set of all categories currently in the

object

Extras

Key-value pairs for additional information that should be delivered to the component handling

the intent Just as some actions are paired with particular kinds of data URIs some are paired

with particular extras For example an ACTION_TIMEZONE_CHANGED intent has a time-

zone extra that identifies the new time zone and ACTION_HEADSET_PLUG has a state

extra indicating whether the headset is now plugged in or unplugged as well as a name extra

for the type of headset If you were to invent a SHOW_COLOR action the color value would be

set in an extra key-value pair

The Intent object has a series of put() methods for inserting various types of extra data and a

similar set of get() methods for reading the data These methods parallel those for Bundle

objects In fact the extras can be installed and read as a Bundle using the putExtras() and

getExtras() methods

Flags

Flags of various sorts Many instruct the Android system how to launch an activity (for example

which task the activity should belong to) and how to treat it after its launched (for example

whether it belongs in the list of recent activities) All these flags are defined in the Intent class

The Android system and the applications that come with the platform employ Intent objects both to

send out system-originated broadcasts and to activate system-defined components To see how to

structure an intent to activate a system component consult the list of intents in the reference

Intent Resolution

Intents can be divided into two groups

Explicit intents designate the target component by its name (the component name field mentioned

earlier has a value set) Since component names would generally not be known to developers of other

applications explicit intents are typically used for application-internal messages mdash such as an activity

starting a subordinate service or launching a sister activity

Implicit intents do not name a target (the field for the component name is blank) Implicit intents are

often used to activate components in other applications

Android delivers an explicit intent to an instance of the designated target class Nothing in the Intent

object other than the component name matters for determining which component should get the intent

A different strategy is needed for implicit intents In the absence of a designated target the Android

system must find the best component (or components) to handle the intent mdash a single activity or

service to perform the requested action or the set of broadcast receivers to respond to the broadcast

announcement It does so by comparing the contents of the Intent object to intent filters structures

associated with components that can potentially receive intents Filters advertise the capabilities of a

component and delimit the intents it can handle They open the component to the possibility of

receiving implicit intents of the advertised type If a component does not have any intent filters it can

receive only explicit intents A component with filters can receive both explicit and implicit intents

Only three aspects of an Intent object are consulted when the object is tested against an intent filter

action

data (both URI and data type)

category

The extras and flags play no part in resolving which component receives an intent

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 mdash but only unwanted implicit intents (those that dont 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

components 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 mdash 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 Pads filters are described in the Note Pad Example

section later)

Filters and security

An intent filter cannot be relied on for security While it opens a component to receiving only certain

kinds of implicit intents it does nothing to prevent explicit intents from targeting the component Even

though a filter restricts the intents a component will be asked to handle to certain actions and data

sources someone could always put together an explicit intent with a different action and data source

and name the component as the target

An intent filter is an instance of the IntentFilter class However since the Android system must know

about the capabilities of a component before it can launch that component intent filters are generally

not set up in Java code but in the applications manifest file (AndroidManifestxml) as ltintent-filtergt

elements (The one exception would be filters for broadcast receivers that are registered dynamically

by calling ContextregisterReceiver() they are directly created as IntentFilter objects)

A filter has fields that parallel the action data and category fields of an Intent object An implicit intent

is tested against the filter in all three areas To be delivered to the component that owns the filter it

must pass all three tests If it fails even one of them the Android system wont deliver it to the

component mdash at least not on the basis of that filter However since a component can have multiple

intent filters an intent that does not pass through one of a components filters might make it through on

another

Each of the three tests is described in detail below

Action test

An ltintent-filtergt element in the manifest file lists actions as ltactiongt subelements For

example

ltintent-filter gt ltaction androidname=comexampleprojectSHOW_CURRENT gt ltaction androidname=comexampleprojectSHOW_RECENT gt ltaction androidname=comexampleprojectSHOW_PENDING gt ltintent-filtergt

As the example shows while an Intent object names just a single action a filter may list more

than one The list cannot be empty a filter must contain at least one ltactiongt element or it will

block all intents

To pass this test the action specified in the Intent object must match one of the actions listed in

the filter If the object or the filter does not specify an action the results are as follows

If the filter fails to list any actions there is nothing for an intent to match so all intents fail the

test No intents can get through the filter

On the other hand an Intent object that doesnt specify an action automatically passes the test

mdash as long as the filter contains at least one action

Category test

An ltintent-filtergt element also lists categories as subelements For example

ltintent-filter gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryBROWSABLE gt ltintent-filtergt

Note that the constants described earlier for actions and categories are not used in the manifest

file The full string values are used instead For instance the

androidintentcategoryBROWSABLE string in the example above corresponds to the

CATEGORY_BROWSABLE constant mentioned earlier in this document Similarly the string

androidintentactionEDIT corresponds to the ACTION_EDIT constant

For an intent to pass the category test every category in the Intent object must match a

category in the filter The filter can list additional categories but it cannot omit any that are in the

intent

In principle therefore an Intent object with no categories should always pass this test

regardless of whats in the filter Thats mostly true However with one exception Android treats

all implicit intents passed to startActivity() as if they contained at least one category

androidintentcategoryDEFAULT (the CATEGORY_DEFAULT constant) Therefore activities

that are willing to receive implicit intents must include androidintentcategoryDEFAULT in

their intent filters (Filters with androidintentactionMAIN and

androidintentcategoryLAUNCHER settings are the exception They mark activities that begin

new tasks and that are represented on the launcher screen They can include

androidintentcategoryDEFAULT in the list of categories but dont need to) See Using intent

matching later for more on these filters)

Data test

Like the action and categories the data specification for an intent filter is contained in a

subelement And as in those cases the subelement can appear multiple times or not at all For

example

ltintent-filter gt ltdata androidmimeType=videompeg androidscheme=http gt ltdata androidmimeType=audiompeg androidscheme=http gt ltintent-filtergt

Each ltdatagt element can specify a URI and a data type (MIME media type) There are

separate attributes mdash scheme host port and path mdash for each part of the URI

schemehostportpath

For example in the following URI

contentcomexampleproject200foldersubfolderetc

the scheme is content the host is comexampleproject the port is 200 and the path is

foldersubfolderetc The host and port together constitute the URI authority if a host is not

specified the port is ignored

Each of these attributes is optional but they are not independent of each other For an authority

to be meaningful a scheme must also be specified For a path to be meaningful both a scheme

and an authority must be specified

When the URI in an Intent object is compared to a URI specification in a filter its compared

only to the parts of the URI actually mentioned in the filter For example if a filter specifies only

a scheme all URIs with that scheme match the filter If a filter specifies a scheme and an

authority but no path all URIs with the same scheme and authority match regardless of their

paths If a filter specifies a scheme an authority and a path only URIs with the same scheme

authority and path match However a path specification in the filter can contain wildcards to

require only a partial match of the path

The type attribute of a ltdatagt element specifies the MIME type of the data Its more common in

filters than a URI Both the Intent object and the filter can use a wildcard for the subtype field

mdash for example text or audio mdash indicating any subtype matches

The data test compares both the URI and the data type in the Intent object to a URI and data

type specified in the filter The rules are as follows

a An Intent object that contains neither a URI nor a data type passes the test only if the filter

likewise does not specify any URIs or data types

b An Intent object that contains a URI but no data type (and a type cannot be inferred from the

URI) passes the test only if its URI matches a URI in the filter and the filter likewise does not

specify a type This will be the case only for URIs like mailto and tel that do not refer to actual

data

c An Intent object that contains a data type but not a URI passes the test only if the filter lists the

same data type and similarly does not specify a URI

d An Intent object that contains both a URI and a data type (or a data type can be inferred from

the URI) passes the data type part of the test only if its type matches a type listed in the filter It

passes the URI part of the test either if its URI matches a URI in the filter or if it has a content

or file URI and the filter does not specify a URI In other words a component is presumed to

support content and file data if its filter lists only a data type

If an intent can pass through the filters of more than one activity or service the user may be asked

which component to activate An exception is raised if no target can be found

Common cases

The last rule shown above for the data test rule (d) reflects the expectation that components are able

to get local data from a file or content provider Therefore their filters can list just a data type and do

not need to explicitly name the content and file schemes This is a typical case A ltdatagt element like

the following for example tells Android that the component can get image data from a content

provider and display it

ltdata androidmimeType=image gt

Since most available data is dispensed by content providers filters that specify a data type but not a

URI are perhaps the most common

Another common configuration is filters with a scheme and a data type For example a ltdatagt

element like the following tells Android that the component can get video data from the network and

display it

ltdata androidscheme=http androidtype=video gt

Consider for example what the browser application does when the user follows a link on a web page

It first tries to display the data (as it could if the link was to an HTML page) If it cant display the data it

puts together an implicit intent with the scheme and data type and tries to start an activity that can do

the job If there are no takers it asks the download manager to download the data That puts it under

the control of a content provider so a potentially larger pool of activities (those with filters that just

name a data type) can respond

Most applications also have a way to start fresh without a reference to any particular data Activities

that can initiate applications have filters with androidintentactionMAIN specified as the action If

they are to be represented in the application launcher they also specify the

androidintentcategoryLAUNCHER category

ltintent-filter gt ltaction androidname=code androidintentactionMAIN gt ltcategory androidname=code androidintentcategoryLAUNCHER gt ltintent-filtergt

Using intent matching

Intents are matched against intent filters not only to discover a target component to activate but also

to discover something about the set of components on the device For example the Android system

populates the application launcher the top-level screen that shows the applications that are available

for the user to launch by finding all the activities with intent filters that specify the

androidintentactionMAIN action and androidintentcategoryLAUNCHER category (as illustrated

in the previous section) It then displays the icons and labels of those activities in the launcher

Similarly it discovers the home screen by looking for the activity with androidintentcategoryHOME

in its filter

Your application can use intent matching is a similar way The PackageManager has a set of query()

methods that return all components that can accept a particular intent and a similar series of

resolve() methods that determine the best component to respond to an intent For example

queryIntentActivities() returns a list of all activities that can perform the intent passed as an argument

and queryIntentServices() returns a similar list of services Neither method activates the components

they just list the ones that can respond Theres a similar method queryBroadcastReceivers() for

broadcast receivers

Note Pad Example

The Note Pad sample application enables users to browse through a list of notes view details about

individual items in the list edit the items and add a new item to the list This section looks at the intent

filters declared in its manifest file (If youre working offline in the SDK you can find all the source files

for this sample application including its manifest file at ltsdkgtsamplesNotePadindexhtml If youre

viewing the documentation online the source files are in the Tutorials and Sample Code section here)

In its manifest file the Note Pad application declares three activities each with at least one intent filter

It also declares a content provider that manages the note data Here is the manifest file in its entirety

ltmanifest xmlnsandroid=httpschemasandroidcomapkresandroid package=comexampleandroidnotepadgt ltapplication androidicon=drawableapp_notes androidlabel=stringapp_name gt ltprovider androidname=NotePadProvider androidauthorities=comgoogleproviderNotePad gt ltactivity androidname=NotesList androidlabel=stringtitle_notes_listgt ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltactivity androidname=NoteEditor androidtheme=androidstyleThemeLight androidlabel=stringtitle_note gt ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltactivitygt

ltactivity androidname=TitleEditor androidlabel=stringtitle_edit_title androidtheme=androidstyleThemeDialoggt ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltapplicationgt ltmanifestgt

The first activity NotesList is distinguished from the other activities by the fact that it operates on a

directory of notes (the note list) rather than on a single note It would generally serve as the initial user

interface into the application It can do three things as described by its three intent filters

1 ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt

This filter declares the main entry point into the Note Pad application The standard MAIN action is an

entry point that does not require any other information in the Intent (no data specification for example)

and the LAUNCHER category says that this entry point should be listed in the application launcher

2 ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

This filter declares the things that the activity can do on a directory of notes It can allow the user to

view or edit the directory (via the VIEW and EDIT actions) or to pick a particular note from the

directory (via the PICK action)

The mimeType attribute of the ltdatagt element specifies the kind of data that these actions operate on

It indicates that the activity can get a Cursor over zero or more items (vndandroidcursordir) from a

content provider that holds Note Pad data (vndgooglenote) The Intent object that launches the

activity would include a content URI specifying the exact data of this type that the activity should open

Note also the DEFAULT category supplied in this filter Its there because the ContextstartActivity()

and ActivitystartActivityForResult() methods treat all intents as if they contained the DEFAULT

category mdash with just two exceptions

o Intents that explicitly name the target activity

o Intents consisting of the MAIN action and LAUNCHER category

Therefore the DEFAULT category is required for all filters mdash except for those with the MAIN action

and LAUNCHER category (Intent filters are not consulted for explicit intents)

3 ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

This filter describes the activitys ability to return a note selected by the user without requiring any

specification of the directory the user should choose from The GET_CONTENT action is similar to the

PICK action In both cases the activity returns the URI for a note selected by the user (In each case

its returned to the activity that called startActivityForResult() to start the NoteList activity) Here

however the caller specifies the type of data desired instead of the directory of data the user will be

picking from

The data type vndandroidcursoritemvndgooglenote indicates the type of data the activity can

return mdash a URI for a single note From the returned URI the caller can get a Cursor for exactly one

item (vndandroidcursoritem) from the content provider that holds Note Pad data (vndgooglenote)

In other words for the PICK action in the previous filter the data type indicates the type of data the

activity could display to the user For the GET_CONTENT filter it indicates the type of data the activity

can return to the caller

Given these capabilities the following intents will resolve to the NotesList activity

action androidintentactionMAIN

Launches the activity with no data specified

action androidintentactionMAIN

category androidintentcategoryLAUNCHER

Launches the activity with no data selected specified This is the actual intent used by the

Launcher to populate its top-level list All activities with filters that match this action and

category are added to the list

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of all the notes under

contentcomgoogleproviderNotePadnotes The user can then browse through the list and

get information about the items in it

action androidintentactionPICK

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of the notes under

contentcomgoogleproviderNotePadnotes The user can then pick a note from the list and

the activity will return the URI for that item back to the activity that started the NoteList activity

action androidintentactionGET_CONTENT

data type vndandroidcursoritemvndgooglenote

Asks the activity to supply a single item of Note Pad data

The second activity NoteEditor shows users a single note entry and allows them to edit it It can do

two things as described by its two intent filters

1 ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The first primary purpose of this activity is to enable the user to interact with a single note ampmdash to

either VIEW the note or EDIT it (The EDIT_NOTE category is a synonym for EDIT) The intent would

contain the URI for data matching the MIME type vndandroidcursoritemvndgooglenote mdash that is

the URI for a single specific note It would typically be a URI that was returned by the PICK or

GET_CONTENT actions of the NoteList activity

As before this filter lists the DEFAULT category so that the activity can be launched by intents that

dont explicitly specify the NoteEditor class

2 ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

The secondary purpose of this activity is to enable the user to create a new note which it will INSERT

into an existing directory of notes The intent would contain the URI for data matching the MIME type

vndandroidcursordirvndgooglenote mdash that is the URI for the directory where the note should be

placed

Given these capabilities the following intents will resolve to the NoteEditor activity

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID (For details on how content

URIs specify individual members of a group see Content Providers)

action androidintentactionEDIT

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID and to let the user edit it If

the user saves the changes the activity updates the data for the note in the content provider

action androidintentactionINSERT

data contentcomgoogleproviderNotePadnotes

Asks the activity to create a new empty note in the notes list at

contentcomgoogleproviderNotePadnotes and allow the user to edit it If the user saves the

note its URI is returned to the caller

The last activity TitleEditor enables the user to edit the title of a note This could be implemented by

directly invoking the activity (by explicitly setting its component name in the Intent) without using an

intent filter But here we take the opportunity to show how to publish alternative operations on existing

data

ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The single intent filter for this activity uses a custom action called

comandroidnotepadactionEDIT_TITLE It must be invoked on a specific note (data type

vndandroidcursoritemvndgooglenote) like the previous VIEW and EDIT actions However here the

activity displays the title contained in the note data not the content of the note itself

In addition to supporting the usual DEFAULT category the title editor also supports two other standard

categories ALTERNATIVE and SELECTED_ALTERNATIVE These categories identify activities that

can be presented to users in a menu of options (much as the LAUNCHER category identifies activities

that should be presented to user in the application launcher) Note that the filter also supplies an

explicit label (via androidlabel=stringresolve_title) to better control what users see when

presented with this activity as an alternative action to the data they are currently viewing (For more

information on these categories and building options menus see the

PackageManagerqueryIntentActivityOptions() and MenuaddIntentOptions() methods)

Given these capabilities the following intent will resolve to the TitleEditor activity

action comandroidnotepadactionEDIT_TITLE

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the title associated with note ID and allow the user to edit the title

Processes and Threads

When an application component starts and the application does not have any other components

running the Android system starts a new Linux process for the application with a single thread of

execution By default all components of the same application run in the same process and thread

(called the main thread) If an application component starts and there already exists a process for

that application (because another component from the application exists) then the component is

started within that process and uses the same thread of execution However you can arrange for

different components in your application to run in separate processes and you can create additional

threads for any process

This document discusses how processes and threads work in an Android application

Processes

By default all components of the same application run in the same process and most applications

should not change this However if you find that you need to control which process a certain

component belongs to you can do so in the manifest file

The manifest entry for each type of component elementmdashltactivitygt ltservicegt ltreceivergt and

ltprovidergtmdashsupports an androidprocess attribute that can specify a process in which that component

should run You can set this attribute so that each component runs in its own process or so that some

components share a process while others do not You can also set androidprocess so that

components of different applications run in the same processmdashprovided that the applications share the

same Linux user ID and are signed with the same certificates

The ltapplicationgt element also supports an androidprocess attribute to set a default value that

applies to all components

Android might 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 thats killed are consequently destroyed A process is started again for those components

when theres again work for them to do

When deciding which processes to kill the Android system weighs their relative importance to the

user For example it more readily shuts down a process hosting activities that are no longer visible on

screen compared to a process hosting visible activities The decision whether to terminate a process

therefore depends on the state of the components running in that process The rules used to decide

which processes to terminate is discussed below

Process lifecycle

The Android system tries to maintain an application process for as long as possible but eventually

needs to remove old processes to reclaim memory for new or more important processes To determine

which processes to keep and which to kill the system places each process into an importance

hierarchy based on the components running in the process and the state of those components

Processes with the lowest importance are eliminated first then those with the next lowest importance

and so on as necessary to recover system resources

There are five levels in the importance hierarchy The following list presents the different types of

processes in order of importance (the first process is most important and is killed last)

1 Foreground process

A process that is required for what the user is currently doing A process is considered to be in the

foreground if any of the following conditions are true

o It hosts an Activity that the user is interacting with (the Activitys onResume() method has been called)

o It hosts a Service thats bound to the activity that the user is interacting with

o It hosts a Service thats running in the foregroundmdashthe service has called startForeground()

o It hosts a Service thats executing one of its lifecycle callbacks (onCreate() onStart() or onDestroy())

o It hosts a BroadcastReceiver thats executing its onReceive() method

Generally only a few foreground processes exist at any given time They are killed only as a last

resortmdashif memory is so low that they cannot all continue to run Generally at that point the device has

reached a memory paging state so killing some foreground processes is required to keep the user

interface responsive

2 Visible process

A process that doesnt have any foreground components but still can affect what the user sees on

screen A process is considered to be visible if either of the following conditions are true

o It hosts an Activity that is not in the foreground but is still visible to the user (its onPause() method has

been called) This might occur for example if the foreground activity started a dialog which allows the

previous activity to be seen behind it

o It hosts a Service thats bound to a visible (or foreground) activity

A visible process is considered extremely important and will not be killed unless doing so is required to

keep all foreground processes running

3 Service process

A process that is running a service that has been started with the startService() method and does not

fall into either of the two higher categories Although service processes are not directly tied to anything

the user sees they are generally doing things that the user cares about (such as playing music in the

background or downloading data on the network) so the system keeps them running unless theres

not enough memory to retain them along with all foreground and visible processes

4 Background process

A process holding an activity thats not currently visible to the user (the activitys onStop() method has

been called) These processes have no direct impact on the user experience and the system can kill

them at any time to reclaim memory for a foreground visible or service process Usually there are

many background processes running so they are kept in an LRU (least recently used) list to ensure

that the process with the activity that was most recently seen by the user is the last to be killed If an

activity implements its lifecycle methods correctly and saves its current state killing its process will not

have a visible effect on the user experience because when the user navigates back to the activity the

activity restores all of its visible state See the Activities document for information about saving and

restoring state

5 Empty process

A process that doesnt hold any active application components The only reason to keep this kind of

process alive is for caching purposes to improve startup time the next time a component needs to run

in it The system often kills these processes in order to balance overall system resources between

process caches and the underlying kernel caches

Android ranks a process at the highest level it can based upon the importance of the components

currently active in the process For example if a process hosts a service and a visible activity the

process is ranked as a visible process not a service process

In addition a processs ranking might be increased because other processes are dependent on itmdasha

process that is serving another process can never be ranked lower than the process it is serving For

example if a content provider in process A is serving a client in process B or if a service in process A

is bound to a component in process B process A is always considered at least as important as

process B

Because a process running a service is ranked higher than a process with background activities an

activity that initiates a long-running operation might do well to start a service for that operation rather

than simply create a worker threadmdashparticularly if the operation will likely outlast the activity For

example an activity thats uploading a picture to a web site should start a service to perform the

upload so that the upload can continue in the background even if the user leaves the activity Using a

service guarantees that the operation will have at least service process priority regardless of what

happens to the activity This is the same reason that broadcast receivers should employ services

rather than simply put time-consuming operations in a thread

Threads

When an application is launched the system creates a thread of execution for the application called

main This thread is very important because it is in charge of dispatching events to the appropriate

user interface widgets including drawing events It is also the thread in which your application interacts

with components from the Android UI toolkit (components from the androidwidget and androidview

packages) As such the main thread is also sometimes called the UI thread

The system does not create a separate thread for each instance of a component All components that

run in the same process are instantiated in the UI thread and system calls to each component are

dispatched from that thread Consequently methods that respond to system callbacks (such as

onKeyDown() to report user actions or a lifecycle callback method) always run in the UI thread of the

process

For instance when the user touches a button on the screen your apps UI thread dispatches the touch

event to the widget which in turn sets its pressed state and posts an invalidate request to the event

queue The UI thread dequeues the request and notifies the widget that it should redraw itself

When your app performs intensive work in response to user interaction this single thread model can

yield poor performance unless you implement your application properly Specifically if everything is

happening in the UI thread performing long operations such as network access or database queries

will block the whole UI When the thread is blocked no events can be dispatched including drawing

events From the users perspective the application appears to hang Even worse if the UI thread is

blocked for more than a few seconds (about 5 seconds currently) the user is presented with the

infamous application not responding (ANR) dialog The user might then decide to quit your

application and uninstall it if they are unhappy

Additionally the Andoid UI toolkit is not thread-safe So you must not manipulate your UI from a

worker threadmdashyou must do all manipulation to your user interface from the UI thread Thus there are

simply two rules to Androids single thread model

1 Do not block the UI thread

2 Do not access the Android UI toolkit from outside the UI thread

Worker threads

Because of the single thread model described above its vital to the responsiveness of your

applications UI that you do not block the UI thread If you have operations to perform that are not

instantaneous you should make sure to do them in separate threads (background or worker

threads)

For example below is some code for a click listener that downloads an image from a separate thread

and displays it in an ImageView

public void onClick(View v) new Thread(new Runnable() public void run() Bitmap b = loadImageFromNetwork(httpexamplecomimagepng) mImageViewsetImageBitmap(b) )start()

At first this seems to work fine because it creates a new thread to handle the network operation

However it violates the second rule of the single-threaded model do not access the Android UI toolkit

from outside the UI threadmdashthis sample modifies the ImageView from the worker thread instead of the

UI thread This can result in undefined and unexpected behavior which can be difficult and time-

consuming to track down

To fix this problem Android offers several ways to access the UI thread from other threads Here is a

list of methods that can help

ActivityrunOnUiThread(Runnable)

Viewpost(Runnable)

ViewpostDelayed(Runnable long)

For example you can fix the above code by using the Viewpost(Runnable) method

public void onClick(View v) new Thread(new Runnable() public void run() final Bitmap bitmap = loadImageFromNetwork(httpexamplecomimagepng) mImageViewpost(new Runnable() public void run() mImageViewsetImageBitmap(bitmap) ) )start()

Now this implementation is thread-safe the network operation is done from a separate thread while

the ImageView is manipulated from the UI thread

However as the complexity of the operation grows this kind of code can get complicated and difficult

to maintain To handle more complex interactions with a worker thread you might consider using a

Handler in your worker thread to process messages delivered from the UI thread Perhaps the best

solution though is to extend the AsyncTask class which simplifies the execution of worker thread

tasks that need to interact with the UI

Using AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface It performs the blocking

operations in a worker thread and then publishes the results on the UI thread without requiring you to

handle threads andor handlers yourself

To use it you must subclass AsyncTask and implement the doInBackground() callback method which

runs in a pool of background threads To update your UI you should implement onPostExecute()

which delivers the result from doInBackground() and runs in the UI thread so you can safely update

your UI You can then run the task by calling execute() from the UI thread

For example you can implement the previous example using AsyncTask this way

public void onClick(View v) new DownloadImageTask()execute(httpexamplecomimagepng) private class DownloadImageTask extends AsyncTaskltString Void Bitmapgt The system calls this to perform work in a worker thread and delivers it the parameters given to AsyncTaskexecute() protected Bitmap doInBackground(String urls) return loadImageFromNetwork(urls[0])

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 42: 03 services

announcement It does so by comparing the contents of the Intent object to intent filters structures

associated with components that can potentially receive intents Filters advertise the capabilities of a

component and delimit the intents it can handle They open the component to the possibility of

receiving implicit intents of the advertised type If a component does not have any intent filters it can

receive only explicit intents A component with filters can receive both explicit and implicit intents

Only three aspects of an Intent object are consulted when the object is tested against an intent filter

action

data (both URI and data type)

category

The extras and flags play no part in resolving which component receives an intent

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 mdash but only unwanted implicit intents (those that dont 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

components 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 mdash 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 Pads filters are described in the Note Pad Example

section later)

Filters and security

An intent filter cannot be relied on for security While it opens a component to receiving only certain

kinds of implicit intents it does nothing to prevent explicit intents from targeting the component Even

though a filter restricts the intents a component will be asked to handle to certain actions and data

sources someone could always put together an explicit intent with a different action and data source

and name the component as the target

An intent filter is an instance of the IntentFilter class However since the Android system must know

about the capabilities of a component before it can launch that component intent filters are generally

not set up in Java code but in the applications manifest file (AndroidManifestxml) as ltintent-filtergt

elements (The one exception would be filters for broadcast receivers that are registered dynamically

by calling ContextregisterReceiver() they are directly created as IntentFilter objects)

A filter has fields that parallel the action data and category fields of an Intent object An implicit intent

is tested against the filter in all three areas To be delivered to the component that owns the filter it

must pass all three tests If it fails even one of them the Android system wont deliver it to the

component mdash at least not on the basis of that filter However since a component can have multiple

intent filters an intent that does not pass through one of a components filters might make it through on

another

Each of the three tests is described in detail below

Action test

An ltintent-filtergt element in the manifest file lists actions as ltactiongt subelements For

example

ltintent-filter gt ltaction androidname=comexampleprojectSHOW_CURRENT gt ltaction androidname=comexampleprojectSHOW_RECENT gt ltaction androidname=comexampleprojectSHOW_PENDING gt ltintent-filtergt

As the example shows while an Intent object names just a single action a filter may list more

than one The list cannot be empty a filter must contain at least one ltactiongt element or it will

block all intents

To pass this test the action specified in the Intent object must match one of the actions listed in

the filter If the object or the filter does not specify an action the results are as follows

If the filter fails to list any actions there is nothing for an intent to match so all intents fail the

test No intents can get through the filter

On the other hand an Intent object that doesnt specify an action automatically passes the test

mdash as long as the filter contains at least one action

Category test

An ltintent-filtergt element also lists categories as subelements For example

ltintent-filter gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryBROWSABLE gt ltintent-filtergt

Note that the constants described earlier for actions and categories are not used in the manifest

file The full string values are used instead For instance the

androidintentcategoryBROWSABLE string in the example above corresponds to the

CATEGORY_BROWSABLE constant mentioned earlier in this document Similarly the string

androidintentactionEDIT corresponds to the ACTION_EDIT constant

For an intent to pass the category test every category in the Intent object must match a

category in the filter The filter can list additional categories but it cannot omit any that are in the

intent

In principle therefore an Intent object with no categories should always pass this test

regardless of whats in the filter Thats mostly true However with one exception Android treats

all implicit intents passed to startActivity() as if they contained at least one category

androidintentcategoryDEFAULT (the CATEGORY_DEFAULT constant) Therefore activities

that are willing to receive implicit intents must include androidintentcategoryDEFAULT in

their intent filters (Filters with androidintentactionMAIN and

androidintentcategoryLAUNCHER settings are the exception They mark activities that begin

new tasks and that are represented on the launcher screen They can include

androidintentcategoryDEFAULT in the list of categories but dont need to) See Using intent

matching later for more on these filters)

Data test

Like the action and categories the data specification for an intent filter is contained in a

subelement And as in those cases the subelement can appear multiple times or not at all For

example

ltintent-filter gt ltdata androidmimeType=videompeg androidscheme=http gt ltdata androidmimeType=audiompeg androidscheme=http gt ltintent-filtergt

Each ltdatagt element can specify a URI and a data type (MIME media type) There are

separate attributes mdash scheme host port and path mdash for each part of the URI

schemehostportpath

For example in the following URI

contentcomexampleproject200foldersubfolderetc

the scheme is content the host is comexampleproject the port is 200 and the path is

foldersubfolderetc The host and port together constitute the URI authority if a host is not

specified the port is ignored

Each of these attributes is optional but they are not independent of each other For an authority

to be meaningful a scheme must also be specified For a path to be meaningful both a scheme

and an authority must be specified

When the URI in an Intent object is compared to a URI specification in a filter its compared

only to the parts of the URI actually mentioned in the filter For example if a filter specifies only

a scheme all URIs with that scheme match the filter If a filter specifies a scheme and an

authority but no path all URIs with the same scheme and authority match regardless of their

paths If a filter specifies a scheme an authority and a path only URIs with the same scheme

authority and path match However a path specification in the filter can contain wildcards to

require only a partial match of the path

The type attribute of a ltdatagt element specifies the MIME type of the data Its more common in

filters than a URI Both the Intent object and the filter can use a wildcard for the subtype field

mdash for example text or audio mdash indicating any subtype matches

The data test compares both the URI and the data type in the Intent object to a URI and data

type specified in the filter The rules are as follows

a An Intent object that contains neither a URI nor a data type passes the test only if the filter

likewise does not specify any URIs or data types

b An Intent object that contains a URI but no data type (and a type cannot be inferred from the

URI) passes the test only if its URI matches a URI in the filter and the filter likewise does not

specify a type This will be the case only for URIs like mailto and tel that do not refer to actual

data

c An Intent object that contains a data type but not a URI passes the test only if the filter lists the

same data type and similarly does not specify a URI

d An Intent object that contains both a URI and a data type (or a data type can be inferred from

the URI) passes the data type part of the test only if its type matches a type listed in the filter It

passes the URI part of the test either if its URI matches a URI in the filter or if it has a content

or file URI and the filter does not specify a URI In other words a component is presumed to

support content and file data if its filter lists only a data type

If an intent can pass through the filters of more than one activity or service the user may be asked

which component to activate An exception is raised if no target can be found

Common cases

The last rule shown above for the data test rule (d) reflects the expectation that components are able

to get local data from a file or content provider Therefore their filters can list just a data type and do

not need to explicitly name the content and file schemes This is a typical case A ltdatagt element like

the following for example tells Android that the component can get image data from a content

provider and display it

ltdata androidmimeType=image gt

Since most available data is dispensed by content providers filters that specify a data type but not a

URI are perhaps the most common

Another common configuration is filters with a scheme and a data type For example a ltdatagt

element like the following tells Android that the component can get video data from the network and

display it

ltdata androidscheme=http androidtype=video gt

Consider for example what the browser application does when the user follows a link on a web page

It first tries to display the data (as it could if the link was to an HTML page) If it cant display the data it

puts together an implicit intent with the scheme and data type and tries to start an activity that can do

the job If there are no takers it asks the download manager to download the data That puts it under

the control of a content provider so a potentially larger pool of activities (those with filters that just

name a data type) can respond

Most applications also have a way to start fresh without a reference to any particular data Activities

that can initiate applications have filters with androidintentactionMAIN specified as the action If

they are to be represented in the application launcher they also specify the

androidintentcategoryLAUNCHER category

ltintent-filter gt ltaction androidname=code androidintentactionMAIN gt ltcategory androidname=code androidintentcategoryLAUNCHER gt ltintent-filtergt

Using intent matching

Intents are matched against intent filters not only to discover a target component to activate but also

to discover something about the set of components on the device For example the Android system

populates the application launcher the top-level screen that shows the applications that are available

for the user to launch by finding all the activities with intent filters that specify the

androidintentactionMAIN action and androidintentcategoryLAUNCHER category (as illustrated

in the previous section) It then displays the icons and labels of those activities in the launcher

Similarly it discovers the home screen by looking for the activity with androidintentcategoryHOME

in its filter

Your application can use intent matching is a similar way The PackageManager has a set of query()

methods that return all components that can accept a particular intent and a similar series of

resolve() methods that determine the best component to respond to an intent For example

queryIntentActivities() returns a list of all activities that can perform the intent passed as an argument

and queryIntentServices() returns a similar list of services Neither method activates the components

they just list the ones that can respond Theres a similar method queryBroadcastReceivers() for

broadcast receivers

Note Pad Example

The Note Pad sample application enables users to browse through a list of notes view details about

individual items in the list edit the items and add a new item to the list This section looks at the intent

filters declared in its manifest file (If youre working offline in the SDK you can find all the source files

for this sample application including its manifest file at ltsdkgtsamplesNotePadindexhtml If youre

viewing the documentation online the source files are in the Tutorials and Sample Code section here)

In its manifest file the Note Pad application declares three activities each with at least one intent filter

It also declares a content provider that manages the note data Here is the manifest file in its entirety

ltmanifest xmlnsandroid=httpschemasandroidcomapkresandroid package=comexampleandroidnotepadgt ltapplication androidicon=drawableapp_notes androidlabel=stringapp_name gt ltprovider androidname=NotePadProvider androidauthorities=comgoogleproviderNotePad gt ltactivity androidname=NotesList androidlabel=stringtitle_notes_listgt ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltactivity androidname=NoteEditor androidtheme=androidstyleThemeLight androidlabel=stringtitle_note gt ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltactivitygt

ltactivity androidname=TitleEditor androidlabel=stringtitle_edit_title androidtheme=androidstyleThemeDialoggt ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltapplicationgt ltmanifestgt

The first activity NotesList is distinguished from the other activities by the fact that it operates on a

directory of notes (the note list) rather than on a single note It would generally serve as the initial user

interface into the application It can do three things as described by its three intent filters

1 ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt

This filter declares the main entry point into the Note Pad application The standard MAIN action is an

entry point that does not require any other information in the Intent (no data specification for example)

and the LAUNCHER category says that this entry point should be listed in the application launcher

2 ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

This filter declares the things that the activity can do on a directory of notes It can allow the user to

view or edit the directory (via the VIEW and EDIT actions) or to pick a particular note from the

directory (via the PICK action)

The mimeType attribute of the ltdatagt element specifies the kind of data that these actions operate on

It indicates that the activity can get a Cursor over zero or more items (vndandroidcursordir) from a

content provider that holds Note Pad data (vndgooglenote) The Intent object that launches the

activity would include a content URI specifying the exact data of this type that the activity should open

Note also the DEFAULT category supplied in this filter Its there because the ContextstartActivity()

and ActivitystartActivityForResult() methods treat all intents as if they contained the DEFAULT

category mdash with just two exceptions

o Intents that explicitly name the target activity

o Intents consisting of the MAIN action and LAUNCHER category

Therefore the DEFAULT category is required for all filters mdash except for those with the MAIN action

and LAUNCHER category (Intent filters are not consulted for explicit intents)

3 ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

This filter describes the activitys ability to return a note selected by the user without requiring any

specification of the directory the user should choose from The GET_CONTENT action is similar to the

PICK action In both cases the activity returns the URI for a note selected by the user (In each case

its returned to the activity that called startActivityForResult() to start the NoteList activity) Here

however the caller specifies the type of data desired instead of the directory of data the user will be

picking from

The data type vndandroidcursoritemvndgooglenote indicates the type of data the activity can

return mdash a URI for a single note From the returned URI the caller can get a Cursor for exactly one

item (vndandroidcursoritem) from the content provider that holds Note Pad data (vndgooglenote)

In other words for the PICK action in the previous filter the data type indicates the type of data the

activity could display to the user For the GET_CONTENT filter it indicates the type of data the activity

can return to the caller

Given these capabilities the following intents will resolve to the NotesList activity

action androidintentactionMAIN

Launches the activity with no data specified

action androidintentactionMAIN

category androidintentcategoryLAUNCHER

Launches the activity with no data selected specified This is the actual intent used by the

Launcher to populate its top-level list All activities with filters that match this action and

category are added to the list

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of all the notes under

contentcomgoogleproviderNotePadnotes The user can then browse through the list and

get information about the items in it

action androidintentactionPICK

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of the notes under

contentcomgoogleproviderNotePadnotes The user can then pick a note from the list and

the activity will return the URI for that item back to the activity that started the NoteList activity

action androidintentactionGET_CONTENT

data type vndandroidcursoritemvndgooglenote

Asks the activity to supply a single item of Note Pad data

The second activity NoteEditor shows users a single note entry and allows them to edit it It can do

two things as described by its two intent filters

1 ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The first primary purpose of this activity is to enable the user to interact with a single note ampmdash to

either VIEW the note or EDIT it (The EDIT_NOTE category is a synonym for EDIT) The intent would

contain the URI for data matching the MIME type vndandroidcursoritemvndgooglenote mdash that is

the URI for a single specific note It would typically be a URI that was returned by the PICK or

GET_CONTENT actions of the NoteList activity

As before this filter lists the DEFAULT category so that the activity can be launched by intents that

dont explicitly specify the NoteEditor class

2 ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

The secondary purpose of this activity is to enable the user to create a new note which it will INSERT

into an existing directory of notes The intent would contain the URI for data matching the MIME type

vndandroidcursordirvndgooglenote mdash that is the URI for the directory where the note should be

placed

Given these capabilities the following intents will resolve to the NoteEditor activity

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID (For details on how content

URIs specify individual members of a group see Content Providers)

action androidintentactionEDIT

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID and to let the user edit it If

the user saves the changes the activity updates the data for the note in the content provider

action androidintentactionINSERT

data contentcomgoogleproviderNotePadnotes

Asks the activity to create a new empty note in the notes list at

contentcomgoogleproviderNotePadnotes and allow the user to edit it If the user saves the

note its URI is returned to the caller

The last activity TitleEditor enables the user to edit the title of a note This could be implemented by

directly invoking the activity (by explicitly setting its component name in the Intent) without using an

intent filter But here we take the opportunity to show how to publish alternative operations on existing

data

ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The single intent filter for this activity uses a custom action called

comandroidnotepadactionEDIT_TITLE It must be invoked on a specific note (data type

vndandroidcursoritemvndgooglenote) like the previous VIEW and EDIT actions However here the

activity displays the title contained in the note data not the content of the note itself

In addition to supporting the usual DEFAULT category the title editor also supports two other standard

categories ALTERNATIVE and SELECTED_ALTERNATIVE These categories identify activities that

can be presented to users in a menu of options (much as the LAUNCHER category identifies activities

that should be presented to user in the application launcher) Note that the filter also supplies an

explicit label (via androidlabel=stringresolve_title) to better control what users see when

presented with this activity as an alternative action to the data they are currently viewing (For more

information on these categories and building options menus see the

PackageManagerqueryIntentActivityOptions() and MenuaddIntentOptions() methods)

Given these capabilities the following intent will resolve to the TitleEditor activity

action comandroidnotepadactionEDIT_TITLE

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the title associated with note ID and allow the user to edit the title

Processes and Threads

When an application component starts and the application does not have any other components

running the Android system starts a new Linux process for the application with a single thread of

execution By default all components of the same application run in the same process and thread

(called the main thread) If an application component starts and there already exists a process for

that application (because another component from the application exists) then the component is

started within that process and uses the same thread of execution However you can arrange for

different components in your application to run in separate processes and you can create additional

threads for any process

This document discusses how processes and threads work in an Android application

Processes

By default all components of the same application run in the same process and most applications

should not change this However if you find that you need to control which process a certain

component belongs to you can do so in the manifest file

The manifest entry for each type of component elementmdashltactivitygt ltservicegt ltreceivergt and

ltprovidergtmdashsupports an androidprocess attribute that can specify a process in which that component

should run You can set this attribute so that each component runs in its own process or so that some

components share a process while others do not You can also set androidprocess so that

components of different applications run in the same processmdashprovided that the applications share the

same Linux user ID and are signed with the same certificates

The ltapplicationgt element also supports an androidprocess attribute to set a default value that

applies to all components

Android might 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 thats killed are consequently destroyed A process is started again for those components

when theres again work for them to do

When deciding which processes to kill the Android system weighs their relative importance to the

user For example it more readily shuts down a process hosting activities that are no longer visible on

screen compared to a process hosting visible activities The decision whether to terminate a process

therefore depends on the state of the components running in that process The rules used to decide

which processes to terminate is discussed below

Process lifecycle

The Android system tries to maintain an application process for as long as possible but eventually

needs to remove old processes to reclaim memory for new or more important processes To determine

which processes to keep and which to kill the system places each process into an importance

hierarchy based on the components running in the process and the state of those components

Processes with the lowest importance are eliminated first then those with the next lowest importance

and so on as necessary to recover system resources

There are five levels in the importance hierarchy The following list presents the different types of

processes in order of importance (the first process is most important and is killed last)

1 Foreground process

A process that is required for what the user is currently doing A process is considered to be in the

foreground if any of the following conditions are true

o It hosts an Activity that the user is interacting with (the Activitys onResume() method has been called)

o It hosts a Service thats bound to the activity that the user is interacting with

o It hosts a Service thats running in the foregroundmdashthe service has called startForeground()

o It hosts a Service thats executing one of its lifecycle callbacks (onCreate() onStart() or onDestroy())

o It hosts a BroadcastReceiver thats executing its onReceive() method

Generally only a few foreground processes exist at any given time They are killed only as a last

resortmdashif memory is so low that they cannot all continue to run Generally at that point the device has

reached a memory paging state so killing some foreground processes is required to keep the user

interface responsive

2 Visible process

A process that doesnt have any foreground components but still can affect what the user sees on

screen A process is considered to be visible if either of the following conditions are true

o It hosts an Activity that is not in the foreground but is still visible to the user (its onPause() method has

been called) This might occur for example if the foreground activity started a dialog which allows the

previous activity to be seen behind it

o It hosts a Service thats bound to a visible (or foreground) activity

A visible process is considered extremely important and will not be killed unless doing so is required to

keep all foreground processes running

3 Service process

A process that is running a service that has been started with the startService() method and does not

fall into either of the two higher categories Although service processes are not directly tied to anything

the user sees they are generally doing things that the user cares about (such as playing music in the

background or downloading data on the network) so the system keeps them running unless theres

not enough memory to retain them along with all foreground and visible processes

4 Background process

A process holding an activity thats not currently visible to the user (the activitys onStop() method has

been called) These processes have no direct impact on the user experience and the system can kill

them at any time to reclaim memory for a foreground visible or service process Usually there are

many background processes running so they are kept in an LRU (least recently used) list to ensure

that the process with the activity that was most recently seen by the user is the last to be killed If an

activity implements its lifecycle methods correctly and saves its current state killing its process will not

have a visible effect on the user experience because when the user navigates back to the activity the

activity restores all of its visible state See the Activities document for information about saving and

restoring state

5 Empty process

A process that doesnt hold any active application components The only reason to keep this kind of

process alive is for caching purposes to improve startup time the next time a component needs to run

in it The system often kills these processes in order to balance overall system resources between

process caches and the underlying kernel caches

Android ranks a process at the highest level it can based upon the importance of the components

currently active in the process For example if a process hosts a service and a visible activity the

process is ranked as a visible process not a service process

In addition a processs ranking might be increased because other processes are dependent on itmdasha

process that is serving another process can never be ranked lower than the process it is serving For

example if a content provider in process A is serving a client in process B or if a service in process A

is bound to a component in process B process A is always considered at least as important as

process B

Because a process running a service is ranked higher than a process with background activities an

activity that initiates a long-running operation might do well to start a service for that operation rather

than simply create a worker threadmdashparticularly if the operation will likely outlast the activity For

example an activity thats uploading a picture to a web site should start a service to perform the

upload so that the upload can continue in the background even if the user leaves the activity Using a

service guarantees that the operation will have at least service process priority regardless of what

happens to the activity This is the same reason that broadcast receivers should employ services

rather than simply put time-consuming operations in a thread

Threads

When an application is launched the system creates a thread of execution for the application called

main This thread is very important because it is in charge of dispatching events to the appropriate

user interface widgets including drawing events It is also the thread in which your application interacts

with components from the Android UI toolkit (components from the androidwidget and androidview

packages) As such the main thread is also sometimes called the UI thread

The system does not create a separate thread for each instance of a component All components that

run in the same process are instantiated in the UI thread and system calls to each component are

dispatched from that thread Consequently methods that respond to system callbacks (such as

onKeyDown() to report user actions or a lifecycle callback method) always run in the UI thread of the

process

For instance when the user touches a button on the screen your apps UI thread dispatches the touch

event to the widget which in turn sets its pressed state and posts an invalidate request to the event

queue The UI thread dequeues the request and notifies the widget that it should redraw itself

When your app performs intensive work in response to user interaction this single thread model can

yield poor performance unless you implement your application properly Specifically if everything is

happening in the UI thread performing long operations such as network access or database queries

will block the whole UI When the thread is blocked no events can be dispatched including drawing

events From the users perspective the application appears to hang Even worse if the UI thread is

blocked for more than a few seconds (about 5 seconds currently) the user is presented with the

infamous application not responding (ANR) dialog The user might then decide to quit your

application and uninstall it if they are unhappy

Additionally the Andoid UI toolkit is not thread-safe So you must not manipulate your UI from a

worker threadmdashyou must do all manipulation to your user interface from the UI thread Thus there are

simply two rules to Androids single thread model

1 Do not block the UI thread

2 Do not access the Android UI toolkit from outside the UI thread

Worker threads

Because of the single thread model described above its vital to the responsiveness of your

applications UI that you do not block the UI thread If you have operations to perform that are not

instantaneous you should make sure to do them in separate threads (background or worker

threads)

For example below is some code for a click listener that downloads an image from a separate thread

and displays it in an ImageView

public void onClick(View v) new Thread(new Runnable() public void run() Bitmap b = loadImageFromNetwork(httpexamplecomimagepng) mImageViewsetImageBitmap(b) )start()

At first this seems to work fine because it creates a new thread to handle the network operation

However it violates the second rule of the single-threaded model do not access the Android UI toolkit

from outside the UI threadmdashthis sample modifies the ImageView from the worker thread instead of the

UI thread This can result in undefined and unexpected behavior which can be difficult and time-

consuming to track down

To fix this problem Android offers several ways to access the UI thread from other threads Here is a

list of methods that can help

ActivityrunOnUiThread(Runnable)

Viewpost(Runnable)

ViewpostDelayed(Runnable long)

For example you can fix the above code by using the Viewpost(Runnable) method

public void onClick(View v) new Thread(new Runnable() public void run() final Bitmap bitmap = loadImageFromNetwork(httpexamplecomimagepng) mImageViewpost(new Runnable() public void run() mImageViewsetImageBitmap(bitmap) ) )start()

Now this implementation is thread-safe the network operation is done from a separate thread while

the ImageView is manipulated from the UI thread

However as the complexity of the operation grows this kind of code can get complicated and difficult

to maintain To handle more complex interactions with a worker thread you might consider using a

Handler in your worker thread to process messages delivered from the UI thread Perhaps the best

solution though is to extend the AsyncTask class which simplifies the execution of worker thread

tasks that need to interact with the UI

Using AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface It performs the blocking

operations in a worker thread and then publishes the results on the UI thread without requiring you to

handle threads andor handlers yourself

To use it you must subclass AsyncTask and implement the doInBackground() callback method which

runs in a pool of background threads To update your UI you should implement onPostExecute()

which delivers the result from doInBackground() and runs in the UI thread so you can safely update

your UI You can then run the task by calling execute() from the UI thread

For example you can implement the previous example using AsyncTask this way

public void onClick(View v) new DownloadImageTask()execute(httpexamplecomimagepng) private class DownloadImageTask extends AsyncTaskltString Void Bitmapgt The system calls this to perform work in a worker thread and delivers it the parameters given to AsyncTaskexecute() protected Bitmap doInBackground(String urls) return loadImageFromNetwork(urls[0])

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 43: 03 services

intent filters an intent that does not pass through one of a components filters might make it through on

another

Each of the three tests is described in detail below

Action test

An ltintent-filtergt element in the manifest file lists actions as ltactiongt subelements For

example

ltintent-filter gt ltaction androidname=comexampleprojectSHOW_CURRENT gt ltaction androidname=comexampleprojectSHOW_RECENT gt ltaction androidname=comexampleprojectSHOW_PENDING gt ltintent-filtergt

As the example shows while an Intent object names just a single action a filter may list more

than one The list cannot be empty a filter must contain at least one ltactiongt element or it will

block all intents

To pass this test the action specified in the Intent object must match one of the actions listed in

the filter If the object or the filter does not specify an action the results are as follows

If the filter fails to list any actions there is nothing for an intent to match so all intents fail the

test No intents can get through the filter

On the other hand an Intent object that doesnt specify an action automatically passes the test

mdash as long as the filter contains at least one action

Category test

An ltintent-filtergt element also lists categories as subelements For example

ltintent-filter gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryBROWSABLE gt ltintent-filtergt

Note that the constants described earlier for actions and categories are not used in the manifest

file The full string values are used instead For instance the

androidintentcategoryBROWSABLE string in the example above corresponds to the

CATEGORY_BROWSABLE constant mentioned earlier in this document Similarly the string

androidintentactionEDIT corresponds to the ACTION_EDIT constant

For an intent to pass the category test every category in the Intent object must match a

category in the filter The filter can list additional categories but it cannot omit any that are in the

intent

In principle therefore an Intent object with no categories should always pass this test

regardless of whats in the filter Thats mostly true However with one exception Android treats

all implicit intents passed to startActivity() as if they contained at least one category

androidintentcategoryDEFAULT (the CATEGORY_DEFAULT constant) Therefore activities

that are willing to receive implicit intents must include androidintentcategoryDEFAULT in

their intent filters (Filters with androidintentactionMAIN and

androidintentcategoryLAUNCHER settings are the exception They mark activities that begin

new tasks and that are represented on the launcher screen They can include

androidintentcategoryDEFAULT in the list of categories but dont need to) See Using intent

matching later for more on these filters)

Data test

Like the action and categories the data specification for an intent filter is contained in a

subelement And as in those cases the subelement can appear multiple times or not at all For

example

ltintent-filter gt ltdata androidmimeType=videompeg androidscheme=http gt ltdata androidmimeType=audiompeg androidscheme=http gt ltintent-filtergt

Each ltdatagt element can specify a URI and a data type (MIME media type) There are

separate attributes mdash scheme host port and path mdash for each part of the URI

schemehostportpath

For example in the following URI

contentcomexampleproject200foldersubfolderetc

the scheme is content the host is comexampleproject the port is 200 and the path is

foldersubfolderetc The host and port together constitute the URI authority if a host is not

specified the port is ignored

Each of these attributes is optional but they are not independent of each other For an authority

to be meaningful a scheme must also be specified For a path to be meaningful both a scheme

and an authority must be specified

When the URI in an Intent object is compared to a URI specification in a filter its compared

only to the parts of the URI actually mentioned in the filter For example if a filter specifies only

a scheme all URIs with that scheme match the filter If a filter specifies a scheme and an

authority but no path all URIs with the same scheme and authority match regardless of their

paths If a filter specifies a scheme an authority and a path only URIs with the same scheme

authority and path match However a path specification in the filter can contain wildcards to

require only a partial match of the path

The type attribute of a ltdatagt element specifies the MIME type of the data Its more common in

filters than a URI Both the Intent object and the filter can use a wildcard for the subtype field

mdash for example text or audio mdash indicating any subtype matches

The data test compares both the URI and the data type in the Intent object to a URI and data

type specified in the filter The rules are as follows

a An Intent object that contains neither a URI nor a data type passes the test only if the filter

likewise does not specify any URIs or data types

b An Intent object that contains a URI but no data type (and a type cannot be inferred from the

URI) passes the test only if its URI matches a URI in the filter and the filter likewise does not

specify a type This will be the case only for URIs like mailto and tel that do not refer to actual

data

c An Intent object that contains a data type but not a URI passes the test only if the filter lists the

same data type and similarly does not specify a URI

d An Intent object that contains both a URI and a data type (or a data type can be inferred from

the URI) passes the data type part of the test only if its type matches a type listed in the filter It

passes the URI part of the test either if its URI matches a URI in the filter or if it has a content

or file URI and the filter does not specify a URI In other words a component is presumed to

support content and file data if its filter lists only a data type

If an intent can pass through the filters of more than one activity or service the user may be asked

which component to activate An exception is raised if no target can be found

Common cases

The last rule shown above for the data test rule (d) reflects the expectation that components are able

to get local data from a file or content provider Therefore their filters can list just a data type and do

not need to explicitly name the content and file schemes This is a typical case A ltdatagt element like

the following for example tells Android that the component can get image data from a content

provider and display it

ltdata androidmimeType=image gt

Since most available data is dispensed by content providers filters that specify a data type but not a

URI are perhaps the most common

Another common configuration is filters with a scheme and a data type For example a ltdatagt

element like the following tells Android that the component can get video data from the network and

display it

ltdata androidscheme=http androidtype=video gt

Consider for example what the browser application does when the user follows a link on a web page

It first tries to display the data (as it could if the link was to an HTML page) If it cant display the data it

puts together an implicit intent with the scheme and data type and tries to start an activity that can do

the job If there are no takers it asks the download manager to download the data That puts it under

the control of a content provider so a potentially larger pool of activities (those with filters that just

name a data type) can respond

Most applications also have a way to start fresh without a reference to any particular data Activities

that can initiate applications have filters with androidintentactionMAIN specified as the action If

they are to be represented in the application launcher they also specify the

androidintentcategoryLAUNCHER category

ltintent-filter gt ltaction androidname=code androidintentactionMAIN gt ltcategory androidname=code androidintentcategoryLAUNCHER gt ltintent-filtergt

Using intent matching

Intents are matched against intent filters not only to discover a target component to activate but also

to discover something about the set of components on the device For example the Android system

populates the application launcher the top-level screen that shows the applications that are available

for the user to launch by finding all the activities with intent filters that specify the

androidintentactionMAIN action and androidintentcategoryLAUNCHER category (as illustrated

in the previous section) It then displays the icons and labels of those activities in the launcher

Similarly it discovers the home screen by looking for the activity with androidintentcategoryHOME

in its filter

Your application can use intent matching is a similar way The PackageManager has a set of query()

methods that return all components that can accept a particular intent and a similar series of

resolve() methods that determine the best component to respond to an intent For example

queryIntentActivities() returns a list of all activities that can perform the intent passed as an argument

and queryIntentServices() returns a similar list of services Neither method activates the components

they just list the ones that can respond Theres a similar method queryBroadcastReceivers() for

broadcast receivers

Note Pad Example

The Note Pad sample application enables users to browse through a list of notes view details about

individual items in the list edit the items and add a new item to the list This section looks at the intent

filters declared in its manifest file (If youre working offline in the SDK you can find all the source files

for this sample application including its manifest file at ltsdkgtsamplesNotePadindexhtml If youre

viewing the documentation online the source files are in the Tutorials and Sample Code section here)

In its manifest file the Note Pad application declares three activities each with at least one intent filter

It also declares a content provider that manages the note data Here is the manifest file in its entirety

ltmanifest xmlnsandroid=httpschemasandroidcomapkresandroid package=comexampleandroidnotepadgt ltapplication androidicon=drawableapp_notes androidlabel=stringapp_name gt ltprovider androidname=NotePadProvider androidauthorities=comgoogleproviderNotePad gt ltactivity androidname=NotesList androidlabel=stringtitle_notes_listgt ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltactivity androidname=NoteEditor androidtheme=androidstyleThemeLight androidlabel=stringtitle_note gt ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltactivitygt

ltactivity androidname=TitleEditor androidlabel=stringtitle_edit_title androidtheme=androidstyleThemeDialoggt ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltapplicationgt ltmanifestgt

The first activity NotesList is distinguished from the other activities by the fact that it operates on a

directory of notes (the note list) rather than on a single note It would generally serve as the initial user

interface into the application It can do three things as described by its three intent filters

1 ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt

This filter declares the main entry point into the Note Pad application The standard MAIN action is an

entry point that does not require any other information in the Intent (no data specification for example)

and the LAUNCHER category says that this entry point should be listed in the application launcher

2 ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

This filter declares the things that the activity can do on a directory of notes It can allow the user to

view or edit the directory (via the VIEW and EDIT actions) or to pick a particular note from the

directory (via the PICK action)

The mimeType attribute of the ltdatagt element specifies the kind of data that these actions operate on

It indicates that the activity can get a Cursor over zero or more items (vndandroidcursordir) from a

content provider that holds Note Pad data (vndgooglenote) The Intent object that launches the

activity would include a content URI specifying the exact data of this type that the activity should open

Note also the DEFAULT category supplied in this filter Its there because the ContextstartActivity()

and ActivitystartActivityForResult() methods treat all intents as if they contained the DEFAULT

category mdash with just two exceptions

o Intents that explicitly name the target activity

o Intents consisting of the MAIN action and LAUNCHER category

Therefore the DEFAULT category is required for all filters mdash except for those with the MAIN action

and LAUNCHER category (Intent filters are not consulted for explicit intents)

3 ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

This filter describes the activitys ability to return a note selected by the user without requiring any

specification of the directory the user should choose from The GET_CONTENT action is similar to the

PICK action In both cases the activity returns the URI for a note selected by the user (In each case

its returned to the activity that called startActivityForResult() to start the NoteList activity) Here

however the caller specifies the type of data desired instead of the directory of data the user will be

picking from

The data type vndandroidcursoritemvndgooglenote indicates the type of data the activity can

return mdash a URI for a single note From the returned URI the caller can get a Cursor for exactly one

item (vndandroidcursoritem) from the content provider that holds Note Pad data (vndgooglenote)

In other words for the PICK action in the previous filter the data type indicates the type of data the

activity could display to the user For the GET_CONTENT filter it indicates the type of data the activity

can return to the caller

Given these capabilities the following intents will resolve to the NotesList activity

action androidintentactionMAIN

Launches the activity with no data specified

action androidintentactionMAIN

category androidintentcategoryLAUNCHER

Launches the activity with no data selected specified This is the actual intent used by the

Launcher to populate its top-level list All activities with filters that match this action and

category are added to the list

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of all the notes under

contentcomgoogleproviderNotePadnotes The user can then browse through the list and

get information about the items in it

action androidintentactionPICK

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of the notes under

contentcomgoogleproviderNotePadnotes The user can then pick a note from the list and

the activity will return the URI for that item back to the activity that started the NoteList activity

action androidintentactionGET_CONTENT

data type vndandroidcursoritemvndgooglenote

Asks the activity to supply a single item of Note Pad data

The second activity NoteEditor shows users a single note entry and allows them to edit it It can do

two things as described by its two intent filters

1 ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The first primary purpose of this activity is to enable the user to interact with a single note ampmdash to

either VIEW the note or EDIT it (The EDIT_NOTE category is a synonym for EDIT) The intent would

contain the URI for data matching the MIME type vndandroidcursoritemvndgooglenote mdash that is

the URI for a single specific note It would typically be a URI that was returned by the PICK or

GET_CONTENT actions of the NoteList activity

As before this filter lists the DEFAULT category so that the activity can be launched by intents that

dont explicitly specify the NoteEditor class

2 ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

The secondary purpose of this activity is to enable the user to create a new note which it will INSERT

into an existing directory of notes The intent would contain the URI for data matching the MIME type

vndandroidcursordirvndgooglenote mdash that is the URI for the directory where the note should be

placed

Given these capabilities the following intents will resolve to the NoteEditor activity

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID (For details on how content

URIs specify individual members of a group see Content Providers)

action androidintentactionEDIT

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID and to let the user edit it If

the user saves the changes the activity updates the data for the note in the content provider

action androidintentactionINSERT

data contentcomgoogleproviderNotePadnotes

Asks the activity to create a new empty note in the notes list at

contentcomgoogleproviderNotePadnotes and allow the user to edit it If the user saves the

note its URI is returned to the caller

The last activity TitleEditor enables the user to edit the title of a note This could be implemented by

directly invoking the activity (by explicitly setting its component name in the Intent) without using an

intent filter But here we take the opportunity to show how to publish alternative operations on existing

data

ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The single intent filter for this activity uses a custom action called

comandroidnotepadactionEDIT_TITLE It must be invoked on a specific note (data type

vndandroidcursoritemvndgooglenote) like the previous VIEW and EDIT actions However here the

activity displays the title contained in the note data not the content of the note itself

In addition to supporting the usual DEFAULT category the title editor also supports two other standard

categories ALTERNATIVE and SELECTED_ALTERNATIVE These categories identify activities that

can be presented to users in a menu of options (much as the LAUNCHER category identifies activities

that should be presented to user in the application launcher) Note that the filter also supplies an

explicit label (via androidlabel=stringresolve_title) to better control what users see when

presented with this activity as an alternative action to the data they are currently viewing (For more

information on these categories and building options menus see the

PackageManagerqueryIntentActivityOptions() and MenuaddIntentOptions() methods)

Given these capabilities the following intent will resolve to the TitleEditor activity

action comandroidnotepadactionEDIT_TITLE

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the title associated with note ID and allow the user to edit the title

Processes and Threads

When an application component starts and the application does not have any other components

running the Android system starts a new Linux process for the application with a single thread of

execution By default all components of the same application run in the same process and thread

(called the main thread) If an application component starts and there already exists a process for

that application (because another component from the application exists) then the component is

started within that process and uses the same thread of execution However you can arrange for

different components in your application to run in separate processes and you can create additional

threads for any process

This document discusses how processes and threads work in an Android application

Processes

By default all components of the same application run in the same process and most applications

should not change this However if you find that you need to control which process a certain

component belongs to you can do so in the manifest file

The manifest entry for each type of component elementmdashltactivitygt ltservicegt ltreceivergt and

ltprovidergtmdashsupports an androidprocess attribute that can specify a process in which that component

should run You can set this attribute so that each component runs in its own process or so that some

components share a process while others do not You can also set androidprocess so that

components of different applications run in the same processmdashprovided that the applications share the

same Linux user ID and are signed with the same certificates

The ltapplicationgt element also supports an androidprocess attribute to set a default value that

applies to all components

Android might 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 thats killed are consequently destroyed A process is started again for those components

when theres again work for them to do

When deciding which processes to kill the Android system weighs their relative importance to the

user For example it more readily shuts down a process hosting activities that are no longer visible on

screen compared to a process hosting visible activities The decision whether to terminate a process

therefore depends on the state of the components running in that process The rules used to decide

which processes to terminate is discussed below

Process lifecycle

The Android system tries to maintain an application process for as long as possible but eventually

needs to remove old processes to reclaim memory for new or more important processes To determine

which processes to keep and which to kill the system places each process into an importance

hierarchy based on the components running in the process and the state of those components

Processes with the lowest importance are eliminated first then those with the next lowest importance

and so on as necessary to recover system resources

There are five levels in the importance hierarchy The following list presents the different types of

processes in order of importance (the first process is most important and is killed last)

1 Foreground process

A process that is required for what the user is currently doing A process is considered to be in the

foreground if any of the following conditions are true

o It hosts an Activity that the user is interacting with (the Activitys onResume() method has been called)

o It hosts a Service thats bound to the activity that the user is interacting with

o It hosts a Service thats running in the foregroundmdashthe service has called startForeground()

o It hosts a Service thats executing one of its lifecycle callbacks (onCreate() onStart() or onDestroy())

o It hosts a BroadcastReceiver thats executing its onReceive() method

Generally only a few foreground processes exist at any given time They are killed only as a last

resortmdashif memory is so low that they cannot all continue to run Generally at that point the device has

reached a memory paging state so killing some foreground processes is required to keep the user

interface responsive

2 Visible process

A process that doesnt have any foreground components but still can affect what the user sees on

screen A process is considered to be visible if either of the following conditions are true

o It hosts an Activity that is not in the foreground but is still visible to the user (its onPause() method has

been called) This might occur for example if the foreground activity started a dialog which allows the

previous activity to be seen behind it

o It hosts a Service thats bound to a visible (or foreground) activity

A visible process is considered extremely important and will not be killed unless doing so is required to

keep all foreground processes running

3 Service process

A process that is running a service that has been started with the startService() method and does not

fall into either of the two higher categories Although service processes are not directly tied to anything

the user sees they are generally doing things that the user cares about (such as playing music in the

background or downloading data on the network) so the system keeps them running unless theres

not enough memory to retain them along with all foreground and visible processes

4 Background process

A process holding an activity thats not currently visible to the user (the activitys onStop() method has

been called) These processes have no direct impact on the user experience and the system can kill

them at any time to reclaim memory for a foreground visible or service process Usually there are

many background processes running so they are kept in an LRU (least recently used) list to ensure

that the process with the activity that was most recently seen by the user is the last to be killed If an

activity implements its lifecycle methods correctly and saves its current state killing its process will not

have a visible effect on the user experience because when the user navigates back to the activity the

activity restores all of its visible state See the Activities document for information about saving and

restoring state

5 Empty process

A process that doesnt hold any active application components The only reason to keep this kind of

process alive is for caching purposes to improve startup time the next time a component needs to run

in it The system often kills these processes in order to balance overall system resources between

process caches and the underlying kernel caches

Android ranks a process at the highest level it can based upon the importance of the components

currently active in the process For example if a process hosts a service and a visible activity the

process is ranked as a visible process not a service process

In addition a processs ranking might be increased because other processes are dependent on itmdasha

process that is serving another process can never be ranked lower than the process it is serving For

example if a content provider in process A is serving a client in process B or if a service in process A

is bound to a component in process B process A is always considered at least as important as

process B

Because a process running a service is ranked higher than a process with background activities an

activity that initiates a long-running operation might do well to start a service for that operation rather

than simply create a worker threadmdashparticularly if the operation will likely outlast the activity For

example an activity thats uploading a picture to a web site should start a service to perform the

upload so that the upload can continue in the background even if the user leaves the activity Using a

service guarantees that the operation will have at least service process priority regardless of what

happens to the activity This is the same reason that broadcast receivers should employ services

rather than simply put time-consuming operations in a thread

Threads

When an application is launched the system creates a thread of execution for the application called

main This thread is very important because it is in charge of dispatching events to the appropriate

user interface widgets including drawing events It is also the thread in which your application interacts

with components from the Android UI toolkit (components from the androidwidget and androidview

packages) As such the main thread is also sometimes called the UI thread

The system does not create a separate thread for each instance of a component All components that

run in the same process are instantiated in the UI thread and system calls to each component are

dispatched from that thread Consequently methods that respond to system callbacks (such as

onKeyDown() to report user actions or a lifecycle callback method) always run in the UI thread of the

process

For instance when the user touches a button on the screen your apps UI thread dispatches the touch

event to the widget which in turn sets its pressed state and posts an invalidate request to the event

queue The UI thread dequeues the request and notifies the widget that it should redraw itself

When your app performs intensive work in response to user interaction this single thread model can

yield poor performance unless you implement your application properly Specifically if everything is

happening in the UI thread performing long operations such as network access or database queries

will block the whole UI When the thread is blocked no events can be dispatched including drawing

events From the users perspective the application appears to hang Even worse if the UI thread is

blocked for more than a few seconds (about 5 seconds currently) the user is presented with the

infamous application not responding (ANR) dialog The user might then decide to quit your

application and uninstall it if they are unhappy

Additionally the Andoid UI toolkit is not thread-safe So you must not manipulate your UI from a

worker threadmdashyou must do all manipulation to your user interface from the UI thread Thus there are

simply two rules to Androids single thread model

1 Do not block the UI thread

2 Do not access the Android UI toolkit from outside the UI thread

Worker threads

Because of the single thread model described above its vital to the responsiveness of your

applications UI that you do not block the UI thread If you have operations to perform that are not

instantaneous you should make sure to do them in separate threads (background or worker

threads)

For example below is some code for a click listener that downloads an image from a separate thread

and displays it in an ImageView

public void onClick(View v) new Thread(new Runnable() public void run() Bitmap b = loadImageFromNetwork(httpexamplecomimagepng) mImageViewsetImageBitmap(b) )start()

At first this seems to work fine because it creates a new thread to handle the network operation

However it violates the second rule of the single-threaded model do not access the Android UI toolkit

from outside the UI threadmdashthis sample modifies the ImageView from the worker thread instead of the

UI thread This can result in undefined and unexpected behavior which can be difficult and time-

consuming to track down

To fix this problem Android offers several ways to access the UI thread from other threads Here is a

list of methods that can help

ActivityrunOnUiThread(Runnable)

Viewpost(Runnable)

ViewpostDelayed(Runnable long)

For example you can fix the above code by using the Viewpost(Runnable) method

public void onClick(View v) new Thread(new Runnable() public void run() final Bitmap bitmap = loadImageFromNetwork(httpexamplecomimagepng) mImageViewpost(new Runnable() public void run() mImageViewsetImageBitmap(bitmap) ) )start()

Now this implementation is thread-safe the network operation is done from a separate thread while

the ImageView is manipulated from the UI thread

However as the complexity of the operation grows this kind of code can get complicated and difficult

to maintain To handle more complex interactions with a worker thread you might consider using a

Handler in your worker thread to process messages delivered from the UI thread Perhaps the best

solution though is to extend the AsyncTask class which simplifies the execution of worker thread

tasks that need to interact with the UI

Using AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface It performs the blocking

operations in a worker thread and then publishes the results on the UI thread without requiring you to

handle threads andor handlers yourself

To use it you must subclass AsyncTask and implement the doInBackground() callback method which

runs in a pool of background threads To update your UI you should implement onPostExecute()

which delivers the result from doInBackground() and runs in the UI thread so you can safely update

your UI You can then run the task by calling execute() from the UI thread

For example you can implement the previous example using AsyncTask this way

public void onClick(View v) new DownloadImageTask()execute(httpexamplecomimagepng) private class DownloadImageTask extends AsyncTaskltString Void Bitmapgt The system calls this to perform work in a worker thread and delivers it the parameters given to AsyncTaskexecute() protected Bitmap doInBackground(String urls) return loadImageFromNetwork(urls[0])

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 44: 03 services

For an intent to pass the category test every category in the Intent object must match a

category in the filter The filter can list additional categories but it cannot omit any that are in the

intent

In principle therefore an Intent object with no categories should always pass this test

regardless of whats in the filter Thats mostly true However with one exception Android treats

all implicit intents passed to startActivity() as if they contained at least one category

androidintentcategoryDEFAULT (the CATEGORY_DEFAULT constant) Therefore activities

that are willing to receive implicit intents must include androidintentcategoryDEFAULT in

their intent filters (Filters with androidintentactionMAIN and

androidintentcategoryLAUNCHER settings are the exception They mark activities that begin

new tasks and that are represented on the launcher screen They can include

androidintentcategoryDEFAULT in the list of categories but dont need to) See Using intent

matching later for more on these filters)

Data test

Like the action and categories the data specification for an intent filter is contained in a

subelement And as in those cases the subelement can appear multiple times or not at all For

example

ltintent-filter gt ltdata androidmimeType=videompeg androidscheme=http gt ltdata androidmimeType=audiompeg androidscheme=http gt ltintent-filtergt

Each ltdatagt element can specify a URI and a data type (MIME media type) There are

separate attributes mdash scheme host port and path mdash for each part of the URI

schemehostportpath

For example in the following URI

contentcomexampleproject200foldersubfolderetc

the scheme is content the host is comexampleproject the port is 200 and the path is

foldersubfolderetc The host and port together constitute the URI authority if a host is not

specified the port is ignored

Each of these attributes is optional but they are not independent of each other For an authority

to be meaningful a scheme must also be specified For a path to be meaningful both a scheme

and an authority must be specified

When the URI in an Intent object is compared to a URI specification in a filter its compared

only to the parts of the URI actually mentioned in the filter For example if a filter specifies only

a scheme all URIs with that scheme match the filter If a filter specifies a scheme and an

authority but no path all URIs with the same scheme and authority match regardless of their

paths If a filter specifies a scheme an authority and a path only URIs with the same scheme

authority and path match However a path specification in the filter can contain wildcards to

require only a partial match of the path

The type attribute of a ltdatagt element specifies the MIME type of the data Its more common in

filters than a URI Both the Intent object and the filter can use a wildcard for the subtype field

mdash for example text or audio mdash indicating any subtype matches

The data test compares both the URI and the data type in the Intent object to a URI and data

type specified in the filter The rules are as follows

a An Intent object that contains neither a URI nor a data type passes the test only if the filter

likewise does not specify any URIs or data types

b An Intent object that contains a URI but no data type (and a type cannot be inferred from the

URI) passes the test only if its URI matches a URI in the filter and the filter likewise does not

specify a type This will be the case only for URIs like mailto and tel that do not refer to actual

data

c An Intent object that contains a data type but not a URI passes the test only if the filter lists the

same data type and similarly does not specify a URI

d An Intent object that contains both a URI and a data type (or a data type can be inferred from

the URI) passes the data type part of the test only if its type matches a type listed in the filter It

passes the URI part of the test either if its URI matches a URI in the filter or if it has a content

or file URI and the filter does not specify a URI In other words a component is presumed to

support content and file data if its filter lists only a data type

If an intent can pass through the filters of more than one activity or service the user may be asked

which component to activate An exception is raised if no target can be found

Common cases

The last rule shown above for the data test rule (d) reflects the expectation that components are able

to get local data from a file or content provider Therefore their filters can list just a data type and do

not need to explicitly name the content and file schemes This is a typical case A ltdatagt element like

the following for example tells Android that the component can get image data from a content

provider and display it

ltdata androidmimeType=image gt

Since most available data is dispensed by content providers filters that specify a data type but not a

URI are perhaps the most common

Another common configuration is filters with a scheme and a data type For example a ltdatagt

element like the following tells Android that the component can get video data from the network and

display it

ltdata androidscheme=http androidtype=video gt

Consider for example what the browser application does when the user follows a link on a web page

It first tries to display the data (as it could if the link was to an HTML page) If it cant display the data it

puts together an implicit intent with the scheme and data type and tries to start an activity that can do

the job If there are no takers it asks the download manager to download the data That puts it under

the control of a content provider so a potentially larger pool of activities (those with filters that just

name a data type) can respond

Most applications also have a way to start fresh without a reference to any particular data Activities

that can initiate applications have filters with androidintentactionMAIN specified as the action If

they are to be represented in the application launcher they also specify the

androidintentcategoryLAUNCHER category

ltintent-filter gt ltaction androidname=code androidintentactionMAIN gt ltcategory androidname=code androidintentcategoryLAUNCHER gt ltintent-filtergt

Using intent matching

Intents are matched against intent filters not only to discover a target component to activate but also

to discover something about the set of components on the device For example the Android system

populates the application launcher the top-level screen that shows the applications that are available

for the user to launch by finding all the activities with intent filters that specify the

androidintentactionMAIN action and androidintentcategoryLAUNCHER category (as illustrated

in the previous section) It then displays the icons and labels of those activities in the launcher

Similarly it discovers the home screen by looking for the activity with androidintentcategoryHOME

in its filter

Your application can use intent matching is a similar way The PackageManager has a set of query()

methods that return all components that can accept a particular intent and a similar series of

resolve() methods that determine the best component to respond to an intent For example

queryIntentActivities() returns a list of all activities that can perform the intent passed as an argument

and queryIntentServices() returns a similar list of services Neither method activates the components

they just list the ones that can respond Theres a similar method queryBroadcastReceivers() for

broadcast receivers

Note Pad Example

The Note Pad sample application enables users to browse through a list of notes view details about

individual items in the list edit the items and add a new item to the list This section looks at the intent

filters declared in its manifest file (If youre working offline in the SDK you can find all the source files

for this sample application including its manifest file at ltsdkgtsamplesNotePadindexhtml If youre

viewing the documentation online the source files are in the Tutorials and Sample Code section here)

In its manifest file the Note Pad application declares three activities each with at least one intent filter

It also declares a content provider that manages the note data Here is the manifest file in its entirety

ltmanifest xmlnsandroid=httpschemasandroidcomapkresandroid package=comexampleandroidnotepadgt ltapplication androidicon=drawableapp_notes androidlabel=stringapp_name gt ltprovider androidname=NotePadProvider androidauthorities=comgoogleproviderNotePad gt ltactivity androidname=NotesList androidlabel=stringtitle_notes_listgt ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltactivity androidname=NoteEditor androidtheme=androidstyleThemeLight androidlabel=stringtitle_note gt ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltactivitygt

ltactivity androidname=TitleEditor androidlabel=stringtitle_edit_title androidtheme=androidstyleThemeDialoggt ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltapplicationgt ltmanifestgt

The first activity NotesList is distinguished from the other activities by the fact that it operates on a

directory of notes (the note list) rather than on a single note It would generally serve as the initial user

interface into the application It can do three things as described by its three intent filters

1 ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt

This filter declares the main entry point into the Note Pad application The standard MAIN action is an

entry point that does not require any other information in the Intent (no data specification for example)

and the LAUNCHER category says that this entry point should be listed in the application launcher

2 ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

This filter declares the things that the activity can do on a directory of notes It can allow the user to

view or edit the directory (via the VIEW and EDIT actions) or to pick a particular note from the

directory (via the PICK action)

The mimeType attribute of the ltdatagt element specifies the kind of data that these actions operate on

It indicates that the activity can get a Cursor over zero or more items (vndandroidcursordir) from a

content provider that holds Note Pad data (vndgooglenote) The Intent object that launches the

activity would include a content URI specifying the exact data of this type that the activity should open

Note also the DEFAULT category supplied in this filter Its there because the ContextstartActivity()

and ActivitystartActivityForResult() methods treat all intents as if they contained the DEFAULT

category mdash with just two exceptions

o Intents that explicitly name the target activity

o Intents consisting of the MAIN action and LAUNCHER category

Therefore the DEFAULT category is required for all filters mdash except for those with the MAIN action

and LAUNCHER category (Intent filters are not consulted for explicit intents)

3 ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

This filter describes the activitys ability to return a note selected by the user without requiring any

specification of the directory the user should choose from The GET_CONTENT action is similar to the

PICK action In both cases the activity returns the URI for a note selected by the user (In each case

its returned to the activity that called startActivityForResult() to start the NoteList activity) Here

however the caller specifies the type of data desired instead of the directory of data the user will be

picking from

The data type vndandroidcursoritemvndgooglenote indicates the type of data the activity can

return mdash a URI for a single note From the returned URI the caller can get a Cursor for exactly one

item (vndandroidcursoritem) from the content provider that holds Note Pad data (vndgooglenote)

In other words for the PICK action in the previous filter the data type indicates the type of data the

activity could display to the user For the GET_CONTENT filter it indicates the type of data the activity

can return to the caller

Given these capabilities the following intents will resolve to the NotesList activity

action androidintentactionMAIN

Launches the activity with no data specified

action androidintentactionMAIN

category androidintentcategoryLAUNCHER

Launches the activity with no data selected specified This is the actual intent used by the

Launcher to populate its top-level list All activities with filters that match this action and

category are added to the list

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of all the notes under

contentcomgoogleproviderNotePadnotes The user can then browse through the list and

get information about the items in it

action androidintentactionPICK

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of the notes under

contentcomgoogleproviderNotePadnotes The user can then pick a note from the list and

the activity will return the URI for that item back to the activity that started the NoteList activity

action androidintentactionGET_CONTENT

data type vndandroidcursoritemvndgooglenote

Asks the activity to supply a single item of Note Pad data

The second activity NoteEditor shows users a single note entry and allows them to edit it It can do

two things as described by its two intent filters

1 ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The first primary purpose of this activity is to enable the user to interact with a single note ampmdash to

either VIEW the note or EDIT it (The EDIT_NOTE category is a synonym for EDIT) The intent would

contain the URI for data matching the MIME type vndandroidcursoritemvndgooglenote mdash that is

the URI for a single specific note It would typically be a URI that was returned by the PICK or

GET_CONTENT actions of the NoteList activity

As before this filter lists the DEFAULT category so that the activity can be launched by intents that

dont explicitly specify the NoteEditor class

2 ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

The secondary purpose of this activity is to enable the user to create a new note which it will INSERT

into an existing directory of notes The intent would contain the URI for data matching the MIME type

vndandroidcursordirvndgooglenote mdash that is the URI for the directory where the note should be

placed

Given these capabilities the following intents will resolve to the NoteEditor activity

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID (For details on how content

URIs specify individual members of a group see Content Providers)

action androidintentactionEDIT

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID and to let the user edit it If

the user saves the changes the activity updates the data for the note in the content provider

action androidintentactionINSERT

data contentcomgoogleproviderNotePadnotes

Asks the activity to create a new empty note in the notes list at

contentcomgoogleproviderNotePadnotes and allow the user to edit it If the user saves the

note its URI is returned to the caller

The last activity TitleEditor enables the user to edit the title of a note This could be implemented by

directly invoking the activity (by explicitly setting its component name in the Intent) without using an

intent filter But here we take the opportunity to show how to publish alternative operations on existing

data

ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The single intent filter for this activity uses a custom action called

comandroidnotepadactionEDIT_TITLE It must be invoked on a specific note (data type

vndandroidcursoritemvndgooglenote) like the previous VIEW and EDIT actions However here the

activity displays the title contained in the note data not the content of the note itself

In addition to supporting the usual DEFAULT category the title editor also supports two other standard

categories ALTERNATIVE and SELECTED_ALTERNATIVE These categories identify activities that

can be presented to users in a menu of options (much as the LAUNCHER category identifies activities

that should be presented to user in the application launcher) Note that the filter also supplies an

explicit label (via androidlabel=stringresolve_title) to better control what users see when

presented with this activity as an alternative action to the data they are currently viewing (For more

information on these categories and building options menus see the

PackageManagerqueryIntentActivityOptions() and MenuaddIntentOptions() methods)

Given these capabilities the following intent will resolve to the TitleEditor activity

action comandroidnotepadactionEDIT_TITLE

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the title associated with note ID and allow the user to edit the title

Processes and Threads

When an application component starts and the application does not have any other components

running the Android system starts a new Linux process for the application with a single thread of

execution By default all components of the same application run in the same process and thread

(called the main thread) If an application component starts and there already exists a process for

that application (because another component from the application exists) then the component is

started within that process and uses the same thread of execution However you can arrange for

different components in your application to run in separate processes and you can create additional

threads for any process

This document discusses how processes and threads work in an Android application

Processes

By default all components of the same application run in the same process and most applications

should not change this However if you find that you need to control which process a certain

component belongs to you can do so in the manifest file

The manifest entry for each type of component elementmdashltactivitygt ltservicegt ltreceivergt and

ltprovidergtmdashsupports an androidprocess attribute that can specify a process in which that component

should run You can set this attribute so that each component runs in its own process or so that some

components share a process while others do not You can also set androidprocess so that

components of different applications run in the same processmdashprovided that the applications share the

same Linux user ID and are signed with the same certificates

The ltapplicationgt element also supports an androidprocess attribute to set a default value that

applies to all components

Android might 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 thats killed are consequently destroyed A process is started again for those components

when theres again work for them to do

When deciding which processes to kill the Android system weighs their relative importance to the

user For example it more readily shuts down a process hosting activities that are no longer visible on

screen compared to a process hosting visible activities The decision whether to terminate a process

therefore depends on the state of the components running in that process The rules used to decide

which processes to terminate is discussed below

Process lifecycle

The Android system tries to maintain an application process for as long as possible but eventually

needs to remove old processes to reclaim memory for new or more important processes To determine

which processes to keep and which to kill the system places each process into an importance

hierarchy based on the components running in the process and the state of those components

Processes with the lowest importance are eliminated first then those with the next lowest importance

and so on as necessary to recover system resources

There are five levels in the importance hierarchy The following list presents the different types of

processes in order of importance (the first process is most important and is killed last)

1 Foreground process

A process that is required for what the user is currently doing A process is considered to be in the

foreground if any of the following conditions are true

o It hosts an Activity that the user is interacting with (the Activitys onResume() method has been called)

o It hosts a Service thats bound to the activity that the user is interacting with

o It hosts a Service thats running in the foregroundmdashthe service has called startForeground()

o It hosts a Service thats executing one of its lifecycle callbacks (onCreate() onStart() or onDestroy())

o It hosts a BroadcastReceiver thats executing its onReceive() method

Generally only a few foreground processes exist at any given time They are killed only as a last

resortmdashif memory is so low that they cannot all continue to run Generally at that point the device has

reached a memory paging state so killing some foreground processes is required to keep the user

interface responsive

2 Visible process

A process that doesnt have any foreground components but still can affect what the user sees on

screen A process is considered to be visible if either of the following conditions are true

o It hosts an Activity that is not in the foreground but is still visible to the user (its onPause() method has

been called) This might occur for example if the foreground activity started a dialog which allows the

previous activity to be seen behind it

o It hosts a Service thats bound to a visible (or foreground) activity

A visible process is considered extremely important and will not be killed unless doing so is required to

keep all foreground processes running

3 Service process

A process that is running a service that has been started with the startService() method and does not

fall into either of the two higher categories Although service processes are not directly tied to anything

the user sees they are generally doing things that the user cares about (such as playing music in the

background or downloading data on the network) so the system keeps them running unless theres

not enough memory to retain them along with all foreground and visible processes

4 Background process

A process holding an activity thats not currently visible to the user (the activitys onStop() method has

been called) These processes have no direct impact on the user experience and the system can kill

them at any time to reclaim memory for a foreground visible or service process Usually there are

many background processes running so they are kept in an LRU (least recently used) list to ensure

that the process with the activity that was most recently seen by the user is the last to be killed If an

activity implements its lifecycle methods correctly and saves its current state killing its process will not

have a visible effect on the user experience because when the user navigates back to the activity the

activity restores all of its visible state See the Activities document for information about saving and

restoring state

5 Empty process

A process that doesnt hold any active application components The only reason to keep this kind of

process alive is for caching purposes to improve startup time the next time a component needs to run

in it The system often kills these processes in order to balance overall system resources between

process caches and the underlying kernel caches

Android ranks a process at the highest level it can based upon the importance of the components

currently active in the process For example if a process hosts a service and a visible activity the

process is ranked as a visible process not a service process

In addition a processs ranking might be increased because other processes are dependent on itmdasha

process that is serving another process can never be ranked lower than the process it is serving For

example if a content provider in process A is serving a client in process B or if a service in process A

is bound to a component in process B process A is always considered at least as important as

process B

Because a process running a service is ranked higher than a process with background activities an

activity that initiates a long-running operation might do well to start a service for that operation rather

than simply create a worker threadmdashparticularly if the operation will likely outlast the activity For

example an activity thats uploading a picture to a web site should start a service to perform the

upload so that the upload can continue in the background even if the user leaves the activity Using a

service guarantees that the operation will have at least service process priority regardless of what

happens to the activity This is the same reason that broadcast receivers should employ services

rather than simply put time-consuming operations in a thread

Threads

When an application is launched the system creates a thread of execution for the application called

main This thread is very important because it is in charge of dispatching events to the appropriate

user interface widgets including drawing events It is also the thread in which your application interacts

with components from the Android UI toolkit (components from the androidwidget and androidview

packages) As such the main thread is also sometimes called the UI thread

The system does not create a separate thread for each instance of a component All components that

run in the same process are instantiated in the UI thread and system calls to each component are

dispatched from that thread Consequently methods that respond to system callbacks (such as

onKeyDown() to report user actions or a lifecycle callback method) always run in the UI thread of the

process

For instance when the user touches a button on the screen your apps UI thread dispatches the touch

event to the widget which in turn sets its pressed state and posts an invalidate request to the event

queue The UI thread dequeues the request and notifies the widget that it should redraw itself

When your app performs intensive work in response to user interaction this single thread model can

yield poor performance unless you implement your application properly Specifically if everything is

happening in the UI thread performing long operations such as network access or database queries

will block the whole UI When the thread is blocked no events can be dispatched including drawing

events From the users perspective the application appears to hang Even worse if the UI thread is

blocked for more than a few seconds (about 5 seconds currently) the user is presented with the

infamous application not responding (ANR) dialog The user might then decide to quit your

application and uninstall it if they are unhappy

Additionally the Andoid UI toolkit is not thread-safe So you must not manipulate your UI from a

worker threadmdashyou must do all manipulation to your user interface from the UI thread Thus there are

simply two rules to Androids single thread model

1 Do not block the UI thread

2 Do not access the Android UI toolkit from outside the UI thread

Worker threads

Because of the single thread model described above its vital to the responsiveness of your

applications UI that you do not block the UI thread If you have operations to perform that are not

instantaneous you should make sure to do them in separate threads (background or worker

threads)

For example below is some code for a click listener that downloads an image from a separate thread

and displays it in an ImageView

public void onClick(View v) new Thread(new Runnable() public void run() Bitmap b = loadImageFromNetwork(httpexamplecomimagepng) mImageViewsetImageBitmap(b) )start()

At first this seems to work fine because it creates a new thread to handle the network operation

However it violates the second rule of the single-threaded model do not access the Android UI toolkit

from outside the UI threadmdashthis sample modifies the ImageView from the worker thread instead of the

UI thread This can result in undefined and unexpected behavior which can be difficult and time-

consuming to track down

To fix this problem Android offers several ways to access the UI thread from other threads Here is a

list of methods that can help

ActivityrunOnUiThread(Runnable)

Viewpost(Runnable)

ViewpostDelayed(Runnable long)

For example you can fix the above code by using the Viewpost(Runnable) method

public void onClick(View v) new Thread(new Runnable() public void run() final Bitmap bitmap = loadImageFromNetwork(httpexamplecomimagepng) mImageViewpost(new Runnable() public void run() mImageViewsetImageBitmap(bitmap) ) )start()

Now this implementation is thread-safe the network operation is done from a separate thread while

the ImageView is manipulated from the UI thread

However as the complexity of the operation grows this kind of code can get complicated and difficult

to maintain To handle more complex interactions with a worker thread you might consider using a

Handler in your worker thread to process messages delivered from the UI thread Perhaps the best

solution though is to extend the AsyncTask class which simplifies the execution of worker thread

tasks that need to interact with the UI

Using AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface It performs the blocking

operations in a worker thread and then publishes the results on the UI thread without requiring you to

handle threads andor handlers yourself

To use it you must subclass AsyncTask and implement the doInBackground() callback method which

runs in a pool of background threads To update your UI you should implement onPostExecute()

which delivers the result from doInBackground() and runs in the UI thread so you can safely update

your UI You can then run the task by calling execute() from the UI thread

For example you can implement the previous example using AsyncTask this way

public void onClick(View v) new DownloadImageTask()execute(httpexamplecomimagepng) private class DownloadImageTask extends AsyncTaskltString Void Bitmapgt The system calls this to perform work in a worker thread and delivers it the parameters given to AsyncTaskexecute() protected Bitmap doInBackground(String urls) return loadImageFromNetwork(urls[0])

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 45: 03 services

paths If a filter specifies a scheme an authority and a path only URIs with the same scheme

authority and path match However a path specification in the filter can contain wildcards to

require only a partial match of the path

The type attribute of a ltdatagt element specifies the MIME type of the data Its more common in

filters than a URI Both the Intent object and the filter can use a wildcard for the subtype field

mdash for example text or audio mdash indicating any subtype matches

The data test compares both the URI and the data type in the Intent object to a URI and data

type specified in the filter The rules are as follows

a An Intent object that contains neither a URI nor a data type passes the test only if the filter

likewise does not specify any URIs or data types

b An Intent object that contains a URI but no data type (and a type cannot be inferred from the

URI) passes the test only if its URI matches a URI in the filter and the filter likewise does not

specify a type This will be the case only for URIs like mailto and tel that do not refer to actual

data

c An Intent object that contains a data type but not a URI passes the test only if the filter lists the

same data type and similarly does not specify a URI

d An Intent object that contains both a URI and a data type (or a data type can be inferred from

the URI) passes the data type part of the test only if its type matches a type listed in the filter It

passes the URI part of the test either if its URI matches a URI in the filter or if it has a content

or file URI and the filter does not specify a URI In other words a component is presumed to

support content and file data if its filter lists only a data type

If an intent can pass through the filters of more than one activity or service the user may be asked

which component to activate An exception is raised if no target can be found

Common cases

The last rule shown above for the data test rule (d) reflects the expectation that components are able

to get local data from a file or content provider Therefore their filters can list just a data type and do

not need to explicitly name the content and file schemes This is a typical case A ltdatagt element like

the following for example tells Android that the component can get image data from a content

provider and display it

ltdata androidmimeType=image gt

Since most available data is dispensed by content providers filters that specify a data type but not a

URI are perhaps the most common

Another common configuration is filters with a scheme and a data type For example a ltdatagt

element like the following tells Android that the component can get video data from the network and

display it

ltdata androidscheme=http androidtype=video gt

Consider for example what the browser application does when the user follows a link on a web page

It first tries to display the data (as it could if the link was to an HTML page) If it cant display the data it

puts together an implicit intent with the scheme and data type and tries to start an activity that can do

the job If there are no takers it asks the download manager to download the data That puts it under

the control of a content provider so a potentially larger pool of activities (those with filters that just

name a data type) can respond

Most applications also have a way to start fresh without a reference to any particular data Activities

that can initiate applications have filters with androidintentactionMAIN specified as the action If

they are to be represented in the application launcher they also specify the

androidintentcategoryLAUNCHER category

ltintent-filter gt ltaction androidname=code androidintentactionMAIN gt ltcategory androidname=code androidintentcategoryLAUNCHER gt ltintent-filtergt

Using intent matching

Intents are matched against intent filters not only to discover a target component to activate but also

to discover something about the set of components on the device For example the Android system

populates the application launcher the top-level screen that shows the applications that are available

for the user to launch by finding all the activities with intent filters that specify the

androidintentactionMAIN action and androidintentcategoryLAUNCHER category (as illustrated

in the previous section) It then displays the icons and labels of those activities in the launcher

Similarly it discovers the home screen by looking for the activity with androidintentcategoryHOME

in its filter

Your application can use intent matching is a similar way The PackageManager has a set of query()

methods that return all components that can accept a particular intent and a similar series of

resolve() methods that determine the best component to respond to an intent For example

queryIntentActivities() returns a list of all activities that can perform the intent passed as an argument

and queryIntentServices() returns a similar list of services Neither method activates the components

they just list the ones that can respond Theres a similar method queryBroadcastReceivers() for

broadcast receivers

Note Pad Example

The Note Pad sample application enables users to browse through a list of notes view details about

individual items in the list edit the items and add a new item to the list This section looks at the intent

filters declared in its manifest file (If youre working offline in the SDK you can find all the source files

for this sample application including its manifest file at ltsdkgtsamplesNotePadindexhtml If youre

viewing the documentation online the source files are in the Tutorials and Sample Code section here)

In its manifest file the Note Pad application declares three activities each with at least one intent filter

It also declares a content provider that manages the note data Here is the manifest file in its entirety

ltmanifest xmlnsandroid=httpschemasandroidcomapkresandroid package=comexampleandroidnotepadgt ltapplication androidicon=drawableapp_notes androidlabel=stringapp_name gt ltprovider androidname=NotePadProvider androidauthorities=comgoogleproviderNotePad gt ltactivity androidname=NotesList androidlabel=stringtitle_notes_listgt ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltactivity androidname=NoteEditor androidtheme=androidstyleThemeLight androidlabel=stringtitle_note gt ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltactivitygt

ltactivity androidname=TitleEditor androidlabel=stringtitle_edit_title androidtheme=androidstyleThemeDialoggt ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltapplicationgt ltmanifestgt

The first activity NotesList is distinguished from the other activities by the fact that it operates on a

directory of notes (the note list) rather than on a single note It would generally serve as the initial user

interface into the application It can do three things as described by its three intent filters

1 ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt

This filter declares the main entry point into the Note Pad application The standard MAIN action is an

entry point that does not require any other information in the Intent (no data specification for example)

and the LAUNCHER category says that this entry point should be listed in the application launcher

2 ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

This filter declares the things that the activity can do on a directory of notes It can allow the user to

view or edit the directory (via the VIEW and EDIT actions) or to pick a particular note from the

directory (via the PICK action)

The mimeType attribute of the ltdatagt element specifies the kind of data that these actions operate on

It indicates that the activity can get a Cursor over zero or more items (vndandroidcursordir) from a

content provider that holds Note Pad data (vndgooglenote) The Intent object that launches the

activity would include a content URI specifying the exact data of this type that the activity should open

Note also the DEFAULT category supplied in this filter Its there because the ContextstartActivity()

and ActivitystartActivityForResult() methods treat all intents as if they contained the DEFAULT

category mdash with just two exceptions

o Intents that explicitly name the target activity

o Intents consisting of the MAIN action and LAUNCHER category

Therefore the DEFAULT category is required for all filters mdash except for those with the MAIN action

and LAUNCHER category (Intent filters are not consulted for explicit intents)

3 ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

This filter describes the activitys ability to return a note selected by the user without requiring any

specification of the directory the user should choose from The GET_CONTENT action is similar to the

PICK action In both cases the activity returns the URI for a note selected by the user (In each case

its returned to the activity that called startActivityForResult() to start the NoteList activity) Here

however the caller specifies the type of data desired instead of the directory of data the user will be

picking from

The data type vndandroidcursoritemvndgooglenote indicates the type of data the activity can

return mdash a URI for a single note From the returned URI the caller can get a Cursor for exactly one

item (vndandroidcursoritem) from the content provider that holds Note Pad data (vndgooglenote)

In other words for the PICK action in the previous filter the data type indicates the type of data the

activity could display to the user For the GET_CONTENT filter it indicates the type of data the activity

can return to the caller

Given these capabilities the following intents will resolve to the NotesList activity

action androidintentactionMAIN

Launches the activity with no data specified

action androidintentactionMAIN

category androidintentcategoryLAUNCHER

Launches the activity with no data selected specified This is the actual intent used by the

Launcher to populate its top-level list All activities with filters that match this action and

category are added to the list

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of all the notes under

contentcomgoogleproviderNotePadnotes The user can then browse through the list and

get information about the items in it

action androidintentactionPICK

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of the notes under

contentcomgoogleproviderNotePadnotes The user can then pick a note from the list and

the activity will return the URI for that item back to the activity that started the NoteList activity

action androidintentactionGET_CONTENT

data type vndandroidcursoritemvndgooglenote

Asks the activity to supply a single item of Note Pad data

The second activity NoteEditor shows users a single note entry and allows them to edit it It can do

two things as described by its two intent filters

1 ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The first primary purpose of this activity is to enable the user to interact with a single note ampmdash to

either VIEW the note or EDIT it (The EDIT_NOTE category is a synonym for EDIT) The intent would

contain the URI for data matching the MIME type vndandroidcursoritemvndgooglenote mdash that is

the URI for a single specific note It would typically be a URI that was returned by the PICK or

GET_CONTENT actions of the NoteList activity

As before this filter lists the DEFAULT category so that the activity can be launched by intents that

dont explicitly specify the NoteEditor class

2 ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

The secondary purpose of this activity is to enable the user to create a new note which it will INSERT

into an existing directory of notes The intent would contain the URI for data matching the MIME type

vndandroidcursordirvndgooglenote mdash that is the URI for the directory where the note should be

placed

Given these capabilities the following intents will resolve to the NoteEditor activity

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID (For details on how content

URIs specify individual members of a group see Content Providers)

action androidintentactionEDIT

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID and to let the user edit it If

the user saves the changes the activity updates the data for the note in the content provider

action androidintentactionINSERT

data contentcomgoogleproviderNotePadnotes

Asks the activity to create a new empty note in the notes list at

contentcomgoogleproviderNotePadnotes and allow the user to edit it If the user saves the

note its URI is returned to the caller

The last activity TitleEditor enables the user to edit the title of a note This could be implemented by

directly invoking the activity (by explicitly setting its component name in the Intent) without using an

intent filter But here we take the opportunity to show how to publish alternative operations on existing

data

ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The single intent filter for this activity uses a custom action called

comandroidnotepadactionEDIT_TITLE It must be invoked on a specific note (data type

vndandroidcursoritemvndgooglenote) like the previous VIEW and EDIT actions However here the

activity displays the title contained in the note data not the content of the note itself

In addition to supporting the usual DEFAULT category the title editor also supports two other standard

categories ALTERNATIVE and SELECTED_ALTERNATIVE These categories identify activities that

can be presented to users in a menu of options (much as the LAUNCHER category identifies activities

that should be presented to user in the application launcher) Note that the filter also supplies an

explicit label (via androidlabel=stringresolve_title) to better control what users see when

presented with this activity as an alternative action to the data they are currently viewing (For more

information on these categories and building options menus see the

PackageManagerqueryIntentActivityOptions() and MenuaddIntentOptions() methods)

Given these capabilities the following intent will resolve to the TitleEditor activity

action comandroidnotepadactionEDIT_TITLE

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the title associated with note ID and allow the user to edit the title

Processes and Threads

When an application component starts and the application does not have any other components

running the Android system starts a new Linux process for the application with a single thread of

execution By default all components of the same application run in the same process and thread

(called the main thread) If an application component starts and there already exists a process for

that application (because another component from the application exists) then the component is

started within that process and uses the same thread of execution However you can arrange for

different components in your application to run in separate processes and you can create additional

threads for any process

This document discusses how processes and threads work in an Android application

Processes

By default all components of the same application run in the same process and most applications

should not change this However if you find that you need to control which process a certain

component belongs to you can do so in the manifest file

The manifest entry for each type of component elementmdashltactivitygt ltservicegt ltreceivergt and

ltprovidergtmdashsupports an androidprocess attribute that can specify a process in which that component

should run You can set this attribute so that each component runs in its own process or so that some

components share a process while others do not You can also set androidprocess so that

components of different applications run in the same processmdashprovided that the applications share the

same Linux user ID and are signed with the same certificates

The ltapplicationgt element also supports an androidprocess attribute to set a default value that

applies to all components

Android might 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 thats killed are consequently destroyed A process is started again for those components

when theres again work for them to do

When deciding which processes to kill the Android system weighs their relative importance to the

user For example it more readily shuts down a process hosting activities that are no longer visible on

screen compared to a process hosting visible activities The decision whether to terminate a process

therefore depends on the state of the components running in that process The rules used to decide

which processes to terminate is discussed below

Process lifecycle

The Android system tries to maintain an application process for as long as possible but eventually

needs to remove old processes to reclaim memory for new or more important processes To determine

which processes to keep and which to kill the system places each process into an importance

hierarchy based on the components running in the process and the state of those components

Processes with the lowest importance are eliminated first then those with the next lowest importance

and so on as necessary to recover system resources

There are five levels in the importance hierarchy The following list presents the different types of

processes in order of importance (the first process is most important and is killed last)

1 Foreground process

A process that is required for what the user is currently doing A process is considered to be in the

foreground if any of the following conditions are true

o It hosts an Activity that the user is interacting with (the Activitys onResume() method has been called)

o It hosts a Service thats bound to the activity that the user is interacting with

o It hosts a Service thats running in the foregroundmdashthe service has called startForeground()

o It hosts a Service thats executing one of its lifecycle callbacks (onCreate() onStart() or onDestroy())

o It hosts a BroadcastReceiver thats executing its onReceive() method

Generally only a few foreground processes exist at any given time They are killed only as a last

resortmdashif memory is so low that they cannot all continue to run Generally at that point the device has

reached a memory paging state so killing some foreground processes is required to keep the user

interface responsive

2 Visible process

A process that doesnt have any foreground components but still can affect what the user sees on

screen A process is considered to be visible if either of the following conditions are true

o It hosts an Activity that is not in the foreground but is still visible to the user (its onPause() method has

been called) This might occur for example if the foreground activity started a dialog which allows the

previous activity to be seen behind it

o It hosts a Service thats bound to a visible (or foreground) activity

A visible process is considered extremely important and will not be killed unless doing so is required to

keep all foreground processes running

3 Service process

A process that is running a service that has been started with the startService() method and does not

fall into either of the two higher categories Although service processes are not directly tied to anything

the user sees they are generally doing things that the user cares about (such as playing music in the

background or downloading data on the network) so the system keeps them running unless theres

not enough memory to retain them along with all foreground and visible processes

4 Background process

A process holding an activity thats not currently visible to the user (the activitys onStop() method has

been called) These processes have no direct impact on the user experience and the system can kill

them at any time to reclaim memory for a foreground visible or service process Usually there are

many background processes running so they are kept in an LRU (least recently used) list to ensure

that the process with the activity that was most recently seen by the user is the last to be killed If an

activity implements its lifecycle methods correctly and saves its current state killing its process will not

have a visible effect on the user experience because when the user navigates back to the activity the

activity restores all of its visible state See the Activities document for information about saving and

restoring state

5 Empty process

A process that doesnt hold any active application components The only reason to keep this kind of

process alive is for caching purposes to improve startup time the next time a component needs to run

in it The system often kills these processes in order to balance overall system resources between

process caches and the underlying kernel caches

Android ranks a process at the highest level it can based upon the importance of the components

currently active in the process For example if a process hosts a service and a visible activity the

process is ranked as a visible process not a service process

In addition a processs ranking might be increased because other processes are dependent on itmdasha

process that is serving another process can never be ranked lower than the process it is serving For

example if a content provider in process A is serving a client in process B or if a service in process A

is bound to a component in process B process A is always considered at least as important as

process B

Because a process running a service is ranked higher than a process with background activities an

activity that initiates a long-running operation might do well to start a service for that operation rather

than simply create a worker threadmdashparticularly if the operation will likely outlast the activity For

example an activity thats uploading a picture to a web site should start a service to perform the

upload so that the upload can continue in the background even if the user leaves the activity Using a

service guarantees that the operation will have at least service process priority regardless of what

happens to the activity This is the same reason that broadcast receivers should employ services

rather than simply put time-consuming operations in a thread

Threads

When an application is launched the system creates a thread of execution for the application called

main This thread is very important because it is in charge of dispatching events to the appropriate

user interface widgets including drawing events It is also the thread in which your application interacts

with components from the Android UI toolkit (components from the androidwidget and androidview

packages) As such the main thread is also sometimes called the UI thread

The system does not create a separate thread for each instance of a component All components that

run in the same process are instantiated in the UI thread and system calls to each component are

dispatched from that thread Consequently methods that respond to system callbacks (such as

onKeyDown() to report user actions or a lifecycle callback method) always run in the UI thread of the

process

For instance when the user touches a button on the screen your apps UI thread dispatches the touch

event to the widget which in turn sets its pressed state and posts an invalidate request to the event

queue The UI thread dequeues the request and notifies the widget that it should redraw itself

When your app performs intensive work in response to user interaction this single thread model can

yield poor performance unless you implement your application properly Specifically if everything is

happening in the UI thread performing long operations such as network access or database queries

will block the whole UI When the thread is blocked no events can be dispatched including drawing

events From the users perspective the application appears to hang Even worse if the UI thread is

blocked for more than a few seconds (about 5 seconds currently) the user is presented with the

infamous application not responding (ANR) dialog The user might then decide to quit your

application and uninstall it if they are unhappy

Additionally the Andoid UI toolkit is not thread-safe So you must not manipulate your UI from a

worker threadmdashyou must do all manipulation to your user interface from the UI thread Thus there are

simply two rules to Androids single thread model

1 Do not block the UI thread

2 Do not access the Android UI toolkit from outside the UI thread

Worker threads

Because of the single thread model described above its vital to the responsiveness of your

applications UI that you do not block the UI thread If you have operations to perform that are not

instantaneous you should make sure to do them in separate threads (background or worker

threads)

For example below is some code for a click listener that downloads an image from a separate thread

and displays it in an ImageView

public void onClick(View v) new Thread(new Runnable() public void run() Bitmap b = loadImageFromNetwork(httpexamplecomimagepng) mImageViewsetImageBitmap(b) )start()

At first this seems to work fine because it creates a new thread to handle the network operation

However it violates the second rule of the single-threaded model do not access the Android UI toolkit

from outside the UI threadmdashthis sample modifies the ImageView from the worker thread instead of the

UI thread This can result in undefined and unexpected behavior which can be difficult and time-

consuming to track down

To fix this problem Android offers several ways to access the UI thread from other threads Here is a

list of methods that can help

ActivityrunOnUiThread(Runnable)

Viewpost(Runnable)

ViewpostDelayed(Runnable long)

For example you can fix the above code by using the Viewpost(Runnable) method

public void onClick(View v) new Thread(new Runnable() public void run() final Bitmap bitmap = loadImageFromNetwork(httpexamplecomimagepng) mImageViewpost(new Runnable() public void run() mImageViewsetImageBitmap(bitmap) ) )start()

Now this implementation is thread-safe the network operation is done from a separate thread while

the ImageView is manipulated from the UI thread

However as the complexity of the operation grows this kind of code can get complicated and difficult

to maintain To handle more complex interactions with a worker thread you might consider using a

Handler in your worker thread to process messages delivered from the UI thread Perhaps the best

solution though is to extend the AsyncTask class which simplifies the execution of worker thread

tasks that need to interact with the UI

Using AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface It performs the blocking

operations in a worker thread and then publishes the results on the UI thread without requiring you to

handle threads andor handlers yourself

To use it you must subclass AsyncTask and implement the doInBackground() callback method which

runs in a pool of background threads To update your UI you should implement onPostExecute()

which delivers the result from doInBackground() and runs in the UI thread so you can safely update

your UI You can then run the task by calling execute() from the UI thread

For example you can implement the previous example using AsyncTask this way

public void onClick(View v) new DownloadImageTask()execute(httpexamplecomimagepng) private class DownloadImageTask extends AsyncTaskltString Void Bitmapgt The system calls this to perform work in a worker thread and delivers it the parameters given to AsyncTaskexecute() protected Bitmap doInBackground(String urls) return loadImageFromNetwork(urls[0])

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 46: 03 services

ltdata androidscheme=http androidtype=video gt

Consider for example what the browser application does when the user follows a link on a web page

It first tries to display the data (as it could if the link was to an HTML page) If it cant display the data it

puts together an implicit intent with the scheme and data type and tries to start an activity that can do

the job If there are no takers it asks the download manager to download the data That puts it under

the control of a content provider so a potentially larger pool of activities (those with filters that just

name a data type) can respond

Most applications also have a way to start fresh without a reference to any particular data Activities

that can initiate applications have filters with androidintentactionMAIN specified as the action If

they are to be represented in the application launcher they also specify the

androidintentcategoryLAUNCHER category

ltintent-filter gt ltaction androidname=code androidintentactionMAIN gt ltcategory androidname=code androidintentcategoryLAUNCHER gt ltintent-filtergt

Using intent matching

Intents are matched against intent filters not only to discover a target component to activate but also

to discover something about the set of components on the device For example the Android system

populates the application launcher the top-level screen that shows the applications that are available

for the user to launch by finding all the activities with intent filters that specify the

androidintentactionMAIN action and androidintentcategoryLAUNCHER category (as illustrated

in the previous section) It then displays the icons and labels of those activities in the launcher

Similarly it discovers the home screen by looking for the activity with androidintentcategoryHOME

in its filter

Your application can use intent matching is a similar way The PackageManager has a set of query()

methods that return all components that can accept a particular intent and a similar series of

resolve() methods that determine the best component to respond to an intent For example

queryIntentActivities() returns a list of all activities that can perform the intent passed as an argument

and queryIntentServices() returns a similar list of services Neither method activates the components

they just list the ones that can respond Theres a similar method queryBroadcastReceivers() for

broadcast receivers

Note Pad Example

The Note Pad sample application enables users to browse through a list of notes view details about

individual items in the list edit the items and add a new item to the list This section looks at the intent

filters declared in its manifest file (If youre working offline in the SDK you can find all the source files

for this sample application including its manifest file at ltsdkgtsamplesNotePadindexhtml If youre

viewing the documentation online the source files are in the Tutorials and Sample Code section here)

In its manifest file the Note Pad application declares three activities each with at least one intent filter

It also declares a content provider that manages the note data Here is the manifest file in its entirety

ltmanifest xmlnsandroid=httpschemasandroidcomapkresandroid package=comexampleandroidnotepadgt ltapplication androidicon=drawableapp_notes androidlabel=stringapp_name gt ltprovider androidname=NotePadProvider androidauthorities=comgoogleproviderNotePad gt ltactivity androidname=NotesList androidlabel=stringtitle_notes_listgt ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltactivity androidname=NoteEditor androidtheme=androidstyleThemeLight androidlabel=stringtitle_note gt ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltactivitygt

ltactivity androidname=TitleEditor androidlabel=stringtitle_edit_title androidtheme=androidstyleThemeDialoggt ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltapplicationgt ltmanifestgt

The first activity NotesList is distinguished from the other activities by the fact that it operates on a

directory of notes (the note list) rather than on a single note It would generally serve as the initial user

interface into the application It can do three things as described by its three intent filters

1 ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt

This filter declares the main entry point into the Note Pad application The standard MAIN action is an

entry point that does not require any other information in the Intent (no data specification for example)

and the LAUNCHER category says that this entry point should be listed in the application launcher

2 ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

This filter declares the things that the activity can do on a directory of notes It can allow the user to

view or edit the directory (via the VIEW and EDIT actions) or to pick a particular note from the

directory (via the PICK action)

The mimeType attribute of the ltdatagt element specifies the kind of data that these actions operate on

It indicates that the activity can get a Cursor over zero or more items (vndandroidcursordir) from a

content provider that holds Note Pad data (vndgooglenote) The Intent object that launches the

activity would include a content URI specifying the exact data of this type that the activity should open

Note also the DEFAULT category supplied in this filter Its there because the ContextstartActivity()

and ActivitystartActivityForResult() methods treat all intents as if they contained the DEFAULT

category mdash with just two exceptions

o Intents that explicitly name the target activity

o Intents consisting of the MAIN action and LAUNCHER category

Therefore the DEFAULT category is required for all filters mdash except for those with the MAIN action

and LAUNCHER category (Intent filters are not consulted for explicit intents)

3 ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

This filter describes the activitys ability to return a note selected by the user without requiring any

specification of the directory the user should choose from The GET_CONTENT action is similar to the

PICK action In both cases the activity returns the URI for a note selected by the user (In each case

its returned to the activity that called startActivityForResult() to start the NoteList activity) Here

however the caller specifies the type of data desired instead of the directory of data the user will be

picking from

The data type vndandroidcursoritemvndgooglenote indicates the type of data the activity can

return mdash a URI for a single note From the returned URI the caller can get a Cursor for exactly one

item (vndandroidcursoritem) from the content provider that holds Note Pad data (vndgooglenote)

In other words for the PICK action in the previous filter the data type indicates the type of data the

activity could display to the user For the GET_CONTENT filter it indicates the type of data the activity

can return to the caller

Given these capabilities the following intents will resolve to the NotesList activity

action androidintentactionMAIN

Launches the activity with no data specified

action androidintentactionMAIN

category androidintentcategoryLAUNCHER

Launches the activity with no data selected specified This is the actual intent used by the

Launcher to populate its top-level list All activities with filters that match this action and

category are added to the list

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of all the notes under

contentcomgoogleproviderNotePadnotes The user can then browse through the list and

get information about the items in it

action androidintentactionPICK

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of the notes under

contentcomgoogleproviderNotePadnotes The user can then pick a note from the list and

the activity will return the URI for that item back to the activity that started the NoteList activity

action androidintentactionGET_CONTENT

data type vndandroidcursoritemvndgooglenote

Asks the activity to supply a single item of Note Pad data

The second activity NoteEditor shows users a single note entry and allows them to edit it It can do

two things as described by its two intent filters

1 ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The first primary purpose of this activity is to enable the user to interact with a single note ampmdash to

either VIEW the note or EDIT it (The EDIT_NOTE category is a synonym for EDIT) The intent would

contain the URI for data matching the MIME type vndandroidcursoritemvndgooglenote mdash that is

the URI for a single specific note It would typically be a URI that was returned by the PICK or

GET_CONTENT actions of the NoteList activity

As before this filter lists the DEFAULT category so that the activity can be launched by intents that

dont explicitly specify the NoteEditor class

2 ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

The secondary purpose of this activity is to enable the user to create a new note which it will INSERT

into an existing directory of notes The intent would contain the URI for data matching the MIME type

vndandroidcursordirvndgooglenote mdash that is the URI for the directory where the note should be

placed

Given these capabilities the following intents will resolve to the NoteEditor activity

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID (For details on how content

URIs specify individual members of a group see Content Providers)

action androidintentactionEDIT

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID and to let the user edit it If

the user saves the changes the activity updates the data for the note in the content provider

action androidintentactionINSERT

data contentcomgoogleproviderNotePadnotes

Asks the activity to create a new empty note in the notes list at

contentcomgoogleproviderNotePadnotes and allow the user to edit it If the user saves the

note its URI is returned to the caller

The last activity TitleEditor enables the user to edit the title of a note This could be implemented by

directly invoking the activity (by explicitly setting its component name in the Intent) without using an

intent filter But here we take the opportunity to show how to publish alternative operations on existing

data

ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The single intent filter for this activity uses a custom action called

comandroidnotepadactionEDIT_TITLE It must be invoked on a specific note (data type

vndandroidcursoritemvndgooglenote) like the previous VIEW and EDIT actions However here the

activity displays the title contained in the note data not the content of the note itself

In addition to supporting the usual DEFAULT category the title editor also supports two other standard

categories ALTERNATIVE and SELECTED_ALTERNATIVE These categories identify activities that

can be presented to users in a menu of options (much as the LAUNCHER category identifies activities

that should be presented to user in the application launcher) Note that the filter also supplies an

explicit label (via androidlabel=stringresolve_title) to better control what users see when

presented with this activity as an alternative action to the data they are currently viewing (For more

information on these categories and building options menus see the

PackageManagerqueryIntentActivityOptions() and MenuaddIntentOptions() methods)

Given these capabilities the following intent will resolve to the TitleEditor activity

action comandroidnotepadactionEDIT_TITLE

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the title associated with note ID and allow the user to edit the title

Processes and Threads

When an application component starts and the application does not have any other components

running the Android system starts a new Linux process for the application with a single thread of

execution By default all components of the same application run in the same process and thread

(called the main thread) If an application component starts and there already exists a process for

that application (because another component from the application exists) then the component is

started within that process and uses the same thread of execution However you can arrange for

different components in your application to run in separate processes and you can create additional

threads for any process

This document discusses how processes and threads work in an Android application

Processes

By default all components of the same application run in the same process and most applications

should not change this However if you find that you need to control which process a certain

component belongs to you can do so in the manifest file

The manifest entry for each type of component elementmdashltactivitygt ltservicegt ltreceivergt and

ltprovidergtmdashsupports an androidprocess attribute that can specify a process in which that component

should run You can set this attribute so that each component runs in its own process or so that some

components share a process while others do not You can also set androidprocess so that

components of different applications run in the same processmdashprovided that the applications share the

same Linux user ID and are signed with the same certificates

The ltapplicationgt element also supports an androidprocess attribute to set a default value that

applies to all components

Android might 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 thats killed are consequently destroyed A process is started again for those components

when theres again work for them to do

When deciding which processes to kill the Android system weighs their relative importance to the

user For example it more readily shuts down a process hosting activities that are no longer visible on

screen compared to a process hosting visible activities The decision whether to terminate a process

therefore depends on the state of the components running in that process The rules used to decide

which processes to terminate is discussed below

Process lifecycle

The Android system tries to maintain an application process for as long as possible but eventually

needs to remove old processes to reclaim memory for new or more important processes To determine

which processes to keep and which to kill the system places each process into an importance

hierarchy based on the components running in the process and the state of those components

Processes with the lowest importance are eliminated first then those with the next lowest importance

and so on as necessary to recover system resources

There are five levels in the importance hierarchy The following list presents the different types of

processes in order of importance (the first process is most important and is killed last)

1 Foreground process

A process that is required for what the user is currently doing A process is considered to be in the

foreground if any of the following conditions are true

o It hosts an Activity that the user is interacting with (the Activitys onResume() method has been called)

o It hosts a Service thats bound to the activity that the user is interacting with

o It hosts a Service thats running in the foregroundmdashthe service has called startForeground()

o It hosts a Service thats executing one of its lifecycle callbacks (onCreate() onStart() or onDestroy())

o It hosts a BroadcastReceiver thats executing its onReceive() method

Generally only a few foreground processes exist at any given time They are killed only as a last

resortmdashif memory is so low that they cannot all continue to run Generally at that point the device has

reached a memory paging state so killing some foreground processes is required to keep the user

interface responsive

2 Visible process

A process that doesnt have any foreground components but still can affect what the user sees on

screen A process is considered to be visible if either of the following conditions are true

o It hosts an Activity that is not in the foreground but is still visible to the user (its onPause() method has

been called) This might occur for example if the foreground activity started a dialog which allows the

previous activity to be seen behind it

o It hosts a Service thats bound to a visible (or foreground) activity

A visible process is considered extremely important and will not be killed unless doing so is required to

keep all foreground processes running

3 Service process

A process that is running a service that has been started with the startService() method and does not

fall into either of the two higher categories Although service processes are not directly tied to anything

the user sees they are generally doing things that the user cares about (such as playing music in the

background or downloading data on the network) so the system keeps them running unless theres

not enough memory to retain them along with all foreground and visible processes

4 Background process

A process holding an activity thats not currently visible to the user (the activitys onStop() method has

been called) These processes have no direct impact on the user experience and the system can kill

them at any time to reclaim memory for a foreground visible or service process Usually there are

many background processes running so they are kept in an LRU (least recently used) list to ensure

that the process with the activity that was most recently seen by the user is the last to be killed If an

activity implements its lifecycle methods correctly and saves its current state killing its process will not

have a visible effect on the user experience because when the user navigates back to the activity the

activity restores all of its visible state See the Activities document for information about saving and

restoring state

5 Empty process

A process that doesnt hold any active application components The only reason to keep this kind of

process alive is for caching purposes to improve startup time the next time a component needs to run

in it The system often kills these processes in order to balance overall system resources between

process caches and the underlying kernel caches

Android ranks a process at the highest level it can based upon the importance of the components

currently active in the process For example if a process hosts a service and a visible activity the

process is ranked as a visible process not a service process

In addition a processs ranking might be increased because other processes are dependent on itmdasha

process that is serving another process can never be ranked lower than the process it is serving For

example if a content provider in process A is serving a client in process B or if a service in process A

is bound to a component in process B process A is always considered at least as important as

process B

Because a process running a service is ranked higher than a process with background activities an

activity that initiates a long-running operation might do well to start a service for that operation rather

than simply create a worker threadmdashparticularly if the operation will likely outlast the activity For

example an activity thats uploading a picture to a web site should start a service to perform the

upload so that the upload can continue in the background even if the user leaves the activity Using a

service guarantees that the operation will have at least service process priority regardless of what

happens to the activity This is the same reason that broadcast receivers should employ services

rather than simply put time-consuming operations in a thread

Threads

When an application is launched the system creates a thread of execution for the application called

main This thread is very important because it is in charge of dispatching events to the appropriate

user interface widgets including drawing events It is also the thread in which your application interacts

with components from the Android UI toolkit (components from the androidwidget and androidview

packages) As such the main thread is also sometimes called the UI thread

The system does not create a separate thread for each instance of a component All components that

run in the same process are instantiated in the UI thread and system calls to each component are

dispatched from that thread Consequently methods that respond to system callbacks (such as

onKeyDown() to report user actions or a lifecycle callback method) always run in the UI thread of the

process

For instance when the user touches a button on the screen your apps UI thread dispatches the touch

event to the widget which in turn sets its pressed state and posts an invalidate request to the event

queue The UI thread dequeues the request and notifies the widget that it should redraw itself

When your app performs intensive work in response to user interaction this single thread model can

yield poor performance unless you implement your application properly Specifically if everything is

happening in the UI thread performing long operations such as network access or database queries

will block the whole UI When the thread is blocked no events can be dispatched including drawing

events From the users perspective the application appears to hang Even worse if the UI thread is

blocked for more than a few seconds (about 5 seconds currently) the user is presented with the

infamous application not responding (ANR) dialog The user might then decide to quit your

application and uninstall it if they are unhappy

Additionally the Andoid UI toolkit is not thread-safe So you must not manipulate your UI from a

worker threadmdashyou must do all manipulation to your user interface from the UI thread Thus there are

simply two rules to Androids single thread model

1 Do not block the UI thread

2 Do not access the Android UI toolkit from outside the UI thread

Worker threads

Because of the single thread model described above its vital to the responsiveness of your

applications UI that you do not block the UI thread If you have operations to perform that are not

instantaneous you should make sure to do them in separate threads (background or worker

threads)

For example below is some code for a click listener that downloads an image from a separate thread

and displays it in an ImageView

public void onClick(View v) new Thread(new Runnable() public void run() Bitmap b = loadImageFromNetwork(httpexamplecomimagepng) mImageViewsetImageBitmap(b) )start()

At first this seems to work fine because it creates a new thread to handle the network operation

However it violates the second rule of the single-threaded model do not access the Android UI toolkit

from outside the UI threadmdashthis sample modifies the ImageView from the worker thread instead of the

UI thread This can result in undefined and unexpected behavior which can be difficult and time-

consuming to track down

To fix this problem Android offers several ways to access the UI thread from other threads Here is a

list of methods that can help

ActivityrunOnUiThread(Runnable)

Viewpost(Runnable)

ViewpostDelayed(Runnable long)

For example you can fix the above code by using the Viewpost(Runnable) method

public void onClick(View v) new Thread(new Runnable() public void run() final Bitmap bitmap = loadImageFromNetwork(httpexamplecomimagepng) mImageViewpost(new Runnable() public void run() mImageViewsetImageBitmap(bitmap) ) )start()

Now this implementation is thread-safe the network operation is done from a separate thread while

the ImageView is manipulated from the UI thread

However as the complexity of the operation grows this kind of code can get complicated and difficult

to maintain To handle more complex interactions with a worker thread you might consider using a

Handler in your worker thread to process messages delivered from the UI thread Perhaps the best

solution though is to extend the AsyncTask class which simplifies the execution of worker thread

tasks that need to interact with the UI

Using AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface It performs the blocking

operations in a worker thread and then publishes the results on the UI thread without requiring you to

handle threads andor handlers yourself

To use it you must subclass AsyncTask and implement the doInBackground() callback method which

runs in a pool of background threads To update your UI you should implement onPostExecute()

which delivers the result from doInBackground() and runs in the UI thread so you can safely update

your UI You can then run the task by calling execute() from the UI thread

For example you can implement the previous example using AsyncTask this way

public void onClick(View v) new DownloadImageTask()execute(httpexamplecomimagepng) private class DownloadImageTask extends AsyncTaskltString Void Bitmapgt The system calls this to perform work in a worker thread and delivers it the parameters given to AsyncTaskexecute() protected Bitmap doInBackground(String urls) return loadImageFromNetwork(urls[0])

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 47: 03 services

for this sample application including its manifest file at ltsdkgtsamplesNotePadindexhtml If youre

viewing the documentation online the source files are in the Tutorials and Sample Code section here)

In its manifest file the Note Pad application declares three activities each with at least one intent filter

It also declares a content provider that manages the note data Here is the manifest file in its entirety

ltmanifest xmlnsandroid=httpschemasandroidcomapkresandroid package=comexampleandroidnotepadgt ltapplication androidicon=drawableapp_notes androidlabel=stringapp_name gt ltprovider androidname=NotePadProvider androidauthorities=comgoogleproviderNotePad gt ltactivity androidname=NotesList androidlabel=stringtitle_notes_listgt ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltactivity androidname=NoteEditor androidtheme=androidstyleThemeLight androidlabel=stringtitle_note gt ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt ltactivitygt

ltactivity androidname=TitleEditor androidlabel=stringtitle_edit_title androidtheme=androidstyleThemeDialoggt ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltapplicationgt ltmanifestgt

The first activity NotesList is distinguished from the other activities by the fact that it operates on a

directory of notes (the note list) rather than on a single note It would generally serve as the initial user

interface into the application It can do three things as described by its three intent filters

1 ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt

This filter declares the main entry point into the Note Pad application The standard MAIN action is an

entry point that does not require any other information in the Intent (no data specification for example)

and the LAUNCHER category says that this entry point should be listed in the application launcher

2 ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

This filter declares the things that the activity can do on a directory of notes It can allow the user to

view or edit the directory (via the VIEW and EDIT actions) or to pick a particular note from the

directory (via the PICK action)

The mimeType attribute of the ltdatagt element specifies the kind of data that these actions operate on

It indicates that the activity can get a Cursor over zero or more items (vndandroidcursordir) from a

content provider that holds Note Pad data (vndgooglenote) The Intent object that launches the

activity would include a content URI specifying the exact data of this type that the activity should open

Note also the DEFAULT category supplied in this filter Its there because the ContextstartActivity()

and ActivitystartActivityForResult() methods treat all intents as if they contained the DEFAULT

category mdash with just two exceptions

o Intents that explicitly name the target activity

o Intents consisting of the MAIN action and LAUNCHER category

Therefore the DEFAULT category is required for all filters mdash except for those with the MAIN action

and LAUNCHER category (Intent filters are not consulted for explicit intents)

3 ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

This filter describes the activitys ability to return a note selected by the user without requiring any

specification of the directory the user should choose from The GET_CONTENT action is similar to the

PICK action In both cases the activity returns the URI for a note selected by the user (In each case

its returned to the activity that called startActivityForResult() to start the NoteList activity) Here

however the caller specifies the type of data desired instead of the directory of data the user will be

picking from

The data type vndandroidcursoritemvndgooglenote indicates the type of data the activity can

return mdash a URI for a single note From the returned URI the caller can get a Cursor for exactly one

item (vndandroidcursoritem) from the content provider that holds Note Pad data (vndgooglenote)

In other words for the PICK action in the previous filter the data type indicates the type of data the

activity could display to the user For the GET_CONTENT filter it indicates the type of data the activity

can return to the caller

Given these capabilities the following intents will resolve to the NotesList activity

action androidintentactionMAIN

Launches the activity with no data specified

action androidintentactionMAIN

category androidintentcategoryLAUNCHER

Launches the activity with no data selected specified This is the actual intent used by the

Launcher to populate its top-level list All activities with filters that match this action and

category are added to the list

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of all the notes under

contentcomgoogleproviderNotePadnotes The user can then browse through the list and

get information about the items in it

action androidintentactionPICK

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of the notes under

contentcomgoogleproviderNotePadnotes The user can then pick a note from the list and

the activity will return the URI for that item back to the activity that started the NoteList activity

action androidintentactionGET_CONTENT

data type vndandroidcursoritemvndgooglenote

Asks the activity to supply a single item of Note Pad data

The second activity NoteEditor shows users a single note entry and allows them to edit it It can do

two things as described by its two intent filters

1 ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The first primary purpose of this activity is to enable the user to interact with a single note ampmdash to

either VIEW the note or EDIT it (The EDIT_NOTE category is a synonym for EDIT) The intent would

contain the URI for data matching the MIME type vndandroidcursoritemvndgooglenote mdash that is

the URI for a single specific note It would typically be a URI that was returned by the PICK or

GET_CONTENT actions of the NoteList activity

As before this filter lists the DEFAULT category so that the activity can be launched by intents that

dont explicitly specify the NoteEditor class

2 ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

The secondary purpose of this activity is to enable the user to create a new note which it will INSERT

into an existing directory of notes The intent would contain the URI for data matching the MIME type

vndandroidcursordirvndgooglenote mdash that is the URI for the directory where the note should be

placed

Given these capabilities the following intents will resolve to the NoteEditor activity

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID (For details on how content

URIs specify individual members of a group see Content Providers)

action androidintentactionEDIT

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID and to let the user edit it If

the user saves the changes the activity updates the data for the note in the content provider

action androidintentactionINSERT

data contentcomgoogleproviderNotePadnotes

Asks the activity to create a new empty note in the notes list at

contentcomgoogleproviderNotePadnotes and allow the user to edit it If the user saves the

note its URI is returned to the caller

The last activity TitleEditor enables the user to edit the title of a note This could be implemented by

directly invoking the activity (by explicitly setting its component name in the Intent) without using an

intent filter But here we take the opportunity to show how to publish alternative operations on existing

data

ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The single intent filter for this activity uses a custom action called

comandroidnotepadactionEDIT_TITLE It must be invoked on a specific note (data type

vndandroidcursoritemvndgooglenote) like the previous VIEW and EDIT actions However here the

activity displays the title contained in the note data not the content of the note itself

In addition to supporting the usual DEFAULT category the title editor also supports two other standard

categories ALTERNATIVE and SELECTED_ALTERNATIVE These categories identify activities that

can be presented to users in a menu of options (much as the LAUNCHER category identifies activities

that should be presented to user in the application launcher) Note that the filter also supplies an

explicit label (via androidlabel=stringresolve_title) to better control what users see when

presented with this activity as an alternative action to the data they are currently viewing (For more

information on these categories and building options menus see the

PackageManagerqueryIntentActivityOptions() and MenuaddIntentOptions() methods)

Given these capabilities the following intent will resolve to the TitleEditor activity

action comandroidnotepadactionEDIT_TITLE

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the title associated with note ID and allow the user to edit the title

Processes and Threads

When an application component starts and the application does not have any other components

running the Android system starts a new Linux process for the application with a single thread of

execution By default all components of the same application run in the same process and thread

(called the main thread) If an application component starts and there already exists a process for

that application (because another component from the application exists) then the component is

started within that process and uses the same thread of execution However you can arrange for

different components in your application to run in separate processes and you can create additional

threads for any process

This document discusses how processes and threads work in an Android application

Processes

By default all components of the same application run in the same process and most applications

should not change this However if you find that you need to control which process a certain

component belongs to you can do so in the manifest file

The manifest entry for each type of component elementmdashltactivitygt ltservicegt ltreceivergt and

ltprovidergtmdashsupports an androidprocess attribute that can specify a process in which that component

should run You can set this attribute so that each component runs in its own process or so that some

components share a process while others do not You can also set androidprocess so that

components of different applications run in the same processmdashprovided that the applications share the

same Linux user ID and are signed with the same certificates

The ltapplicationgt element also supports an androidprocess attribute to set a default value that

applies to all components

Android might 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 thats killed are consequently destroyed A process is started again for those components

when theres again work for them to do

When deciding which processes to kill the Android system weighs their relative importance to the

user For example it more readily shuts down a process hosting activities that are no longer visible on

screen compared to a process hosting visible activities The decision whether to terminate a process

therefore depends on the state of the components running in that process The rules used to decide

which processes to terminate is discussed below

Process lifecycle

The Android system tries to maintain an application process for as long as possible but eventually

needs to remove old processes to reclaim memory for new or more important processes To determine

which processes to keep and which to kill the system places each process into an importance

hierarchy based on the components running in the process and the state of those components

Processes with the lowest importance are eliminated first then those with the next lowest importance

and so on as necessary to recover system resources

There are five levels in the importance hierarchy The following list presents the different types of

processes in order of importance (the first process is most important and is killed last)

1 Foreground process

A process that is required for what the user is currently doing A process is considered to be in the

foreground if any of the following conditions are true

o It hosts an Activity that the user is interacting with (the Activitys onResume() method has been called)

o It hosts a Service thats bound to the activity that the user is interacting with

o It hosts a Service thats running in the foregroundmdashthe service has called startForeground()

o It hosts a Service thats executing one of its lifecycle callbacks (onCreate() onStart() or onDestroy())

o It hosts a BroadcastReceiver thats executing its onReceive() method

Generally only a few foreground processes exist at any given time They are killed only as a last

resortmdashif memory is so low that they cannot all continue to run Generally at that point the device has

reached a memory paging state so killing some foreground processes is required to keep the user

interface responsive

2 Visible process

A process that doesnt have any foreground components but still can affect what the user sees on

screen A process is considered to be visible if either of the following conditions are true

o It hosts an Activity that is not in the foreground but is still visible to the user (its onPause() method has

been called) This might occur for example if the foreground activity started a dialog which allows the

previous activity to be seen behind it

o It hosts a Service thats bound to a visible (or foreground) activity

A visible process is considered extremely important and will not be killed unless doing so is required to

keep all foreground processes running

3 Service process

A process that is running a service that has been started with the startService() method and does not

fall into either of the two higher categories Although service processes are not directly tied to anything

the user sees they are generally doing things that the user cares about (such as playing music in the

background or downloading data on the network) so the system keeps them running unless theres

not enough memory to retain them along with all foreground and visible processes

4 Background process

A process holding an activity thats not currently visible to the user (the activitys onStop() method has

been called) These processes have no direct impact on the user experience and the system can kill

them at any time to reclaim memory for a foreground visible or service process Usually there are

many background processes running so they are kept in an LRU (least recently used) list to ensure

that the process with the activity that was most recently seen by the user is the last to be killed If an

activity implements its lifecycle methods correctly and saves its current state killing its process will not

have a visible effect on the user experience because when the user navigates back to the activity the

activity restores all of its visible state See the Activities document for information about saving and

restoring state

5 Empty process

A process that doesnt hold any active application components The only reason to keep this kind of

process alive is for caching purposes to improve startup time the next time a component needs to run

in it The system often kills these processes in order to balance overall system resources between

process caches and the underlying kernel caches

Android ranks a process at the highest level it can based upon the importance of the components

currently active in the process For example if a process hosts a service and a visible activity the

process is ranked as a visible process not a service process

In addition a processs ranking might be increased because other processes are dependent on itmdasha

process that is serving another process can never be ranked lower than the process it is serving For

example if a content provider in process A is serving a client in process B or if a service in process A

is bound to a component in process B process A is always considered at least as important as

process B

Because a process running a service is ranked higher than a process with background activities an

activity that initiates a long-running operation might do well to start a service for that operation rather

than simply create a worker threadmdashparticularly if the operation will likely outlast the activity For

example an activity thats uploading a picture to a web site should start a service to perform the

upload so that the upload can continue in the background even if the user leaves the activity Using a

service guarantees that the operation will have at least service process priority regardless of what

happens to the activity This is the same reason that broadcast receivers should employ services

rather than simply put time-consuming operations in a thread

Threads

When an application is launched the system creates a thread of execution for the application called

main This thread is very important because it is in charge of dispatching events to the appropriate

user interface widgets including drawing events It is also the thread in which your application interacts

with components from the Android UI toolkit (components from the androidwidget and androidview

packages) As such the main thread is also sometimes called the UI thread

The system does not create a separate thread for each instance of a component All components that

run in the same process are instantiated in the UI thread and system calls to each component are

dispatched from that thread Consequently methods that respond to system callbacks (such as

onKeyDown() to report user actions or a lifecycle callback method) always run in the UI thread of the

process

For instance when the user touches a button on the screen your apps UI thread dispatches the touch

event to the widget which in turn sets its pressed state and posts an invalidate request to the event

queue The UI thread dequeues the request and notifies the widget that it should redraw itself

When your app performs intensive work in response to user interaction this single thread model can

yield poor performance unless you implement your application properly Specifically if everything is

happening in the UI thread performing long operations such as network access or database queries

will block the whole UI When the thread is blocked no events can be dispatched including drawing

events From the users perspective the application appears to hang Even worse if the UI thread is

blocked for more than a few seconds (about 5 seconds currently) the user is presented with the

infamous application not responding (ANR) dialog The user might then decide to quit your

application and uninstall it if they are unhappy

Additionally the Andoid UI toolkit is not thread-safe So you must not manipulate your UI from a

worker threadmdashyou must do all manipulation to your user interface from the UI thread Thus there are

simply two rules to Androids single thread model

1 Do not block the UI thread

2 Do not access the Android UI toolkit from outside the UI thread

Worker threads

Because of the single thread model described above its vital to the responsiveness of your

applications UI that you do not block the UI thread If you have operations to perform that are not

instantaneous you should make sure to do them in separate threads (background or worker

threads)

For example below is some code for a click listener that downloads an image from a separate thread

and displays it in an ImageView

public void onClick(View v) new Thread(new Runnable() public void run() Bitmap b = loadImageFromNetwork(httpexamplecomimagepng) mImageViewsetImageBitmap(b) )start()

At first this seems to work fine because it creates a new thread to handle the network operation

However it violates the second rule of the single-threaded model do not access the Android UI toolkit

from outside the UI threadmdashthis sample modifies the ImageView from the worker thread instead of the

UI thread This can result in undefined and unexpected behavior which can be difficult and time-

consuming to track down

To fix this problem Android offers several ways to access the UI thread from other threads Here is a

list of methods that can help

ActivityrunOnUiThread(Runnable)

Viewpost(Runnable)

ViewpostDelayed(Runnable long)

For example you can fix the above code by using the Viewpost(Runnable) method

public void onClick(View v) new Thread(new Runnable() public void run() final Bitmap bitmap = loadImageFromNetwork(httpexamplecomimagepng) mImageViewpost(new Runnable() public void run() mImageViewsetImageBitmap(bitmap) ) )start()

Now this implementation is thread-safe the network operation is done from a separate thread while

the ImageView is manipulated from the UI thread

However as the complexity of the operation grows this kind of code can get complicated and difficult

to maintain To handle more complex interactions with a worker thread you might consider using a

Handler in your worker thread to process messages delivered from the UI thread Perhaps the best

solution though is to extend the AsyncTask class which simplifies the execution of worker thread

tasks that need to interact with the UI

Using AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface It performs the blocking

operations in a worker thread and then publishes the results on the UI thread without requiring you to

handle threads andor handlers yourself

To use it you must subclass AsyncTask and implement the doInBackground() callback method which

runs in a pool of background threads To update your UI you should implement onPostExecute()

which delivers the result from doInBackground() and runs in the UI thread so you can safely update

your UI You can then run the task by calling execute() from the UI thread

For example you can implement the previous example using AsyncTask this way

public void onClick(View v) new DownloadImageTask()execute(httpexamplecomimagepng) private class DownloadImageTask extends AsyncTaskltString Void Bitmapgt The system calls this to perform work in a worker thread and delivers it the parameters given to AsyncTaskexecute() protected Bitmap doInBackground(String urls) return loadImageFromNetwork(urls[0])

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 48: 03 services

ltactivity androidname=TitleEditor androidlabel=stringtitle_edit_title androidtheme=androidstyleThemeDialoggt ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt ltactivitygt ltapplicationgt ltmanifestgt

The first activity NotesList is distinguished from the other activities by the fact that it operates on a

directory of notes (the note list) rather than on a single note It would generally serve as the initial user

interface into the application It can do three things as described by its three intent filters

1 ltintent-filtergt ltaction androidname=androidintentactionMAIN gt ltcategory androidname=androidintentcategoryLAUNCHER gt ltintent-filtergt

This filter declares the main entry point into the Note Pad application The standard MAIN action is an

entry point that does not require any other information in the Intent (no data specification for example)

and the LAUNCHER category says that this entry point should be listed in the application launcher

2 ltintent-filtergt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=androidintentactionPICK gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

This filter declares the things that the activity can do on a directory of notes It can allow the user to

view or edit the directory (via the VIEW and EDIT actions) or to pick a particular note from the

directory (via the PICK action)

The mimeType attribute of the ltdatagt element specifies the kind of data that these actions operate on

It indicates that the activity can get a Cursor over zero or more items (vndandroidcursordir) from a

content provider that holds Note Pad data (vndgooglenote) The Intent object that launches the

activity would include a content URI specifying the exact data of this type that the activity should open

Note also the DEFAULT category supplied in this filter Its there because the ContextstartActivity()

and ActivitystartActivityForResult() methods treat all intents as if they contained the DEFAULT

category mdash with just two exceptions

o Intents that explicitly name the target activity

o Intents consisting of the MAIN action and LAUNCHER category

Therefore the DEFAULT category is required for all filters mdash except for those with the MAIN action

and LAUNCHER category (Intent filters are not consulted for explicit intents)

3 ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

This filter describes the activitys ability to return a note selected by the user without requiring any

specification of the directory the user should choose from The GET_CONTENT action is similar to the

PICK action In both cases the activity returns the URI for a note selected by the user (In each case

its returned to the activity that called startActivityForResult() to start the NoteList activity) Here

however the caller specifies the type of data desired instead of the directory of data the user will be

picking from

The data type vndandroidcursoritemvndgooglenote indicates the type of data the activity can

return mdash a URI for a single note From the returned URI the caller can get a Cursor for exactly one

item (vndandroidcursoritem) from the content provider that holds Note Pad data (vndgooglenote)

In other words for the PICK action in the previous filter the data type indicates the type of data the

activity could display to the user For the GET_CONTENT filter it indicates the type of data the activity

can return to the caller

Given these capabilities the following intents will resolve to the NotesList activity

action androidintentactionMAIN

Launches the activity with no data specified

action androidintentactionMAIN

category androidintentcategoryLAUNCHER

Launches the activity with no data selected specified This is the actual intent used by the

Launcher to populate its top-level list All activities with filters that match this action and

category are added to the list

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of all the notes under

contentcomgoogleproviderNotePadnotes The user can then browse through the list and

get information about the items in it

action androidintentactionPICK

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of the notes under

contentcomgoogleproviderNotePadnotes The user can then pick a note from the list and

the activity will return the URI for that item back to the activity that started the NoteList activity

action androidintentactionGET_CONTENT

data type vndandroidcursoritemvndgooglenote

Asks the activity to supply a single item of Note Pad data

The second activity NoteEditor shows users a single note entry and allows them to edit it It can do

two things as described by its two intent filters

1 ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The first primary purpose of this activity is to enable the user to interact with a single note ampmdash to

either VIEW the note or EDIT it (The EDIT_NOTE category is a synonym for EDIT) The intent would

contain the URI for data matching the MIME type vndandroidcursoritemvndgooglenote mdash that is

the URI for a single specific note It would typically be a URI that was returned by the PICK or

GET_CONTENT actions of the NoteList activity

As before this filter lists the DEFAULT category so that the activity can be launched by intents that

dont explicitly specify the NoteEditor class

2 ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

The secondary purpose of this activity is to enable the user to create a new note which it will INSERT

into an existing directory of notes The intent would contain the URI for data matching the MIME type

vndandroidcursordirvndgooglenote mdash that is the URI for the directory where the note should be

placed

Given these capabilities the following intents will resolve to the NoteEditor activity

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID (For details on how content

URIs specify individual members of a group see Content Providers)

action androidintentactionEDIT

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID and to let the user edit it If

the user saves the changes the activity updates the data for the note in the content provider

action androidintentactionINSERT

data contentcomgoogleproviderNotePadnotes

Asks the activity to create a new empty note in the notes list at

contentcomgoogleproviderNotePadnotes and allow the user to edit it If the user saves the

note its URI is returned to the caller

The last activity TitleEditor enables the user to edit the title of a note This could be implemented by

directly invoking the activity (by explicitly setting its component name in the Intent) without using an

intent filter But here we take the opportunity to show how to publish alternative operations on existing

data

ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The single intent filter for this activity uses a custom action called

comandroidnotepadactionEDIT_TITLE It must be invoked on a specific note (data type

vndandroidcursoritemvndgooglenote) like the previous VIEW and EDIT actions However here the

activity displays the title contained in the note data not the content of the note itself

In addition to supporting the usual DEFAULT category the title editor also supports two other standard

categories ALTERNATIVE and SELECTED_ALTERNATIVE These categories identify activities that

can be presented to users in a menu of options (much as the LAUNCHER category identifies activities

that should be presented to user in the application launcher) Note that the filter also supplies an

explicit label (via androidlabel=stringresolve_title) to better control what users see when

presented with this activity as an alternative action to the data they are currently viewing (For more

information on these categories and building options menus see the

PackageManagerqueryIntentActivityOptions() and MenuaddIntentOptions() methods)

Given these capabilities the following intent will resolve to the TitleEditor activity

action comandroidnotepadactionEDIT_TITLE

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the title associated with note ID and allow the user to edit the title

Processes and Threads

When an application component starts and the application does not have any other components

running the Android system starts a new Linux process for the application with a single thread of

execution By default all components of the same application run in the same process and thread

(called the main thread) If an application component starts and there already exists a process for

that application (because another component from the application exists) then the component is

started within that process and uses the same thread of execution However you can arrange for

different components in your application to run in separate processes and you can create additional

threads for any process

This document discusses how processes and threads work in an Android application

Processes

By default all components of the same application run in the same process and most applications

should not change this However if you find that you need to control which process a certain

component belongs to you can do so in the manifest file

The manifest entry for each type of component elementmdashltactivitygt ltservicegt ltreceivergt and

ltprovidergtmdashsupports an androidprocess attribute that can specify a process in which that component

should run You can set this attribute so that each component runs in its own process or so that some

components share a process while others do not You can also set androidprocess so that

components of different applications run in the same processmdashprovided that the applications share the

same Linux user ID and are signed with the same certificates

The ltapplicationgt element also supports an androidprocess attribute to set a default value that

applies to all components

Android might 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 thats killed are consequently destroyed A process is started again for those components

when theres again work for them to do

When deciding which processes to kill the Android system weighs their relative importance to the

user For example it more readily shuts down a process hosting activities that are no longer visible on

screen compared to a process hosting visible activities The decision whether to terminate a process

therefore depends on the state of the components running in that process The rules used to decide

which processes to terminate is discussed below

Process lifecycle

The Android system tries to maintain an application process for as long as possible but eventually

needs to remove old processes to reclaim memory for new or more important processes To determine

which processes to keep and which to kill the system places each process into an importance

hierarchy based on the components running in the process and the state of those components

Processes with the lowest importance are eliminated first then those with the next lowest importance

and so on as necessary to recover system resources

There are five levels in the importance hierarchy The following list presents the different types of

processes in order of importance (the first process is most important and is killed last)

1 Foreground process

A process that is required for what the user is currently doing A process is considered to be in the

foreground if any of the following conditions are true

o It hosts an Activity that the user is interacting with (the Activitys onResume() method has been called)

o It hosts a Service thats bound to the activity that the user is interacting with

o It hosts a Service thats running in the foregroundmdashthe service has called startForeground()

o It hosts a Service thats executing one of its lifecycle callbacks (onCreate() onStart() or onDestroy())

o It hosts a BroadcastReceiver thats executing its onReceive() method

Generally only a few foreground processes exist at any given time They are killed only as a last

resortmdashif memory is so low that they cannot all continue to run Generally at that point the device has

reached a memory paging state so killing some foreground processes is required to keep the user

interface responsive

2 Visible process

A process that doesnt have any foreground components but still can affect what the user sees on

screen A process is considered to be visible if either of the following conditions are true

o It hosts an Activity that is not in the foreground but is still visible to the user (its onPause() method has

been called) This might occur for example if the foreground activity started a dialog which allows the

previous activity to be seen behind it

o It hosts a Service thats bound to a visible (or foreground) activity

A visible process is considered extremely important and will not be killed unless doing so is required to

keep all foreground processes running

3 Service process

A process that is running a service that has been started with the startService() method and does not

fall into either of the two higher categories Although service processes are not directly tied to anything

the user sees they are generally doing things that the user cares about (such as playing music in the

background or downloading data on the network) so the system keeps them running unless theres

not enough memory to retain them along with all foreground and visible processes

4 Background process

A process holding an activity thats not currently visible to the user (the activitys onStop() method has

been called) These processes have no direct impact on the user experience and the system can kill

them at any time to reclaim memory for a foreground visible or service process Usually there are

many background processes running so they are kept in an LRU (least recently used) list to ensure

that the process with the activity that was most recently seen by the user is the last to be killed If an

activity implements its lifecycle methods correctly and saves its current state killing its process will not

have a visible effect on the user experience because when the user navigates back to the activity the

activity restores all of its visible state See the Activities document for information about saving and

restoring state

5 Empty process

A process that doesnt hold any active application components The only reason to keep this kind of

process alive is for caching purposes to improve startup time the next time a component needs to run

in it The system often kills these processes in order to balance overall system resources between

process caches and the underlying kernel caches

Android ranks a process at the highest level it can based upon the importance of the components

currently active in the process For example if a process hosts a service and a visible activity the

process is ranked as a visible process not a service process

In addition a processs ranking might be increased because other processes are dependent on itmdasha

process that is serving another process can never be ranked lower than the process it is serving For

example if a content provider in process A is serving a client in process B or if a service in process A

is bound to a component in process B process A is always considered at least as important as

process B

Because a process running a service is ranked higher than a process with background activities an

activity that initiates a long-running operation might do well to start a service for that operation rather

than simply create a worker threadmdashparticularly if the operation will likely outlast the activity For

example an activity thats uploading a picture to a web site should start a service to perform the

upload so that the upload can continue in the background even if the user leaves the activity Using a

service guarantees that the operation will have at least service process priority regardless of what

happens to the activity This is the same reason that broadcast receivers should employ services

rather than simply put time-consuming operations in a thread

Threads

When an application is launched the system creates a thread of execution for the application called

main This thread is very important because it is in charge of dispatching events to the appropriate

user interface widgets including drawing events It is also the thread in which your application interacts

with components from the Android UI toolkit (components from the androidwidget and androidview

packages) As such the main thread is also sometimes called the UI thread

The system does not create a separate thread for each instance of a component All components that

run in the same process are instantiated in the UI thread and system calls to each component are

dispatched from that thread Consequently methods that respond to system callbacks (such as

onKeyDown() to report user actions or a lifecycle callback method) always run in the UI thread of the

process

For instance when the user touches a button on the screen your apps UI thread dispatches the touch

event to the widget which in turn sets its pressed state and posts an invalidate request to the event

queue The UI thread dequeues the request and notifies the widget that it should redraw itself

When your app performs intensive work in response to user interaction this single thread model can

yield poor performance unless you implement your application properly Specifically if everything is

happening in the UI thread performing long operations such as network access or database queries

will block the whole UI When the thread is blocked no events can be dispatched including drawing

events From the users perspective the application appears to hang Even worse if the UI thread is

blocked for more than a few seconds (about 5 seconds currently) the user is presented with the

infamous application not responding (ANR) dialog The user might then decide to quit your

application and uninstall it if they are unhappy

Additionally the Andoid UI toolkit is not thread-safe So you must not manipulate your UI from a

worker threadmdashyou must do all manipulation to your user interface from the UI thread Thus there are

simply two rules to Androids single thread model

1 Do not block the UI thread

2 Do not access the Android UI toolkit from outside the UI thread

Worker threads

Because of the single thread model described above its vital to the responsiveness of your

applications UI that you do not block the UI thread If you have operations to perform that are not

instantaneous you should make sure to do them in separate threads (background or worker

threads)

For example below is some code for a click listener that downloads an image from a separate thread

and displays it in an ImageView

public void onClick(View v) new Thread(new Runnable() public void run() Bitmap b = loadImageFromNetwork(httpexamplecomimagepng) mImageViewsetImageBitmap(b) )start()

At first this seems to work fine because it creates a new thread to handle the network operation

However it violates the second rule of the single-threaded model do not access the Android UI toolkit

from outside the UI threadmdashthis sample modifies the ImageView from the worker thread instead of the

UI thread This can result in undefined and unexpected behavior which can be difficult and time-

consuming to track down

To fix this problem Android offers several ways to access the UI thread from other threads Here is a

list of methods that can help

ActivityrunOnUiThread(Runnable)

Viewpost(Runnable)

ViewpostDelayed(Runnable long)

For example you can fix the above code by using the Viewpost(Runnable) method

public void onClick(View v) new Thread(new Runnable() public void run() final Bitmap bitmap = loadImageFromNetwork(httpexamplecomimagepng) mImageViewpost(new Runnable() public void run() mImageViewsetImageBitmap(bitmap) ) )start()

Now this implementation is thread-safe the network operation is done from a separate thread while

the ImageView is manipulated from the UI thread

However as the complexity of the operation grows this kind of code can get complicated and difficult

to maintain To handle more complex interactions with a worker thread you might consider using a

Handler in your worker thread to process messages delivered from the UI thread Perhaps the best

solution though is to extend the AsyncTask class which simplifies the execution of worker thread

tasks that need to interact with the UI

Using AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface It performs the blocking

operations in a worker thread and then publishes the results on the UI thread without requiring you to

handle threads andor handlers yourself

To use it you must subclass AsyncTask and implement the doInBackground() callback method which

runs in a pool of background threads To update your UI you should implement onPostExecute()

which delivers the result from doInBackground() and runs in the UI thread so you can safely update

your UI You can then run the task by calling execute() from the UI thread

For example you can implement the previous example using AsyncTask this way

public void onClick(View v) new DownloadImageTask()execute(httpexamplecomimagepng) private class DownloadImageTask extends AsyncTaskltString Void Bitmapgt The system calls this to perform work in a worker thread and delivers it the parameters given to AsyncTaskexecute() protected Bitmap doInBackground(String urls) return loadImageFromNetwork(urls[0])

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 49: 03 services

o Intents that explicitly name the target activity

o Intents consisting of the MAIN action and LAUNCHER category

Therefore the DEFAULT category is required for all filters mdash except for those with the MAIN action

and LAUNCHER category (Intent filters are not consulted for explicit intents)

3 ltintent-filtergt ltaction androidname=androidintentactionGET_CONTENT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

This filter describes the activitys ability to return a note selected by the user without requiring any

specification of the directory the user should choose from The GET_CONTENT action is similar to the

PICK action In both cases the activity returns the URI for a note selected by the user (In each case

its returned to the activity that called startActivityForResult() to start the NoteList activity) Here

however the caller specifies the type of data desired instead of the directory of data the user will be

picking from

The data type vndandroidcursoritemvndgooglenote indicates the type of data the activity can

return mdash a URI for a single note From the returned URI the caller can get a Cursor for exactly one

item (vndandroidcursoritem) from the content provider that holds Note Pad data (vndgooglenote)

In other words for the PICK action in the previous filter the data type indicates the type of data the

activity could display to the user For the GET_CONTENT filter it indicates the type of data the activity

can return to the caller

Given these capabilities the following intents will resolve to the NotesList activity

action androidintentactionMAIN

Launches the activity with no data specified

action androidintentactionMAIN

category androidintentcategoryLAUNCHER

Launches the activity with no data selected specified This is the actual intent used by the

Launcher to populate its top-level list All activities with filters that match this action and

category are added to the list

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of all the notes under

contentcomgoogleproviderNotePadnotes The user can then browse through the list and

get information about the items in it

action androidintentactionPICK

data contentcomgoogleproviderNotePadnotes

Asks the activity to display a list of the notes under

contentcomgoogleproviderNotePadnotes The user can then pick a note from the list and

the activity will return the URI for that item back to the activity that started the NoteList activity

action androidintentactionGET_CONTENT

data type vndandroidcursoritemvndgooglenote

Asks the activity to supply a single item of Note Pad data

The second activity NoteEditor shows users a single note entry and allows them to edit it It can do

two things as described by its two intent filters

1 ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The first primary purpose of this activity is to enable the user to interact with a single note ampmdash to

either VIEW the note or EDIT it (The EDIT_NOTE category is a synonym for EDIT) The intent would

contain the URI for data matching the MIME type vndandroidcursoritemvndgooglenote mdash that is

the URI for a single specific note It would typically be a URI that was returned by the PICK or

GET_CONTENT actions of the NoteList activity

As before this filter lists the DEFAULT category so that the activity can be launched by intents that

dont explicitly specify the NoteEditor class

2 ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

The secondary purpose of this activity is to enable the user to create a new note which it will INSERT

into an existing directory of notes The intent would contain the URI for data matching the MIME type

vndandroidcursordirvndgooglenote mdash that is the URI for the directory where the note should be

placed

Given these capabilities the following intents will resolve to the NoteEditor activity

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID (For details on how content

URIs specify individual members of a group see Content Providers)

action androidintentactionEDIT

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID and to let the user edit it If

the user saves the changes the activity updates the data for the note in the content provider

action androidintentactionINSERT

data contentcomgoogleproviderNotePadnotes

Asks the activity to create a new empty note in the notes list at

contentcomgoogleproviderNotePadnotes and allow the user to edit it If the user saves the

note its URI is returned to the caller

The last activity TitleEditor enables the user to edit the title of a note This could be implemented by

directly invoking the activity (by explicitly setting its component name in the Intent) without using an

intent filter But here we take the opportunity to show how to publish alternative operations on existing

data

ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The single intent filter for this activity uses a custom action called

comandroidnotepadactionEDIT_TITLE It must be invoked on a specific note (data type

vndandroidcursoritemvndgooglenote) like the previous VIEW and EDIT actions However here the

activity displays the title contained in the note data not the content of the note itself

In addition to supporting the usual DEFAULT category the title editor also supports two other standard

categories ALTERNATIVE and SELECTED_ALTERNATIVE These categories identify activities that

can be presented to users in a menu of options (much as the LAUNCHER category identifies activities

that should be presented to user in the application launcher) Note that the filter also supplies an

explicit label (via androidlabel=stringresolve_title) to better control what users see when

presented with this activity as an alternative action to the data they are currently viewing (For more

information on these categories and building options menus see the

PackageManagerqueryIntentActivityOptions() and MenuaddIntentOptions() methods)

Given these capabilities the following intent will resolve to the TitleEditor activity

action comandroidnotepadactionEDIT_TITLE

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the title associated with note ID and allow the user to edit the title

Processes and Threads

When an application component starts and the application does not have any other components

running the Android system starts a new Linux process for the application with a single thread of

execution By default all components of the same application run in the same process and thread

(called the main thread) If an application component starts and there already exists a process for

that application (because another component from the application exists) then the component is

started within that process and uses the same thread of execution However you can arrange for

different components in your application to run in separate processes and you can create additional

threads for any process

This document discusses how processes and threads work in an Android application

Processes

By default all components of the same application run in the same process and most applications

should not change this However if you find that you need to control which process a certain

component belongs to you can do so in the manifest file

The manifest entry for each type of component elementmdashltactivitygt ltservicegt ltreceivergt and

ltprovidergtmdashsupports an androidprocess attribute that can specify a process in which that component

should run You can set this attribute so that each component runs in its own process or so that some

components share a process while others do not You can also set androidprocess so that

components of different applications run in the same processmdashprovided that the applications share the

same Linux user ID and are signed with the same certificates

The ltapplicationgt element also supports an androidprocess attribute to set a default value that

applies to all components

Android might 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 thats killed are consequently destroyed A process is started again for those components

when theres again work for them to do

When deciding which processes to kill the Android system weighs their relative importance to the

user For example it more readily shuts down a process hosting activities that are no longer visible on

screen compared to a process hosting visible activities The decision whether to terminate a process

therefore depends on the state of the components running in that process The rules used to decide

which processes to terminate is discussed below

Process lifecycle

The Android system tries to maintain an application process for as long as possible but eventually

needs to remove old processes to reclaim memory for new or more important processes To determine

which processes to keep and which to kill the system places each process into an importance

hierarchy based on the components running in the process and the state of those components

Processes with the lowest importance are eliminated first then those with the next lowest importance

and so on as necessary to recover system resources

There are five levels in the importance hierarchy The following list presents the different types of

processes in order of importance (the first process is most important and is killed last)

1 Foreground process

A process that is required for what the user is currently doing A process is considered to be in the

foreground if any of the following conditions are true

o It hosts an Activity that the user is interacting with (the Activitys onResume() method has been called)

o It hosts a Service thats bound to the activity that the user is interacting with

o It hosts a Service thats running in the foregroundmdashthe service has called startForeground()

o It hosts a Service thats executing one of its lifecycle callbacks (onCreate() onStart() or onDestroy())

o It hosts a BroadcastReceiver thats executing its onReceive() method

Generally only a few foreground processes exist at any given time They are killed only as a last

resortmdashif memory is so low that they cannot all continue to run Generally at that point the device has

reached a memory paging state so killing some foreground processes is required to keep the user

interface responsive

2 Visible process

A process that doesnt have any foreground components but still can affect what the user sees on

screen A process is considered to be visible if either of the following conditions are true

o It hosts an Activity that is not in the foreground but is still visible to the user (its onPause() method has

been called) This might occur for example if the foreground activity started a dialog which allows the

previous activity to be seen behind it

o It hosts a Service thats bound to a visible (or foreground) activity

A visible process is considered extremely important and will not be killed unless doing so is required to

keep all foreground processes running

3 Service process

A process that is running a service that has been started with the startService() method and does not

fall into either of the two higher categories Although service processes are not directly tied to anything

the user sees they are generally doing things that the user cares about (such as playing music in the

background or downloading data on the network) so the system keeps them running unless theres

not enough memory to retain them along with all foreground and visible processes

4 Background process

A process holding an activity thats not currently visible to the user (the activitys onStop() method has

been called) These processes have no direct impact on the user experience and the system can kill

them at any time to reclaim memory for a foreground visible or service process Usually there are

many background processes running so they are kept in an LRU (least recently used) list to ensure

that the process with the activity that was most recently seen by the user is the last to be killed If an

activity implements its lifecycle methods correctly and saves its current state killing its process will not

have a visible effect on the user experience because when the user navigates back to the activity the

activity restores all of its visible state See the Activities document for information about saving and

restoring state

5 Empty process

A process that doesnt hold any active application components The only reason to keep this kind of

process alive is for caching purposes to improve startup time the next time a component needs to run

in it The system often kills these processes in order to balance overall system resources between

process caches and the underlying kernel caches

Android ranks a process at the highest level it can based upon the importance of the components

currently active in the process For example if a process hosts a service and a visible activity the

process is ranked as a visible process not a service process

In addition a processs ranking might be increased because other processes are dependent on itmdasha

process that is serving another process can never be ranked lower than the process it is serving For

example if a content provider in process A is serving a client in process B or if a service in process A

is bound to a component in process B process A is always considered at least as important as

process B

Because a process running a service is ranked higher than a process with background activities an

activity that initiates a long-running operation might do well to start a service for that operation rather

than simply create a worker threadmdashparticularly if the operation will likely outlast the activity For

example an activity thats uploading a picture to a web site should start a service to perform the

upload so that the upload can continue in the background even if the user leaves the activity Using a

service guarantees that the operation will have at least service process priority regardless of what

happens to the activity This is the same reason that broadcast receivers should employ services

rather than simply put time-consuming operations in a thread

Threads

When an application is launched the system creates a thread of execution for the application called

main This thread is very important because it is in charge of dispatching events to the appropriate

user interface widgets including drawing events It is also the thread in which your application interacts

with components from the Android UI toolkit (components from the androidwidget and androidview

packages) As such the main thread is also sometimes called the UI thread

The system does not create a separate thread for each instance of a component All components that

run in the same process are instantiated in the UI thread and system calls to each component are

dispatched from that thread Consequently methods that respond to system callbacks (such as

onKeyDown() to report user actions or a lifecycle callback method) always run in the UI thread of the

process

For instance when the user touches a button on the screen your apps UI thread dispatches the touch

event to the widget which in turn sets its pressed state and posts an invalidate request to the event

queue The UI thread dequeues the request and notifies the widget that it should redraw itself

When your app performs intensive work in response to user interaction this single thread model can

yield poor performance unless you implement your application properly Specifically if everything is

happening in the UI thread performing long operations such as network access or database queries

will block the whole UI When the thread is blocked no events can be dispatched including drawing

events From the users perspective the application appears to hang Even worse if the UI thread is

blocked for more than a few seconds (about 5 seconds currently) the user is presented with the

infamous application not responding (ANR) dialog The user might then decide to quit your

application and uninstall it if they are unhappy

Additionally the Andoid UI toolkit is not thread-safe So you must not manipulate your UI from a

worker threadmdashyou must do all manipulation to your user interface from the UI thread Thus there are

simply two rules to Androids single thread model

1 Do not block the UI thread

2 Do not access the Android UI toolkit from outside the UI thread

Worker threads

Because of the single thread model described above its vital to the responsiveness of your

applications UI that you do not block the UI thread If you have operations to perform that are not

instantaneous you should make sure to do them in separate threads (background or worker

threads)

For example below is some code for a click listener that downloads an image from a separate thread

and displays it in an ImageView

public void onClick(View v) new Thread(new Runnable() public void run() Bitmap b = loadImageFromNetwork(httpexamplecomimagepng) mImageViewsetImageBitmap(b) )start()

At first this seems to work fine because it creates a new thread to handle the network operation

However it violates the second rule of the single-threaded model do not access the Android UI toolkit

from outside the UI threadmdashthis sample modifies the ImageView from the worker thread instead of the

UI thread This can result in undefined and unexpected behavior which can be difficult and time-

consuming to track down

To fix this problem Android offers several ways to access the UI thread from other threads Here is a

list of methods that can help

ActivityrunOnUiThread(Runnable)

Viewpost(Runnable)

ViewpostDelayed(Runnable long)

For example you can fix the above code by using the Viewpost(Runnable) method

public void onClick(View v) new Thread(new Runnable() public void run() final Bitmap bitmap = loadImageFromNetwork(httpexamplecomimagepng) mImageViewpost(new Runnable() public void run() mImageViewsetImageBitmap(bitmap) ) )start()

Now this implementation is thread-safe the network operation is done from a separate thread while

the ImageView is manipulated from the UI thread

However as the complexity of the operation grows this kind of code can get complicated and difficult

to maintain To handle more complex interactions with a worker thread you might consider using a

Handler in your worker thread to process messages delivered from the UI thread Perhaps the best

solution though is to extend the AsyncTask class which simplifies the execution of worker thread

tasks that need to interact with the UI

Using AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface It performs the blocking

operations in a worker thread and then publishes the results on the UI thread without requiring you to

handle threads andor handlers yourself

To use it you must subclass AsyncTask and implement the doInBackground() callback method which

runs in a pool of background threads To update your UI you should implement onPostExecute()

which delivers the result from doInBackground() and runs in the UI thread so you can safely update

your UI You can then run the task by calling execute() from the UI thread

For example you can implement the previous example using AsyncTask this way

public void onClick(View v) new DownloadImageTask()execute(httpexamplecomimagepng) private class DownloadImageTask extends AsyncTaskltString Void Bitmapgt The system calls this to perform work in a worker thread and delivers it the parameters given to AsyncTaskexecute() protected Bitmap doInBackground(String urls) return loadImageFromNetwork(urls[0])

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 50: 03 services

Asks the activity to display a list of the notes under

contentcomgoogleproviderNotePadnotes The user can then pick a note from the list and

the activity will return the URI for that item back to the activity that started the NoteList activity

action androidintentactionGET_CONTENT

data type vndandroidcursoritemvndgooglenote

Asks the activity to supply a single item of Note Pad data

The second activity NoteEditor shows users a single note entry and allows them to edit it It can do

two things as described by its two intent filters

1 ltintent-filter androidlabel=stringresolve_editgt ltaction androidname=androidintentactionVIEW gt ltaction androidname=androidintentactionEDIT gt ltaction androidname=comandroidnotepadactionEDIT_NOTE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The first primary purpose of this activity is to enable the user to interact with a single note ampmdash to

either VIEW the note or EDIT it (The EDIT_NOTE category is a synonym for EDIT) The intent would

contain the URI for data matching the MIME type vndandroidcursoritemvndgooglenote mdash that is

the URI for a single specific note It would typically be a URI that was returned by the PICK or

GET_CONTENT actions of the NoteList activity

As before this filter lists the DEFAULT category so that the activity can be launched by intents that

dont explicitly specify the NoteEditor class

2 ltintent-filtergt ltaction androidname=androidintentactionINSERT gt ltcategory androidname=androidintentcategoryDEFAULT gt ltdata androidmimeType=vndandroidcursordirvndgooglenote gt ltintent-filtergt

The secondary purpose of this activity is to enable the user to create a new note which it will INSERT

into an existing directory of notes The intent would contain the URI for data matching the MIME type

vndandroidcursordirvndgooglenote mdash that is the URI for the directory where the note should be

placed

Given these capabilities the following intents will resolve to the NoteEditor activity

action androidintentactionVIEW

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID (For details on how content

URIs specify individual members of a group see Content Providers)

action androidintentactionEDIT

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID and to let the user edit it If

the user saves the changes the activity updates the data for the note in the content provider

action androidintentactionINSERT

data contentcomgoogleproviderNotePadnotes

Asks the activity to create a new empty note in the notes list at

contentcomgoogleproviderNotePadnotes and allow the user to edit it If the user saves the

note its URI is returned to the caller

The last activity TitleEditor enables the user to edit the title of a note This could be implemented by

directly invoking the activity (by explicitly setting its component name in the Intent) without using an

intent filter But here we take the opportunity to show how to publish alternative operations on existing

data

ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The single intent filter for this activity uses a custom action called

comandroidnotepadactionEDIT_TITLE It must be invoked on a specific note (data type

vndandroidcursoritemvndgooglenote) like the previous VIEW and EDIT actions However here the

activity displays the title contained in the note data not the content of the note itself

In addition to supporting the usual DEFAULT category the title editor also supports two other standard

categories ALTERNATIVE and SELECTED_ALTERNATIVE These categories identify activities that

can be presented to users in a menu of options (much as the LAUNCHER category identifies activities

that should be presented to user in the application launcher) Note that the filter also supplies an

explicit label (via androidlabel=stringresolve_title) to better control what users see when

presented with this activity as an alternative action to the data they are currently viewing (For more

information on these categories and building options menus see the

PackageManagerqueryIntentActivityOptions() and MenuaddIntentOptions() methods)

Given these capabilities the following intent will resolve to the TitleEditor activity

action comandroidnotepadactionEDIT_TITLE

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the title associated with note ID and allow the user to edit the title

Processes and Threads

When an application component starts and the application does not have any other components

running the Android system starts a new Linux process for the application with a single thread of

execution By default all components of the same application run in the same process and thread

(called the main thread) If an application component starts and there already exists a process for

that application (because another component from the application exists) then the component is

started within that process and uses the same thread of execution However you can arrange for

different components in your application to run in separate processes and you can create additional

threads for any process

This document discusses how processes and threads work in an Android application

Processes

By default all components of the same application run in the same process and most applications

should not change this However if you find that you need to control which process a certain

component belongs to you can do so in the manifest file

The manifest entry for each type of component elementmdashltactivitygt ltservicegt ltreceivergt and

ltprovidergtmdashsupports an androidprocess attribute that can specify a process in which that component

should run You can set this attribute so that each component runs in its own process or so that some

components share a process while others do not You can also set androidprocess so that

components of different applications run in the same processmdashprovided that the applications share the

same Linux user ID and are signed with the same certificates

The ltapplicationgt element also supports an androidprocess attribute to set a default value that

applies to all components

Android might 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 thats killed are consequently destroyed A process is started again for those components

when theres again work for them to do

When deciding which processes to kill the Android system weighs their relative importance to the

user For example it more readily shuts down a process hosting activities that are no longer visible on

screen compared to a process hosting visible activities The decision whether to terminate a process

therefore depends on the state of the components running in that process The rules used to decide

which processes to terminate is discussed below

Process lifecycle

The Android system tries to maintain an application process for as long as possible but eventually

needs to remove old processes to reclaim memory for new or more important processes To determine

which processes to keep and which to kill the system places each process into an importance

hierarchy based on the components running in the process and the state of those components

Processes with the lowest importance are eliminated first then those with the next lowest importance

and so on as necessary to recover system resources

There are five levels in the importance hierarchy The following list presents the different types of

processes in order of importance (the first process is most important and is killed last)

1 Foreground process

A process that is required for what the user is currently doing A process is considered to be in the

foreground if any of the following conditions are true

o It hosts an Activity that the user is interacting with (the Activitys onResume() method has been called)

o It hosts a Service thats bound to the activity that the user is interacting with

o It hosts a Service thats running in the foregroundmdashthe service has called startForeground()

o It hosts a Service thats executing one of its lifecycle callbacks (onCreate() onStart() or onDestroy())

o It hosts a BroadcastReceiver thats executing its onReceive() method

Generally only a few foreground processes exist at any given time They are killed only as a last

resortmdashif memory is so low that they cannot all continue to run Generally at that point the device has

reached a memory paging state so killing some foreground processes is required to keep the user

interface responsive

2 Visible process

A process that doesnt have any foreground components but still can affect what the user sees on

screen A process is considered to be visible if either of the following conditions are true

o It hosts an Activity that is not in the foreground but is still visible to the user (its onPause() method has

been called) This might occur for example if the foreground activity started a dialog which allows the

previous activity to be seen behind it

o It hosts a Service thats bound to a visible (or foreground) activity

A visible process is considered extremely important and will not be killed unless doing so is required to

keep all foreground processes running

3 Service process

A process that is running a service that has been started with the startService() method and does not

fall into either of the two higher categories Although service processes are not directly tied to anything

the user sees they are generally doing things that the user cares about (such as playing music in the

background or downloading data on the network) so the system keeps them running unless theres

not enough memory to retain them along with all foreground and visible processes

4 Background process

A process holding an activity thats not currently visible to the user (the activitys onStop() method has

been called) These processes have no direct impact on the user experience and the system can kill

them at any time to reclaim memory for a foreground visible or service process Usually there are

many background processes running so they are kept in an LRU (least recently used) list to ensure

that the process with the activity that was most recently seen by the user is the last to be killed If an

activity implements its lifecycle methods correctly and saves its current state killing its process will not

have a visible effect on the user experience because when the user navigates back to the activity the

activity restores all of its visible state See the Activities document for information about saving and

restoring state

5 Empty process

A process that doesnt hold any active application components The only reason to keep this kind of

process alive is for caching purposes to improve startup time the next time a component needs to run

in it The system often kills these processes in order to balance overall system resources between

process caches and the underlying kernel caches

Android ranks a process at the highest level it can based upon the importance of the components

currently active in the process For example if a process hosts a service and a visible activity the

process is ranked as a visible process not a service process

In addition a processs ranking might be increased because other processes are dependent on itmdasha

process that is serving another process can never be ranked lower than the process it is serving For

example if a content provider in process A is serving a client in process B or if a service in process A

is bound to a component in process B process A is always considered at least as important as

process B

Because a process running a service is ranked higher than a process with background activities an

activity that initiates a long-running operation might do well to start a service for that operation rather

than simply create a worker threadmdashparticularly if the operation will likely outlast the activity For

example an activity thats uploading a picture to a web site should start a service to perform the

upload so that the upload can continue in the background even if the user leaves the activity Using a

service guarantees that the operation will have at least service process priority regardless of what

happens to the activity This is the same reason that broadcast receivers should employ services

rather than simply put time-consuming operations in a thread

Threads

When an application is launched the system creates a thread of execution for the application called

main This thread is very important because it is in charge of dispatching events to the appropriate

user interface widgets including drawing events It is also the thread in which your application interacts

with components from the Android UI toolkit (components from the androidwidget and androidview

packages) As such the main thread is also sometimes called the UI thread

The system does not create a separate thread for each instance of a component All components that

run in the same process are instantiated in the UI thread and system calls to each component are

dispatched from that thread Consequently methods that respond to system callbacks (such as

onKeyDown() to report user actions or a lifecycle callback method) always run in the UI thread of the

process

For instance when the user touches a button on the screen your apps UI thread dispatches the touch

event to the widget which in turn sets its pressed state and posts an invalidate request to the event

queue The UI thread dequeues the request and notifies the widget that it should redraw itself

When your app performs intensive work in response to user interaction this single thread model can

yield poor performance unless you implement your application properly Specifically if everything is

happening in the UI thread performing long operations such as network access or database queries

will block the whole UI When the thread is blocked no events can be dispatched including drawing

events From the users perspective the application appears to hang Even worse if the UI thread is

blocked for more than a few seconds (about 5 seconds currently) the user is presented with the

infamous application not responding (ANR) dialog The user might then decide to quit your

application and uninstall it if they are unhappy

Additionally the Andoid UI toolkit is not thread-safe So you must not manipulate your UI from a

worker threadmdashyou must do all manipulation to your user interface from the UI thread Thus there are

simply two rules to Androids single thread model

1 Do not block the UI thread

2 Do not access the Android UI toolkit from outside the UI thread

Worker threads

Because of the single thread model described above its vital to the responsiveness of your

applications UI that you do not block the UI thread If you have operations to perform that are not

instantaneous you should make sure to do them in separate threads (background or worker

threads)

For example below is some code for a click listener that downloads an image from a separate thread

and displays it in an ImageView

public void onClick(View v) new Thread(new Runnable() public void run() Bitmap b = loadImageFromNetwork(httpexamplecomimagepng) mImageViewsetImageBitmap(b) )start()

At first this seems to work fine because it creates a new thread to handle the network operation

However it violates the second rule of the single-threaded model do not access the Android UI toolkit

from outside the UI threadmdashthis sample modifies the ImageView from the worker thread instead of the

UI thread This can result in undefined and unexpected behavior which can be difficult and time-

consuming to track down

To fix this problem Android offers several ways to access the UI thread from other threads Here is a

list of methods that can help

ActivityrunOnUiThread(Runnable)

Viewpost(Runnable)

ViewpostDelayed(Runnable long)

For example you can fix the above code by using the Viewpost(Runnable) method

public void onClick(View v) new Thread(new Runnable() public void run() final Bitmap bitmap = loadImageFromNetwork(httpexamplecomimagepng) mImageViewpost(new Runnable() public void run() mImageViewsetImageBitmap(bitmap) ) )start()

Now this implementation is thread-safe the network operation is done from a separate thread while

the ImageView is manipulated from the UI thread

However as the complexity of the operation grows this kind of code can get complicated and difficult

to maintain To handle more complex interactions with a worker thread you might consider using a

Handler in your worker thread to process messages delivered from the UI thread Perhaps the best

solution though is to extend the AsyncTask class which simplifies the execution of worker thread

tasks that need to interact with the UI

Using AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface It performs the blocking

operations in a worker thread and then publishes the results on the UI thread without requiring you to

handle threads andor handlers yourself

To use it you must subclass AsyncTask and implement the doInBackground() callback method which

runs in a pool of background threads To update your UI you should implement onPostExecute()

which delivers the result from doInBackground() and runs in the UI thread so you can safely update

your UI You can then run the task by calling execute() from the UI thread

For example you can implement the previous example using AsyncTask this way

public void onClick(View v) new DownloadImageTask()execute(httpexamplecomimagepng) private class DownloadImageTask extends AsyncTaskltString Void Bitmapgt The system calls this to perform work in a worker thread and delivers it the parameters given to AsyncTaskexecute() protected Bitmap doInBackground(String urls) return loadImageFromNetwork(urls[0])

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 51: 03 services

action androidintentactionEDIT

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the content of the note identified by ID and to let the user edit it If

the user saves the changes the activity updates the data for the note in the content provider

action androidintentactionINSERT

data contentcomgoogleproviderNotePadnotes

Asks the activity to create a new empty note in the notes list at

contentcomgoogleproviderNotePadnotes and allow the user to edit it If the user saves the

note its URI is returned to the caller

The last activity TitleEditor enables the user to edit the title of a note This could be implemented by

directly invoking the activity (by explicitly setting its component name in the Intent) without using an

intent filter But here we take the opportunity to show how to publish alternative operations on existing

data

ltintent-filter androidlabel=stringresolve_titlegt ltaction androidname=comandroidnotepadactionEDIT_TITLE gt ltcategory androidname=androidintentcategoryDEFAULT gt ltcategory androidname=androidintentcategoryALTERNATIVE gt ltcategory androidname=androidintentcategorySELECTED_ALTERNATIVE gt ltdata androidmimeType=vndandroidcursoritemvndgooglenote gt ltintent-filtergt

The single intent filter for this activity uses a custom action called

comandroidnotepadactionEDIT_TITLE It must be invoked on a specific note (data type

vndandroidcursoritemvndgooglenote) like the previous VIEW and EDIT actions However here the

activity displays the title contained in the note data not the content of the note itself

In addition to supporting the usual DEFAULT category the title editor also supports two other standard

categories ALTERNATIVE and SELECTED_ALTERNATIVE These categories identify activities that

can be presented to users in a menu of options (much as the LAUNCHER category identifies activities

that should be presented to user in the application launcher) Note that the filter also supplies an

explicit label (via androidlabel=stringresolve_title) to better control what users see when

presented with this activity as an alternative action to the data they are currently viewing (For more

information on these categories and building options menus see the

PackageManagerqueryIntentActivityOptions() and MenuaddIntentOptions() methods)

Given these capabilities the following intent will resolve to the TitleEditor activity

action comandroidnotepadactionEDIT_TITLE

data contentcomgoogleproviderNotePadnotesID

Asks the activity to display the title associated with note ID and allow the user to edit the title

Processes and Threads

When an application component starts and the application does not have any other components

running the Android system starts a new Linux process for the application with a single thread of

execution By default all components of the same application run in the same process and thread

(called the main thread) If an application component starts and there already exists a process for

that application (because another component from the application exists) then the component is

started within that process and uses the same thread of execution However you can arrange for

different components in your application to run in separate processes and you can create additional

threads for any process

This document discusses how processes and threads work in an Android application

Processes

By default all components of the same application run in the same process and most applications

should not change this However if you find that you need to control which process a certain

component belongs to you can do so in the manifest file

The manifest entry for each type of component elementmdashltactivitygt ltservicegt ltreceivergt and

ltprovidergtmdashsupports an androidprocess attribute that can specify a process in which that component

should run You can set this attribute so that each component runs in its own process or so that some

components share a process while others do not You can also set androidprocess so that

components of different applications run in the same processmdashprovided that the applications share the

same Linux user ID and are signed with the same certificates

The ltapplicationgt element also supports an androidprocess attribute to set a default value that

applies to all components

Android might 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 thats killed are consequently destroyed A process is started again for those components

when theres again work for them to do

When deciding which processes to kill the Android system weighs their relative importance to the

user For example it more readily shuts down a process hosting activities that are no longer visible on

screen compared to a process hosting visible activities The decision whether to terminate a process

therefore depends on the state of the components running in that process The rules used to decide

which processes to terminate is discussed below

Process lifecycle

The Android system tries to maintain an application process for as long as possible but eventually

needs to remove old processes to reclaim memory for new or more important processes To determine

which processes to keep and which to kill the system places each process into an importance

hierarchy based on the components running in the process and the state of those components

Processes with the lowest importance are eliminated first then those with the next lowest importance

and so on as necessary to recover system resources

There are five levels in the importance hierarchy The following list presents the different types of

processes in order of importance (the first process is most important and is killed last)

1 Foreground process

A process that is required for what the user is currently doing A process is considered to be in the

foreground if any of the following conditions are true

o It hosts an Activity that the user is interacting with (the Activitys onResume() method has been called)

o It hosts a Service thats bound to the activity that the user is interacting with

o It hosts a Service thats running in the foregroundmdashthe service has called startForeground()

o It hosts a Service thats executing one of its lifecycle callbacks (onCreate() onStart() or onDestroy())

o It hosts a BroadcastReceiver thats executing its onReceive() method

Generally only a few foreground processes exist at any given time They are killed only as a last

resortmdashif memory is so low that they cannot all continue to run Generally at that point the device has

reached a memory paging state so killing some foreground processes is required to keep the user

interface responsive

2 Visible process

A process that doesnt have any foreground components but still can affect what the user sees on

screen A process is considered to be visible if either of the following conditions are true

o It hosts an Activity that is not in the foreground but is still visible to the user (its onPause() method has

been called) This might occur for example if the foreground activity started a dialog which allows the

previous activity to be seen behind it

o It hosts a Service thats bound to a visible (or foreground) activity

A visible process is considered extremely important and will not be killed unless doing so is required to

keep all foreground processes running

3 Service process

A process that is running a service that has been started with the startService() method and does not

fall into either of the two higher categories Although service processes are not directly tied to anything

the user sees they are generally doing things that the user cares about (such as playing music in the

background or downloading data on the network) so the system keeps them running unless theres

not enough memory to retain them along with all foreground and visible processes

4 Background process

A process holding an activity thats not currently visible to the user (the activitys onStop() method has

been called) These processes have no direct impact on the user experience and the system can kill

them at any time to reclaim memory for a foreground visible or service process Usually there are

many background processes running so they are kept in an LRU (least recently used) list to ensure

that the process with the activity that was most recently seen by the user is the last to be killed If an

activity implements its lifecycle methods correctly and saves its current state killing its process will not

have a visible effect on the user experience because when the user navigates back to the activity the

activity restores all of its visible state See the Activities document for information about saving and

restoring state

5 Empty process

A process that doesnt hold any active application components The only reason to keep this kind of

process alive is for caching purposes to improve startup time the next time a component needs to run

in it The system often kills these processes in order to balance overall system resources between

process caches and the underlying kernel caches

Android ranks a process at the highest level it can based upon the importance of the components

currently active in the process For example if a process hosts a service and a visible activity the

process is ranked as a visible process not a service process

In addition a processs ranking might be increased because other processes are dependent on itmdasha

process that is serving another process can never be ranked lower than the process it is serving For

example if a content provider in process A is serving a client in process B or if a service in process A

is bound to a component in process B process A is always considered at least as important as

process B

Because a process running a service is ranked higher than a process with background activities an

activity that initiates a long-running operation might do well to start a service for that operation rather

than simply create a worker threadmdashparticularly if the operation will likely outlast the activity For

example an activity thats uploading a picture to a web site should start a service to perform the

upload so that the upload can continue in the background even if the user leaves the activity Using a

service guarantees that the operation will have at least service process priority regardless of what

happens to the activity This is the same reason that broadcast receivers should employ services

rather than simply put time-consuming operations in a thread

Threads

When an application is launched the system creates a thread of execution for the application called

main This thread is very important because it is in charge of dispatching events to the appropriate

user interface widgets including drawing events It is also the thread in which your application interacts

with components from the Android UI toolkit (components from the androidwidget and androidview

packages) As such the main thread is also sometimes called the UI thread

The system does not create a separate thread for each instance of a component All components that

run in the same process are instantiated in the UI thread and system calls to each component are

dispatched from that thread Consequently methods that respond to system callbacks (such as

onKeyDown() to report user actions or a lifecycle callback method) always run in the UI thread of the

process

For instance when the user touches a button on the screen your apps UI thread dispatches the touch

event to the widget which in turn sets its pressed state and posts an invalidate request to the event

queue The UI thread dequeues the request and notifies the widget that it should redraw itself

When your app performs intensive work in response to user interaction this single thread model can

yield poor performance unless you implement your application properly Specifically if everything is

happening in the UI thread performing long operations such as network access or database queries

will block the whole UI When the thread is blocked no events can be dispatched including drawing

events From the users perspective the application appears to hang Even worse if the UI thread is

blocked for more than a few seconds (about 5 seconds currently) the user is presented with the

infamous application not responding (ANR) dialog The user might then decide to quit your

application and uninstall it if they are unhappy

Additionally the Andoid UI toolkit is not thread-safe So you must not manipulate your UI from a

worker threadmdashyou must do all manipulation to your user interface from the UI thread Thus there are

simply two rules to Androids single thread model

1 Do not block the UI thread

2 Do not access the Android UI toolkit from outside the UI thread

Worker threads

Because of the single thread model described above its vital to the responsiveness of your

applications UI that you do not block the UI thread If you have operations to perform that are not

instantaneous you should make sure to do them in separate threads (background or worker

threads)

For example below is some code for a click listener that downloads an image from a separate thread

and displays it in an ImageView

public void onClick(View v) new Thread(new Runnable() public void run() Bitmap b = loadImageFromNetwork(httpexamplecomimagepng) mImageViewsetImageBitmap(b) )start()

At first this seems to work fine because it creates a new thread to handle the network operation

However it violates the second rule of the single-threaded model do not access the Android UI toolkit

from outside the UI threadmdashthis sample modifies the ImageView from the worker thread instead of the

UI thread This can result in undefined and unexpected behavior which can be difficult and time-

consuming to track down

To fix this problem Android offers several ways to access the UI thread from other threads Here is a

list of methods that can help

ActivityrunOnUiThread(Runnable)

Viewpost(Runnable)

ViewpostDelayed(Runnable long)

For example you can fix the above code by using the Viewpost(Runnable) method

public void onClick(View v) new Thread(new Runnable() public void run() final Bitmap bitmap = loadImageFromNetwork(httpexamplecomimagepng) mImageViewpost(new Runnable() public void run() mImageViewsetImageBitmap(bitmap) ) )start()

Now this implementation is thread-safe the network operation is done from a separate thread while

the ImageView is manipulated from the UI thread

However as the complexity of the operation grows this kind of code can get complicated and difficult

to maintain To handle more complex interactions with a worker thread you might consider using a

Handler in your worker thread to process messages delivered from the UI thread Perhaps the best

solution though is to extend the AsyncTask class which simplifies the execution of worker thread

tasks that need to interact with the UI

Using AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface It performs the blocking

operations in a worker thread and then publishes the results on the UI thread without requiring you to

handle threads andor handlers yourself

To use it you must subclass AsyncTask and implement the doInBackground() callback method which

runs in a pool of background threads To update your UI you should implement onPostExecute()

which delivers the result from doInBackground() and runs in the UI thread so you can safely update

your UI You can then run the task by calling execute() from the UI thread

For example you can implement the previous example using AsyncTask this way

public void onClick(View v) new DownloadImageTask()execute(httpexamplecomimagepng) private class DownloadImageTask extends AsyncTaskltString Void Bitmapgt The system calls this to perform work in a worker thread and delivers it the parameters given to AsyncTaskexecute() protected Bitmap doInBackground(String urls) return loadImageFromNetwork(urls[0])

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 52: 03 services

When an application component starts and the application does not have any other components

running the Android system starts a new Linux process for the application with a single thread of

execution By default all components of the same application run in the same process and thread

(called the main thread) If an application component starts and there already exists a process for

that application (because another component from the application exists) then the component is

started within that process and uses the same thread of execution However you can arrange for

different components in your application to run in separate processes and you can create additional

threads for any process

This document discusses how processes and threads work in an Android application

Processes

By default all components of the same application run in the same process and most applications

should not change this However if you find that you need to control which process a certain

component belongs to you can do so in the manifest file

The manifest entry for each type of component elementmdashltactivitygt ltservicegt ltreceivergt and

ltprovidergtmdashsupports an androidprocess attribute that can specify a process in which that component

should run You can set this attribute so that each component runs in its own process or so that some

components share a process while others do not You can also set androidprocess so that

components of different applications run in the same processmdashprovided that the applications share the

same Linux user ID and are signed with the same certificates

The ltapplicationgt element also supports an androidprocess attribute to set a default value that

applies to all components

Android might 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 thats killed are consequently destroyed A process is started again for those components

when theres again work for them to do

When deciding which processes to kill the Android system weighs their relative importance to the

user For example it more readily shuts down a process hosting activities that are no longer visible on

screen compared to a process hosting visible activities The decision whether to terminate a process

therefore depends on the state of the components running in that process The rules used to decide

which processes to terminate is discussed below

Process lifecycle

The Android system tries to maintain an application process for as long as possible but eventually

needs to remove old processes to reclaim memory for new or more important processes To determine

which processes to keep and which to kill the system places each process into an importance

hierarchy based on the components running in the process and the state of those components

Processes with the lowest importance are eliminated first then those with the next lowest importance

and so on as necessary to recover system resources

There are five levels in the importance hierarchy The following list presents the different types of

processes in order of importance (the first process is most important and is killed last)

1 Foreground process

A process that is required for what the user is currently doing A process is considered to be in the

foreground if any of the following conditions are true

o It hosts an Activity that the user is interacting with (the Activitys onResume() method has been called)

o It hosts a Service thats bound to the activity that the user is interacting with

o It hosts a Service thats running in the foregroundmdashthe service has called startForeground()

o It hosts a Service thats executing one of its lifecycle callbacks (onCreate() onStart() or onDestroy())

o It hosts a BroadcastReceiver thats executing its onReceive() method

Generally only a few foreground processes exist at any given time They are killed only as a last

resortmdashif memory is so low that they cannot all continue to run Generally at that point the device has

reached a memory paging state so killing some foreground processes is required to keep the user

interface responsive

2 Visible process

A process that doesnt have any foreground components but still can affect what the user sees on

screen A process is considered to be visible if either of the following conditions are true

o It hosts an Activity that is not in the foreground but is still visible to the user (its onPause() method has

been called) This might occur for example if the foreground activity started a dialog which allows the

previous activity to be seen behind it

o It hosts a Service thats bound to a visible (or foreground) activity

A visible process is considered extremely important and will not be killed unless doing so is required to

keep all foreground processes running

3 Service process

A process that is running a service that has been started with the startService() method and does not

fall into either of the two higher categories Although service processes are not directly tied to anything

the user sees they are generally doing things that the user cares about (such as playing music in the

background or downloading data on the network) so the system keeps them running unless theres

not enough memory to retain them along with all foreground and visible processes

4 Background process

A process holding an activity thats not currently visible to the user (the activitys onStop() method has

been called) These processes have no direct impact on the user experience and the system can kill

them at any time to reclaim memory for a foreground visible or service process Usually there are

many background processes running so they are kept in an LRU (least recently used) list to ensure

that the process with the activity that was most recently seen by the user is the last to be killed If an

activity implements its lifecycle methods correctly and saves its current state killing its process will not

have a visible effect on the user experience because when the user navigates back to the activity the

activity restores all of its visible state See the Activities document for information about saving and

restoring state

5 Empty process

A process that doesnt hold any active application components The only reason to keep this kind of

process alive is for caching purposes to improve startup time the next time a component needs to run

in it The system often kills these processes in order to balance overall system resources between

process caches and the underlying kernel caches

Android ranks a process at the highest level it can based upon the importance of the components

currently active in the process For example if a process hosts a service and a visible activity the

process is ranked as a visible process not a service process

In addition a processs ranking might be increased because other processes are dependent on itmdasha

process that is serving another process can never be ranked lower than the process it is serving For

example if a content provider in process A is serving a client in process B or if a service in process A

is bound to a component in process B process A is always considered at least as important as

process B

Because a process running a service is ranked higher than a process with background activities an

activity that initiates a long-running operation might do well to start a service for that operation rather

than simply create a worker threadmdashparticularly if the operation will likely outlast the activity For

example an activity thats uploading a picture to a web site should start a service to perform the

upload so that the upload can continue in the background even if the user leaves the activity Using a

service guarantees that the operation will have at least service process priority regardless of what

happens to the activity This is the same reason that broadcast receivers should employ services

rather than simply put time-consuming operations in a thread

Threads

When an application is launched the system creates a thread of execution for the application called

main This thread is very important because it is in charge of dispatching events to the appropriate

user interface widgets including drawing events It is also the thread in which your application interacts

with components from the Android UI toolkit (components from the androidwidget and androidview

packages) As such the main thread is also sometimes called the UI thread

The system does not create a separate thread for each instance of a component All components that

run in the same process are instantiated in the UI thread and system calls to each component are

dispatched from that thread Consequently methods that respond to system callbacks (such as

onKeyDown() to report user actions or a lifecycle callback method) always run in the UI thread of the

process

For instance when the user touches a button on the screen your apps UI thread dispatches the touch

event to the widget which in turn sets its pressed state and posts an invalidate request to the event

queue The UI thread dequeues the request and notifies the widget that it should redraw itself

When your app performs intensive work in response to user interaction this single thread model can

yield poor performance unless you implement your application properly Specifically if everything is

happening in the UI thread performing long operations such as network access or database queries

will block the whole UI When the thread is blocked no events can be dispatched including drawing

events From the users perspective the application appears to hang Even worse if the UI thread is

blocked for more than a few seconds (about 5 seconds currently) the user is presented with the

infamous application not responding (ANR) dialog The user might then decide to quit your

application and uninstall it if they are unhappy

Additionally the Andoid UI toolkit is not thread-safe So you must not manipulate your UI from a

worker threadmdashyou must do all manipulation to your user interface from the UI thread Thus there are

simply two rules to Androids single thread model

1 Do not block the UI thread

2 Do not access the Android UI toolkit from outside the UI thread

Worker threads

Because of the single thread model described above its vital to the responsiveness of your

applications UI that you do not block the UI thread If you have operations to perform that are not

instantaneous you should make sure to do them in separate threads (background or worker

threads)

For example below is some code for a click listener that downloads an image from a separate thread

and displays it in an ImageView

public void onClick(View v) new Thread(new Runnable() public void run() Bitmap b = loadImageFromNetwork(httpexamplecomimagepng) mImageViewsetImageBitmap(b) )start()

At first this seems to work fine because it creates a new thread to handle the network operation

However it violates the second rule of the single-threaded model do not access the Android UI toolkit

from outside the UI threadmdashthis sample modifies the ImageView from the worker thread instead of the

UI thread This can result in undefined and unexpected behavior which can be difficult and time-

consuming to track down

To fix this problem Android offers several ways to access the UI thread from other threads Here is a

list of methods that can help

ActivityrunOnUiThread(Runnable)

Viewpost(Runnable)

ViewpostDelayed(Runnable long)

For example you can fix the above code by using the Viewpost(Runnable) method

public void onClick(View v) new Thread(new Runnable() public void run() final Bitmap bitmap = loadImageFromNetwork(httpexamplecomimagepng) mImageViewpost(new Runnable() public void run() mImageViewsetImageBitmap(bitmap) ) )start()

Now this implementation is thread-safe the network operation is done from a separate thread while

the ImageView is manipulated from the UI thread

However as the complexity of the operation grows this kind of code can get complicated and difficult

to maintain To handle more complex interactions with a worker thread you might consider using a

Handler in your worker thread to process messages delivered from the UI thread Perhaps the best

solution though is to extend the AsyncTask class which simplifies the execution of worker thread

tasks that need to interact with the UI

Using AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface It performs the blocking

operations in a worker thread and then publishes the results on the UI thread without requiring you to

handle threads andor handlers yourself

To use it you must subclass AsyncTask and implement the doInBackground() callback method which

runs in a pool of background threads To update your UI you should implement onPostExecute()

which delivers the result from doInBackground() and runs in the UI thread so you can safely update

your UI You can then run the task by calling execute() from the UI thread

For example you can implement the previous example using AsyncTask this way

public void onClick(View v) new DownloadImageTask()execute(httpexamplecomimagepng) private class DownloadImageTask extends AsyncTaskltString Void Bitmapgt The system calls this to perform work in a worker thread and delivers it the parameters given to AsyncTaskexecute() protected Bitmap doInBackground(String urls) return loadImageFromNetwork(urls[0])

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 53: 03 services

There are five levels in the importance hierarchy The following list presents the different types of

processes in order of importance (the first process is most important and is killed last)

1 Foreground process

A process that is required for what the user is currently doing A process is considered to be in the

foreground if any of the following conditions are true

o It hosts an Activity that the user is interacting with (the Activitys onResume() method has been called)

o It hosts a Service thats bound to the activity that the user is interacting with

o It hosts a Service thats running in the foregroundmdashthe service has called startForeground()

o It hosts a Service thats executing one of its lifecycle callbacks (onCreate() onStart() or onDestroy())

o It hosts a BroadcastReceiver thats executing its onReceive() method

Generally only a few foreground processes exist at any given time They are killed only as a last

resortmdashif memory is so low that they cannot all continue to run Generally at that point the device has

reached a memory paging state so killing some foreground processes is required to keep the user

interface responsive

2 Visible process

A process that doesnt have any foreground components but still can affect what the user sees on

screen A process is considered to be visible if either of the following conditions are true

o It hosts an Activity that is not in the foreground but is still visible to the user (its onPause() method has

been called) This might occur for example if the foreground activity started a dialog which allows the

previous activity to be seen behind it

o It hosts a Service thats bound to a visible (or foreground) activity

A visible process is considered extremely important and will not be killed unless doing so is required to

keep all foreground processes running

3 Service process

A process that is running a service that has been started with the startService() method and does not

fall into either of the two higher categories Although service processes are not directly tied to anything

the user sees they are generally doing things that the user cares about (such as playing music in the

background or downloading data on the network) so the system keeps them running unless theres

not enough memory to retain them along with all foreground and visible processes

4 Background process

A process holding an activity thats not currently visible to the user (the activitys onStop() method has

been called) These processes have no direct impact on the user experience and the system can kill

them at any time to reclaim memory for a foreground visible or service process Usually there are

many background processes running so they are kept in an LRU (least recently used) list to ensure

that the process with the activity that was most recently seen by the user is the last to be killed If an

activity implements its lifecycle methods correctly and saves its current state killing its process will not

have a visible effect on the user experience because when the user navigates back to the activity the

activity restores all of its visible state See the Activities document for information about saving and

restoring state

5 Empty process

A process that doesnt hold any active application components The only reason to keep this kind of

process alive is for caching purposes to improve startup time the next time a component needs to run

in it The system often kills these processes in order to balance overall system resources between

process caches and the underlying kernel caches

Android ranks a process at the highest level it can based upon the importance of the components

currently active in the process For example if a process hosts a service and a visible activity the

process is ranked as a visible process not a service process

In addition a processs ranking might be increased because other processes are dependent on itmdasha

process that is serving another process can never be ranked lower than the process it is serving For

example if a content provider in process A is serving a client in process B or if a service in process A

is bound to a component in process B process A is always considered at least as important as

process B

Because a process running a service is ranked higher than a process with background activities an

activity that initiates a long-running operation might do well to start a service for that operation rather

than simply create a worker threadmdashparticularly if the operation will likely outlast the activity For

example an activity thats uploading a picture to a web site should start a service to perform the

upload so that the upload can continue in the background even if the user leaves the activity Using a

service guarantees that the operation will have at least service process priority regardless of what

happens to the activity This is the same reason that broadcast receivers should employ services

rather than simply put time-consuming operations in a thread

Threads

When an application is launched the system creates a thread of execution for the application called

main This thread is very important because it is in charge of dispatching events to the appropriate

user interface widgets including drawing events It is also the thread in which your application interacts

with components from the Android UI toolkit (components from the androidwidget and androidview

packages) As such the main thread is also sometimes called the UI thread

The system does not create a separate thread for each instance of a component All components that

run in the same process are instantiated in the UI thread and system calls to each component are

dispatched from that thread Consequently methods that respond to system callbacks (such as

onKeyDown() to report user actions or a lifecycle callback method) always run in the UI thread of the

process

For instance when the user touches a button on the screen your apps UI thread dispatches the touch

event to the widget which in turn sets its pressed state and posts an invalidate request to the event

queue The UI thread dequeues the request and notifies the widget that it should redraw itself

When your app performs intensive work in response to user interaction this single thread model can

yield poor performance unless you implement your application properly Specifically if everything is

happening in the UI thread performing long operations such as network access or database queries

will block the whole UI When the thread is blocked no events can be dispatched including drawing

events From the users perspective the application appears to hang Even worse if the UI thread is

blocked for more than a few seconds (about 5 seconds currently) the user is presented with the

infamous application not responding (ANR) dialog The user might then decide to quit your

application and uninstall it if they are unhappy

Additionally the Andoid UI toolkit is not thread-safe So you must not manipulate your UI from a

worker threadmdashyou must do all manipulation to your user interface from the UI thread Thus there are

simply two rules to Androids single thread model

1 Do not block the UI thread

2 Do not access the Android UI toolkit from outside the UI thread

Worker threads

Because of the single thread model described above its vital to the responsiveness of your

applications UI that you do not block the UI thread If you have operations to perform that are not

instantaneous you should make sure to do them in separate threads (background or worker

threads)

For example below is some code for a click listener that downloads an image from a separate thread

and displays it in an ImageView

public void onClick(View v) new Thread(new Runnable() public void run() Bitmap b = loadImageFromNetwork(httpexamplecomimagepng) mImageViewsetImageBitmap(b) )start()

At first this seems to work fine because it creates a new thread to handle the network operation

However it violates the second rule of the single-threaded model do not access the Android UI toolkit

from outside the UI threadmdashthis sample modifies the ImageView from the worker thread instead of the

UI thread This can result in undefined and unexpected behavior which can be difficult and time-

consuming to track down

To fix this problem Android offers several ways to access the UI thread from other threads Here is a

list of methods that can help

ActivityrunOnUiThread(Runnable)

Viewpost(Runnable)

ViewpostDelayed(Runnable long)

For example you can fix the above code by using the Viewpost(Runnable) method

public void onClick(View v) new Thread(new Runnable() public void run() final Bitmap bitmap = loadImageFromNetwork(httpexamplecomimagepng) mImageViewpost(new Runnable() public void run() mImageViewsetImageBitmap(bitmap) ) )start()

Now this implementation is thread-safe the network operation is done from a separate thread while

the ImageView is manipulated from the UI thread

However as the complexity of the operation grows this kind of code can get complicated and difficult

to maintain To handle more complex interactions with a worker thread you might consider using a

Handler in your worker thread to process messages delivered from the UI thread Perhaps the best

solution though is to extend the AsyncTask class which simplifies the execution of worker thread

tasks that need to interact with the UI

Using AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface It performs the blocking

operations in a worker thread and then publishes the results on the UI thread without requiring you to

handle threads andor handlers yourself

To use it you must subclass AsyncTask and implement the doInBackground() callback method which

runs in a pool of background threads To update your UI you should implement onPostExecute()

which delivers the result from doInBackground() and runs in the UI thread so you can safely update

your UI You can then run the task by calling execute() from the UI thread

For example you can implement the previous example using AsyncTask this way

public void onClick(View v) new DownloadImageTask()execute(httpexamplecomimagepng) private class DownloadImageTask extends AsyncTaskltString Void Bitmapgt The system calls this to perform work in a worker thread and delivers it the parameters given to AsyncTaskexecute() protected Bitmap doInBackground(String urls) return loadImageFromNetwork(urls[0])

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 54: 03 services

activity restores all of its visible state See the Activities document for information about saving and

restoring state

5 Empty process

A process that doesnt hold any active application components The only reason to keep this kind of

process alive is for caching purposes to improve startup time the next time a component needs to run

in it The system often kills these processes in order to balance overall system resources between

process caches and the underlying kernel caches

Android ranks a process at the highest level it can based upon the importance of the components

currently active in the process For example if a process hosts a service and a visible activity the

process is ranked as a visible process not a service process

In addition a processs ranking might be increased because other processes are dependent on itmdasha

process that is serving another process can never be ranked lower than the process it is serving For

example if a content provider in process A is serving a client in process B or if a service in process A

is bound to a component in process B process A is always considered at least as important as

process B

Because a process running a service is ranked higher than a process with background activities an

activity that initiates a long-running operation might do well to start a service for that operation rather

than simply create a worker threadmdashparticularly if the operation will likely outlast the activity For

example an activity thats uploading a picture to a web site should start a service to perform the

upload so that the upload can continue in the background even if the user leaves the activity Using a

service guarantees that the operation will have at least service process priority regardless of what

happens to the activity This is the same reason that broadcast receivers should employ services

rather than simply put time-consuming operations in a thread

Threads

When an application is launched the system creates a thread of execution for the application called

main This thread is very important because it is in charge of dispatching events to the appropriate

user interface widgets including drawing events It is also the thread in which your application interacts

with components from the Android UI toolkit (components from the androidwidget and androidview

packages) As such the main thread is also sometimes called the UI thread

The system does not create a separate thread for each instance of a component All components that

run in the same process are instantiated in the UI thread and system calls to each component are

dispatched from that thread Consequently methods that respond to system callbacks (such as

onKeyDown() to report user actions or a lifecycle callback method) always run in the UI thread of the

process

For instance when the user touches a button on the screen your apps UI thread dispatches the touch

event to the widget which in turn sets its pressed state and posts an invalidate request to the event

queue The UI thread dequeues the request and notifies the widget that it should redraw itself

When your app performs intensive work in response to user interaction this single thread model can

yield poor performance unless you implement your application properly Specifically if everything is

happening in the UI thread performing long operations such as network access or database queries

will block the whole UI When the thread is blocked no events can be dispatched including drawing

events From the users perspective the application appears to hang Even worse if the UI thread is

blocked for more than a few seconds (about 5 seconds currently) the user is presented with the

infamous application not responding (ANR) dialog The user might then decide to quit your

application and uninstall it if they are unhappy

Additionally the Andoid UI toolkit is not thread-safe So you must not manipulate your UI from a

worker threadmdashyou must do all manipulation to your user interface from the UI thread Thus there are

simply two rules to Androids single thread model

1 Do not block the UI thread

2 Do not access the Android UI toolkit from outside the UI thread

Worker threads

Because of the single thread model described above its vital to the responsiveness of your

applications UI that you do not block the UI thread If you have operations to perform that are not

instantaneous you should make sure to do them in separate threads (background or worker

threads)

For example below is some code for a click listener that downloads an image from a separate thread

and displays it in an ImageView

public void onClick(View v) new Thread(new Runnable() public void run() Bitmap b = loadImageFromNetwork(httpexamplecomimagepng) mImageViewsetImageBitmap(b) )start()

At first this seems to work fine because it creates a new thread to handle the network operation

However it violates the second rule of the single-threaded model do not access the Android UI toolkit

from outside the UI threadmdashthis sample modifies the ImageView from the worker thread instead of the

UI thread This can result in undefined and unexpected behavior which can be difficult and time-

consuming to track down

To fix this problem Android offers several ways to access the UI thread from other threads Here is a

list of methods that can help

ActivityrunOnUiThread(Runnable)

Viewpost(Runnable)

ViewpostDelayed(Runnable long)

For example you can fix the above code by using the Viewpost(Runnable) method

public void onClick(View v) new Thread(new Runnable() public void run() final Bitmap bitmap = loadImageFromNetwork(httpexamplecomimagepng) mImageViewpost(new Runnable() public void run() mImageViewsetImageBitmap(bitmap) ) )start()

Now this implementation is thread-safe the network operation is done from a separate thread while

the ImageView is manipulated from the UI thread

However as the complexity of the operation grows this kind of code can get complicated and difficult

to maintain To handle more complex interactions with a worker thread you might consider using a

Handler in your worker thread to process messages delivered from the UI thread Perhaps the best

solution though is to extend the AsyncTask class which simplifies the execution of worker thread

tasks that need to interact with the UI

Using AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface It performs the blocking

operations in a worker thread and then publishes the results on the UI thread without requiring you to

handle threads andor handlers yourself

To use it you must subclass AsyncTask and implement the doInBackground() callback method which

runs in a pool of background threads To update your UI you should implement onPostExecute()

which delivers the result from doInBackground() and runs in the UI thread so you can safely update

your UI You can then run the task by calling execute() from the UI thread

For example you can implement the previous example using AsyncTask this way

public void onClick(View v) new DownloadImageTask()execute(httpexamplecomimagepng) private class DownloadImageTask extends AsyncTaskltString Void Bitmapgt The system calls this to perform work in a worker thread and delivers it the parameters given to AsyncTaskexecute() protected Bitmap doInBackground(String urls) return loadImageFromNetwork(urls[0])

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 55: 03 services

When your app performs intensive work in response to user interaction this single thread model can

yield poor performance unless you implement your application properly Specifically if everything is

happening in the UI thread performing long operations such as network access or database queries

will block the whole UI When the thread is blocked no events can be dispatched including drawing

events From the users perspective the application appears to hang Even worse if the UI thread is

blocked for more than a few seconds (about 5 seconds currently) the user is presented with the

infamous application not responding (ANR) dialog The user might then decide to quit your

application and uninstall it if they are unhappy

Additionally the Andoid UI toolkit is not thread-safe So you must not manipulate your UI from a

worker threadmdashyou must do all manipulation to your user interface from the UI thread Thus there are

simply two rules to Androids single thread model

1 Do not block the UI thread

2 Do not access the Android UI toolkit from outside the UI thread

Worker threads

Because of the single thread model described above its vital to the responsiveness of your

applications UI that you do not block the UI thread If you have operations to perform that are not

instantaneous you should make sure to do them in separate threads (background or worker

threads)

For example below is some code for a click listener that downloads an image from a separate thread

and displays it in an ImageView

public void onClick(View v) new Thread(new Runnable() public void run() Bitmap b = loadImageFromNetwork(httpexamplecomimagepng) mImageViewsetImageBitmap(b) )start()

At first this seems to work fine because it creates a new thread to handle the network operation

However it violates the second rule of the single-threaded model do not access the Android UI toolkit

from outside the UI threadmdashthis sample modifies the ImageView from the worker thread instead of the

UI thread This can result in undefined and unexpected behavior which can be difficult and time-

consuming to track down

To fix this problem Android offers several ways to access the UI thread from other threads Here is a

list of methods that can help

ActivityrunOnUiThread(Runnable)

Viewpost(Runnable)

ViewpostDelayed(Runnable long)

For example you can fix the above code by using the Viewpost(Runnable) method

public void onClick(View v) new Thread(new Runnable() public void run() final Bitmap bitmap = loadImageFromNetwork(httpexamplecomimagepng) mImageViewpost(new Runnable() public void run() mImageViewsetImageBitmap(bitmap) ) )start()

Now this implementation is thread-safe the network operation is done from a separate thread while

the ImageView is manipulated from the UI thread

However as the complexity of the operation grows this kind of code can get complicated and difficult

to maintain To handle more complex interactions with a worker thread you might consider using a

Handler in your worker thread to process messages delivered from the UI thread Perhaps the best

solution though is to extend the AsyncTask class which simplifies the execution of worker thread

tasks that need to interact with the UI

Using AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface It performs the blocking

operations in a worker thread and then publishes the results on the UI thread without requiring you to

handle threads andor handlers yourself

To use it you must subclass AsyncTask and implement the doInBackground() callback method which

runs in a pool of background threads To update your UI you should implement onPostExecute()

which delivers the result from doInBackground() and runs in the UI thread so you can safely update

your UI You can then run the task by calling execute() from the UI thread

For example you can implement the previous example using AsyncTask this way

public void onClick(View v) new DownloadImageTask()execute(httpexamplecomimagepng) private class DownloadImageTask extends AsyncTaskltString Void Bitmapgt The system calls this to perform work in a worker thread and delivers it the parameters given to AsyncTaskexecute() protected Bitmap doInBackground(String urls) return loadImageFromNetwork(urls[0])

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 56: 03 services

For example you can fix the above code by using the Viewpost(Runnable) method

public void onClick(View v) new Thread(new Runnable() public void run() final Bitmap bitmap = loadImageFromNetwork(httpexamplecomimagepng) mImageViewpost(new Runnable() public void run() mImageViewsetImageBitmap(bitmap) ) )start()

Now this implementation is thread-safe the network operation is done from a separate thread while

the ImageView is manipulated from the UI thread

However as the complexity of the operation grows this kind of code can get complicated and difficult

to maintain To handle more complex interactions with a worker thread you might consider using a

Handler in your worker thread to process messages delivered from the UI thread Perhaps the best

solution though is to extend the AsyncTask class which simplifies the execution of worker thread

tasks that need to interact with the UI

Using AsyncTask

AsyncTask allows you to perform asynchronous work on your user interface It performs the blocking

operations in a worker thread and then publishes the results on the UI thread without requiring you to

handle threads andor handlers yourself

To use it you must subclass AsyncTask and implement the doInBackground() callback method which

runs in a pool of background threads To update your UI you should implement onPostExecute()

which delivers the result from doInBackground() and runs in the UI thread so you can safely update

your UI You can then run the task by calling execute() from the UI thread

For example you can implement the previous example using AsyncTask this way

public void onClick(View v) new DownloadImageTask()execute(httpexamplecomimagepng) private class DownloadImageTask extends AsyncTaskltString Void Bitmapgt The system calls this to perform work in a worker thread and delivers it the parameters given to AsyncTaskexecute() protected Bitmap doInBackground(String urls) return loadImageFromNetwork(urls[0])

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 57: 03 services

The system calls this to perform work in the UI thread and delivers the result from doInBackground() protected void onPostExecute(Bitmap result) mImageViewsetImageBitmap(result)

Now the UI is safe and the code is simpler because it separates the work into the part that should be

done on a worker thread and the part that should be done on the UI thread

You should read the AsyncTask reference for a full understanding on how to use this class but here is

a quick overview of how it works

You can specify the type of the parameters the progress values and the final value of the task using

generics

The method doInBackground() executes automatically on a worker thread

onPreExecute() onPostExecute() and onProgressUpdate() are all invoked on the UI thread

The value returned by doInBackground() is sent to onPostExecute()

You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the

UI thread

You can cancel the task at any time from any thread

Caution Another problem you might encounter when using a worker thread is unexpected

restarts in your activity due to a runtime configuration change (such as when the user changes the

screen orientation) which may destroy your worker thread To see how you can persist your task

during one of these restarts and how to properly cancel the task when the activity is destroyed

see the source code for the Shelves sample application

Thread-safe methods

In some situations the methods you implement might 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 remotelymdashsuch as methods in a bound service

When a call on a method implemented in an IBinder originates in the same process in which the

IBinder is running the method is executed in the callers thread However when the call originates in

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

maintains in the same process as the IBinder (its not executed in the UI thread of the process) For

example whereas a services onBind() method would be called from the UI thread of the services

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

implements RPC methods) would be called from threads in the pool Because a service 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 requestsmdashthe methods query() insert()

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide

Page 58: 03 services

delete() update() and getType()mdashare called from a pool of threads in the content providers process

not the UI thread for the process Because these methods might be called from any number of threads

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

Interprocess Communication

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls

(RPCs) in which a method is called by an activity or other application component but executed

remotely (in another process) with any result returned back to the caller This entails decomposing a

method call and its 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 then reassembling and

reenacting the call there Return values are then transmitted in the opposite direction Android provides

all the code to perform these IPC transactions so you can focus on defining and implementing the

RPC programming interface

To perform IPC your application must bind to a service using bindService() For more information

see the Services developer guide