diff options
Diffstat (limited to 'docs')
20 files changed, 2282 insertions, 286 deletions
diff --git a/docs/html/guide/topics/fundamentals.jd b/docs/html/guide/topics/fundamentals.jd index a095087..84c2ed2 100644 --- a/docs/html/guide/topics/fundamentals.jd +++ b/docs/html/guide/topics/fundamentals.jd @@ -294,8 +294,8 @@ onActivityResult()}</code> method. <li><p>A service is started (or new instructions are given to an ongoing service) by passing an Intent object to <code>{@link android.content.Context#startService Context.startService()}</code>. -Android calls the service's <code>{@link android.app.Service#onStart -onStart()}</code> method and passes it the Intent object.</p> +Android calls the service's <code>{@link android.app.Service#onStartCommand +onStartCommand()}</code> method and passes it the Intent object.</p> <p> Similarly, an intent can be passed to <code>{@link @@ -1510,9 +1510,9 @@ a music playback service could create the thread where the music will be played in {@code onCreate()}, and then stop the thread in {@code onDestroy()}.</li> <li><p>The <b>active lifetime</b> of a service begins with a call to -<code>{@link android.app.Service#onStart onStart()}</code>. This method +<code>{@link android.app.Service#onStartCommand onStartCommand()}</code>. This method is handed the Intent object that was passed to {@code startService()}. -The music service would open the Intent to discover which music to +The music service would open the Intent to discover which music to play, and begin the playback.</p> <p> @@ -1527,7 +1527,7 @@ services, whether they're started by <code>{@link android.content.Context#startService Context.startService()}</code> or <code>{@link android.content.Context#bindService Context.bindService()}</code>. -However, {@code onStart()} is called only for services started by {@code +However, {@code onStartCommand()} is called only for services started by {@code startService()}. </p> @@ -1631,7 +1631,7 @@ to the activity that the user is interacting with.</p></li> <li><p>It has a {@link android.app.Service} object that's executing one of its lifecycle callbacks (<code>{@link android.app.Service#onCreate -onCreate()}</code>, <code>{@link android.app.Service#onStart onStart()}</code>, +onCreate()}</code>, <code>{@link android.app.Service#onStartCommand onStartCommand()}</code>, or <code>{@link android.app.Service#onDestroy onDestroy()}</code>).</p></li> <li><p>It has a {@link android.content.BroadcastReceiver} object that's diff --git a/docs/html/guide/topics/fundamentals/activities.jd b/docs/html/guide/topics/fundamentals/activities.jd new file mode 100644 index 0000000..b616ab8 --- /dev/null +++ b/docs/html/guide/topics/fundamentals/activities.jd @@ -0,0 +1,762 @@ +page.title=Activities +parent.title=Application Fundamentals +parent.link=index.html +@jd:body + +<div id="qv-wrapper"> +<div id="qv"> +<h2>Quickview</h2> +<ul> + <li>An activity provides a user interface for a single screen in your application</li> + <li>Activities can move into the background and then be resumed with their state restored</li> +</ul> + +<h2>In this document</h2> +<ol> + <li><a href="#Creating">Creating an Activity</a> + <ol> + <li><a href="#UI">Implementing a user interface</a></li> + <li><a href="#Declaring">Declaring the activity in the manifest</a></li> + </ol> + </li> + <li><a href="#StartingAnActivity">Starting an Activity</a> + <ol> + <li><a href="#StartingAnActivityForResult">Starting an Activity for a Result</a></li> + </ol> + </li> + <li><a href="#Lifecycle">Managing the Activity Lifecycle</a> + <ol> + <li><a href="#ImplementingLifecycleCallbacks">Implementing the lifecycle callbacks</a></li> + <li><a href="#SavingActivityState">Saving activity state</a></li> + <li><a href="#ConfigurationChanges">Handling configuration changes</a></li> + <li><a href="#CoordinatingActivities">Coordinating activities</a></li> + </ol> + </li> +</ol> + +<h2>Key classes</h2> +<ol> + <li>{@link android.app.Activity}</li> +</ol> + +<h2>See also</h2> +<ol> + <li><a href="{@docRoot}resources/tutorials/hello-world.html">Hello World Tutorial</a></li> + <li><a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack">Tasks and Back +Stack</a></li> +</ol> + +</div> +</div> + + + +<p>An {@link android.app.Activity} is an application component that provides a screen with which +users can interact in order to do something, such as dial the phone, take a photo, send an email, or +view a map. Each activity is given a window in which to draw its user interface. The window +typically fills the screen, but may be smaller than the screen and float on top of other +windows.</p> + +<p> An application usually consists of multiple activities that are loosely bound +to each other. Typically, one activity in an application is specified as the "main" activity, which +is presented to the user when launching the application for the first time. Each +activity can then start another activity in order to perform different actions. Each time a new +activity starts, the previous activity is stopped, but the system preserves the activity +in a stack (the "back stack"). When a new activity starts, it is pushed onto the back stack and +takes user focus. The back stack abides to the basic "last in, first out" queue mechanism, +so, when the user is done with the current activity and presses the BACK key, it +is popped from the stack (and destroyed) and the previous activity resumes. (The back stack is +discussed more in the <a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks +and Back Stack</a> document.)</p> + +<p>When an activity is stopped because a new activity starts, it is notified of this change in state +through the activity's lifecycle callback methods. +There are several callback methods that an activity might receive, due to a change in its +state—whether the system is creating it, stopping it, resuming it, or destroying it—and +each callback provides you the opportunity to perform specific work that's +appropriate to that state change. For instance, when stopped, your activity should release any +large objects, such as network or database connections. When the activity resumes, you can +reacquire the necessary resources and resume actions that were interrupted. These state transitions +are all part of the activity lifecycle.</p> + +<p>The rest of this document discusses the basics of how to build and use an activity, +including a complete discussion of how the activity lifecycle works, so you can properly manage +the transition between various activity states.</p> + + + +<h2 id="Creating">Creating an Activity</h2> + +<p>To create an activity, you must create a subclass of {@link android.app.Activity} (or +an existing subclass of it). In your subclass, you need to implement callback methods that the +system calls when the activity transitions between various states of its lifecycle, such as when +the activity is being created, stopped, resumed, or destroyed. The two most important callback +methods are:</p> + +<dl> + <dt>{@link android.app.Activity#onCreate onCreate()}</dt> + <dd>You must implement this method. The system calls this when creating your + activity. Within your implementation, you should initialize the essential components of your +activity. + Most importantly, this is where you must call {@link android.app.Activity#setContentView + setContentView()} to define the layout for the activity's user interface.</dd> + <dt>{@link android.app.Activity#onPause onPause()}</dt> + <dd>The system calls this method as the first indication that the user is leaving your +activity (though it does not always mean the activity is being destroyed). This is usually where you +should commit any changes that should be persisted beyond the current user session (because +the user might not come back).</dd> +</dl> + +<p>There are several other lifecycle callback methods that you should use in order to provide a +fluid user experience between activities and handle unexpected interuptions that cause your activity +to be stopped and even destroyed. All of the lifecycle callback methods are discussed later, in +the section about <a href="#Lifecycle">Managing the Activity Lifecycle</a>.</p> + + + +<h3 id="UI">Implementing a user interface</h3> + +<p> The user interface for an activity is provided by a hierarchy of views—objects derived +from the {@link android.view.View} class. Each view controls a particular rectangular space +within the activity's window and can respond to user interaction. For example, a view might be a +button that initiates an action when the user touches it.</p> + +<p>Android provides a number of ready-made views that you can use to design and organize your +layout. "Widgets" are views that provide a visual (and interactive) elements for the screen, such +as a button, text field, checkbox, or just an image. "Layouts" are views derived from {@link +android.view.ViewGroup} that provide a unique layout model for its child views, such as a linear +layout, a grid layout, or relative layout. You can also subclass the {@link android.view.View} and +{@link android.view.ViewGroup} classes (or existing subclasses) to create your own widgets and +layouts and apply them to your activity layout.</p> + +<p>The most common way to define a layout using views is with an XML layout file saved in your +application resources. This way, you can maintain the design of your user interface separately from +the source code that defines the activity's behavior. You can set the layout as the UI for your +activity with {@link android.app.Activity#setContentView(int) setContentView()}, passing the +resource ID for the layout. However, you can also create new {@link android.view.View}s in your +activity code and build a view hierarchy by inserting new {@link +android.view.View}s into a {@link android.view.ViewGroup}, then use that layout by passing the root +{@link android.view.ViewGroup} to {@link android.app.Activity#setContentView(View) +setContentView()}.</p> + +<p>For information about creating a user interface, see the <a +href="{@docRoot}guide/topics/ui/index.html">User Interface</a> documentation.</p> + + + +<h3 id="Declaring">Declaring the activity in the manifest</h3> + +<p>You must declare your activity in the manifest file in order for it to +be accessible to the system. To decalare your activity, open your manifest file and add an <a +href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> element +as a child of the <a +href="{@docRoot}guide/topics/manifest/application-element.html">{@code <application>}</a> +element. For example:</p> + +<pre> +<manifest ... > + <application ... > + <activity android:name=".ExampleActivity" /> + ... + </application ... > + ... +</manifest > +</pre> + +<p>There are several other attributes that you can include in this element, to define properties +such as the label for the activity, an icon for the activity, or a theme to style the activity's +UI. See the <a +href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> element +reference for more information about available attributes.</p> + + +<h4>Using intent filters</h4> + +<p>An <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code +<activity>}</a> element can also specify various intent filters—using the <a +href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code +<intent-filter>}</a> element—in order to declare how other application components may +activate it.</p> + +<p>When you create a new application using the Android SDK tools, the stub activity +that's created for you automatically includes an intent filter that declares the activity +responds to the "main" action and should be placed in the "launcher" category. The intent filter +looks like this:</p> + +<pre> +<activity android:name=".ExampleActivity" android:icon="@drawable/app_icon"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> +</activity> +</pre> + +<p>The <a href="{@docRoot}guide/topics/manifest/action-element.html">{@code +<action>}</a> element specifies that this is the "main" entry point to the application. The <a +href="{@docRoot}guide/topics/manifest/category-element.html">{@code +<category>}</a> element specifies that this activity should be listed in the +system's application launcher (to allow users to launch this activity).</p> + +<p>If you intend for your application to be self-contained and not allow other applications to +activate its activities, then you don't need any other intent filters. Only one activity should +have the "main" action and "launcher" category, as in the previous example. Activities that +you don't want to make available to other applications should have no intent filters and you can +start them yourself using explicit intents (as discussed in the following section).</p> + +<p>However, if you want your activity to respond to implicit intents that are delivered from +other applications (and your own), then you must define additional intent filters for your +activity. For each type of intent to which you want to respond, you must include an <a +href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code +<intent-filter>}</a> that includes an +<a href="{@docRoot}guide/topics/manifest/action-element.html">{@code +<action>}</a> element and, optionally, a <a +href="{@docRoot}guide/topics/manifest/category-element.html">{@code +<category>}</a> element and/or a <a +href="{@docRoot}guide/topics/manifest/data-element.html">{@code +<data>}</a> element. These elements specify the type of intent to which your activity can +respond.</p> + +<p>For more information about how your activities can respond to intents, see the <a +href="{@docRoot}guide/topics/intents/intents-filters.html">Intents and Intent Filters</a> +document.</p> + + + +<h2 id="StartingAnActivity">Starting an Activity</h2> + +<p>You can start another activity by calling {@link android.app.Activity#startActivity + startActivity()}, passing it an {@link android.content.Intent} that describes the activity you + want to start. The intent specifies either the exact activity you want to start or describes the + type of action you want to perform (and the system selects the appropriate activity for you, +which + can even be from a different application). An intent can also carry small amounts of data to be + used by the activity that is started.</p> + +<p>When working within your own application, you'll often need to simply launch a known activity. + You can do so by creating an intent that explicitly defines the activity you want to start, +using the class name. For example, here's how one activity starts another activity named {@code +SignInActivity}:</p> + +<pre> +Intent intent = new Intent(this, SignInActivity.class); +startActivity(intent); +</pre> + +<p>However, your application might also want to perform some action, such as send an email, text + message, or status update, using data from your activity. In this case, your application might + not have its own activities to perform such actions, so you can instead leverage the activities + provided by other applications on the device, which can perform the actions for you. This is where +intents are really valuable—you can create an intent that describes an action you want to +perform and the system + launches the appropriate activity from another application. If there are + multiple activities that can handle the intent, then the user can select which one to use. For + example, if you want to allow the user to send an email message, you can create the + following intent:</p> + +<pre> +Intent intent = new Intent(Intent.ACTION_SEND); +intent.putExtra(Intent.EXTRA_EMAIL, recipientArray); +startActivity(intent); +</pre> + +<p>The {@link android.content.Intent#EXTRA_EMAIL} extra added to the intent is a string array of + email addresses to which the email should be sent. When an email application responds to this + intent, it reads the string array provided in the extra and places them in the "to" field of the + email composition form. In this situation, the email application's activity starts and when the + user is done, your activity resumes.</p> + + + + +<h3 id="StartingAnActivityForResult">Starting an activity for a result</h3> + +<p>Sometimes, you might want to receive a result from the activity that you start. In that case, + start the activity by calling {@link android.app.Activity#startActivityForResult + startActivityForResult()} (instead of {@link android.app.Activity#startActivity + startActivity()}). To then receive the result from the subsequent +activity, implement the {@link android.app.Activity#onActivityResult onActivityResult()} callback + method. When the subsequent activity is done, it returns a result in an {@link +android.content.Intent} to your {@link android.app.Activity#onActivityResult onActivityResult()} +method.</p> + +<p>For example, perhaps you want the user to pick one of their contacts, so your activity can +do something with the information in that contact. Here's how you can create such an intent and +handle the result:</p> + +<pre> +private void pickContact() { + // Create an intent to "pick" a contact, as defined by the content provider URI + Intent intent = new Intent(Intent.ACTION_PICK, Contacts.CONTENT_URI); + startActivityForResult(intent, PICK_CONTACT_REQUEST); +} + +@Override +protected void onActivityResult(int requestCode, int resultCode, Intent data) { + // If the request went well (OK) and the request was PICK_CONTACT_REQUEST + if (resultCode == Activity.RESULT_OK && requestCode == PICK_CONTACT_REQUEST) { + // Perform a query to the contact's content provider for the contact's name + Cursor cursor = getContentResolver().query(data.getData(), + new String[] {Contacts.DISPLAY_NAME}, null, null, null); + if (cursor.moveToFirst()) { // True if the cursor is not empty + int columnIndex = cursor.getColumnIndex(Contacts.DISPLAY_NAME); + String name = cursor.getString(columnIndex); + // Do something with the selected contact's name... + } + } +} +</pre> + +<p>This example shows the basic logic you should use in your {@link +android.app.Activity#onActivityResult onActivityResult()} method in order to handle an +activity result. The first condition checks whether the request was successful—if it was, then +the {@code resultCode} will be {@link android.app.Activity#RESULT_OK}—and whether the request +to which this result is responding is known—in this case, the {@code requestCode} matches the +second parameter sent with {@link android.app.Activity#startActivityForResult +startActivityForResult()}. From there, the code handles the activity result by querying the +data returned in an {@link android.content.Intent} (the {@code data} parameter).</p> + +<p>What happens is, a {@link +android.content.ContentResolver} performs a query against a content provider, which returns a +{@link android.database.Cursor} that allows the queried data to be read. For more information, see +the <a +href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a> document.</p> + +<p>For more information about using intents, see the <a +href="{@docRoot}guide/topics/intents/intents-filters.html">Intents and Intent +Filters</a> document.</p> + + +<h2 id="ShuttingDown">Shutting Down an Activity</h2> + +<p>You can shut down an activity by calling its {@link android.app.Activity#finish +finish()} method. You can also shut down a separate activity that you previously started by calling +{@link android.app.Activity#finishActivity finishActivity()}.</p> + +<p class="note"><strong>Note:</strong> In most cases, you should not explicitly finish an activity +using these methods. As discussed in the following section about the activity lifecycle, the +Android system manages the life of an activity for you, so you do not need to finish your own +activities. Calling these methods could adversely affect the expected user +experience and should only be used when you absolutely do not want the user to return to this +instance of the activity.</p> + + +<h2 id="Lifecycle">Managing the Activity Lifecycle</h2> + +<p>Managing the lifecycle of your activities by implementing callback methods is +crucial to developing a strong +and flexible application. The lifecycle of an activity is directly affected by its association with +other activities, its task and back stack.</p> + +<p>An activity can exist in essentially three states:</p> + +<dl> + <dt><i>Resumed</i></dt> + <dd>The activity is in the foreground of the screen and has user focus. (This state is +also sometimes referred to as "running".)</dd> + + <dt><i>Paused</i></dt> + <dd>Another activity is in the foreground and has focus, but this one is still visible. That is, +another activity is visible on top of this one and that activity is partially transparent or doesn't +cover the entire screen. A paused activity is completely alive (the {@link android.app.Activity} +object is retained in memory, it maintains all state and member information, and remains attached to +the window manager), but can be killed by the system in extremely low memory situations.</dd> + + <dt><i>Stopped</i></dt> + <dd>The activity is completely obscured by another activity (the activity is now in the +"background"). A stopped activity is also still alive (the {@link android.app.Activity} +object is retained in memory, it maintains all state and member information, but is <em>not</em> +attached to the window manager). However, it is no longer visible to the user and it +can be killed by the system when memory is needed elsewhere.</dd> +</dl> + +<p>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 the activity is opened again (after being finished or killed), it must be created all +over.</p> + + + +<h3 id="ImplementingLifecycleCallbacks">Implementing the lifecycle callbacks</h3> + +<p>When an activity transitions into and out of the different states described above, it is notified +through various callback methods. All of the callback methods are hooks that you +can override to do appropriate work when the state of your activity changes. The following skeleton +activity includes each of the fundamental lifecycle methods:</p> + + +<pre> +public class ExampleActivity extends Activity { + @Override + public void {@link android.app.Activity#onCreate onCreate}(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + // The activity is being created. + } + @Override + protected void {@link android.app.Activity#onStart onStart()} { + super.onStart(); + // The activity is about to become visible. + } + @Override + protected void {@link android.app.Activity#onResume onResume()} { + super.onResume(); + // The activity has become visible (it is now "resumed"). + } + @Override + protected void {@link android.app.Activity#onPause onPause()} { + super.onPause(); + // Another activity is taking focus (this activity is about to be "paused"). + } + @Override + protected void {@link android.app.Activity#onStop onStop()} { + super.onStop(); + // The activity is no longer visible (it is now "stopped") + } + @Override + protected void {@link android.app.Activity#onDestroy onDestroy()} { + super.onDestroy(); + // The activity is about to be destroyed. + } +} +</pre> + +<p class="note"><strong>Note:</strong> Your implementation of these lifecycle methods must +always call the superclass implementation before doing any work, as shown in the examples above.</p> + +<p>Taken together, these methods define the entire lifecycle of an activity. By implementing these +methods, you can monitor three nested loops in the activity lifecycle: </p> + +<ul> +<li>The <b>entire lifetime</b> of an activity happens between the call to {@link +android.app.Activity#onCreate onCreate()} and the call to {@link +android.app.Activity#onDestroy}. Your activity should perform setup of +"global" state (such as defining layout) in {@link android.app.Activity#onCreate onCreate()}, and +release all remaining resources in {@link android.app.Activity#onDestroy}. For example, if your +activity has a thread running in the background to download data from the network, it might create +that thread in {@link android.app.Activity#onCreate onCreate()} and then stop the thread in {@link +android.app.Activity#onDestroy}.</li> + +<li><p>The <b>visible lifetime</b> of an activity happens between the call to {@link +android.app.Activity#onStart onStart()} and the call to {@link +android.app.Activity#onStop onStop()}. During this time, the user can see the activity +on-screen and interact with it. For example, {@link android.app.Activity#onStop onStop()} is called +when a new activity starts and this one is no longer visible. Between these two methods, you can +maintain resources that are needed to show the activity to the user. For example, you can register a +{@link android.content.BroadcastReceiver} in {@link +android.app.Activity#onStart onStart()} to monitor changes that impact your UI, and unregister +it in {@link android.app.Activity#onStop onStop()} when the user can no longer see what you are +displaying. The system might call {@link android.app.Activity#onStart onStart()} and {@link +android.app.Activity#onStop onStop()} multiple times during the entire lifetime of the activity, as +the activity alternates between being visible and hidden to the user.</p></li> + +<li><p>The <b>foreground lifetime</b> of an activity happens between the call to {@link +android.app.Activity#onResume onResume()} and the call to {@link android.app.Activity#onPause +onPause()}. During this time, the activity is in front of all other activities on screen and has +user input focus. An activity can frequently transition in and out of the foreground—for +example, {@link android.app.Activity#onPause onPause()} is called when the device goes to sleep or +when a dialog appears. Because this state can transition often, the code in these two methods should +be fairly lightweight in order to avoid slow transitions that make the user wait.</p></li> +</ul> + +<p>Figure 1 illustrates these loops and the paths an activity might take between states. +The rectangles represent the callback methods you can implement to perform operations when +the activity transitions between states. <p> + +<img src="{@docRoot}images/activity_lifecycle.png" alt="" /> +<p class="img-caption"><strong>Figure 1.</strong> The activity lifecycle.</p> + +<p>The same lifecycle callback methods are listed in table 1, which describes each of the callback +methods in more detail and locates each one within the +activity's overall lifecycle, including whether the system can kill the activity after the +callback method completes.</p> + +<p class="table-caption"><strong>Table 1.</strong> A summary of the activity lifecycle's +callback methods.</p> + +<table border="2" width="85%" frame="hsides" rules="rows"> +<colgroup align="left" span="3"></colgroup> +<colgroup align="left"></colgroup> +<colgroup align="center"></colgroup> +<colgroup align="center"></colgroup> + +<thead> +<tr><th colspan="3">Method</th> <th>Description</th> <th>Killable after?</th> <th>Next</th></tr> +</thead> + +<tbody> +<tr> + <td colspan="3" align="left"><code>{@link android.app.Activity#onCreate onCreate()}</code></td> + <td>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 <a href="#actstate">Saving Activity State</a>, + later). + <p>Always followed by {@code onStart()}.</p></td> + <td align="center">No</td> + <td align="center">{@code onStart()}</td> +</tr> + +<tr> + <td rowspan="5" style="border-left: none; border-right: none;"> </td> + <td colspan="2" align="left"><code>{@link android.app.Activity#onRestart +onRestart()}</code></td> + <td>Called after the activity has been stopped, just prior to it being + started again. + <p>Always followed by {@code onStart()}</p></td> + <td align="center">No</td> + <td align="center">{@code onStart()}</td> +</tr> + +<tr> + <td colspan="2" align="left"><code>{@link android.app.Activity#onStart onStart()}</code></td> + <td>Called just before the activity becomes visible to the user. + <p>Followed by {@code onResume()} if the activity comes + to the foreground, or {@code onStop()} if it becomes hidden.</p></td> + <td align="center">No</td> + <td align="center">{@code onResume()} <br/>or<br/> {@code onStop()}</td> +</tr> + +<tr> + <td rowspan="2" style="border-left: none;"> </td> + <td align="left"><code>{@link android.app.Activity#onResume onResume()}</code></td> + <td>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. + <p>Always followed by {@code onPause()}.</p></td> + <td align="center">No</td> + <td align="center">{@code onPause()}</td> +</tr> + +<tr> + <td align="left"><code>{@link android.app.Activity#onPause onPause()}</code></td> + <td>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. + <p>Followed either by {@code onResume()} if the activity + returns back to the front, or by {@code onStop()} if it becomes + invisible to the user.</td> + <td align="center"><strong style="color:#800000">Yes</strong></td> + <td align="center">{@code onResume()} <br/>or<br/> {@code onStop()}</td> +</tr> + +<tr> + <td colspan="2" align="left"><code>{@link android.app.Activity#onStop onStop()}</code></td> + <td>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. + <p>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.</p></td> + <td align="center"><strong style="color:#800000">Yes</strong></td> + <td align="center">{@code onRestart()} <br/>or<br/> {@code onDestroy()}</td> +</tr> + +<tr> + <td colspan="3" align="left"><code>{@link android.app.Activity#onDestroy +onDestroy()}</code></td> + <td>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 <code>{@link android.app.Activity#finish + finish()}</code> 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 <code>{@link + android.app.Activity#isFinishing isFinishing()}</code> method.</td> + <td align="center"><strong style="color:#800000">Yes</strong></td> + <td align="center"><em>nothing</em></td> +</tr> +</tbody> +</table> + +<p>The column labeled "Killable after?" indicates whether or not the system can +kill the process hosting the activity at any time <em>after the method returns</em>, without +executing another line of the activity's code. Three methods are marked "yes": ({@link +android.app.Activity#onPause +onPause()}, {@link android.app.Activity#onStop onStop()}, and {@link android.app.Activity#onDestroy +onDestroy()}). Because {@link android.app.Activity#onPause onPause()} is the first +of the three, once the activity is created, {@link android.app.Activity#onPause onPause()} is the +last method that's guaranteed to be called before the process <em>can</em> be killed—if +the system must recover memory in an emergency, then {@link +android.app.Activity#onStop onStop()} and {@link android.app.Activity#onDestroy onDestroy()} might +not be called. Therefore, you should use {@link android.app.Activity#onPause onPause()} to write +crucial persistent data (such as user edits) to storage. However, you should be selective about +what information must be retained during {@link android.app.Activity#onPause onPause()}, because any +blocking procedures in this method block the transition to the next activity and slow the user +experience.</p> + +<p> Methods that are marked "No" in the <b>Killable</b> column protect the process hosting the +activity from being killed from the moment they are called. Thus, an activity is killable +from the time {@link android.app.Activity#onPause onPause()} returns to the time +{@link android.app.Activity#onResume onResume()} is called. It will not again be killable until +{@link android.app.Activity#onPause onPause()} is again called and returns. </p> + +<p class="note"><strong>Note:</strong> An activity that's not technically "killable" by this +definition in table 1 might still be killed by the system—but that would happen only in +extreme circumstances when there is no other recourse. When an activity might be killed is +discussed more in the <a +href="{@docRoot}guide/topics/fundamentals/processes-and-threading.html">Processes and +Threading</a> document.</p> + + +<h3 id="SavingActivityState">Saving activity state</h3> + +<p>The introduction to <a href="Lifecycle">Managing the Activity Lifecycle</a> briefly mentions that +when an activity is paused or stopped, the state of the activity is retained. This is true because +the {@link android.app.Activity} object is still held in memory when it is paused or +stopped—all information about its members and current state is still alive. Thus, any changes +the user made within the activity are retained in memory, so that when the activity returns to the +foreground (when it "resumes"), those changes are still there.</p> + +<div class="figure" style="width:615px"> +<img src="{@docRoot}images/fundamentals/restore_instance.png" alt="" /> +<p class="img-caption"><strong>Figure 2.</strong> The two ways in which an activity returns to user +focus with its state intact: either the activity is stopped, then resumed and the activity state +remains intact (left), or the activity is destroyed, then recreated and the activity must restore +the previous activity state (right).</p> +</div> + +<p>However, when the system destroys an activity in order to recover memory, the {@link +android.app.Activity} object is destroyed, so the system cannot simply resume it with its state +intact. Instead, the system must recreate the {@link android.app.Activity} object if the user +navigates back to it. Yet, the user is unaware +that the system destroyed the activity and recreated it and, thus, probably +expects the activity to be exactly as it was. In this situation, you can ensure that +important information about the activity state is preserved by implementing an additional +callback method that allows you to save information about the state of your activity and then +restore it when the the system recreates the activity.</p> + +<p>The callback method in which you can save information about the current state of your activity is +{@link android.app.Activity#onSaveInstanceState onSaveInstanceState()}. The system calls this method +before making the activity vulnerable to being destroyed and passes it +a {@link android.os.Bundle} object. The {@link android.os.Bundle} is where you can store +state information about the activity as name-value pairs, using methods such as {@link +android.os.Bundle#putString putString()}. Then, if the system kills your activity's +process and the user navigates back to your activity, the system passes the {@link +android.os.Bundle} to {@link android.app.Activity#onCreate onCreate()} so you can restore the +activity state you saved during {@link android.app.Activity#onSaveInstanceState +onSaveInstanceState()}. If there is no state information to restore, then the {@link +android.os.Bundle} passed to {@link android.app.Activity#onCreate onCreate()} is null.</p> + +<p class="note"><strong>Note:</strong> There's no guarantee that {@link +android.app.Activity#onSaveInstanceState onSaveInstanceState()} will be called before your +activity is destroyed, because there are cases in which it won't be necessary to save the state +(such as when the user leaves your activity using the BACK key, because the user is explicitly +closing the activity). If the method is called, it is always called before {@link +android.app.Activity#onStop onStop()} and possibly before {@link android.app.Activity#onPause +onPause()}.</p> + +<p>However, even if you do nothing and do not implement {@link +android.app.Activity#onSaveInstanceState onSaveInstanceState()}, some of the activity state is +restored by the {@link android.app.Activity} class's default implementation of {@link +android.app.Activity#onSaveInstanceState onSaveInstanceState()}. Specifically, the default +implementation calls {@link +android.view.View#onSaveInstanceState onSaveInstanceState()} for every {@link android.view.View} +in the layout, which allows each view to provide information about itself +that should be saved. Almost every widget in the Android framework implements this method as +appropriate, such that any visible changes to the UI are automatically saved and restored when your +activity is recreated. For example, the {@link android.widget.EditText} widget saves any text +entered by the user and the {@link android.widget.CheckBox} widget saves whether it's checked or +not. The only work required by you is to provide a unique ID (with the <a +href="{@docRoot}guide/topics/resources/layout-resource.html#idvalue">{@code android:id}</a> +attribute) for each widget you want to save its state. If a widget does not have an ID, then it +cannot save its state.</p> + +<div class="sidebox-wrapper"> +<div class="sidebox"> +<p>You can also explicitly stop a view in your layout from saving its state by setting the +{@link android.R.attr#saveEnabled android:saveEnabled} attribute to {@code "false"} or by calling +the {@link android.view.View#setSaveEnabled setSaveEnabled()} method. Usually, you should not +disable this, but you might if you want to restore the state of the activity UI differently.</p> +</div> +</div> + +<p>Although the default implementation of {@link +android.app.Activity#onSaveInstanceState onSaveInstanceState()} saves useful information about +your activity's UI, you still might need to override it to save additional information. +For example, you might need to save member values that changed during the activity's life (which +might correlate to values restored in the UI, but the members that hold those UI values are not +restored, by default).</p> + +<p>Because the default implementation of {@link +android.app.Activity#onSaveInstanceState onSaveInstanceState()} helps save the state of the UI, if +you override the method in order to save additional state information, you should always call the +superclass implementation of {@link android.app.Activity#onSaveInstanceState onSaveInstanceState()} +before doing any work.</p> + +<p class="note"><strong>Note:</strong> Because {@link android.app.Activity#onSaveInstanceState +onSaveInstanceState()} is not guaranteed +to be called, you should use it only to record the transient state of the activity (the state of +the UI)—you should never use it to store persistent data. Instead, you should use {@link +android.app.Activity#onPause onPause()} to store persistent data (such as data that should be saved +to a database) when the user leaves the activity.</p> + +<p>A good way to test your application's ability to restore its state is to simply rotate the +device so that the screen orientation changes. When the screen orientation changes, the system +destroys and recreates the activity in order to apply alternative resources that might be available +for the new orientation. For this reason alone, it's very important that your activity +completely restores its state when it is recreated, because users regularly rotate the screen while +using applications.</p> + + +<h3 id="ConfigurationChanges">Handling configuration changes</h3> + +<p>Some device configurations can change during runtime (such as screen orientation, keyboard +availability, and language). When such a change occurs, Android restarts the running Activity +({@link android.app.Activity#onDestroy} is called, followed immediately by {@link +android.app.Activity#onCreate onCreate()}). The restart behavior is +designed to help your application adapt to new configurations by automatically reloading your +application with alternative resources that you've provided. If you design your activity to +properly handle this event, it will be more resilient to unexpected events in the activity +lifecycle.</p> + +<p>The best way to handle a configuration change, such as a change in the screen orientation, is + to simply preserve the state of your application using {@link + android.app.Activity#onSaveInstanceState onSaveInstanceState()} and {@link +android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} (or {@link +android.app.Activity#onCreate onCreate()}), as discussed in the previous section.</p> + +<p>For a detailed discussion about configuration changes that happen at runtime and how you should +handle them, read <a href="{@docRoot}guide/topics/resources/runtime-changes.html">Handling +Runtime Changes</a>.</p> + + + +<h3 id="CoordinatingActivities">Coordinating activities</h3> + + <p>When one activity starts another, they both experience lifecycle transitions. The first activity +pauses and stops (though, it won't stop if it's still visible in the background), while the other +activity is created. In case these activities share data saved to disc or elsewhere, it's important +to understand that the first activity is not completely stopped before the second one is created. +Rather, the process of starting the second one overlaps with the process of stopping the first +one.</p> + +<p>The order of lifecycle callbacks is well defined, particularly when the two activities are in the +same process and one is starting the other. Here's the order of operations that occur when Activity +A starts Acivity B: </p> + +<ol> +<li>Activity A's {@link android.app.Activity#onPause onPause()} method executes.</li> + +<li>Activity B's {@link android.app.Activity#onCreate onCreate()}, {@link +android.app.Activity#onStart onStart()}, and {@link android.app.Activity#onResume onResume()} +methods execute in sequence. (Activity B now has user focus.)</li> + +<li>Then, if Activity A is no longer visible on screen, its {@link +android.app.Activity#onStop onStop()} method executes.</li> +</ol> + + <p>This predictable sequence of lifecycle callbacks allows you to manage the transition of +information from one activity to another. For example, if you must write to a database when the +first activity stops so that the following activity can read it, then you should write to the +database during {@link android.app.Activity#onPause onPause()} instead of during {@link +android.app.Activity#onStop onStop()}.</p> + + +<h2>Beginner's Path</h2> + +<p>For more information about how Android maintains a history of activities and +enables user multitasking, continue with the <b><a +href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and Back +Stack</a></b> document.</p> diff --git a/docs/html/guide/topics/fundamentals/tasks-and-back-stack.jd b/docs/html/guide/topics/fundamentals/tasks-and-back-stack.jd new file mode 100644 index 0000000..47dc547 --- /dev/null +++ b/docs/html/guide/topics/fundamentals/tasks-and-back-stack.jd @@ -0,0 +1,568 @@ +page.title=Tasks and Back Stack +parent.title=Application Fundamentals +parent.link=index.html +@jd:body + +<div id="qv-wrapper"> +<div id="qv"> +<h2>Quickview</h2> +<ul> + <li>All activities belong to a task</li> + <li>A task contains a collection of activities in the order in which the user interacts with +them</li> + <li>Tasks can move to the background and retain the state of each activity in order for the user +to perform other tasks without loosing their work</li> +</ul> + +<h2>In this document</h2> +<ol> +<li><a href="#ActivityState">Saving Activity State</a></li></li> +<li><a href="#ManagingTasks">Managing Tasks</a> + <ol> + <li><a href="#TaskLaunchModes">Defining launch modes</a></li> + <li><a href="#Affinities">Handling affinities</a></li> + <li><a href="#Clearing">Clearing the back stack</a></li> + <li><a href="#Starting">Starting a task</a></li> + </ol> +</li> +</ol> + +<h2>See also</h2> +<ol> + <li><a><a href="{@docRoot}videos/index.html#v=fL6gSd4ugSI">Application Lifecycle video</a></li> + <li><a +href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>} manifest +element</a></li> +</ol> +</div> +</div> + + +<p>An application usually contains multiple <a +href="{@docRoot}guide/topics/fundamentals/activities.html">activities</a>. Each activity +should be designed around a specific kind of action the user can perform and can start other +activities. For example, an email application might have one activity to show a list of new email. +When the user selects an email, a new activity opens to view that email.</p> + +<p>An activity can even start activities that exist in other applications on the device. For +example, if your application wants to send an email, you can define an intent to perform a "send" +action and include some data, such as an email address and a message. An activity from another +application that declares itself to handle this kind of intent then opens. In this case, the intent +is to send an email, so an email application's "compose" activity starts (if multiple activities +support the same intent, then the system lets the user select which one to use). When the email is +sent, your activity resumes and it seems as if the email activity was part of your application. Even +though the activities may be from different applications, Android maintains this seamless user +experience by keeping both activities in the same <em>task</em>.</p> + +<p>A task is a collection of activities that users interact with +when performing a certain job. The activities are arranged in a stack (the "back stack"), in the +order in which each activity is opened.</p> + +<!-- SAVE FOR WHEN THE FRAGMENT DOC IS ADDED +<div class="sidebox-wrapper"> +<div class="sidebox"> +<h3>Adding fragments to a task's back stack</h3> + +<p>Your activity can also include {@link android.app.Fragment}s to the back stack. For example, +suppose you have a two-pane layout using fragments, one of which is a list view (fragment A) and the +other being a layout to display an item from the list (fragment B). When the user selects an item +from the list, fragment B is replaced by a new fragment (fragment C). In this case, it might be +desireable for the user to navigate back to reveal fragment B, using the BACK key.</p> +<p>In order to add fragment B to the back stack so that this is possible, you must call {@link +android.app.FragmentTransaction#addToBackStack addToBackStack()} before you {@link +android.app.FragmentTransaction#commit()} the transaction that replaces fragment B with fragment +C.</p> +<p>For more information about using fragments and adding them to the back stack, see the {@link +android.app.Fragment} class documentation.</p> + +</div> +</div> +--> + +<p>The device Home screen is the starting place for most tasks. When the user touches an icon in the +application +launcher (or a shortcut on the Home screen), that application's task comes to the foreground. If no +task exists for the application (the application has not been used recently), then a new task +is created and the "main" activity for that application opens as the root activity in the stack.</p> + +<p>When the current activity starts another, the new activity is pushed on the top of the stack and +takes focus. The previous activity remains in the stack, but is stopped. When an activity +stops, the system retains the current state of its user interface. When the user presses the BACK +key, the current activity is popped from the top of the stack (the activity is destroyed) and the +previous activity resumes (the previous state of its UI is restored). Activities in the stack are +never rearranged, only pushed and popped from the stack—pushed onto the stack when started by +the current activity and popped off when the user leaves it using the BACK key. As such, the back +stack operates as a "last in, first out" object structure. Figure 1 visualizes +this behavior with a timeline showing the progress between activities along with the current back +stack at each point in time.</p> + +<img src="{@docRoot}images/fundamentals/diagram_backstack.png" alt="" /> +<p class="img-caption"><strong>Figure 1.</strong> A representation of how each new activity in a +task adds an item to the back stack. When the user presses the BACK key, the current activity is +destroyed and the previous activity resumes.</p> + + +<p>If the user continues to press BACK, then each activity in the stack is popped off to reveal the +previous one, until the user returns to the Home screen (or to whichever activity was running when +the task began). When all activities are removed from the stack, the task no longer exists.</p> + +<div class="figure" style="width:369px"> +<img src="{@docRoot}images/fundamentals/diagram_multitasking.png" alt="" /> <p +class="img-caption"><strong>Figure 2.</strong> Two tasks: Task A is in the background, waiting +to be resumed, while Task B receives user interaction in the foreground.</p> +</div> +<div class="figure" style="width:178px"> + <img src="{@docRoot}images/fundamentals/diagram_multiple_instances.png" alt="" /> <p +class="img-caption"><strong>Figure 3.</strong> A single activity is instantiated multiple times.</p> +</div> + +<p>A task is a cohesive unit that can move to the "background" when users begin a new task or go +to the Home screen, via the HOME key. While in the background, all the activities in the task are +stopped, but the back stack for the task remains intact—the task has simply lost focus while +another task takes place, as shown in figure 2. A task can then return to the "foreground" so users +can pick up where they left off. Suppose, for example, that the current task (Task A) has three +activities in its stack—two under the current activity. The user presses the HOME key, then +starts a new application from the application launcher. When the Home screen appears, Task A goes +into the background. When the new application starts, the system starts a task for that application +(Task B) with its own stack of activities. After interacting with +that application, the user returns Home again and selects the application that originally +started Task A. Now, Task A comes to the +foreground—all three activities in its stack are intact and the activity at the top of the +stack resumes. At +this point, the user can also switch back to Task B by going Home and selecting the application icon +that started that task (or by touching and holding the HOME key to reveal recent tasks and selecting +one). This is an example of multitasking on Android.</p> + +<p class="note"><strong>Note:</strong> Multiple tasks can be held in the background at once. +However, if the user is running many background tasks at the same time, the system might begin +destroying background activities in order to recover memory, causing the activity states to be lost. +See the following section about <a href="#ActivityState">Activity state</a>.</p> + +<p>Because the activities in the back stack are never rearranged, if your application allows +users to start a particular activity from more than one activity, a new instance of +that activity is created and popped onto the stack (rather than bringing any previous instance of +the activity to the top). As such, one activity in your application might be instantiated multiple +times (even from different tasks), as shown in figure 3. As such, if the user navigates backward +using the BACK key, each instance of the activity is revealed in the order they were opened (each +with their own UI state). However, you can modify this behavior if you do not want an activity to be +instantiated more than once. How to do so is discussed in the later section about <a +href="#ManagingTasks">Managing Tasks</a>.</p> + + +<p>To summarize the default behavior for activities and tasks:</p> + +<ul> + <li>When Activity A starts Activity B, Activity A is stopped, but the system retains its state +(such as scroll position and text entered into forms). +If the user presses the BACK key while in Activity B, Activity A resumes with its state +restored.</li> + <li>When the user leaves a task by pressing the HOME key, the current activity is stopped and +its task goes into the background. The system retains the state of every activity in the task. If +the user later resumes the task by selecting the launcher icon that began the task, the task comes +to the foreground and resumes the activity at the top of the stack.</li> + <li>If the user presses the BACK key, the current activity is popped from the stack and +destroyed. The previous activity in the stack is resumed. When an activity is destroyed, the system +<em>does not</em> retain the activity's state.</li> + <li>Activities can be instantiated multiple times, even from other tasks.</li> +</ul> + + +<h2 id="ActivityState">Saving Activity State</h2> + +<p>As discussed above, the system's default behavior preserves the state of an activity when it is +stopped. This way, when users navigate back to a previous activity, its user interface appears +the way they left it. However, you can—and <strong>should</strong>—proactively retain +the state of your activities using callback methods, in case the activity is destroyed and must +be recreated.</p> + +<p>When the system stops one of your activities (such as when a new activity starts or the task +moves to the background), the system might destroy that activity completely if it needs to recover +system memory. When this happens, information about the activity state is lost. If this happens, the +system still +knows that the activity has a place in the back stack, but when the activity is brought to the +top of the stack the system must recreate it (rather than resume it). In order to +avoid loosing the user's work, you should proactively retain it by implementing the {@link +android.app.Activity#onSaveInstanceState onSaveInstanceState()} callback +methods in your activity.</p> + +<p>For more information about how to save your activity state, see the <a +href="{@docRoot}guide/topics/fundamentals/activities.html#SavingActivityState">Activities</a> +document.</p> + + + +<h2 id="ManagingTasks">Managing Tasks</h2> + +<p>The way Android manages tasks and the back stack, as described above—by placing all +activities started in succession in the same task and in a "last in, first out" stack—works +great for most applications and you shouldn't have to worry about how your activities are associated +with tasks or how they exist in the back stack. However, you might decide that you want to interrupt +the normal behavior. Perhaps you want an activity in your application to begin a new task when it is +started (instead of being placed within the current task); or, when you start an activity, you want +to bring forward an existing instance of it (instead of creating a new +instance on top of the back stack); or, you want your back stack to be cleared of all +activitiesstart an activity except for the root activity when the user leaves the task.</p> + +<p>You can do these things and more, with attributes in the +<a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code +<activity>}</a> manifest element and with flags in the intent that you pass to {@link +android.app.Activity#startActivity startActivity()}.</p> + +<p>In this regard, the the principal <a +href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> +attributes you can use are:</p> + +<ul class="nolist"> + <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#aff">{@code +taskAffinity}</a></li> + <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code +launchMode}</a></li> + <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#reparent">{@code +allowTaskReparenting}</a></li> + <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#clear">{@code +clearTaskOnLaunch}</a></li> + <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#always">{@code +alwaysRetainTaskState}</a></li> + <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#finish">{@code +finishOnTaskLaunch}</a></li> +</ul> + +<p>And the principal intent flags you can use are:</p> + +<ul class="nolist"> + <li>{@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK}</li> + <li>{@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TOP}</li> + <li>{@link android.content.Intent#FLAG_ACTIVITY_SINGLE_TOP}</li> +</ul> + +<p>In the following sections, you'll see how you can use these manifest attributes and intent +flags to define how activities are associated with tasks and how the behave in the back stack.</p> + + +<p class="caution"><strong>Caution:</strong> Most applications should not interrupt the default +behavior for activities and tasks. If you determine that it's necessary for your activity to modify +the default behaviors, use caution and be sure to test the usability of the activity during +launch and when navigating back to it from other activities and tasks with the BACK key. Be sure +to test for navigation behaviors that might conflict with the user's expected behavior.</p> + + +<h3 id="TaskLaunchModes">Defining launch modes</h3> + +<p>Launch modes allow you to define how a new instance of an activity is associated with the +current task. You can define different launch modes in two ways:</p> +<ul class="nolist"> + <li><a href="#ManifestForTasks">Using the manifest file</a> + <p>When you declare an activity in your manifest file, you can specify how the activity +should associate with tasks when it starts.</li> + <li><a href="#IntentFlagsForTasks">Using Intent flags</a> + <p>When you call {@link android.app.Activity#startActivity startActivity()}, +you can include a flag in the {@link android.content.Intent} that declares how (or +whether) the new activity should associate with the current task.</p></li> +</ul> + +<p>As such, if Activity A starts Activity B, Activity B can define in its manifest how it +should associate with the current task (if at all) and Activity A can also request how Activity +B should associate with current task. If both activities define how Activity B +should associate with a task, then Activity A's request (as defined in the intent) is honored +over Activity B's request (as defined in its manifest).</p> + +<p class="note"><strong>Note:</strong> Some the launch modes available in the manifest +are not available as flags for an intent and, likewise, some launch modes available as flags +for an intent cannot be defined in the manifest.</p> + + +<h4 id="ManifestForTasks">Using the manifest file</h4> + +<p>When declaring an activity in your manifest file, you can specify how the activity should +associate with a task using the <a +href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> +element's <a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code +launchMode}</a> attribute.</p> + +<p>The <a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code +launchMode}</a> attribute specifies an instruction on how the activity should be launched into a +task. There are four different launch modes you can assign to the +<code><a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">launchMode</a></code> +attribute:</p> + +<dl> +<dt>{@code "standard"} (the default mode)</dt> + <dd>Default. The system creates a new instance of the activity in the task from +which it was started and routes the intent to it. The activity can be instantiated multiple times, +each instance can belong to different tasks, and one task can have multiple instances.</dd> +<dt>{@code "singleTop"}</dt> + <dd>If an instance of the activity already exists at the top of the current task, the system +routes the intent to that instance through a call to its {@link +android.app.Activity#onNewIntent onNewIntent()} method, rather than creating a new instance of the +activity. The activity can be instantiated multiple times, each instance can +belong to different tasks, and one task can have multiple instances (but only if the the +activity at the top of the back stack is <em>not</em> an existing instance of the activity). + <p>For example, suppose a task's back stack consists of root activity A with activities B, C, +and D on top (the stack is A-B-C-D; D is on top). An intent arrives for an activity of type D. +If D has the default {@code "standard"} launch mode, a new instance of the class is launched and the +stack becomes A-B-C-D-D. However, if D's launch mode is {@code "singleTop"}, the existing instance +of D is deliverd the intent through {@link +android.app.Activity#onNewIntent onNewIntent()}, because it's at the top of the stack—the +stack remains A-B-C-D. However, if an intent arrives for an activity of type B, then a new +instance of B is added to the stack, even if its launch mode is {@code "singleTop"}.</p> + <p class="note"><strong>Note:</strong> When a new instance of an activity is created, +the user can press the BACK key to return 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 the state of +the activity before the new intent arrived in {@link android.app.Activity#onNewIntent +onNewIntent()}.</p> +</dd> + +<dt>{@code "singleTask"}</dt> + <dd>The system creates a new task and instantiates the activity at the root of the new task. +However, if an instance of the activity already exists in a separate task, the system routes the +intent to the existing instance through a call to its {@link +android.app.Activity#onNewIntent onNewIntent()} method, rather than creating a new instance. Only +one instance of the activity can exist at a time. + <p class="note"><strong>Note:</strong> Although the activity starts in a new task, the +BACK key still returns the user to the previous activity.</p></dd> +<dt>{@code "singleInstance"}.</dt> + <dd>Same as {@code "singleTask"}, except that the system doesn't launch any other activities into +the task holding the instance. The activity is always the single and only member of its task; +any activities started by this one open in a separate task.</dd> +</dl> + + +<p>As another example, the Android Browser application declares that the web browser activity should +always open in its own task—by specifying the {@code singleTask} launch mode in the <a +href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> element. +This means that if your application issues an +intent to open the Android Browser, its activity is <em>not</em> placed in the same +task as your application. Instead, either a new task starts for the Browser or, if the Browser +already has a task running in the background, that task is brought forward to handle the new +intent.</p> + +<p>Regardless of whether an activity starts in a new task or in the same task as the activity that +started it, the BACK key always takes the user to the previous activity. However, if you +start an activity from your task (Task A) that specifies the {@code singleTask} launch mode, then +that activity might have an instance in the background that belongs to a task with its own back +stack (Task B). In this +case, when Task B is brought forward to handle a new intent, the BACK key first navigates +backward through the activities in Task B before returning to +the top-most activity in Task A. Figure 4 visualizes this type of scenario.</p> + +<img src="{@docRoot}images/fundamentals/diagram_backstack_singletask_multiactivity.png" alt="" /> +<p class="img-caption"><strong>Figure 4.</strong> A representation of how an activity with +launch mode "singleTask" is added to the back stack. If the activity is already a part of a +background task with its own back stack (Task B), then the entire back stack also comes +forward, on top of the current task (Task A).</p> + +<p>For more information about using launch modes in the manifest file, see the +<code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code> +element documentation, where the {@code launchMode} attribute and the accepted values are +discussed more.</p> + +<p class="note"><strong>Note:</strong> The behaviors that you specify for your activity with the <a +href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code launchMode}</a> attribute +can be overriden by flags included with the intent that start your activity, as discussed in the +next section.</p> + + + +<h4 id="#IntentFlagsForTasks">Using Intent flags</h4> + +<p>When starting an activity, you can modify the default association of an activity to its task +by including flags in the intent that you deliver to {@link +android.app.Activity#startActivity startActivity()}. The flags you can use to modify the +default behavior are:</p> + +<p> + <dt>{@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK}</dt> + <dd>Start the activity in a new task. If a task is already running for the activity you are now +starting, that task is brought to the foreground with its last state restored and the activity +receives the new intent in {@link android.app.Activity#onNewIntent onNewIntent()}. + <p>This produces the same behavior as the {@code "singleTask"} <a +href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code launchMode}</a> value, +discussed in the previous section.</p></dd> + <dt>{@link android.content.Intent#FLAG_ACTIVITY_SINGLE_TOP}</dt> + <dd>If the activity being started is the current activity (at the top of the back stack), then +the existing instance receives a call to {@link android.app.Activity#onNewIntent onNewIntent()}, +instead of creating a new instance of the activity. + <p>This produces the same behavior as the {@code "singleTop"} <a +href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code launchMode}</a> value, +discussed in the previous section.</p></dd> + <dt>{@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TOP}</dt> + <dd>If the activity being started is already running in the current task, then instead +of launching a new instance of that activity, all of the other activities on top of it are +destroyed and this intent is delivered to the resumed instance of the activity (now on top), +through {@link android.app.Activity#onNewIntent onNewIntent()}). + <p>There is no value for the <a +href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code launchMode}</a> +attribute that produces this behavior.</p> + <p>{@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. </p> + <p class="note"><strong>Note:</strong> If the launch mode of the designated activity is {@code +"standard"}, it too is removed from the stack and a new instance is launched in its place 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"}. </p> +</dd> +</dl> + + + + + +<h3 id="Affinities">Handling affinities</h3> + +<p>The <em>affinity</em> indicates which task an activity prefers to belong to. By default, all the +activities from the same application have an affinity for each other. So, by default, all +activities in the same application prefer to be in the same task. However, you can modify +the default affinity for an activity. Activities defined in +different applications can share an affinity, or activities defined in the same application can be +assigned different task affinities.</p> + +<p>You can modify the affinity for any given activity with the <a +href="{@docRoot}guide/topics/manifest/activity-element.html#aff">{@code taskAffinity}</a> attribute +of the <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> +element.</p> + +<p>The <a +href="{@docRoot}guide/topics/manifest/activity-element.html#aff">{@code taskAffinity}</a> +attribute takes a string value, which must be unique from the default package name +declared in the <a href="{@docRoot}guide/topics/manifest/manifest-element.html">{@code +<manifest>}</a> element, because the system uses that name to identify the default task +affinity for the application.</p> + +<p>The affinity comes into play in two circumstances:</p> +<ul> + <li>When the intent that launches an activity contains the {@link +android.content.Intent#FLAG_ACTIVITY_NEW_TASK} flag. + +<p>A new activity is, by default, launched into the task of the activity +that called {@link android.app.Activity#startActivity startActivity()}. It's pushed onto the same +back stack as the caller. However, if the intent passed to {@link +android.app.Activity#startActivity startActivity()} contains the {@link +android.content.Intent#FLAG_ACTIVITY_NEW_TASK} +flag, the system looks for a different task to house the new activity. Often, 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.</p> + +<p>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 the task. 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 {@link +android.app.Activity#startActivity 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, such as with a launcher icon (the root activity of the task +has a {@link android.content.Intent#CATEGORY_LAUNCHER} intent filter; see the <a +href="#Starting">Starting a task</a> section below).</p> +</li> + + <li>When an activity has its <a +href="{@docRoot}guide/topics/manifest/activity-element.html#reparent">{@code +allowTaskReparenting}</a> attribute set to {@code "true"}. + <p>In this case, the activity can move from the task it starts to the task it has an affinity +for, when that task comes to the foreground.</p> + <p>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 application affinity) and it allows re-parenting with this attribute. +When one of your activities starts the weather reporter activity, it initially belongs to the same +task as your activity. However, when the travel application's task comes to the foreground, the +weather reporter activity is reassigned to that task and displayed within it.</p> +</li> +</ul> + +<p class="note"><strong>Tip:</strong> If an {@code .apk} file contains more than one "application" +from the user's point of view, you probably want to use the <a +href="{@docRoot}guide/topics/manifest/activity-element.html#aff">{@code taskAffinity}</a> +attribute to assign different affinities to the activities associated with each "application".</p> + + + +<h3 id="Clearing">Clearing the back stack</h3> + +<p>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, only the root activity is restored. +The system behaves this way, because, after an extended amount of time, users likely have abandoned +what they were doing before and are returning to the task to begin something new. </p> + +<p>There are some activity attributes that you can use to modify this behavior: </p> + +<dl> +<dt><code><a +href="{@docRoot}guide/topics/manifest/activity-element.html#always">alwaysRetainTaskState</a></code> +</dt> +<dd>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.</dd> + +<dt><code><a +href="{@docRoot}guide/topics/manifest/activity-element.html#clear">clearTaskOnLaunch</a></code></dt> +<dd>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 opposite of <a +href="{@docRoot}guide/topics/manifest/activity-element.html#always">{@code +alwaysRetainTaskState}</a>. The user always returns to the task in its +initial state, even after a leaving the task for only a moment.</dd> + +<dt><code><a +href="{@docRoot}guide/topics/manifest/activity-element.html#finish">finishOnTaskLaunch</a></code> +</dt> +<dd>This attribute is like <a +href="{@docRoot}guide/topics/manifest/activity-element.html#clear">{@code clearTaskOnLaunch}</a>, +but it operates on a +single activity, not an entire task. It can also 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 is no longer present.</dd> +</dl> + + + + +<h3 id="Starting">Starting a task</h3> + +<p>You can set up an activity 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. For example:</p> + +<pre> +<activity ... > + <intent-filter ... > + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + ... +</activity> +</pre> + +<p>An intent filter of this kind causes an icon and label for the +activity to be displayed in the application launcher, giving users a way to launch the activity and +to return to the task that it creates any time after it has been launched. +</p> + +<p>This second ability is important: Users must be able to leave a task and then come back to it +later using this activity launcher. For this reason, the two <a href="#LaunchModes">launch +modes</a> that mark activities as always initiating a task, {@code "singleTask"} and "{@code +"singleInstance"}, should be used only when the activity has an {@link +android.content.Intent#ACTION_MAIN} +and a {@link android.content.Intent#CATEGORY_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 sent to the background and not +visible. Because it is not represented in the application launcher, the user has no way to return to +the task. +</p> + +<p>For those cases where you don't want the user to be able to return to an activity, set the + <code><a +href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code> element's +<a href="{@docRoot}guide/topics/manifest/activity-element.html#finish">{@code +finishOnTaskLaunch}</a> to {@code "true"} (see <a +href="#Clearing">Clearing the stack</a>).</p> + + + + +<h2>Beginner's Path</h2> + +<p>For more information about how to use intents to +activate other application components and publish the intents to which your components +respond, continue with the <b><a +href="{@docRoot}guide/topics/intents/intents-filters.html">Intents and Intent +Filters</a></b> document.</p> diff --git a/docs/html/guide/topics/resources/string-resource.jd b/docs/html/guide/topics/resources/string-resource.jd index 81c5d55..2db38f1 100644 --- a/docs/html/guide/topics/resources/string-resource.jd +++ b/docs/html/guide/topics/resources/string-resource.jd @@ -12,8 +12,8 @@ your application with strings:</p> <dd>XML resource that provides a single string.</dd> <dt><a href="#StringArray">String Array</a></dt> <dd>XML resource that provides an array of strings.</dd> - <dt><a href="#Plurals">Plurals</a></dt> - <dd>XML resource that carries different strings for different pluralizations + <dt><a href="#Plurals">Quantity Strings (Plurals)</a></dt> + <dd>XML resource that carries different strings for different quantities of the same word or phrase.</dd> </dl> @@ -218,13 +218,30 @@ getStringArray}(R.array.planets_array); -<h2 id="Plurals">Plurals</h2> +<h2 id="Plurals">Quantity Strings (Plurals)</h2> -<p>A pair of strings that each provide a different plural form of the same word or phrase, -which you can collectively reference from the application. When you request the plurals -resource using a method such as {@link android.content.res.Resources#getQuantityString(int,int) -getQuantityString()}, you must pass a "count", which will determine the plural form you -require and return that string to you.</p> +<p>Different languages have different rules for grammatical agreement with quantity. In English, +for example, the quantity 1 is a special case. We write "1 book", but for any other quantity we'd +write "<i>n</i> books". This distinction between singular and plural is very common, but other +languages make finer distinctions. The full set supported by Android is <code>zero</code>, +<code>one</code>, <code>two</code>, <code>few</code>, <code>many</code>, and <code>other</code>. + +<p>The rules for deciding which case to use for a given language and quantity can be very complex, +so Android provides you with methods such as +{@link android.content.res.Resources#getQuantityString(int,int) getQuantityString()} to select +the appropriate resource for you. + +<p>Note that the selection is made based on grammatical necessity. A string for <code>zero</code> +in English will be ignored even if the quantity is 0, because 0 isn't grammatically different +from 2, or any other number except 1 ("zero books", "one book", "two books", et cetera). +Don't be misled either by the fact that, say, <code>two</code> sounds like it could only apply to +the quantity 2: a language may require that 2, 12, 102 (et cetera) are all treated like one +another but differently to other quantities. Rely on your translator to know what distinctions +their language actually insists upon. + +<p>It's often possible to avoid quantity strings by using quantity-neutral formulations such as +"Books: 1". This will make your life and your translators' lives easier, if it's a style that's +in keeping with your application. <p class="note"><strong>Note:</strong> A plurals collection is a simple resource that is referenced using the value provided in the {@code name} attribute (not the name of the XML @@ -251,7 +268,7 @@ In Java: <code>R.plurals.<em>plural_name</em></code> <<a href="#plurals-element">plurals</a> name="<em>plural_name</em>"> <<a href="#plurals-item-element">item</a> - quantity=["one" | "other"] + quantity=["zero" | "one" | "two" | "few" | "many" | "other"] ><em>text_string</em></item> </plurals> </resources> @@ -285,16 +302,27 @@ Styling</a>, below, for information about to properly style and format your stri <p class="caps">attributes:</p> <dl class="atn-list"> <dt><code>quantity</code></dt> - <dd><em>Keyword</em>. A value indicating the case in which this string should be used. Valid -values: + <dd><em>Keyword</em>. A value indicating when this string should be used. Valid +values, with non-exhaustive examples in parentheses: <table> <tr><th>Value</th><th>Description</th></tr> <tr> - <td>{@code one}</td><td>When there is one (a singular string).</td> + <td>{@code zero}</td><td>When the language requires special treatment of the number 0 (as in Arabic).</td> + </tr> + <tr> + <td>{@code one}</td><td>When the language requires special treatment of numbers like one (as with the number 1 in English and most other languages; in Russian, any number ending in 1 but not ending in 11 is in this class).</td> + </tr> + <tr> + <td>{@code two}</td><td>When the language requires special treatment of numbers like two (as in Welsh).</td> + </tr> + <tr> + <td>{@code few}</td><td>When the language requires special treatment of "small" numbers (as with 2, 3, and 4 in Czech; or numbers ending 2, 3, or 4 but not 12, 13, or 14 in Polish).</td> </tr> <tr> - <td>{@code other}</td><td>When the quantity is anything other than one (a plural -string, but also used when the count is zero).</td> + <td>{@code many}</td><td>When the language requires special treatment of "large" numbers (as with numbers ending 11-99 in Maltese).</td> + </tr> + <tr> + <td>{@code other}</td><td>When the language does not require special treatment of the given quantity.</td> </tr> </table> </dd> @@ -315,6 +343,17 @@ string, but also used when the count is zero).</td> </plurals> </resources> </pre> + <p>XML file saved at {@code res/values-pl/strings.xml}:</p> +<pre> +<?xml version="1.0" encoding="utf-8"?> +<resources> + <plurals name="numberOfSongsAvailable"> + <item quantity="one">Znaleziono jedną piosenkę.</item> + <item quantity="few">Znaleziono %d piosenki.</item> + <item quantity="other">Znaleziono %d piosenek.</item> + </plurals> +</resources> +</pre> <p>Java code:</p> <pre> int count = getNumberOfsongsAvailable(); diff --git a/docs/html/guide/topics/ui/dialogs.jd b/docs/html/guide/topics/ui/dialogs.jd index 1a997f9..879eb8b 100644 --- a/docs/html/guide/topics/ui/dialogs.jd +++ b/docs/html/guide/topics/ui/dialogs.jd @@ -473,18 +473,25 @@ public class NotificationTest extends Activity { progressDialog = new ProgressDialog(NotificationTest.this); progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); progressDialog.setMessage("Loading..."); - progressThread = new ProgressThread(handler); - progressThread.start(); return progressDialog; default: return null; } } + @Override + protected void onPrepareDialog(int id, Dialog dialog) { + switch(id) { + case PROGRESS_DIALOG: + progressDialog.setProgress(0); + progressThread = new ProgressThread(handler); + progressThread.start(); + } + // Define the Handler that receives messages from the thread and update the progress final Handler handler = new Handler() { public void handleMessage(Message msg) { - int total = msg.getData().getInt("total"); + int total = msg.arg1; progressDialog.setProgress(total); if (total >= 100){ dismissDialog(PROGRESS_DIALOG); @@ -515,9 +522,7 @@ public class NotificationTest extends Activity { Log.e("ERROR", "Thread Interrupted"); } Message msg = mHandler.obtainMessage(); - Bundle b = new Bundle(); - b.putInt("total", total); - msg.setData(b); + msg.arg1 = total; mHandler.sendMessage(msg); total++; } diff --git a/docs/html/guide/tutorials/notepad/notepad-ex2.jd b/docs/html/guide/tutorials/notepad/notepad-ex2.jd index a945a62..854731f 100644 --- a/docs/html/guide/tutorials/notepad/notepad-ex2.jd +++ b/docs/html/guide/tutorials/notepad/notepad-ex2.jd @@ -87,8 +87,8 @@ Open the Notepadv2 class.</p> menu callback used for the options menu. Here, we add just one line, which will add a menu item to delete a note. Call <code>menu.add()</code> like so: <pre> -public boolean onCreateContextMenu(Menu menu, View v - ContextMenuInfo menuInfo) { +public void onCreateContextMenu(Menu menu, View v, + ContextMenu.ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); menu.add(0, DELETE_ID, 0, R.string.menu_delete); }</pre> diff --git a/docs/html/images/fundamentals/diagram_backstack.png b/docs/html/images/fundamentals/diagram_backstack.png Binary files differnew file mode 100644 index 0000000..2c6e33f --- /dev/null +++ b/docs/html/images/fundamentals/diagram_backstack.png diff --git a/docs/html/images/fundamentals/diagram_backstack_singletask_multiactivity.png b/docs/html/images/fundamentals/diagram_backstack_singletask_multiactivity.png Binary files differnew file mode 100644 index 0000000..d6a21d7 --- /dev/null +++ b/docs/html/images/fundamentals/diagram_backstack_singletask_multiactivity.png diff --git a/docs/html/images/fundamentals/diagram_multiple_instances.png b/docs/html/images/fundamentals/diagram_multiple_instances.png Binary files differnew file mode 100644 index 0000000..380e7788 --- /dev/null +++ b/docs/html/images/fundamentals/diagram_multiple_instances.png diff --git a/docs/html/images/fundamentals/diagram_multitasking.png b/docs/html/images/fundamentals/diagram_multitasking.png Binary files differnew file mode 100644 index 0000000..b8c7b45 --- /dev/null +++ b/docs/html/images/fundamentals/diagram_multitasking.png diff --git a/docs/html/images/fundamentals/restore_instance.png b/docs/html/images/fundamentals/restore_instance.png Binary files differnew file mode 100644 index 0000000..fa428a7 --- /dev/null +++ b/docs/html/images/fundamentals/restore_instance.png diff --git a/docs/html/resources/browser.jd b/docs/html/resources/browser.jd new file mode 100644 index 0000000..8a08769 --- /dev/null +++ b/docs/html/resources/browser.jd @@ -0,0 +1,49 @@ +page.title=Technical Resources +@jd:body + +<style type="text/css"> + {@literal @import} "{@docRoot}assets/android-developer-resource-browser.css"; +</style> + +<script type="text/javascript" src="{@docRoot}assets/android-developer-resource-browser.js"></script> +<script type="text/javascript" src="{@docRoot}assets/microtemplate.js"></script> + +<div> + <p style="display: none; float: right">Filter: <input id="resource-browser-keyword-filter"/></p> + <p id="resource-browser-search-params">Showing all technical resources:</p> +</div> + +<noscript> + <p class="note"><strong>Error:</strong> + You must have JavaScript enabled to view this page. Resources are also + available offline in the SDK. + </p> +</noscript> + +<div id="resource-browser-results"> + <div class="no-results">No results.</div> +</div> + +<script type="text/html" id="tmpl_resource_browser_result"> +<div class="result"> + <h3> + <% if ('external' in tagsHash) { %><strong>External: </strong> <% } %> + <a href="<%= path %>"><%= title.en %></a> + <% if ('new' in tagsHash) { %><span class="new">new!</span> <% } %> + </h3> + <p class="resource-meta"><% + var __g = ['', '']; + if ('article' in tagsHash) { + __g = ['Article', 'about']; + } else if ('tutorial' in tagsHash) { + __g = ['Tutorial', 'on']; + } else if ('sample' in tagsHash) { + __g = ['Sample', 'for']; + } else if ('video' in tagsHash) { + __g = ['Video', 'about']; + } + %> + <%= __g[0] %><% if (topicsHtml) { %> <%= __g[1] %><% } %> <%= topicsHtml %></p> + <p><%= description.en %></p> +</div> +</script> diff --git a/docs/html/resources/index.jd b/docs/html/resources/index.jd index 1668721..9055868 100644 --- a/docs/html/resources/index.jd +++ b/docs/html/resources/index.jd @@ -1,38 +1,90 @@ page.title=Developer Resources @jd:body +<style type="text/css"> + #resource-list-table td { + border: 0; + padding: 0 24px; + width: 33%; + max-width: 250px; + border-right: 1px solid #ddd; + } + + #resource-list-table td.last { + border-right: 0; + padding-right: 0; + } +</style> + <p> -This section provides technical articles, tutorials, sample code, and other +This section provides articles, tutorials, sample code, and other information to help you quickly implement the features you want in your -application. +application. To return to this page later, just click the "Resources" +tab while any Resources page is loaded. </p> -<dl> -<dt><b>Technical Articles</b></dt> -<dd>Focused discussions about Android development subjects, including -optimizations, tips, interesting implementations, -and so on. Most of the articles provide "how-to" instructions for adding -features or functionality to your app. The articles are drawn from posts to the -Android Developers Blog. -</dd> - -<dt><b>Tutorials</b></dt> -<dd>Step-by-step instructions demonstrating how to build an Android application -that has the specific features you want. </dd> - -<dt><b>Sample Code</b></dt> -<dd>Fully-functioning sample applications that you can look at or build and run, -to learn about how Android works. Feel free to reuse any of the code or -techniques that you find in the samples!</dd> +<h2>Technical Resources</h2> + +<table id="resource-list-table"> +<tr> + <td> + <a href="{@docRoot}resources/browser.html?tag=sample"> + <img src="{@docRoot}assets/images/resource-big-sample.png"/> + </a> + <h3><a href="{@docRoot}resources/browser.html?tag=sample"> + Sample Code + </a></h3> + <p>Fully-functioning sample applications that you can build and run + to learn about how Android works. Feel free to reuse any of the code or + techniques in the samples.</p> + </td> + <td> + <a href="{@docRoot}resources/browser.html?tag=article"> + <img src="{@docRoot}assets/images/resource-big-article.png"/> + </a> + <h3><a href="{@docRoot}resources/browser.html?tag=article"> + Articles + </a></h3> + <p>Focused discussions about Android development subjects, including + optimizations, tips, interesting implementations, "how-tos", + and so on.</p> + </td> + <td> + <a href="{@docRoot}resources/browser.html?tag=tutorial"> + <img src="{@docRoot}assets/images/resource-big-tutorial.png"/> + </a> + <h3><a href="{@docRoot}resources/browser.html?tag=tutorial"> + Tutorials + </a></h3> + <p>Step-by-step instructions demonstrating how to build an Android application + that has the specific features you want.</p> + </td> + <!-- <td class="last"> + <a href="{@docRoot}resources/browser.html?tag=video"> + <img src="{@docRoot}assets/images/resource-big-video.png"/> + </a> + <h3><a href="{@docRoot}resources/browser.html?tag=video"> + Videos & Screencasts + </a></h3> + <p>Videos and presentation slides from developer events, along with + screencasts to walk you through common Android development + workflows.</p> + </td> --> +</tr> +</table> +<h2>Other Resources</h2> + +<dl> <dt><b>Community</b></dt> <dd>Links to the Android discussion groups and information about other ways to collaborate with other developers. </dd> +<dt><b>Device Dashboard</b></dt> +<dd>Device distribution data, grouped by various dimensions such as screen size +and Android platform version. </dd> + <dt><b>More</b></dt> <dd>Quick development tips, troubleshooting information, and frequently asked questions (FAQs). </dd> </dl> - -<p>To return to this page later, just click the "Resources" tab while any -Resources page is loaded. </p>
\ No newline at end of file diff --git a/docs/html/resources/resources-data.js b/docs/html/resources/resources-data.js new file mode 100644 index 0000000..d06b695 --- /dev/null +++ b/docs/html/resources/resources-data.js @@ -0,0 +1,632 @@ +var ANDROID_TAGS = { + type: { + 'article': 'Article', + 'tutorial': 'Tutorial', + 'sample': 'Sample', + 'video': 'Video', + 'library': 'Code Library' + }, + topic: { + 'accessibility': 'Accessibility', + 'accountsync': 'Accounts & Sync', + 'bestpractice': 'Best Practices', + 'communication': 'Communication', + 'compatibility': 'Compatibility', + 'data': 'Data Access', + 'drawing': 'Canvas Drawing', + 'gamedev': 'Game Development', + 'gl': 'OpenGL ES', + 'input': 'Input Methods', + 'intent': 'Intents', + 'layout': 'Layouts/Views', + 'media': 'Multimedia', + 'newfeature': 'New Features', + 'performance': 'Performance', + 'search': 'Search', + 'testing': 'Testing', + 'ui': 'User Interface', + 'web': 'Web Content' + }, + misc: { + 'external': 'External', + 'new': 'New' + } +}; + +var ANDROID_RESOURCES = [ + +////////////////////////// +/// TECHNICAL ARTICLES /// +////////////////////////// + + { + tags: ['article', 'performance', 'bestpractice'], + path: 'articles/avoiding-memory-leaks.html', + title: { + en: 'Avoiding Memory Leaks' + }, + description: { + en: 'Mobile devices often have limited memory, and memory leaks can cause your application to waste this valuable resource without your knowledge. This article provides tips to help you avoid common causes of memory leaks on the Android platform.' + } + }, + { + tags: ['article', 'compatibility'], + path: 'articles/backward-compatibility.html', + title: { + en: 'Backward Compatibility' + }, + description: { + en: 'The Android platform strives to ensure backwards compatibility. However, sometimes you want to use new features which aren\'t supported on older platforms. This article discusses strategies for selectively using these features based on availability, allowing you to keep your applications portable across a wide range of devices.' + } + }, + { + tags: ['article', 'intent'], + path: 'articles/can-i-use-this-intent.html', + title: { + en: 'Can I Use this Intent?' + }, + description: { + en: 'Android offers a very powerful and yet easy-to-use message type called an intent. You can use intents to turn applications into high-level libraries and make code modular and reusable. While it is nice to be able to make use of a loosely coupled API, there is no guarantee that the intent you send will be received by another application. This article describes a technique you can use to find out whether the system contains any application capable of responding to the intent you want to use.' + } + }, + { + tags: ['article', 'input'], + path: 'articles/creating-input-method.html', + title: { + en: 'Creating an Input Method' + }, + description: { + en: 'Input Method Editors (IMEs) provide the mechanism for entering text into text fields and other Views. Android devices come bundled with at least one IME, but users can install additional IMEs. This article covers the basics of developing an IME for the Android platform.' + } + }, + { + tags: ['article', 'drawing', 'ui'], + path: 'articles/drawable-mutations.html', + title: { + en: 'Drawable Mutations' + }, + description: { + en: 'Drawables are pluggable drawing containers that allow applications to display graphics. This article explains some common pitfalls when trying to modify the properties of multiple Drawables.' + } + }, + { + tags: ['article', 'bestpractice', 'ui'], + path: 'articles/faster-screen-orientation-change.html', + title: { + en: 'Faster Screen Orientation Change' + }, + description: { + en: 'When an Android device changes its orientation, the default behavior is to automatically restart the current activity with a new configuration. However, this can become a bottleneck in applications that access a large amount of external data. This article discusses how to gracefully handle this situation without resorting to manually processing configuration changes.' + } + }, + { + tags: ['article', 'compatibility'], + path: 'articles/future-proofing.html', + title: { + en: 'Future-Proofing Your Apps' + }, + description: { + en: 'A collection of common sense advice to help you ensure that your applications don\'t break when new versions of the Android platform are released.' + } + }, + { + tags: ['article', 'input'], + path: 'articles/gestures.html', + title: { + en: 'Gestures' + }, + description: { + en: 'Touch screens allow users to perform gestures, such as tapping, dragging, flinging, or sliding, to perform various actions. The gestures API enables your application to recognize even complicated gestures with ease. This article explains how to integrate this API into an application.' + } + }, + { + tags: ['article', 'gamedev', 'gl'], + path: 'articles/glsurfaceview.html', + title: { + en: 'Introducing GLSurfaceView' + }, + description: { + en: 'This article provides an overview of GLSurfaceView, a class that makes it easy to implement 2D or 3D OpenGL rendering inside of an Android application.' + } + }, + { + tags: ['article', 'ui', 'layout'], + path: 'articles/layout-tricks-reuse.html', + title: { + en: 'Layout Tricks: Creating Reusable UI Components' + }, + description: { + en: 'Learn how to combine multiple standard UI widgets into a single high-level component, which can be reused throughout your application.' + } + }, + { + tags: ['article', 'layout', 'ui', 'performance', 'bestpractice'], + path: 'articles/layout-tricks-efficiency.html', + title: { + en: 'Layout Tricks: Creating Efficient Layouts' + }, + description: { + en: 'Learn how to optimize application layouts as this article walks you through converting a LinearLayout into a RelativeLayout, and analyzes the resulting implications on performance.' + } + }, + { + tags: ['article', 'layout', 'ui', 'performance', 'bestpractice'], + path: 'articles/layout-tricks-stubs.html', + title: { + en: 'Layout Tricks: Using ViewStubs' + }, + description: { + en: 'Learn about using ViewStubs inside an application\'s layout in order to inflate rarely used UI elements, without the performance implications which would otherwise be caused by using the <code><include></code> tag.' + } + }, + { + tags: ['article', 'layout', 'ui', 'performance', 'bestpractice'], + path: 'articles/layout-tricks-merge.html', + title: { + en: 'Layout Tricks: Merging Layouts' + }, + description: { + en: 'Learn how to use the <code><merge></code> tag in your XML layouts in order to avoid unnecessary levels of hierarchy within an application\'s view tree.' + } + }, + { + tags: ['article', 'ui', 'performance'], + path: 'articles/listview-backgrounds.html', + title: { + en: 'ListView Backgrounds: An Optimization' + }, + description: { + en: 'ListViews are very popular widgets within the Android framework. This article describes some of the optimizations used by the ListView widget, and how to avoid some common issues that this causes when trying to use a custom background.' + } + }, + { + tags: ['article', 'ui', 'newfeature'], + path: 'articles/live-folders.html', + title: { + en: 'Live Folders' + }, + description: { + en: 'Live Folders allow users to display any source of data on their home screen without launching an application. This article discusses how to export an application\'s data in a format suitable for display inside of a live folder.' + } + }, + { + tags: ['article', 'ui', 'newfeature'], + path: 'articles/live-wallpapers.html', + title: { + en: 'Live Wallpapers' + }, + description: { + en: 'Live wallpapers are richer, animated, interactive backgrounds that users can display in their home screens. Learn how to create a live wallpaper and bundle it in an application that users can install on their devices.' + } + }, + { + tags: ['article', 'input'], + path: 'articles/on-screen-inputs.html', + title: { + en: 'Onscreen Input Methods' + }, + description: { + en: 'The Input Method Framework (IMF) allows users to take advantage of on-screen input methods, such as software keyboards. This article provides an overview of Input Method Editors (IMEs) and how applications interact with them.' + } + }, + { + tags: ['article', 'performance', 'bestpractice'], + path: 'articles/painless-threading.html', + title: { + en: 'Painless Threading' + }, + description: { + en: 'This article discusses the threading model used by Android applications and how applications can ensure best UI performance by spawning worker threads to handle long-running operations, rather than handling them in the main thread. The article also explains the API that your application can use to interact with Android UI toolkit components running on the main thread and spawn managed worker threads.' + } + }, + { + tags: ['article', 'ui', 'search'], + path: 'articles/qsb.html', + title: { + en: 'Quick Search Box' + }, + description: { + en: 'Quick Search Box (QSB) is a powerful, system-wide search framework. QSB makes it possible for users to quickly and easily find what they\'re looking for, both on their devices and on the web. This article discusses how to work with the QSB framework to add new search results for an installed application.' + } + }, + { + tags: ['article', 'ui'], + path: 'articles/touch-mode.html', + title: { + en: 'Touch Mode' + }, + description: { + en: 'This article explains the touch mode, one of the most important principles of Android\'s UI toolkit. Whenever a user interacts with a device\'s touch screen, the system enters touch mode. While simple in concept, there are important implications touch mode that are often overlooked.' + } + }, + { + tags: ['article', 'performance', 'bestpractice'], + path: 'articles/track-mem.html', + title: { + en: 'Tracking Memory Allocations' + }, + description: { + en: 'This article discusses how to use the Allocation Tracker tool to observe memory allocations and avoid performance problems that would otherwise be caused by ignoring the effect of Dalvik\'s garbage collector.' + } + }, + { + tags: ['article', 'newfeature'], + path: 'articles/ui-1.5.html', + title: { + en: 'UI Framework Changes in Android 1.5' + }, + description: { + en: 'Explore the UI changes that were introduced in Android 1.5, compared with the UI provided in Android 1.0 and 1.1.' + } + }, + { + tags: ['article', 'newfeature'], + path: 'articles/ui-1.6.html', + title: { + en: 'UI Framework Changes in Android 1.6' + }, + description: { + en: 'Explore the UI changes that were introduced in Android 1.6, compared with the UI provided in Android 1.5. In particular, this article discusses changes to RelativeLayouts and click listeners.' + } + }, + { + tags: ['article', 'ui', 'bestpractice'], + path: 'articles/timed-ui-updates.html', + title: { + en: 'Updating the UI from a Timer' + }, + description: { + en: 'Learn about how to use Handlers as a more efficient replacement for java.util.Timer on the Android platform.' + } + }, + { + tags: ['article', 'ui', 'accessibility'], + path: 'articles/tts.html', + title: { + en: 'Using Text-to-Speech' + }, + description: { + en: 'The text-to-speech API lets your application "speak" to users, in any of several languages. This article provides an overview of the TTS API and how you use to add speech capabilities to your application.' + } + }, + { + tags: ['article', 'ui', 'web'], + path: 'articles/using-webviews.html', + title: { + en: 'Using WebViews' + }, + description: { + en: 'WebViews allow an application to dynamically display HTML and execute JavaScript, without relinquishing control to a separate browser application. This article introduces the WebView classes and provides a sample application that demonstrates its use.' + } + }, + { + tags: ['article', 'ui'], + path: 'articles/wikinotes-linkify.html', + title: { + en: 'WikiNotes: Linkify your Text!' + }, + description: { + en: 'This article introduces WikiNotes for Android, part of the Apps for Android project. It covers the use of Linkify to turn ordinary text views into richer, link-oriented content that causes Android intents to fire when a link is selected.' + } + }, + { + tags: ['article', 'intent'], + path: 'articles/wikinotes-intents.html', + title: { + en: 'WikiNotes: Routing Intents' + }, + description: { + en: 'This article illustrates how an application, in this case the WikiNotes sample app, can use intents to route various types of linked text to the application that handles that type of data. For example, an app can use intents to route a linked telephone number to a dialer app and a web URL to a browser.' + } + }, + { + tags: ['article', 'ui', 'performance'], + path: 'articles/window-bg-speed.html', + title: { + en: 'Window Backgrounds & UI Speed' + }, + description: { + en: 'Some Android applications need to squeeze every bit of performance out of the UI toolkit and there are many ways to do so. In this article, you will discover how to speed up the drawing and the perceived startup time of your activities. Both of these techniques rely on a single feature, the window\'s background drawable.' + } + }, + { + tags: ['article', 'performance', 'bestpractice'], + path: 'articles/zipalign.html', + title: { + en: 'Zipalign: an Easy Optimization' + }, + description: { + en: 'The Android SDK includes a tool called zipalign that optimizes the way an application is packaged. Running zipalign against your application enables Android to interact with it more efficiently at run time and thus has the potential to make it and the overall system run faster. This article provides a high-level overview of the zipalign tool and its use.' + } + }, + +/////////////////// +/// SAMPLE CODE /// +/////////////////// + + { + tags: ['sample', 'layout', 'ui'], + path: 'samples/ApiDemos/index.html', + title: { + en: 'API Demos' + }, + description: { + en: 'A variety of small applications that demonstrate an extensive collection of framework topics.' + } + }, + { + tags: ['sample', 'data', 'newfeature', 'accountsync', 'new'], + path: 'samples/BackupRestore/index.html', + title: { + en: 'Backup and Restore' + }, + description: { + en: 'Illustrates a few different approaches that an application developer can take when integrating with the Android Backup Manager using the BackupAgent API introduced in Android 2.2.' + } + }, + { + tags: ['sample', 'communication'], + path: 'samples/BluetoothChat/index.html', + title: { + en: 'Bluetooth Chat' + }, + description: { + en: 'An application for two-way text messaging over Bluetooth.' + } + }, + { + tags: ['sample', 'accountsync'], + path: 'samples/BusinessCard/index.html', + title: { + en: 'BusinessCard' + }, + description: { + en: 'An application that demonstrates how to launch the built-in contact picker from within an activity. This sample also uses reflection to ensure that the correct version of the contacts API is used, depending on which API level the application is running under.' + } + }, + { + tags: ['sample', 'accountsync'], + path: 'samples/ContactManager/index.html', + title: { + en: 'Contact Manager' + }, + description: { + en: 'An application that demonstrates how to query the system contacts provider using the <code>ContactsContract</code> API, as well as insert contacts into a specific account.' + } + }, + { + tags: ['sample'], + path: 'samples/Home/index.html', + title: { + en: 'Home' + }, + description: { + en: 'A home screen replacement application.' + } + }, + { + tags: ['sample', 'gamedev', 'media'], + path: 'samples/JetBoy/index.html', + title: { + en: 'JetBoy' + }, + description: { + en: 'A game that demonstrates the SONiVOX JET interactive music technology, with <code><a href="/reference/android/media/JetPlayer.html">JetPlayer</a></code>.' + } + }, + { + tags: ['sample', 'ui', 'newfeature'], + path: 'samples/CubeLiveWallpaper/index.html', + title: { + en: 'Live Wallpaper' + }, + description: { + en: 'An application that demonstrates how to create a live wallpaper and bundle it in an application that users can install on their devices.' + } + }, + { + tags: ['sample', 'gamedev', 'media'], + path: 'samples/LunarLander/index.html', + title: { + en: 'Lunar Lander' + }, + description: { + en: 'A classic Lunar Lander game.' + } + }, + { + tags: ['sample', 'ui', 'bestpractice', 'layout'], + path: 'samples/MultiResolution/index.html', + title: { + en: 'Multiple Resolutions' + }, + description: { + en: 'A sample application that shows how to use resource directory qualifiers to provide different resources for different screen configurations.' + } + }, + { + tags: ['sample', 'data'], + path: 'samples/NotePad/index.html', + title: { + en: 'Note Pad' + }, + description: { + en: 'An application for saving notes. Similar (but not identical) to the <a href="/resources/tutorials/notepad/index.html">Notepad tutorial</a>.' + } + }, + { + tags: ['sample', 'accountsync'], + path: 'samples/SampleSyncAdapter/index.html', + title: { + en: 'SampleSyncAdapter' + }, + description: { + en: 'Demonstrates how an application can communicate with a cloud-based service and synchronize its data with data stored locally in a content provider. The sample uses two related parts of the Android framework — the account manager and the synchronization manager (through a sync adapter).' + } + }, + { + tags: ['sample', 'ui', 'search', 'new'], + path: 'samples/SearchableDictionary/index.html', + title: { + en: 'Searchable Dictionary v2' + }, + description: { + en: 'A sample application that demonstrates Android\'s search framework, including how to provide search suggestions for Quick Search Box.' + } + }, + { + tags: ['sample', 'layout', 'ui'], + path: 'samples/Snake/index.html', + title: { + en: 'Snake' + }, + description: { + en: 'An implementation of the classic game "Snake."' + } + }, + { + tags: ['sample', 'testing', 'new'], + path: 'samples/Spinner/index.html', + title: { + en: 'Spinner' + }, + description: { + en: 'A simple application that serves as an application under test for the SpinnerTest example.' + } + }, + { + tags: ['sample', 'testing', 'new'], + path: 'samples/SpinnerTest/index.html', + title: { + en: 'SpinnerTest' + }, + description: { + en: 'The test application for the Activity Testing tutorial. It tests the Spinner example application.' + } + }, + { + tags: ['sample', 'newfeature', 'new'], + path: 'samples/TicTacToeLib/index.html', + title: { + en: 'TicTacToeLib' + }, + description: { + en: 'An example of an Android library project, a type of project that lets you store and manage shared code and resources in one place, then make them available to your other Android applications.' + } + }, + { + tags: ['sample', 'newfeature', 'new'], + path: 'samples/TicTacToeMain/index.html', + title: { + en: 'TicTacToeMain' + }, + description: { + en: 'Demonstrates how an application can make use of shared code and resources stored in an Android library project.' + } + }, + { + tags: ['sample', 'input'], + path: 'samples/SoftKeyboard/index.html', + title: { + en: 'Soft Keyboard' + }, + description: { + en: 'An example of writing an input method for a software keyboard.' + } + }, + { + tags: ['sample', 'ui'], + path: 'samples/Wiktionary/index.html', + title: { + en: 'Wiktionary' + }, + description: { + en: 'An example of creating interactive widgets for display on the Android home screen.' + } + }, + { + tags: ['sample', 'ui'], + path: 'samples/WiktionarySimple/index.html', + title: { + en: 'Wiktionary (Simplified)' + }, + description: { + en: 'A simple Android home screen widgets example.' + } + }, + { + tags: ['sample', 'layout', 'new'], + path: 'samples/XmlAdapters/index.html', + title: { + en: 'XML Adapters' + }, + description: { + en: 'Binding data to views using XML Adapters examples.' + } + }, + +///////////////// +/// TUTORIALS /// +///////////////// + + { + tags: ['tutorial'], + path: 'tutorials/hello-world.html', + title: { + en: 'Hello World' + }, + description: { + en: 'Beginning basic application development with the Android SDK.' + } + }, + { + tags: ['tutorial', 'ui', 'layout'], + path: 'tutorials/views/index.html', + title: { + en: 'Hello Views' + }, + description: { + en: 'A walk-through of the various types of layouts and views available in the Android SDK.' + } + }, + { + tags: ['tutorial', 'ui', 'bestpractice'], + path: 'tutorials/localization/index.html', + title: { + en: 'Hello Localization' + }, + description: { + en: 'The basics of localizing your applications for multiple languages and locales.' + } + }, + { + tags: ['tutorial', 'data'], + path: 'tutorials/notepad/index.html', + title: { + en: 'Notepad Tutorial' + }, + description: { + en: 'A multi-part tutorial discussing intermediate-level concepts such as data access.' + } + }, + { + tags: ['tutorial', 'testing', 'new'], + path: 'tutorials/testing/helloandroid_test.html', + title: { + en: 'Hello Testing' + }, + description: { + en: 'A basic introduction to the Android testing framework.' + } + }, + { + tags: ['tutorial', 'testing', 'new'], + path: 'tutorials/testing/activity_test.html', + title: { + en: 'Activity Testing' + }, + description: { + en: 'A more advanced demonstration of the Android testing framework and tools.' + } + } +]; diff --git a/docs/html/resources/resources_toc.cs b/docs/html/resources/resources_toc.cs index 628287d..a2c94fe 100644 --- a/docs/html/resources/resources_toc.cs +++ b/docs/html/resources/resources_toc.cs @@ -1,5 +1,56 @@ <ul> <li> + <h2><span class="en">Technical Resources</span> + </h2> + <ul> + <li class="toggle-list"> + <div><a href="<?cs var:toroot ?>resources/browser.html?tag=sample"> + <span class="en">Sample Code</span> + <span class="de" style="display:none">Beispielcode</span> + <span class="es" style="display:none">Código de ejemplo</span> + <span class="fr" style="display:none">Exemple de code</span> + <span class="it" style="display:none">Codice di esempio</span> + <span class="ja" style="display:none">サンプル コード</span> + <span class="zh-CN" style="display:none"></span> + <span class="zh-TW" style="display:none"></span> + </a></div> + <ul id="devdoc-nav-sample-list"> + <li><a href="<?cs var:toroot ?>resources/samples/get.html"> + <span class="en">Getting the Samples</span> + </a></li> + </ul> + </li> + <li class="toggle-list"> + <div><a href="<?cs var:toroot ?>resources/browser.html?tag=article"> + <span class="en">Articles</span> + </a></div> + <ul id="devdoc-nav-article-list"> + </ul> + </li> + <li class="toggle-list"> + <div><a href="<?cs var:toroot ?>resources/browser.html?tag=tutorial"> + <span class="en">Tutorials</span> + <span class="de" style="display:none">Lernprogramme</span> + <span class="es" style="display:none">Tutoriales</span> + <span class="fr" style="display:none">Didacticiels</span> + <span class="it" style="display:none">Esercitazioni</span> + <span class="ja" style="display:none">チュートリアル</span> + <span class="zh-CN" style="display:none"></span> + <span class="zh-TW" style="display:none"></span> + </a></div> + <ul id="devdoc-nav-tutorial-list"> + </ul> + </li> + <li class="toggle-list"> + <div><a href="<?cs var:toroot ?>resources/topics.html"> + <span class="en">Topics</span> + </a></div> + <ul id="devdoc-nav-topic-list"> + </ul> + </li> + </ul> + </li> + <li> <h2><span class="en">Community</span> <span style="display:none" class="de"></span> <span style="display:none" class="es">Comunidad</span> @@ -36,238 +87,6 @@ ?> <li> - <h2><span class="en">Technical Articles</span> - </h2> - <ul> - <li class="toggle-list"> - <div><a href="<?cs var:toroot ?>resources/articles/index.html"> - <span class="en">List of Articles</span> - </a></div> - <ul> - <li><a href="<?cs var:toroot ?>resources/articles/avoiding-memory-leaks.html"> - <span class="en">Avoiding Memory Leaks</span> - </a></li> - <li><a href="<?cs var:toroot ?>resources/articles/backward-compatibility.html"> - <span class="en">Backward Compatibility</span> - </a></li> - <li><a href="<?cs var:toroot ?>resources/articles/can-i-use-this-intent.html"> - <span class="en">Can I Use this Intent?</span> - </a></li> - <li><a href="<?cs var:toroot ?>resources/articles/creating-input-method.html"> - <span class="en">Creating an Input Method</span> - </a></li> - <li><a href="<?cs var:toroot ?>resources/articles/drawable-mutations.html"> - <span class="en">Drawable Mutations</span> - </a></li> - <li><a href="<?cs var:toroot ?>resources/articles/faster-screen-orientation-change.html"> - <span class="en">Faster Screen Orientation Change</span> - </a></li> - <li><a href="<?cs var:toroot ?>resources/articles/future-proofing.html"> - <span class="en">Future-Proofing Your Apps</span> - </a></li> - <li><a href="<?cs var:toroot ?>resources/articles/gestures.html"> - <span class="en">Gestures</span> - </a></li> - <li><a href="<?cs var:toroot ?>resources/articles/glsurfaceview.html"> - <span class="en">Introducing GLSurfaceView</span> - </a></li> - <li><a href="<?cs var:toroot ?>resources/articles/layout-tricks-reuse.html"> - <span class="en">Layout Tricks: Reusing </span> - </a></li> - <li><a href="<?cs var:toroot ?>resources/articles/layout-tricks-efficiency.html"> - <span class="en">Layout Tricks: Efficiency</span> - </a></li> - <li><a href="<?cs var:toroot ?>resources/articles/layout-tricks-stubs.html"> - <span class="en">Layout Tricks: ViewStubs </span> - </a></li> - <li><a href="<?cs var:toroot ?>resources/articles/layout-tricks-merge.html"> - <span class="en">Layout Tricks: Merging </span> - </a></li> - <li><a href="<?cs var:toroot ?>resources/articles/listview-backgrounds.html"> - <span class="en">ListView Backgrounds</span> - </a></li> - <li><a href="<?cs var:toroot ?>resources/articles/live-folders.html"> - <span class="en">Live Folders</span> - </a></li> - <li><a href="<?cs var:toroot ?>resources/articles/live-wallpapers.html"> - <span class="en">Live Wallpapers</span> - </a></li> - <li><a href="<?cs var:toroot ?>resources/articles/on-screen-inputs.html"> - <span class="en">Onscreen Input Methods</span> - </a></li> - <li><a href="<?cs var:toroot ?>resources/articles/painless-threading.html"> - <span class="en">Painless Threading</span> - </a></li> - <li><a href="<?cs var:toroot ?>resources/articles/qsb.html"> - <span class="en">Quick Search Box</span> - </a></li> - <li><a href="<?cs var:toroot ?>resources/articles/speech-input.html"> - <span class="en">Speech Input</span> - </a></li> - <li><a href="<?cs var:toroot ?>resources/articles/touch-mode.html"> - <span class="en">Touch Mode</span> - </a></li> - <li><a href="<?cs var:toroot ?>resources/articles/track-mem.html"> - <span class="en">Tracking Memory Allocations</span> - </a></li> - <li><a href="<?cs var:toroot ?>resources/articles/ui-1.5.html"> - <span class="en">UI Framework Changes in Android 1.5</span> - </a></li> - <li><a href="<?cs var:toroot ?>resources/articles/ui-1.6.html"> - <span class="en">UI Framework Changes in Android 1.6</span> - </a></li> - <li><a href="<?cs var:toroot ?>resources/articles/timed-ui-updates.html"> - <span class="en">Updating the UI from a Timer</span> - </a></li> - <li><a href="<?cs var:toroot ?>resources/articles/tts.html"> - <span class="en">Using Text-to-Speech</span> - </a></li> - <li><a href="<?cs var:toroot ?>resources/articles/contacts.html"> - <span class="en">Using the Contacts API</span> - </a></li> - <li><a href="<?cs var:toroot ?>resources/articles/using-webviews.html"> - <span class="en">Using WebViews</span> - </a></li> - <li><a href="<?cs var:toroot ?>resources/articles/wikinotes-linkify.html"> - <span class="en">WikiNotes: Linkify your Text!</span> - </a></li> - <li><a href="<?cs var:toroot ?>resources/articles/wikinotes-intents.html"> - <span class="en">WikiNotes: Routing Intents</span> - </a></li> - <li><a href="<?cs var:toroot ?>resources/articles/window-bg-speed.html"> - <span class="en">Window Backgrounds & UI Speed</span> - </a></li> - <li><a href="<?cs var:toroot ?>resources/articles/zipalign.html"> - <span class="en">Zipalign: An Easy Optimization</span> - </a></li> - </ul> - </li> - </ul> - </li> - - <li> - <h2><span class="en">Tutorials</span> - <span class="de" style="display:none">Lernprogramme</span> - <span class="es" style="display:none">Tutoriales</span> - <span class="fr" style="display:none">Didacticiels</span> - <span class="it" style="display:none">Esercitazioni</span> - <span class="ja" style="display:none">チュートリアル</span> - <span class="zh-CN" style="display:none"></span> - <span class="zh-TW" style="display:none"></span> - </h2> - <ul> - <li><a href="<?cs var:toroot ?>resources/tutorials/hello-world.html"> - <span class="en">Hello World</span> - </a></li> - <li><a href="<?cs var:toroot ?>resources/tutorials/views/index.html"> - <span class="en">Hello Views</span> - </a></li> - <li><a href="<?cs var:toroot ?>resources/tutorials/localization/index.html"> - <span class="en">Hello Localization</span> - </a></li> - <li><a href="<?cs var:toroot ?>resources/tutorials/testing/helloandroid_test.html"> - <span class="en">Hello Testing</span></a> - </li> - <li><a href="<?cs var:toroot ?>resources/tutorials/notepad/index.html"> - <span class="en">Notepad Tutorial</span> - </a></li> - <li><a href="<?cs var:toroot ?>resources/tutorials/testing/activity_test.html"> - <span class="en">Activity Testing</span></a> - </li> - </ul> - </li> - - - <li> - <h2><span class="en">Sample Code</span> - <span class="de" style="display:none">Beispielcode</span> - <span class="es" style="display:none">Código de ejemplo</span> - <span class="fr" style="display:none">Exemple de code</span> - <span class="it" style="display:none">Codice di esempio</span> - <span class="ja" style="display:none">サンプル コード</span> - <span class="zh-CN" style="display:none"></span> - <span class="zh-TW" style="display:none"></span> - </h2> - <ul> - <li><a href="<?cs var:toroot ?>resources/samples/get.html"> - <span class="en">Getting the Samples</span> - </a></li> - <li class="toggle-list"> - <div><a href="<?cs var:toroot ?>resources/samples/index.html"> - <span class="en">List of Samples</span> - </a></div> - <ul> - <li><a href="<?cs var:toroot ?>resources/samples/ApiDemos/index.html"> - <span class="en">API Demos</span> - </a></li> - <li><a href="<?cs var:toroot ?>resources/samples/BackupRestore/index.html"> - <span class="en">Backup and Restore</span> - </a> <span class="new">new!</span></li> - <li><a href="<?cs var:toroot ?>resources/samples/BluetoothChat/index.html"> - <span class="en">Bluetooth Chat</span> - </a></li> - <li><a href="<?cs var:toroot ?>resources/samples/BusinessCard/index.html"> - <span class="en">Business Card</span> - </a></li> - <li><a href="<?cs var:toroot ?>resources/samples/ContactManager/index.html"> - <span class="en">Contact Manager</span> - </a></li> - <li><a href="<?cs var:toroot ?>resources/samples/Home/index.html"> - <span class="en">Home</span> - </a></li> - <li><a href="<?cs var:toroot ?>resources/samples/JetBoy/index.html"> - <span class="en">JetBoy</span> - </a></li> - <li><a href="<?cs var:toroot ?>resources/samples/CubeLiveWallpaper/index.html"> - <span class="en">Live Wallpaper</span> - </a></li> - <li><a href="<?cs var:toroot ?>resources/samples/LunarLander/index.html"> - <span class="en">Lunar Lander</span> - </a></li> - <li><a href="<?cs var:toroot ?>resources/samples/MultiResolution/index.html"> - <span class="en">Multiple Resolutions</span> - </a></li> - <li><a href="<?cs var:toroot ?>resources/samples/NotePad/index.html"> - <span class="en">Note Pad</span> - </a></li> - <li><a href="<?cs var:toroot ?>resources/samples/SampleSyncAdapter/index.html"> - <span class="en">Sample Sync Adapter</span> - </a></li> - <li><a href="<?cs var:toroot ?>resources/samples/SearchableDictionary/index.html"> - <span class="en">Searchable Dictionary v2</span> - </a> <span class="new">new!</span></li> - <li><a href="<?cs var:toroot ?>resources/samples/Snake/index.html"> - <span class="en">Snake</span> - </a></li> - <li><a href="<?cs var:toroot ?>resources/samples/SoftKeyboard/index.html"> - <span class="en">Soft Keyboard</span> - </a></li> - <li><a href="<?cs var:toroot ?>resources/samples/Spinner/index.html"> - <span class="en">Spinner</span> - </a> <span class="new">new!</span></li> - <li><a href="<?cs var:toroot ?>resources/samples/SpinnerTest/index.html"> - <span class="en">SpinnerTest</span> - </a> <span class="new">new!</span></li> - <li><a href="<?cs var:toroot ?>resources/samples/TicTacToeLib/index.html"> - <span class="en">TicTacToeLib</span> - </a> <span class="new">new!</span></li> - <li><a href="<?cs var:toroot ?>resources/samples/TicTacToeMain/index.html"> - <span class="en">TicTacToeMain</span> - </a> <span class="new">new!</span></li> - <li><a href="<?cs var:toroot ?>resources/samples/Wiktionary/index.html"> - <span class="en">Wiktionary</span> - </a></li> - <li><a href="<?cs var:toroot ?>resources/samples/WiktionarySimple/index.html"> - <span class="en">Wiktionary (Simplified)</span> - </a></li> - </ul> - </li> - </ul> - </li> - - - - <li> <h2><span class="en">More</span> </h2> <ul> @@ -295,8 +114,6 @@ </li> </ul> </li> - - </ul> <script type="text/javascript"> diff --git a/docs/html/resources/samples/images/XmlPhotosAdapter.png b/docs/html/resources/samples/images/XmlPhotosAdapter.png Binary files differnew file mode 100644 index 0000000..c018d54 --- /dev/null +++ b/docs/html/resources/samples/images/XmlPhotosAdapter.png diff --git a/docs/html/resources/samples/images/XmlRssReader.png b/docs/html/resources/samples/images/XmlRssReader.png Binary files differnew file mode 100644 index 0000000..00f841b --- /dev/null +++ b/docs/html/resources/samples/images/XmlRssReader.png diff --git a/docs/html/resources/samples/images/sample_notepadtest_junit.png b/docs/html/resources/samples/images/sample_notepadtest_junit.png Binary files differnew file mode 100644 index 0000000..4cda54e --- /dev/null +++ b/docs/html/resources/samples/images/sample_notepadtest_junit.png diff --git a/docs/html/resources/topics.jd b/docs/html/resources/topics.jd new file mode 100644 index 0000000..b5960ff --- /dev/null +++ b/docs/html/resources/topics.jd @@ -0,0 +1,72 @@ +page.title=Technical Resource Topics +@jd:body + +<style type="text/css"> + #resource-topic-table td { + border: 0; + padding: 0; + margin: 0; + padding-left: 1em; + width: 18em; + } + + #resource-topic-table ul { + padding: 0; + margin: 0; + } + + #resource-topic-table li { + list-style: none; + margin: 0; + padding: 0; + } +</style> + +<p> +You can browse the list of technical resources by topic by clicking on the +links below. Over time, as more topics are added, they will be added to the +list below. +</p> + +<noscript> + <p class="note"><strong>Error:</strong> + You must have JavaScript enabled to view this page. Resources are also + available offline in the SDK. + </p> +</noscript> + +<table id="resource-topic-table"> + <tr></tr> +</table> + +<script type="text/javascript"> +<!-- +(function() { + var topics = []; + for (var topic in ANDROID_TAGS['topic']) { + topics.push({name:topic,title:ANDROID_TAGS['topic'][topic]}); + } + topics.sort(function(x,y){ return (x.title < y.title) ? -1 : 1; }); + var topicParent = null; + for (var i = 0; i < topics.length; i++) { + if (topicParent == null || i % 10 == 0) { + // create a new column + topicParent = $('ul', $('<td><ul>').appendTo('#resource-topic-table tr')); + } + + topicParent.append( + $('<li>').append( + $('<h3>').append( + $('<a>') + .attr('href', toRoot + "resources/browser.html?tag=" + topics[i].name) + .append($('<span>') + .addClass('en') + .html(topics[i].title) + ) + ) + ) + ); + } +})(); +//--> +</script>
\ No newline at end of file diff --git a/docs/html/resources/tutorials/notepad/notepad-ex2.jd b/docs/html/resources/tutorials/notepad/notepad-ex2.jd index 289b5fe..499b796 100644 --- a/docs/html/resources/tutorials/notepad/notepad-ex2.jd +++ b/docs/html/resources/tutorials/notepad/notepad-ex2.jd @@ -87,8 +87,8 @@ Open the Notepadv2 class.</p> menu callback used for the options menu. Here, we add just one line, which will add a menu item to delete a note. Call <code>menu.add()</code> like so: <pre> -public boolean onCreateContextMenu(Menu menu, View v - ContextMenuInfo menuInfo) { +public void onCreateContextMenu(Menu menu, View v, + ContextMenu.ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); menu.add(0, DELETE_ID, 0, R.string.menu_delete); }</pre> |