From d83a98f4ce9cfa908f5c54bbd70f03eec07e7553 Mon Sep 17 00:00:00 2001 From: The Android Open Source Project Date: Tue, 3 Mar 2009 18:28:45 -0800 Subject: auto import from //depot/cupcake/@135843 --- docs/html/guide/topics/fundamentals.jd | 1726 -------------------------------- 1 file changed, 1726 deletions(-) delete mode 100644 docs/html/guide/topics/fundamentals.jd (limited to 'docs/html/guide/topics/fundamentals.jd') diff --git a/docs/html/guide/topics/fundamentals.jd b/docs/html/guide/topics/fundamentals.jd deleted file mode 100644 index 3c7f419..0000000 --- a/docs/html/guide/topics/fundamentals.jd +++ /dev/null @@ -1,1726 +0,0 @@ -page.title=Application Fundamentals -@jd:body - -
-
-

Key classes

-
    -
  1. {@link android.app.Activity}
  2. -
  3. {@link android.app.Service}
  4. -
  5. {@link android.content.BroadcastReceiver}
  6. -
  7. {@link android.content.ContentProvider}
  8. -
  9. {@link android.content.Intent}
  10. -
- -

In this document

-
    -
  1. Application Components -
      -
    1. Activating components: intents
    2. -
    3. Shutting down components
    4. -
    5. The manifest file
    6. -
    7. Intent filters
    8. -
  2. -
  3. Activities and Tasks -
      -
    1. Affinities and new tasks
    2. -
    3. Launch modes
    4. -
    5. Clearing the stack
    6. -
    7. Starting tasks
    8. -
  4. -
  5. Processes and Threads -
      -
    1. Processes
    2. -
    3. Threads
    4. -
    5. Remote procedure calls
    6. -
    7. Thread-safe methods
    8. -
  6. -
  7. Component Lifecycles -
      -
    1. Activity lifecycle
    2. -
    3. Service lifecycle
    4. -
    5. Broadcast receiver lifecycle
    6. -
    7. Processes and lifecycles
    8. -
  8. -
-
-
- -

-Android applications are written in the Java programming language. -The compiled Java code — along with any data and resource -files required by the application — is bundled by the -aapt -tool into an Android package, an archive file -marked by an {@code .apk} suffix. This file is the vehicle -for distributing the application and installing it on mobile devices; -it's the file users download to their devices. All the code in a -single {@code .apk} file is considered to be one application. -

- -

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

- - - -

-It's possible to arrange for two applications to share the same user ID, -in which case they will be able to see each other's files. To conserve -system resources, applications with the same ID can also arrange to run -in the same Linux process, sharing the same VM. -

- - -

Application Components

- -

-A central feature of Android is that one application can make use of elements -of other applications (provided those applications permit it). For example, -if your application needs to display a scrolling list of images and another -application has developed a suitable scroller and made it available to others, -you can call upon that scroller to do the work, rather than develop your own. -Your application doesn't incorporate the code of the other application or -link to it. Rather, it simply starts up that piece of the other application -when the need arises. -

- -

-For this to work, the system must be able to start an application process -when any part of it is needed, and instantiate the Java objects for that part. -Therefore, unlike applications on most other systems, Android applications don't -have a single entry point for everything in the application (no {@code main()} -function, for example). Rather, they have essential components that -the system can instantiate and run as needed. There are four types of components: -

- -
- -
Activities
-
An activity presents a visual user interface for one focused endeavor -the user can undertake. For example, an activity might present a list of -menu items users can choose from or it might display photographs along -with their captions. A text messaging application might have one activity -that shows a list of contacts to send messages to, a second activity to write -the message to the chosen contact, and other activities to review old messages -or change settings. Though they work together to form a cohesive user interface, -each activity is independent of the others. -Each one is implemented as a subclass of the {@link android.app.Activity} base class. - -

-An application might consist of just one activity or, like the text messaging -application just mentioned, it may contain several. -What the activities are, and how many there are depends, of course, on the -application and its design. Typically, one of the activities is marked -as the first one that should be presented to the user when the application is -launched. Moving from one activity to another is accomplished by having the -current activity start the next one. -

- -

-Each activity is given a default window to draw in. Typically, the window -fills the screen, but it might be smaller than the screen and float on top -of other windows. An activity can also make use of additional windows — -for example, a pop-up dialog that calls for a user response in the midst of -the activity, or a window that presents users with vital information when they -select a particular item on-screen. -

- -

-The visual content of the window is provided by a hierarchy of views — -objects derived from the base {@link android.view.View} class. Each view -controls a particular rectangular space within the window. Parent views -contain and organize the layout of their children. Leaf views (those at the -bottom of the hierarchy) draw in the rectangles they control and respond to -user actions directed at that space. Thus, views are where the activity's -interaction with the user takes place. For example, a view might display -a small image and initiate an action when the user taps that image. Android -has a number of ready-made views that you can use — including buttons, -text fields, scroll bars, menu items, check boxes, and more. -

- -

-A view hierarchy is placed within an activity's window by the -{@link android.app.Activity#setContentView Activity.setContentView()} -method. The content view is the View object at the root of the hierarchy. -(See the separate User Interface -document for more information on views and the hierarchy.) -

