| The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1 | page.title=Application Model |
| 2 | @jd:body |
| 3 | <h1>Android Application Model: Applications, Tasks, Processes, and Threads</h1> |
| 4 | |
| 5 | <p>In most operating systems, there is a strong 1-to-1 correlation between |
| 6 | the executable image (such as the .exe on Windows) that an application lives in, |
| 7 | the process it runs in, and the icon and application the user interacts with. |
| 8 | In Android these associations are much more fluid, and it is important to |
| 9 | understand how the various pieces can be put together.</p> |
| 10 | |
| 11 | <p>Because of the flexible nature of Android applications, there is some |
| 12 | basic terminology that needs to be understood when implementing the |
| 13 | various pieces of an application:</p> |
| 14 | |
| 15 | <ul> |
| 16 | <li><p>An <strong>android package</strong> (or <strong>.apk</strong> for short) |
| 17 | is the file containing an application's code and its resources. This is the |
| 18 | file that an application is distributed in and downloaded by the user when |
| 19 | installing that application on their device.</p></li> |
| 20 | |
| 21 | <li><p>A <strong>task</strong> is generally what the user perceives as |
| 22 | an "application" that can be launched: usually a task has an icon in the |
| 23 | home screen through which it is accessed, and it is available as a top-level |
| 24 | item that can be brought to the foreground in front of other |
| 25 | tasks.</p></li> |
| 26 | |
| 27 | <li><p>A <strong>process</strong> is a low-level kernel process in which |
| 28 | an application's code is running. Normally all of the code in a |
| 29 | .apk is run in one, dedicated process for that .apk; however, the |
| 30 | {@link android.R.styleable#AndroidManifestApplication_process process} tag |
| 31 | can be used to modify where that code is run, either for |
| 32 | {@link android.R.styleable#AndroidManifestApplication the entire .apk} |
| 33 | or for individual |
| 34 | {@link android.R.styleable#AndroidManifestActivity activity}, |
| 35 | {@link android.R.styleable#AndroidManifestReceiver receiver}, |
| 36 | {@link android.R.styleable#AndroidManifestService service}, or |
| 37 | {@link android.R.styleable#AndroidManifestProvider provider}, components.</p></li> |
| 38 | </ul> |
| 39 | |
| 40 | <h2 id="Tasks">Tasks</h2> |
| 41 | |
| 42 | <p>A key point here is: <em>when the user sees as an "application," what |
| 43 | they are actually dealing with is a task</em>. If you just create a .apk |
| 44 | with a number of activities, one of which is a top-level entry point (via |
| 45 | an {@link android.R.styleable#AndroidManifestIntentFilter intent-filter} for |
| 46 | the action <code>android.intent.action.MAIN</code> and |
| 47 | category <code>android.intent.category.LAUNCHER</code>), then there will indeed |
| 48 | be one task created for your .apk, and any activities you start from there |
| 49 | will also run as part of that task.</p> |
| 50 | |
| 51 | <p>A task, then, from the user's perspective your application; and from the |
| 52 | application developer's perspective it is one or more activities the user |
| 53 | has traversed through in that task and not yet closed, or an activity stack. |
| 54 | A new task is created by |
| 55 | starting an activity Intent with the {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK |
| 56 | Intent.FLAG_ACTIVITY_NEW_TASK} flag; this Intent will be used as the root Intent of |
| 57 | the task, defining what task it is. Any activity started without this flag |
| 58 | will run in the same task as the activity that is starting it (unless that |
| 59 | activity has requested a special launch mode, as discussed later). Tasks can |
| 60 | be re-ordered: if you use FLAG_ACTIVITY_NEW_TASK but there is already a task |
| 61 | running for that Intent, the current task's activity stack will be brought |
| 62 | to the foreground instead of starting a new task.</p> |
| 63 | |
| 64 | <p>FLAG_ACTIVITY_NEW_TASK must only be used with care: using it says that, |
| 65 | from the user's perspective, a new application starts at this point. If this |
| 66 | is not the behavior you desire, you should not be creating a new task. In |
| 67 | addition, you should only use the new task flag if it is possible for the user |
| 68 | to navigate from home back to where they are and launch the same Intent as a |
| 69 | new task. Otherwise, if the user presses HOME instead of BACK from the task |
| 70 | you have launched, your task and its activities will be ordered behind the |
| 71 | home screen without a way to return to them.</p> |
| 72 | |
| 73 | <h3>Task Affinities</h3> |
| 74 | |
| 75 | <p>In some cases Android needs to know which task an activity belongs to even when |
| 76 | it is not being launched in to a specific task. This is accomplished through |
| 77 | task affinities, which provide a unique static name for the task that one or more |
| 78 | activities are intended to run in. The default task affinity for an activity |
| 79 | is the name of the .apk package name the activity is implemented in. This |
| 80 | provides the normally expected behavior, where all of the activities in a |
| 81 | particular .apk are part of a single application to the user.</p> |
| 82 | |
| 83 | <p>When starting a new activity without the |
| 84 | {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK |
| 85 | Intent.FLAG_ACTIVITY_NEW_TASK} flag, task affinities have no impact on the |
| 86 | task the new activity will run in: it will always run in the task of the |
| 87 | activity that is starting it. However, if the NEW_TASK flag is being used, |
| 88 | then the affinity will be used to determine if a task already exists with |
| 89 | the same affinity. If so, that task will be brought to the front and the |
| 90 | new activity launched at the top of that task.</p> |
| 91 | |
| 92 | <p>This behavior is most useful for situations where you must use the |
| 93 | NEW_TASK flag, in particular launching activities from status bar notifications |
| 94 | or home screen shortcuts. The result is that, when the user launches your |
| 95 | application this way, its current task state will be brought to the foreground, |
| 96 | and the activity they now want to look at placed on top of it.</p> |
| 97 | |
| 98 | <p>You can assign your own task affinities in your manifest's |
| 99 | {@link android.R.styleable#AndroidManifestApplication application} tag for |
| 100 | all activities in the .apk, or the |
| 101 | {@link android.R.styleable#AndroidManifestActivity activity} tag of |
| 102 | individual activities. Some examples of how this can be used are:</p> |
| 103 | |
| 104 | <ul> |
| 105 | <li>If your .apk contains multiple top-level applications that the user can |
| 106 | launch, then you will probably want to assign different affinities to each |
| 107 | of the activities that the users sees for your .apk. A good convention for |
| 108 | coming up with distinct names is to append your .apk's package name with |
| 109 | a colon separated string. For example, the "com.android.contacts" .apk |
| 110 | may have the affinities "com.android.contacts:Dialer" and |
| 111 | "com.android.contacts:ContactsList".</ul> |
| 112 | <li>If you are replacing a notification, shortcut, or other such "inner" |
| 113 | activity of an application that can be launched from outside of it, you may |
| 114 | need to explicitly set the taskAffinity of your replacement activity to be |
| 115 | the same as the application you are replacing. For example, if you are |
| 116 | replacing the contacts details view (which the user can make and invoke |
| 117 | shortcuts to), you would want to set the taskAffinity to |
| 118 | "com.android.contacts".</li> |
| 119 | </ul> |
| 120 | |
| 121 | <h3>Launch Modes and Launch Flags</h3> |
| 122 | |
| 123 | <p>The main way you control how activities interact with tasks is through |
| 124 | the activity's |
| 125 | {@link android.R.styleable#AndroidManifestActivity_launchMode launchMode} |
| 126 | attribute and the {@link android.content.Intent#setFlags flags} associated |
| 127 | with an Intent. These two parameters can work together in various ways |
| 128 | to control the outcome of the activity launch, as described in their |
| 129 | associated documentation. Here we will look at some common use cases and |
| 130 | combinations of these parameters.</p> |
| 131 | |
| 132 | <p>The most common launch mode you will use (besides the default |
| 133 | <code>standard</code> mode) is <code>singleTop</code>. This does not have |
| 134 | an impact on tasks; it just avoids starting the same activity multiple times |
| 135 | on the top of a stack. |
| 136 | |
| 137 | <p>The <code>singleTask</code> launch mode has a major |
| 138 | impact on tasks: it causes the activity to always be started in |
| 139 | a new task (or its existing task to be brought to the foreground). Using |
| 140 | this mode requires a lot of care in how you interact with the rest of the |
| 141 | system, as it impacts every path in to the activity. It should only be used |
| 142 | with activities that are front doors to the application (that is, which |
| 143 | support the MAIN action and LAUNCHER category).</p> |
| 144 | |
| 145 | <p>The <code>singleInstance</code> launch mode is even more specialized, and |
| 146 | should only be used in applications that are implemented entirely as one |
| 147 | activity.</p> |
| 148 | |
| 149 | <p>A situation you will often run in to is when another entity (such as the |
| 150 | {@link android.app.SearchManager} or {@link android.app.NotificationManager}) |
| 151 | starts one of your activities. In this case, the |
| 152 | {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK |
| 153 | Intent.FLAG_ACTIVITY_NEW_TASK} flag must be used, because the activity is |
| 154 | being started outside of a task (and the application/task may not even |
| 155 | exist). As described previously, the standard behavior in this situation |
| 156 | is to bring to the foreground the current task matching the new activity's |
| 157 | affinity and start the new activity at the top of it. There are, however, |
| 158 | other types of behavior that you can implement.</p> |
| 159 | |
| 160 | <p>One common approach is to also use the |
| 161 | {@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TOP |
| 162 | Intent.FLAG_ACTIVITY_CLEAR_TOP} flag in conjunction with NEW_TASK. By doing so, |
| 163 | if your task is already running, then it will be brought to the foreground, |
| 164 | all of the activities on its stack cleared except the root activity, and the |
| 165 | root activity's {@link android.app.Activity#onNewIntent} called with the |
| 166 | Intent being started. Note that the activity often also use the <code>singleTop</code> |
| 167 | or <code>singleTask</code> launch mode when using this approach, so that |
| 168 | the current instance is given the new intent instead of requiring that it |
| 169 | be destroyed and a new instance started.</p> |
| 170 | |
| 171 | <p>Another approach you can take is to set the notification activity's |
| 172 | <code>android:taskAffinity</code> to the empty string "" (indicating no affinity) |
| 173 | and setting the |
| 174 | <code>{@link android.R.styleable#AndroidManifestActivity_noHistory |
| 175 | android:noHistory}</code> and |
| 176 | <code>{@link android.R.styleable#AndroidManifestActivity_excludeFromRecents |
| 177 | android:excludeFromRecents}</code> attributes. |
| 178 | This approach is useful if you would like the notification |
| 179 | to take the user to a separate activity describing it, rather than return |
| 180 | to the application's task. By specifying these attributes, the activity will |
| 181 | be finished whether the user leaves it with BACK or HOME and it will not |
| 182 | show up in the recent tasks list; if the <code>noHistory</code> attribute |
| 183 | isn't specified, pressing HOME will result in the activity and its task |
| 184 | remaining in the system, possibly with no way to return to it.</p> |
| 185 | |
| 186 | <p>Be sure to read the documentation on the |
| 187 | {@link android.R.styleable#AndroidManifestActivity_launchMode launchMode attribute} |
| 188 | and the {@link android.content.Intent#setFlags Intent flags} for the details |
| 189 | on these options.</p> |
| 190 | |
| 191 | <h2 id="Processes">Processes</h2> |
| 192 | |
| 193 | <p>In Android, processes are entirely an implementation detail of applications |
| 194 | and not something the user is normally aware of. Their main uses are simply:</p> |
| 195 | |
| 196 | <ul> |
| 197 | <li> Improving stability or security by putting untrusted or unstable code |
| 198 | into another process. |
| 199 | <li> Reducing overhead by running the code of multiple .apks in the same |
| 200 | process. |
| 201 | <li> Helping the system manage resources by putting heavy-weight code in |
| 202 | a separate process that can be killed independently of other parts of the |
| 203 | application. |
| 204 | </ul> |
| 205 | |
| 206 | <p>As described previously, the |
| 207 | {@link android.R.styleable#AndroidManifestApplication_process process} attribute |
| 208 | is used to control the process that particular application components run in. |
| 209 | Note that this attribute can not be used to violate security of the system: if |
| 210 | two .apks that are not sharing the same user ID try to run in the same process, |
| 211 | this will not be allowed and different distinct processes will be created for |
| 212 | each of them.</p> |
| 213 | |
| 214 | <p>See the <a href="{@docRoot}devel/security.html">security</a> document for |
| 215 | more information on these security restrictions.</p> |
| 216 | |
| 217 | <h2 id="Threads">Threads</h2> |
| 218 | |
| 219 | <p>Every process has one or more threads running in it. In most situations, Android |
| 220 | avoids creating additional threads in a process, keeping an application |
| 221 | single-threaded unless it creates its own threads. An important repercussion |
| 222 | of this is that all calls to {@link android.app.Activity}, |
| 223 | {@link android.content.BroadcastReceiver}, and {@link android.app.Service} |
| 224 | instances are made only from the main thread of the process they are running in.</p> |
| 225 | |
| 226 | <p>Note that a new thread is <strong>not</strong> created for each |
| 227 | Activity, BroadcastReceiver, Service, or ContentProvider instance: |
| 228 | these application components are instantiated in the desired process (all in the |
| 229 | same process unless otherwise specified), in the main thread of that process. |
| 230 | This means that none of these components (including services) should perform |
| 231 | long or blocking operations (such as networking calls or computation loops) |
| 232 | when called by the system, since this will block |
| 233 | all other components in the process. You can use the standard library |
| 234 | {@link java.lang.Thread} class or Android's {@link android.os.HandlerThread} |
| 235 | convenience class to perform long operations on another thread.</p> |
| 236 | |
| 237 | <p>There are a few important exceptions to this threading rule:</p> |
| 238 | |
| 239 | <ul> |
| 240 | <li><p>Calls on to an {@link android.os.IBinder} or interface implemented on |
| 241 | an IBinder are dispatched from the thread calling them or a thread pool in the |
| 242 | local process if coming from another process, <em>not</em> |
| 243 | from the main thread of their process. In particular, calls on to the IBinder |
| 244 | of a {@link android.app.Service} will be called this way. (Though |
| 245 | calls to methods on Service itself are done from the main thread.) |
| 246 | This means that <em>implementations of IBinder interfaces must always be |
| 247 | written in a thread-safe way, since they can be called from any number of |
| 248 | arbitrary threads at the same time</em>.</p></li> |
| 249 | |
| 250 | <li><p>Calls to the main methods of {@link android.content.ContentProvider} |
| 251 | are dispatched from the calling thread or main thread as with IBinder. The |
| 252 | specific methods are documented in the ContentProvider class. |
| 253 | This means that <em>implementations of these methods must always be |
| 254 | written in a thread-safe way, since they can be called from any number of |
| 255 | arbitrary threads at the same time</em>.</p></li> |
| 256 | |
| 257 | <li><p>Calls on {@link android.view.View} and its subclasses are made from the |
| 258 | thread that the view's window is running in. Normally this will be the main |
| 259 | thread of the process, however if you create a thread and show a window from |
| 260 | there then the window's view hierarchy will be called from that thread.</p></li> |
| 261 | </ul> |