50e990c64f
Change-Id: Idc55a0b368c1d2c1e7d4999601b739dd57f08eb3
425 lines
23 KiB
Plaintext
425 lines
23 KiB
Plaintext
page.title=Processes and Threads
|
|
@jd:body
|
|
|
|
<div id="qv-wrapper">
|
|
<div id="qv">
|
|
<h2>Quickview</h2>
|
|
<ul>
|
|
<li>Every application runs in its own process and all components of the application run in that
|
|
process, by default</li>
|
|
<li>Any slow, blocking operations in an activity should be done in a new thread, to avoid slowing
|
|
down the user interface</li>
|
|
</ul>
|
|
|
|
<h2>In this document</h2>
|
|
<ol>
|
|
<li><a href="#Processes">Processes</a>
|
|
<ol>
|
|
<li><a href="#Lifecycle">Process lifecycle</a></li>
|
|
</ol>
|
|
</li>
|
|
<li><a href="#Threads">Threads</a>
|
|
<ol>
|
|
<li><a href="#WorkerThreads">Worker threads</a></li>
|
|
<li><a href="#ThreadSafe">Thread-safe methods</a></li>
|
|
</ol>
|
|
</li>
|
|
<li><a href="#IPC">Interprocess Communication</a></li>
|
|
</ol>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<p>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.</p>
|
|
|
|
<p>This document discusses how processes and threads work in an Android application.</p>
|
|
|
|
|
|
<h2 id="Processes">Processes</h2>
|
|
|
|
<p>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.</p>
|
|
|
|
<p>The manifest entry for each type of component element—<a
|
|
href="{@docRoot}guide/topics/manifest/activity-element.html">{@code
|
|
<activity>}</a>, <a href="{@docRoot}guide/topics/manifest/service-element.html">{@code
|
|
<service>}</a>, <a href="{@docRoot}guide/topics/manifest/receiver-element.html">{@code
|
|
<receiver>}</a>, and <a href="{@docRoot}guide/topics/manifest/provider-element.html">{@code
|
|
<provider>}</a>—supports an {@code android:process} 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
|
|
{@code android:process} so that components of different applications run in the same
|
|
process—provided that the applications share the same Linux user ID and are signed with the
|
|
same certificates.</p>
|
|
|
|
<p>The <a href="{@docRoot}guide/topics/manifest/application-element.html">{@code
|
|
<application>}</a> element also supports an {@code android:process} attribute, to set a
|
|
default value that applies to all components.</p>
|
|
|
|
<p>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 that's killed are consequently destroyed. A process is started
|
|
again for those components when there's again work for them to do.</p>
|
|
|
|
<p>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. </p>
|
|
|
|
|
|
<h3 id="Lifecycle">Process lifecycle</h3>
|
|
|
|
<p>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.</p>
|
|
|
|
<p>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 <em>most important</em> and is
|
|
<em>killed last</em>):</p>
|
|
|
|
<ol>
|
|
<li><b>Foreground process</b>
|
|
<p>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:</p>
|
|
|
|
<ul>
|
|
<li>It hosts an {@link android.app.Activity} that the user is interacting with (the {@link
|
|
android.app.Activity}'s {@link android.app.Activity#onResume onResume()} method has been
|
|
called).</li>
|
|
|
|
<li>It hosts a {@link android.app.Service} that's bound to the activity that the user is
|
|
interacting with.</li>
|
|
|
|
<li>It hosts a {@link android.app.Service} that's running "in the foreground"—the
|
|
service has called {@link android.app.Service#startForeground startForeground()}.
|
|
|
|
<li>It hosts a {@link android.app.Service} 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()}).</li>
|
|
|
|
<li>It hosts a {@link android.content.BroadcastReceiver} that's executing its {@link
|
|
android.content.BroadcastReceiver#onReceive onReceive()} method.</li>
|
|
</ul>
|
|
|
|
<p>Generally, only a few foreground processes exist at any given time. They are killed only as
|
|
a last resort—if memory is so low that they cannot all continue to run. Generally, at that
|
|
point, the device has reached a memory paging state, so killing some foreground processes is
|
|
required to keep the user interface responsive.</p></li>
|
|
|
|
<li><b>Visible process</b>
|
|
<p>A process that doesn't have any foreground components, but still can
|
|
affect what the user sees on screen. A process is considered to be visible if either of the
|
|
following conditions are true:</p>
|
|
|
|
<ul>
|
|
<li>It hosts an {@link android.app.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 might occur, for example, if the foreground activity started a dialog, which allows the
|
|
previous activity to be seen behind it.</li>
|
|
|
|
<li>It hosts a {@link android.app.Service} that's bound to a visible (or foreground)
|
|
activity.</li>
|
|
</ul>
|
|
|
|
<p>A visible process is considered extremely important and will not be killed unless doing so
|
|
is required to keep all foreground processes running. </p>
|
|
</li>
|
|
|
|
<li><b>Service process</b>
|
|
<p>A process that is running a service that has been started with the {@link
|
|
android.content.Context#startService startService()} method and does not fall into either of the two
|
|
higher categories. Although service processes are not directly tied to anything the user sees, they
|
|
are generally doing things that the user cares about (such as playing music in the background or
|
|
downloading data on the network), so the system keeps them running unless there's not enough memory
|
|
to retain them along with all foreground and visible processes. </p>
|
|
</li>
|
|
|
|
<li><b>Background process</b>
|
|
<p>A process holding an activity that's not currently visible to the user (the activity's
|
|
{@link android.app.Activity#onStop 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 <a
|
|
href="{@docRoot}guide/components/activities.html#SavingActivityState">Activities</a>
|
|
document for information about saving and restoring state.</p>
|
|
</li>
|
|
|
|
<li><b>Empty process</b>
|
|
<p>A process that doesn't hold any active application components. The only reason to keep this
|
|
kind of process alive is for caching purposes, to improve startup time the next time a component
|
|
needs to run in it. The system often kills these processes in order to balance overall system
|
|
resources between process caches and the underlying kernel caches.</p>
|
|
</li>
|
|
</ol>
|
|
|
|
|
|
<p>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.</p>
|
|
|
|
<p>In addition, a process's ranking might be increased because other processes are dependent on
|
|
it—a process that is serving another process can never be ranked lower than the process it is
|
|
serving. For example, if a content provider in process A is serving a client in process B, or if a
|
|
service in process A is bound to a component in process B, process A is always considered at least
|
|
as important as process B.</p>
|
|
|
|
<p>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 <a
|
|
href="{@docRoot}guide/components/services.html">service</a> for that operation, rather than
|
|
simply create a worker thread—particularly if the operation will likely outlast the activity.
|
|
For example, an activity that's uploading a picture to a web site should start a service to perform
|
|
the upload so that the upload can continue in the background even if the user leaves the activity.
|
|
Using a service guarantees that the operation will have at least "service process" priority,
|
|
regardless of what happens to the activity. This is the same reason that broadcast receivers should
|
|
employ services rather than simply put time-consuming operations in a thread.</p>
|
|
|
|
|
|
|
|
|
|
<h2 id="Threads">Threads</h2>
|
|
|
|
<p>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 {@link
|
|
android.widget} and {@link android.view} packages). As such, the main thread is also sometimes
|
|
called the UI thread.</p>
|
|
|
|
<p>The system does <em>not</em> 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 {@link android.view.View#onKeyDown onKeyDown()} to report user actions
|
|
or a lifecycle callback method) always run in the UI thread of the process.</p>
|
|
|
|
<p>For instance, when the user touches a button on the screen, your app's 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.</p>
|
|
|
|
<p>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 user's 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 "<a
|
|
href="http://developer.android.com/guide/practices/responsiveness.html">application not
|
|
responding</a>" (ANR) dialog. The user might then decide to quit your application and uninstall it
|
|
if they are unhappy.</p>
|
|
|
|
<p>Additionally, the Andoid UI toolkit is <em>not</em> thread-safe. So, you must not manipulate
|
|
your UI from a worker thread—you must do all manipulation to your user interface from the UI
|
|
thread. Thus, there are simply two rules to Android's single thread model:</p>
|
|
|
|
<ol>
|
|
<li>Do not block the UI thread
|
|
<li>Do not access the Android UI toolkit from outside the UI thread
|
|
</ol>
|
|
|
|
<h3 id="WorkerThreads">Worker threads</h3>
|
|
|
|
<p>Because of the single thread model described above, it's vital to the responsiveness of your
|
|
application's 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).</p>
|
|
|
|
<p>For example, below is some code for a click listener that downloads an image from a separate
|
|
thread and displays it in an {@link android.widget.ImageView}:</p>
|
|
|
|
<pre>
|
|
public void onClick(View v) {
|
|
new Thread(new Runnable() {
|
|
public void run() {
|
|
Bitmap b = loadImageFromNetwork("http://example.com/image.png");
|
|
mImageView.setImageBitmap(b);
|
|
}
|
|
}).start();
|
|
}
|
|
</pre>
|
|
|
|
<p>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: <em>do not access the
|
|
Android UI toolkit from outside the UI thread</em>—this sample modifies the {@link
|
|
android.widget.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.</p>
|
|
|
|
<p>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:</p>
|
|
|
|
<ul>
|
|
<li>{@link android.app.Activity#runOnUiThread(java.lang.Runnable)
|
|
Activity.runOnUiThread(Runnable)}</li>
|
|
<li>{@link android.view.View#post(java.lang.Runnable) View.post(Runnable)}</li>
|
|
<li>{@link android.view.View#postDelayed(java.lang.Runnable, long) View.postDelayed(Runnable,
|
|
long)}</li>
|
|
</ul>
|
|
|
|
<p>For example, you can fix the above code by using the {@link
|
|
android.view.View#post(java.lang.Runnable) View.post(Runnable)} method:</p>
|
|
|
|
<pre>
|
|
public void onClick(View v) {
|
|
new Thread(new Runnable() {
|
|
public void run() {
|
|
final Bitmap bitmap = loadImageFromNetwork("http://example.com/image.png");
|
|
mImageView.post(new Runnable() {
|
|
public void run() {
|
|
mImageView.setImageBitmap(bitmap);
|
|
}
|
|
});
|
|
}
|
|
}).start();
|
|
}
|
|
</pre>
|
|
|
|
<p>Now this implementation is thread-safe: the network operation is done from a separate thread
|
|
while the {@link android.widget.ImageView} is manipulated from the UI thread.</p>
|
|
|
|
<p>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 {@link android.os.Handler} in your worker thread, to process messages delivered from the UI
|
|
thread. Perhaps the best solution, though, is to extend the {@link android.os.AsyncTask} class,
|
|
which simplifies the execution of worker thread tasks that need to interact with the UI.</p>
|
|
|
|
|
|
<h4 id="AsyncTask">Using AsyncTask</h4>
|
|
|
|
<p>{@link android.os.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 and/or handlers yourself.</p>
|
|
|
|
<p>To use it, you must subclass {@link android.os.AsyncTask} and implement the {@link
|
|
android.os.AsyncTask#doInBackground doInBackground()} callback method, which runs in a pool of
|
|
background threads. To update your UI, you should implement {@link
|
|
android.os.AsyncTask#onPostExecute onPostExecute()}, which delivers the result from {@link
|
|
android.os.AsyncTask#doInBackground doInBackground()} and runs in the UI thread, so you can safely
|
|
update your UI. You can then run the task by calling {@link android.os.AsyncTask#execute execute()}
|
|
from the UI thread.</p>
|
|
|
|
<p>For example, you can implement the previous example using {@link android.os.AsyncTask} this
|
|
way:</p>
|
|
|
|
<pre>
|
|
public void onClick(View v) {
|
|
new DownloadImageTask().execute("http://example.com/image.png");
|
|
}
|
|
|
|
private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
|
|
/** The system calls this to perform work in a worker thread and
|
|
* delivers it the parameters given to AsyncTask.execute() */
|
|
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) {
|
|
mImageView.setImageBitmap(result);
|
|
}
|
|
}
|
|
</pre>
|
|
|
|
<p>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.</p>
|
|
|
|
<p>You should read the {@link android.os.AsyncTask} reference for a full understanding on
|
|
how to use this class, but here is a quick overview of how it works:</p>
|
|
|
|
<ul>
|
|
<li>You can specify the type of the parameters, the progress values, and the final
|
|
value of the task, using generics</li>
|
|
<li>The method {@link android.os.AsyncTask#doInBackground doInBackground()} executes automatically
|
|
on a worker thread</li>
|
|
<li>{@link android.os.AsyncTask#onPreExecute onPreExecute()}, {@link
|
|
android.os.AsyncTask#onPostExecute onPostExecute()}, and {@link
|
|
android.os.AsyncTask#onProgressUpdate onProgressUpdate()} are all invoked on the UI thread</li>
|
|
<li>The value returned by {@link android.os.AsyncTask#doInBackground doInBackground()} is sent to
|
|
{@link android.os.AsyncTask#onPostExecute onPostExecute()}</li>
|
|
<li>You can call {@link android.os.AsyncTask#publishProgress publishProgress()} at anytime in {@link
|
|
android.os.AsyncTask#doInBackground doInBackground()} to execute {@link
|
|
android.os.AsyncTask#onProgressUpdate onProgressUpdate()} on the UI thread</li>
|
|
<li>You can cancel the task at any time, from any thread</li>
|
|
</ul>
|
|
|
|
<p class="caution"><strong>Caution:</strong> Another problem you might encounter when using a worker
|
|
thread is unexpected restarts in your activity due to a <a
|
|
href="{@docRoot}guide/topics/resources/runtime-changes.html">runtime configuration change</a>
|
|
(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 <a
|
|
href="http://code.google.com/p/shelves/">Shelves</a> sample application.</p>
|
|
|
|
|
|
<h3 id="ThreadSafe">Thread-safe methods</h3>
|
|
|
|
<p> In some situations, the methods you implement might be called from more than one thread, and
|
|
therefore must be written to be thread-safe. </p>
|
|
|
|
<p>This is primarily true for methods that can be called remotely—such as methods in a <a
|
|
href="{@docRoot}guide/components/bound-services.html">bound service</a>. When a call on a
|
|
method implemented in an {@link android.os.IBinder} originates in the same process in which the
|
|
{@link android.os.IBinder IBinder} is running, 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 the system maintains in the same process as the {@link android.os.IBinder
|
|
IBinder} (it's not executed in the UI thread of the process). For example, whereas a service's
|
|
{@link android.app.Service#onBind onBind()} method would be called from the UI thread of the
|
|
service's process, methods implemented in the object that {@link android.app.Service#onBind
|
|
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 {@link android.os.IBinder IBinder} method at the same time. {@link android.os.IBinder
|
|
IBinder} methods must, therefore, be implemented to be thread-safe.</p>
|
|
|
|
<p> Similarly, a content provider can receive data requests that originate in other processes.
|
|
Although the {@link android.content.ContentResolver} and {@link android.content.ContentProvider}
|
|
classes hide the details of how the interprocess communication is managed, {@link
|
|
android.content.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 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. </p>
|
|
|
|
|
|
<h2 id="IPC">Interprocess Communication</h2>
|
|
|
|
<p>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. </p>
|
|
|
|
<p>To perform IPC, your application must bind to a service, using {@link
|
|
android.content.Context#bindService bindService()}. For more information, see the <a
|
|
href="{@docRoot}guide/components/services.html">Services</a> developer guide.</p>
|
|
|
|
|
|
<!--
|
|
<h2>Beginner's Path</h2>
|
|
|
|
<p>For information about how to perform work in the background for an indefinite period of time
|
|
(without a user interface), continue with the <b><a
|
|
href="{@docRoot}guide/components/services.html">Services</a></b> document.</p>
|
|
-->
|