- -

Services
-
A service doesn't have a visual user interface, but rather runs in -the background for an indefinite period of time. For example, a service might -play background music as the user attends to other matters, or it might fetch -data over the network or calculate something and provide the result to activities -that need it. Each service extends the {@link android.app.Service} base class. - -

-A prime example is a media player playing songs from a play list. The player -application would probably have one or more activities that allow the user to -choose songs and start playing them. However, the music playback itself would -not be handled by an activity because users will expect the music to keep -playing even after they leave the player and begin something different. -To keep the music going, the media player activity could start a service to run -in the background. The system would then keep the music playback service running -even after the activity that started it leaves the screen. -

- -

-It's possible to connect to (bind to) an ongoing service (and start the service -if it's not already running). While connected, you can communicate with the -service through an interface that the service exposes. For the music service, -this interface might allow users to pause, rewind, stop, and restart the playback. -

- -

-Like activities and the other components, services run in the main thread of -the application process. So that they won't block other components or the -user interface, they often spawn another thread for time-consuming tasks -(like music playback). See Processes and Threads, later. -

- -
Broadcast receivers
-
A broadcast receiver is a component that does nothing but -receive and react to broadcast announcements. Many broadcasts originate in -system code — for example, announcements that the timezone has changed, -that the battery is low, that a picture has been taken, or that the user -changed a language preference. Applications can also initiate broadcasts -— for example, to let other applications know that some data has been -downloaded to the device and is available for them to use. - -

-An application can have any number of broadcast receivers to respond to any -announcements it considers important. All receivers extend the {@link -android.content.BroadcastReceiver} base class. -

- -

-Broadcast receivers do not display a user interface. However, they may start -an activity in response to the information they receive, or they may use -the {@link android.app.NotificationManager} to alert the user. Notifications -can get the user's attention in various ways — flashing -the backlight, vibrating the device, playing a sound, and so on. They -typically place a persistent icon in the status bar, which users can open to -get the message. -

- -
Content providers
-
A content provider makes a specific set of the application's data -available to other applications. The data can be stored in the file system, -in an SQLite database, or in any other manner that makes sense. -The content provider extends the {@link android.content.ContentProvider} base -class to implement a standard set of methods that enable other applications -to retrieve and store data of the type it controls. However, applications -do not call these methods directly. Rather they use a {@link -android.content.ContentResolver} object and call its methods instead. -A ContentResolver can talk to any content provider; it cooperates with the -provider to manage any interprocess communication that's involved. - -

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

- -
- -

-Whenever there's a request that should be handled by a particular component, -Android makes sure that the application process of the component is running, -starting it if necessary, and that an appropriate instance of the component -is available, creating the instance if necessary. -

- - -

Activating components: intents

- -

-Content providers are activated when they're targeted by a request from a -ContentResolver. The other three components — activities, services, -and broadcast receivers — are activated by asynchronous messages -called intents. An intent is an {@link android.content.Intent} -object that holds the content of the message. For activities and services, -it names the action being requested and specifies the URI of the data to -act on, among other things. For example, it might convey a request for -an activity to present an image to the user or let the user edit some -text. For broadcast receivers, the Intent object names the action being -announced. For example, it might announce to interested parties that the -camera button has been pressed. -

- -

-There are separate methods for activiating each type of component: -

- - - -

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

- - -

Shutting down components

- -

-A content provider is active only while it's responding to a request from -a ContentResolver. And a broadcast receiver is active only while it's -responding to a broadcast message. So there's no need to explicitly shut -down these components. -

- -

-Activities, on the other hand, provide the user interface. They're -in a long-running conversation with the user and may remain active, -even when idle, as long as the conversation continues. Similarly, services -may also remain running for a long time. So Android has methods to shut -down activities and services in an orderly way: -

- - - -

-Components might also be shut down by the system when they are no longer being -used or when Android must reclaim memory for more active components. A later -section, Component Lifecycles, discusses this -possibility and its ramifications in more detail. -

- - -

The manifest file

- -

-Before Android can start an application component, it must learn that -the component exists. Therefore, applications declare their components -in a manifest file that's bundled into the Android package, the {@code .apk} -file that also holds the application's code, files, and resources. -

- -

-The manifest is a structured XML file and is always named AndroidManifest.xml -for all applications. It does a number of things in addition to declaring the -application's components, such as naming any libraries the application needs -to be linked against (besides the default Android library) and identifying -any permissions the application expects to be granted. -

- -

-But the principal task of the manifest is to inform Android about the application's -components. For example, an activity might be declared as follows: -

- -
<?xml version="1.0" encoding="utf-8"?>
-<manifest . . . >
-    <application . . . >
-        <activity android:name="com.example.project.FreneticActivity"
-                  android:icon="@drawable/small_pic.png"
-                  android:label="@string/freneticLabel" 
-                  . . .  >
-        </activity>
-        . . .
-    </application>
-</manifest>
- -

-The {@code name} attribute of the -<activity> -element names the {@link android.app.Activity} subclass that implements the -activity. The {@code icon} and {@code label} attributes point to -resource files containing an icon and label that can be displayed -to users to represent the activity. -

- -

-The other components are declared in a similar way — -<service> -elements for services, -<receiver> -elements for broadcast receivers, and -<provider> -elements for content providers. Activities, services, and content providers -that are not declared in the manifest are not visible to the system and are -consequently never run. However, broadcast receivers can either be -declared in the manifest, or they can be created dynamically in code -(as {@link android.content.BroadcastReceiver} objects) -and registered with the system by calling -{@link android.content.Context#registerReceiver Context.registerReceiver()}. -

- -

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

- - -

Intent filters

- -

-An Intent object can explicitly name a target component. If it does, -Android finds that component (based on the declarations in the manifest -file) and activates it. But if a target is not explicitly named, -Android must locate the best component to respond to the intent. -It does so by comparing the Intent object to the intent filters -of potential targets. A component's intent filters inform Android of -the kinds of intents the component is able to handle. Like other -essential information about the component, they're declared in the -manifest file. Here's an extension of the previous example that adds -two intent filters to the activity: -

- -
<?xml version="1.0" encoding="utf-8"?>
-<manifest . . . >
-    <application . . . >
-        <activity android:name="com.example.project.FreneticActivity"
-                  android:icon="@drawable/small_pic.png"
-                  android:label="@string/freneticLabel" 
-                  . . .  >
-            <intent-filter . . . >
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-            <intent-filter . . . >
-                <action android:name="com.example.project.BOUNCE" />
-                <data android:type="image/jpeg" />
-                <category android:name="android.intent.category.DEFAULT" />
-            </intent-filter>
-        </activity>
-        . . .
-    </application>
-</manifest>
- -

-The first filter in the example — the combination of the action -"{@code android.intent.action.MAIN}" and the category -"{@code android.intent.category.LAUNCHER}" — is a common one. -It marks the activity as one that should be represented in the -application launcher, the screen listing applications users can launch -on the device. In other words, the activity is the entry point for -the application, the initial one users would see when they choose -the application in the launcher. -

- -

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

- -

-A component can have any number of intent filters, each one declaring a -different set of capabilities. If it doesn't have any filters, it can -be activated only by intents that explicitly name the component as the -target. -

- -

-For a broadcast receiver that's created and registered in code, the -intent filter is instantiated directly as an {@link android.content.IntentFilter} -object. All other filters are set up in the manifest. -

- -

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

- - -

Activities and Tasks

- -

-As noted earlier, one activity can start another, including one defined -in a different application. Suppose, for example, that you'd like -to let users display a street map of some location. There's already an -activity that can do that, so all your activity needs to do is put together -an Intent object with the required information and pass it to -{@code startActivity()}. The map viewer will display the map. When the user -hits the BACK key, your activity will reappear on screen. -

- -

-To the user, it will seem as if the map viewer is part of the same application -as your activity, even though it's defined in another application and runs in -that application's process. Android maintains this user experience by keeping -both activities in the same task. Simply put, a task is what the user -experiences as an "application." It's a group of related activities, arranged -in a stack. The root activity in the stack is the one that began the task -— typically, it's an activity the user selected in the application launcher. -The activity at the top of the stack is one that's currently running — -the one that is the focus for user actions. When one activity starts another, -the new activity is pushed on the stack; it becomes the running activity. -The previous activity remains in the stack. When the user presses the BACK key, -the current activity is popped from the stack, and the previous one resumes as -the running activity. -

- -

-The stack contains objects, so if a task has more than one instance of the same -Activity subclass open — multiple map viewers, for example — the -stack has a separate entry for each instance. Activities in the stack are never -rearranged, only pushed and popped. -

- -

-A task is a stack of activities, not a class or an element in the manifest file. -So there's no way to set values for a task independently of its activities. -Values for the task as a whole are set in the root activity. For example, the -next section will talk about the "affinity of a task"; that value is read from -the affinity set for the task's root activity. -

- -

-All the activities in a task move together as a unit. The entire task (the entire -activity stack) can be brought to the foreground or sent to the background. -Suppose, for instance, that the current task has four activities in its stack -— three under the current activity. The user presses the HOME key, goes -to the application launcher, and selects a new application (actually, a new task). -The current task goes into the background and the root activity for the new task is displayed. -Then, after a short period, the user goes back to the home screen and again selects -the previous application (the previous task). That task, with all four -activities in the stack, comes forward. When the user presses the BACK -key, the screen does not display the activity the user just left (the root -activity of the previous task). Rather, the activity on the top of the stack -is removed and the previous activity in the same task is displayed. -

- -

-The behavior just described is the default behavior for activities and tasks. -But there are ways to modify almost all aspects of it. The association of -activities with tasks, and the behavior of an activity within a task, is -controlled by the interaction between flags set in the Intent object that -started the activity and attributes set in the activity's -<activity> -element in the manifest. Both requester and respondent have a say in what happens. -

- -

-In this regard, the principal Intent flags are: - -

{@code FLAG_ACTIVITY_NEW_TASK} -
{@code FLAG_ACTIVITY_CLEAR_TOP} -
{@code FLAG_ACTIVITY_RESET_TASK_IF_NEEDED} -
{@code FLAG_ACTIVITY_SINGLE_TOP}

- -

-The principal {@code <activity>} attributes are: - -

{@code taskAffinity} -
{@code launchMode} -
{@code allowTaskReparenting} -
{@code clearTaskOnLaunch} -
{@code alwaysRetainTaskState} -
{@code finishOnTaskLaunch}

- -

-The following sections describe what some of these flags and attributes do, -how they interact, and what considerations should govern their use. -

- - -

Affinities and new tasks

- -

-By default, all the activities in an application have an affinity for each -other — that is, there's a preference for them all to belong to the -same task. However, an individual affinity can be set for each activity -with the {@code taskAffinity} attribute of the {@code <activity>} element. -Activities defined in different applications can share an affinity, or activities -defined in the same application can be assigned different affinities. -The affinity comes into play in two circumstances: When the Intent object -that launches an activity contains the {@code FLAG_ACTIVITY_NEW_TASK} flag, -and when an activity has its {@code allowTaskReparenting} attribute set -to "{@code true}". -

- -
-
The {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK} flag
-
As described earlier, a new activity is, by default, launched into -the task of the activity that called {@code startActivity()}. It's pushed - onto the same stack as the caller. However, if the Intent object passed -to {@code startActivity()} contains the {@code FLAG_ACTIVITY_NEW_TASK} -flag, the system looks for a different task to house the new activity. -Often, as the name of the flag implies, it's a new task. However, it -doesn't have to be. If there's already an existing task with the same -affinity as the new activity, the activity is launched into that task. If -not, it begins a new task.
- -
The allowTaskReparenting -attribute
-
If an activity has its {@code allowTaskReparenting} attribute set -to "{@code true}", it can move from the task it starts in to the task -it has an affinity for when that task comes to the fore. For example, -suppose that an activity that reports weather conditions in selected -cities is defined as part of a travel application. It has the same -affinity as other activities in the same application (the default -affinity) and it allows reparenting. One of your activities -starts the weather reporter, so it initially belongs to the same task as -your activity. However, when the travel application next comes forward, -the weather reporter will be reassigned to and displayed with that task.
-
- -

-If an {@code .apk} file contains more than one "application" -from the user's point of view, you will probably want to assign different -affinities to the activities associated with each of them. -

- - -

Launch modes

- -

-There are four different launch modes that can be assigned to an {@code -<activity>} element's -launchMode -attribute: -

- -

"{@code standard}" (the default mode) -
"{@code singleTop}" -
"{@code singleTask}" -
"{@code singleInstance}"

- -

-The modes differ from each other on these four points: -

- - - -

-When an existing activity is asked to handle a new intent, the Intent -object is passed to the activity in an -{@link android.app.Activity#onNewIntent onNewIntent()} call. -(The intent object that originally started the activity can be retrieved by -calling {@link android.app.Activity#getIntent getIntent()}.) -

- -

-Note that when a new instance of an Activity is created to handle a new -intent, the user can always press the BACK key to return to the previous state -(to the previous activity). But when an existing instance of an -Activity handles a new intent, the user cannot press the BACK key to -return to what that instance was doing before the new intent arrived. -

- -

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

- - -

Clearing the stack

- -

-If the user leaves a task for a long time, the system clears the task of all -activities except the root activity. When the user returns to the task again, -it's as the user left it, except that only the initial activity is present. -The idea is that, after -a time, users will likely have abandoned what they were doing before and are -returning to the task to begin something new. -

- -

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

- -
-
The alwaysRetainTaskState -attribute
-
If this attribute is set to "{@code true}" in the root activity of a task, -the default behavior just described does not happen. -The task retains all activities in its stack even after a long period.
- -
The clearTaskOnLaunch -attribute
-
If this attribute is set to "{@code true}" in the root activity of a task, -the stack is cleared down to the root activity whenever the user leaves the task -and returns to it. In other words, it's the polar opposite of -{@code alwaysRetainTaskState}. The user always returns to the task in its -initial state, even after a momentary absence.
- -
The finishOnTaskLaunch -attribute
-
This attribute is like {@code clearTaskOnLaunch}, but it operates on a -single activity, not an entire task. And it can cause any activity to go -away, including the root activity. When it's set to "{@code true}", the -activity remains part of the task only for the current session. If the user -leaves and then returns to the task, it no longer is present.
-
- -

-There's another way to force activities to be removed from the stack. -If an Intent object includes the {@link -android.content.Intent#FLAG_ACTIVITY_CLEAR_TOP FLAG_ACTIVITY_CLEAR_TOP} -flag, and the target task already has an instance of the type of activity that -should handle the intent in its stack, all activities above that instance -are cleared away so that it stands at the top of the stack and can respond -to the intent. -If the launch mode of the designated activity is "{@code standard}", it too -will be removed from the stack, and a new instance will be launched to handle -the incoming intent. That's because a new instance is always created for -a new intent when the launch mode is "{@code standard}". -

- -

-{@code FLAG_ACTIVITY_CLEAR_TOP} is most often used in conjunction -with {@code FLAG_ACTIVITY_NEW_TASK}. When used together, these flags are -a way of locating an existing activity in another task and putting it in -a position where it can respond to the intent. -

- - -

Starting tasks

- -

-An activity is set up as the entry point for a task by giving it -an intent filter with "{@code android.intent.action.MAIN}" as the -specified action and "{@code android.intent.category.LAUNCHER}" as -the specified category. (There's an example of this type of filter -in the earlier Intent Filters section.) -A filter of this kind causes an icon and label for the activity to be -displayed in the application launcher, giving users a way both to -launch the task and to return to it at any time after it has been -launched. -

- -

-This second ability is important: Users must be able to leave a task -and then come back to it later. For this reason, the two launch modes -that mark activities as always initiating a task, "{@code singleTask}" -and "{@code singleInstance}", should be used only when the activity has -a {@code MAIN} and {@code LAUNCHER} filter. -Imagine, for example, what could happen if the filter is missing: -An intent launches a "{@code singleTask}" activity, initiating a new task, -and the user spends some time working in that task. The user then presses -the HOME key. The task is now ordered behind and obscured by the home -screen. And, because it is not represented in the application launcher, -the user has no way to return to it. -

- -

-A similar difficulty attends the {@code FLAG_ACTIVITY_NEW_TASK} flag. -If this flag causes an activity to -begin a new task and the user presses the HOME key to leave it, there -must be some way for the user to navigate back to it again. Some -entities (such as the notification manager) always start activities -in an external task, never as part of their own, so they always put -{@code FLAG_ACTIVITY_NEW_TASK} in the intents they pass to -{@code startActivity()}. If you have an activity that can be invoked -by an external entity that might use this flag, take care that the user -has a independent way to get back to the task that's started. -

- -

-For those cases where you don't want the user to be able to return -to an activity, set the {@code <activity>} element's {@code -finishOnTaskLaunch} to "{@code true}". -See Clearing the stack, earlier. -

- - -

Processes and Threads

- -

-When the first of an application's components needs to be run, Android -starts a Linux process for it with a single thread of execution. By default, -all components of the application run in that process and thread. -

- -

-However, you can arrange for components to run in other processes, and you -can spawn additional threads for any process. -

- - -

Processes

- -

-The process where a component runs is controlled by the manifest file. -The component elements — {@code <activity>}, -{@code <service>}, {@code <receiver>}, and {@code <provider>} -— each have a {@code process} attribute that can specify a process -where that component should run. These attributes can be set so that each -component runs in its own process, or so that some components share a process -while others do not. They can also be set so that components of -different applications run in the same process — provided that the -applications share the same Linux user ID and are signed by the same authorities. -The {@code <application>} element also has a {@code process} attribute, -for setting a default value that applies to all components. -

- -

-All components are instantiated in the main thread of the specified -process, and system calls to the component are dispatched from that -thread. Separate threads are not created for each instance. Consequently, -methods that respond to those calls — methods like -{@link android.view.View#onKeyDown View.onKeyDown()} that report -user actions and the lifecycle notifications discussed later in the -Component Lifecycles section — always run in the -main thread of the process. This means -that no component should perform long or blocking operations (such as networking -operations or computation loops) when called by the system, since this will block -any other components also in the process. You can spawn separate threads for -long operations, as discussed under Threads, next. -

- -

-Android may decide to shut down a process at some point, when memory is -low and required by other processes that are more immediately serving -the user. Application components running in the process are consequently -destroyed. A process is restarted for those components when there's again -work for them to do. -

- -

-When deciding which processes to terminate, Android weighs their relative -importance to the user. For example, it more readily shuts down a process -with activities that are no longer visible on screen than a process with -visible activities. -The decision whether to terminate a process, therefore, depends on the state -of the components running in that process. Those states are the subject of -a later section, Component Lifecycles. -

- - -

Threads

- -

-Even though you may confine your application to a single process, there will -likely be times when you will need to spawn a thread to do some background -work. Since the user interface must always be quick to respond to user actions, -the thread that hosts an activity should not also host time-consuming operations -like network downloads. Anything that may not be completed quickly should be -assigned to a different thread. -

- -

-Threads are created in code using standard Java {@link java.lang.Thread} -objects. Android provides a number of convenience classes for managing -threads — {@link android.os.Looper} for running a message loop within -a thread, {@link android.os.Handler} for processing messages, and -{@link android.os.HandlerThread} for setting up a thread with a message loop. -

- - -

Remote procedure calls

- -

-Android has a lightweight mechanism for remote procedure calls (RPCs) -— where a method is called locally, but executed remotely (in another -process), with any result returned back to the caller. -This entails decomposing the method call and all its attendant data to a -level the operating system can understand, transmitting it from the local -process and address space to the remote process and address space, and -reassembling and reenacting the call there. Return values have to be -transmitted in the opposite direction. Android provides all the code -to do that work, so that you can concentrate on defining and implementing -the RPC interface itself. -

- -

-An RPC interface can include only methods. -All methods are executed synchronously (the local method blocks until the -remote method finishes), even if there is no return value. -

- -

-In brief, the mechanism works as follows: You'd begin by declaring the -RPC interface you want to implement using a simple IDL (interface definition -language). From that declaration, the -aidl -tool generates a Java interface definition that must be made available to -both the local and the remote process. It contains two inner class, as shown -in the following diagram: -

- -

-RPC mechanism. -

- -

-The inner classes have all the code needed to administer remote procedure -calls for the interface you declared with the IDL. -Both inner classes implement the {@link android.os.IBinder} -interface. One of them is used locally and internally by the system; -the code you write can ignore it. -The other, called Stub, extends the {@link android.os.Binder} -class. In addition to internal code for effectuating the IPC calls, it -contains declarations for the methods in the RPC interface you declared. -You would subclass Stub to implement those methods, as indicated in the -diagram. -

- -

-Typically, the remote process would be managed by a service (because a -service can inform the system about the process and its connections to -other processes). It would have both the interface file generated by -the {@code aidl} tool and the Stub subclass implementing the -RPC methods. Clients of the service would have only the interface file -generated by the {@code aidl} tool. -

- -

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

- - - -

-This brief description omits some details of the RPC mechanism. For more -information, see -Designing a Remote -Interface Using AIDL and the {@link android.os.IBinder IBinder} class -description. -

- - -

Thread-safe methods

- -

-In a few contexts, the methods you implement may be called from more -than one thread, and therefore must be written to be thread-safe. -

- -

-This is primarily true for methods that can be called remotely — -as in the RPC mechanism discussed in the previous section. -When a call on a method implemented in an IBinder object originates -in the same process as the IBinder, the method is executed in the -caller's thread. However, when the call originates in another process, -the method is executed in a thread chosen from a pool of threads that -Android maintains in the same process as the IBinder; it's not executed -in the main thread of the process. For example, whereas a service's -{@code onBind()} method would be called from the main thread of the -service's process, methods implemented in the object that {@code onBind()} -returns (for example, a Stub subclass that implements RPC methods) would -be called from threads in the pool. -Since services can have more than one client, more than one pool thread -can engage the same IBinder method at the same time. IBinder methods -must, therefore, be implemented to be thread-safe. -

- -

-Similarly, a content provider can receive data requests that originate in -other processes. Although the ContentResolver and ContentProvider classes -hide the details of how the interprocess communication is managed, -ContentProvider methods that respond to those requests — the methods -{@link android.content.ContentProvider#query query()}, -{@link android.content.ContentProvider#insert insert()}, -{@link android.content.ContentProvider#delete delete()}, -{@link android.content.ContentProvider#update update()}, and -{@link android.content.ContentProvider#getType getType()} -— are called from a pool of threads in the content provider's -process, not the main thread of the process. Since these methods -may be called from any number of threads at the same time, they too must -be implemented to be thread-safe. -

- - -

Component Lifecycles

- -

-Application components have a lifecycle — a beginning when -Android instantiates them to respond to intents through to an end when -the instances are destroyed. In between, they may sometimes be active -or inactive,or, in the case of activities, visible to the user or -invisible. This section discusses the lifecycles of activities, -services, and broadcast receivers — including the states that they -can be in during their lifetimes, the methods that notify you of transitions -between states, and the effect of those states on the possibility that -the process hosting them might be terminated and the instances destroyed. -

- - -

Activity lifecycle

- -

An activity has essentially three states:

- - - -

-If an activity is paused or stopped, the system can drop it from memory either -by asking it to finish (calling its {@link android.app.Activity#finish finish()} -method), or simply killing its process. When it is displayed again -to the user, it must be completely restarted and restored to its previous state. -

- -

-As an activity transitions from state to state, it is notified of the change -by calls to the following protected methods: -

- -

{@code void onCreate(Bundle savedInstanceState)} -
{@code void onStart()} -
{@code void onRestart()} -
{@code void onResume()} -
{@code void onPause()} -
{@code void onStop()} -
{@code void onDestroy()}

- -

-All of these methods are hooks that you can override to do appropriate work -when the state changes. All activities must implement -{@link android.app.Activity#onCreate onCreate()} to do the -initial setup when the object is first instantiated. -Many will also implement {@link android.app.Activity#onPause onPause()} -to commit data changes and otherwise prepare to stop interacting with the user. -

- - - - -

-Taken together, these seven methods define the entire lifecycle of an -activity. There are three nested loops that you can monitor by -implementing them: -

- - - -

-The following diagram illustrates these loops and the paths an activity -may take between states. The colored ovals are major states the activity -can be in. The square rectangles represent the callback methods you can implement -to perform operations when the activity transitions between states. -

- -

- -

-The following table describes each of these methods in more detail and -locates it within the activity's overall lifecycle: -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Method Description Killable? Next
{@link android.app.Activity#onCreate onCreate()}Called when the activity is first created. - This is where you should do all of your normal static set up — - create views, bind data to lists, and so on. This method is passed - a Bundle object containing the activity's previous state, if that - state was captured (see Saving Activity State, - later). -

Always followed by {@code onStart()}.

No{@code onStart()}
    {@link android.app.Activity#onRestart -onRestart()}Called after the activity has been stopped, just prior to it being - started again. -

Always followed by {@code onStart()}

No{@code onStart()}
{@link android.app.Activity#onStart onStart()}Called just before the activity becomes visible to the user. -

Followed by {@code onResume()} if the activity comes - to the foreground, or {@code onStop()} if it becomes hidden.

No{@code onResume()}
or
{@code onStop()}
    {@link android.app.Activity#onResume onResume()}Called just before the activity starts - interacting with the user. At this point the activity is at - the top of the activity stack, with user input going to it. -

Always followed by {@code onPause()}.

No{@code onPause()}
{@link android.app.Activity#onPause onPause()}Called when the system is about to start resuming another - activity. This method is typically used to commit unsaved changes to - persistent data, stop animations and other things that may be consuming - CPU, and so on. It should do whatever it does very quickly, because - the next activity will not be resumed until it returns. -

Followed either by {@code onResume()} if the activity - returns back to the front, or by {@code onStop()} if it becomes - invisible to the user.

Yes{@code onResume()}
or
{@code onStop()}
{@link android.app.Activity#onStop onStop()}Called when the activity is no longer visible to the user. This - may happen because it is being destroyed, or because another activity - (either an existing one or a new one) has been resumed and is covering it. -

Followed either by {@code onRestart()} if - the activity is coming back to interact with the user, or by - {@code onDestroy()} if this activity is going away.

Yes{@code onRestart()}
or
{@code onDestroy()}
{@link android.app.Activity#onDestroy -onDestroy()}Called before the activity is destroyed. This is the final call - that the activity will receive. It could be called either because the - activity is finishing (someone called {@link android.app.Activity#finish - finish()} on it), or because the system is temporarily destroying this - instance of the activity to save space. You can distinguish - between these two scenarios with the {@link - android.app.Activity#isFinishing isFinishing()} method.Yesnothing
- -

-Note the Killable column in the table above. It indicates -whether or not the system can kill the process hosting the activity -at any time after the method returns, without executing another -line of the activity's code. Three methods ({@code onPause()}, -{@code onStop()}, and {@code onDestroy()}) are marked "Yes." Because -{@code onPause()} is the first of the three, it's the only one that's -guaranteed to be called before the process is killed — -{@code onStop()} and {@code onDestroy()} may not be. Therefore, you -should use {@code onPause()} to write any persistent data (such as user -edits) to storage. -

- -

-Methods that are marked "No" in the Killable column protect the -process hosting the activity from being killed from the moment they are -called. Thus an activity is in a killable state, for example, from the -time {@code onPause()} returns to the time {@code onResume()} is called. -It will not again be killable until {@code onPause()} again returns. -

- -

-As noted in a later section, Processes and lifecycle, -an activity that's not technically "killable" by this definition might -still be killed by the system — but that would happen only in -extreme and dire circumstances when there is no other recourse. -

- - -

Saving activity state

- -

-When the system, rather than the user, shuts down an activity to conserve -memory, the user may expect to return to the activity and find it in its -previous state. -

- -

-To capture that state before the activity is killed, you can implement -an {@link android.app.Activity#onSaveInstanceState -onSaveInstanceState()} method for the activity. Android calls this -method before making the activity vulnerable to being destroyed — -that is, before {@code onPause()} is called. It -passes the method a {@link android.os.Bundle} object where you can record -the dynamic state of the activity as name-value pairs. When the activity is -again started, the Bundle is passed both to {@code onCreate()} and to a -method that's called after {@code onStart()}, {@link -android.app.Activity#onRestoreInstanceState onRestoreInstanceState()}, -so that either or both of them can recreate the captured state. -

- -

-Unlike {@code onPause()} and the other methods discussed earlier, -{@code onSaveInstanceState()} and {@code onRestoreInstanceState()} are -not lifecycle methods. They are not always called. For example, Android -calls {@code onSaveInstanceState()} before the activity becomes -vulnerable to being destroyed by the system, but does not bother -calling it when the instance is actually being destroyed by a user action -(such as pressing the BACK key). In that case, the user won't expect to -return to the activity, so there's no reason to save its state. -

- -

-Because {@code onSaveInstanceState()} is not always called, you should -use it only to record the transient state of the activity, not to store -persistent data. Use {@code onPause()} for that purpose instead. -

- - -

Coordinating activities

- -

-When one activity starts another, they both experience lifecycle -transitions. One pauses and may stop, while the other starts up. -On occasion, you may need to coordinate these activities, one with -the other. -

- -

-The order of lifecycle callbacks is well defined, -particularly when the two activities are in the same process: -

- -
    -
  1. The current activity's {@code onPause()} method is called.
  2. - -
  3. Next, the starting activity's {@code onCreate()}, {@code onStart()}, -and {@code onResume()} methods are called in sequence.
  4. - -
  5. Then, if the starting activity is no longer visible -on screen, its {@code onStop()} method is called.
  6. -
- - -

Service lifecycle

- -

-A service can be used in two ways: -

- - - -

-The two modes are not entirely separate. You can bind to a service that -was started with {@code startService()}. For example, a background music -service could be started by calling {@code startService()} with an Intent -object that identifies the music to play. Only later, possibly when the -user wants to exercise some control over the player or get information -about the current song, would an activity -establish a connection to the service by calling {@code bindService()}. -In cases like this, {@code stopService()} -will not actually stop the service until the last binding is closed. -

- -

-Like an activity, a service has lifecycle methods that you can implement -to monitor changes in its state. But they are fewer than the activity -methods — only three — and they are public, not protected: -

- -

{@code void onCreate()} -
{@code void onStart(Intent intent)} -
{@code void onDestroy()}

- -

-By implementing these methods, you can monitor two nested loops of the -service's lifecycle: -

- - - -

-The {@code onCreate()} and {@code onDestroy()} methods are called for all -services, whether they're started by -{@link android.content.Context#startService Context.startService()} -or -{@link android.content.Context#bindService Context.bindService()}. -However, {@code onStart()} is called only for services started by {@code -startService()}. -

- -

-If a service permits others to -bind to it, there are additional callback methods for it to implement: -

- -

{@code IBinder onBind(Intent intent)} -
{@code boolean onUnbind(Intent intent)} -
{@code void onRebind(Intent intent)}

- -

-The {@link android.app.Service#onBind onBind()} callback is passed -the Intent object that was passed to {@code bindService} and -{@link android.app.Service#onUnbind onUnbind()} is handed -the intent that was passed to {@code unbindService()}. -If the service permits the binding, {@code onBind()} -returns the communications channel that clients use to interact with the service. -The {@code onUnbind()} method can ask for -{@link android.app.Service#onRebind onRebind()} -to be called if a new client connects to the service. -

- -

-The following diagram illustrates the callback methods for a service. -Although, it separates services that are created via {@code startService} -from those created by {@code bindService()}, keep in mind that any service, -no matter how it's started, can potentially allow clients to bind to it, -so any service may receive {@code onBind()} and {@code onUnbind()} calls. -

- -

- - -

Broadcast receiver lifecycle

- -

-A broadcast receiver has single callback method: -

- -

{@code void onReceive(Context curContext, Intent broadcastMsg)}

- -

-When a broadcast message arrives for the receiver, Android calls its -{@link android.content.BroadcastReceiver#onReceive onReceive()} -method and passes it the Intent object containing the message. The broadcast -receiver is considered to be active only while it is executing this method. -When {@code onReceive()} returns, it is inactive. -

- -

-A process with an active broadcast receiver is protected from being killed. -But a process with only inactive components can be killed by the system at -any time, when the memory it consumes is needed by other processes. -

- -

-This presents a problem when the response to a broadcast message is time -consuming and, therefore, something that should be done in a separate thread, -away from the main thread where other components of the user interface run. -If {@code onReceive()} spawns the thread and then returns, the entire process, -including the new thread, is judged to be inactive (unless other application -components are active in the process), putting it in jeopardy of being killed. -The solution to this problem is for {@code onReceive()} to start a service -and let the service do the job, so the -system knows that there is still active work being done in the process. -

- -

-The next section has more on the vulnerability of processes to being killed. -

- - -

Processes and lifecycles

- -

The Android system tries to maintain an application process for as -long as possible, but eventually it will need to remove old processes when -memory runs low. To determine which processes to keep and which to kill, -Android places each process into an "importance hierarchy" based on the -components running in it and the state of those components. Processes -with the lowest importance are eliminated first, then those with the next -lowest, and so on. There are five levels in the hierarchy. The following -list presents them in order of importance: -

- -
    - -
  1. A foreground process is one 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 hold: - -
      -
    • It is running an activity that the user is interacting with -(the Activity object's {@link android.app.Activity#onResume -onResume()} method has been called).
    • - -
    • It hosts a service that's bound -to the activity that the user is interacting with.

    • - -
    • It has a {@link android.app.Service} object that's executing -one of its lifecycle callbacks ({@link android.app.Service#onCreate -onCreate()}, {@link android.app.Service#onStart onStart()}, -or {@link android.app.Service#onDestroy onDestroy()}).

    • - -
    • It has a {@link android.content.BroadcastReceiver} object that's -executing its {@link android.content.BroadcastReceiver#onReceive -onReceive()} method.

    • -
    - -

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

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

    - -
      -
    • It hosts an activity that is not in the foreground, but is still visible -to the user (its {@link android.app.Activity#onPause onPause()} -method has been called). This may occur, for example, if the foreground -activity is a dialog that allows the previous activity to be seen behind it.
    • - -
    • It hosts a service that's bound to a visible activity.

    • -
    - -

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

  4. - -
  5. A service process is one that is running a service that -has been started with the -{@link android.content.Context#startService startService()} -method and that 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 an mp3 in the background or downloading data on the network), -so the system keeps them running unless there's not enough -memory to retain them along with all foreground and visible processes. -

  6. - -
  7. A background process is one holding an activity -that's not currently visible to the user (the Activity object's -{@link android.app.Activity#onStop onStop()} method has been called). -These processes have no direct impact on the user experience, and can be killed -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 captures its current -state, killing its process will not have a deleterious effect on the user experience. -

  8. - -
  9. An empty process is one that doesn't hold any active application -components. The only reason to keep such a process around is as a cache 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.

  10. - -
- -

-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 will be -ranked as a visible process, not a service process. -

- -

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

- -

-Because a process running a service is ranked higher than one with background -activities, an activity that initiates a long-running operation might do -well to start a service for that operation, rather than simply spawn a thread -— particularly if the operation will likely outlast the activity. -Examples of this are playing music in the background -and uploading a picture taken by the camera to a web site. Using a service -guarantees that the operation will have at least "service process" priority, -regardless of what happens to the activity. As noted in the -Broadcast receiver lifecycle section earlier, this -is the same reason that broadcast receivers should employ services rather -than simply put time-consuming operations in a thread. -

-- cgit v1.1