diff options
author | Scott Main <smain@google.com> | 2012-04-02 12:56:42 -0700 |
---|---|---|
committer | Scott Main <smain@google.com> | 2012-04-19 18:53:40 -0700 |
commit | be2f4edd2ca2b4ba9bbed7262719064ca55b54ff (patch) | |
tree | f12e768d0388b854d8a9d30ecefe7c4b27351348 /docs/html/training/basics | |
parent | 93a333e32646778cd96265783e531dddd046367c (diff) | |
download | frameworks_base-be2f4edd2ca2b4ba9bbed7262719064ca55b54ff.zip frameworks_base-be2f4edd2ca2b4ba9bbed7262719064ca55b54ff.tar.gz frameworks_base-be2f4edd2ca2b4ba9bbed7262719064ca55b54ff.tar.bz2 |
docs: Add 101 class on activity lifecycle
including ZIP for sample app
Change-Id: Id2659ebe15094dad10da4d9bdefed527984fccd9
Diffstat (limited to 'docs/html/training/basics')
5 files changed, 886 insertions, 0 deletions
diff --git a/docs/html/training/basics/activity-lifecycle/index.jd b/docs/html/training/basics/activity-lifecycle/index.jd new file mode 100644 index 0000000..d278f04 --- /dev/null +++ b/docs/html/training/basics/activity-lifecycle/index.jd @@ -0,0 +1,74 @@ +page.title=Managing the Activity Lifecycle + +trainingnavtop=true +startpage=true +next.title=Launching an Activity +next.link=starting.html + +@jd:body + +<div id="tb-wrapper"> +<div id="tb"> + + +<h2>Dependencies and prerequisites</h2> +<ul> + <li>How to create an Android project (see <a +href="{@docRoot}training/basics/firstapp/creating-project.html">Creating an Android +Project</a>)</li> +</ul> + + +<h2>You should also read</h2> +<ul> + <li><a href="{@docRoot}guide/topics/fundamentals/activities.html">Activities</a></li> +</ul> + + +<h2>Try it out</h2> + +<div class="download-box"> + <a href="http://developer.android.com/shareables/training/ActivityLifecycle.zip" +class="button">Download the demo</a> + <p class="filename">ActivityLifecycle.zip</p> +</div> + +</div> +</div> + +<p>As a user navigates through, out of, and back to your app, the +{@link android.app.Activity} instances in your app transition between different states in their +lifecycle. For instance, when your +activity starts for the first time, it comes to the foreground of the system and receives user +focus. During this process, the Android system calls a series of lifecycle methods on the +activity in which you set up the user interface and other components. If the user performs an +action that starts another activity or switches to another app, the system calls another set of +lifecycle methods on your activity as it moves into the background (where the activity is no +longer visible, but the instance and its state remains intact).</p> + +<p>Within the lifecycle callback methods, you can declare how your activity behaves when the +user leaves and re-enters the activity. For example, if you're building a streaming video player, +you might pause the video and terminate the network connection when the user switches to another +app. When the user returns, you can reconnect to the network and allow the user to resume the video +from the same spot.</p> + +<p>This class explains important lifecycle callback methods that each {@link +android.app.Activity} instance receives and how you can use them so your activity does what the +user expects and does not consume system resources when your activity doesn't need them.</p> + +<h2>Lessons</h2> + +<dl> + <dt><b><a href="starting.html">Starting an Activity</a></b></dt> + <dd>Learn the basics about the activity lifecycle, how the user can launch your app, and how +to perform basic activity creation.</dd> + <dt><b><a href="pausing.html">Pausing and Resuming an Activity</a></b></dt> + <dd>Learn what happens when your activity is paused (partially obscured) and resumed and what you +should do during these state changes.</dd> + <dt><b><a href="stopping.html">Stopping and Restarting an Activity</a></b></dt> + <dd>Learn what happens when the user completely leaves your activity and returns to it.</dd> + <dt><b><a href="recreating.html">Recreating an Activity</a></b></dt> + <dd>Learn what happens when your activity is destroyed and how you can rebuild the activity +state when necessary.</dd> +</dl> + diff --git a/docs/html/training/basics/activity-lifecycle/pausing.jd b/docs/html/training/basics/activity-lifecycle/pausing.jd new file mode 100644 index 0000000..216d55e --- /dev/null +++ b/docs/html/training/basics/activity-lifecycle/pausing.jd @@ -0,0 +1,152 @@ +page.title=Pausing and Resuming an Activity +parent.title=Managing the Activity Lifecycle +parent.link=index.html + +trainingnavtop=true +previous.title=Starting an Activity +previous.link=starting.html +next.title=Stopping and Restarting an Activity +next.link=stopping.html + +@jd:body + +<div id="tb-wrapper"> + <div id="tb"> + + <h2>This lesson teaches you to</h2> + <ol> + <li><a href="#Pause">Pause Your Activity</a></li> + <li><a href="#Resume">Resume Your Activity</a></li> + </ol> + + <h2>You should also read</h2> + <ul> + <li><a href="{@docRoot}guide/topics/fundamentals/activities.html">Activities</a> + </li> + </ul> + +<h2>Try it out</h2> + +<div class="download-box"> + <a href="http://developer.android.com/shareables/training/ActivityLifecycle.zip" +class="button">Download the demo</a> + <p class="filename">ActivityLifecycle.zip</p> +</div> + + </div> +</div> + +<p>During normal app use, the foreground activity is sometimes obstructed by other +visual components that cause the activity to <em>pause</em>. For example, when a semi-transparent +activity opens (such as one in the style of a dialog), the previous activity pauses. As long as the +activity is still partially visible but currently not the activity in focus, it remains paused.</p> + +<p>However, once the activity is fully-obstructed and not visible, it <em>stops</em> (which is +discussed in the next lesson).</p> + +<p>As your activity enters the paused state, the system calls the {@link +android.app.Activity#onPause onPause()} method on your {@link android.app.Activity}, which allows +you to stop ongoing actions that should not continue while paused (such as a video) or persist +any information that should be permanently saved in case the user continues to leave your app. If +the user returns to your activity from the paused state, the system resumes it and calls the +{@link android.app.Activity#onResume onResume()} method.</p> + +<p class="note"><strong>Note:</strong> When your activity receives a call to {@link +android.app.Activity#onPause()}, it may be an indication that the activity will be paused for a +moment and the user may return focus to your activity. However, it's usually the first indication +that the user is leaving your activity.</p> + +<img src="{@docRoot}images/training/basics/basic-lifecycle-paused.png" /> +<p class="img-caption"><strong>Figure 1.</strong> When a semi-transparent activity obscures +your activity, the system calls {@link android.app.Activity#onPause onPause()} and the activity +waits in the Paused state (1). If the user returns to the activity while it's still paused, the +system calls {@link android.app.Activity#onResume onResume()} (2).</p> + + +<h2 id="Pause">Pause Your Activity</h2> + +<p>When the system calls {@link android.app.Activity#onPause()} for your activity, it +technically means your activity is still partially visible, but most often is an indication that +the user is leaving the activity and it will soon enter the Stopped state. You should usually use +the {@link android.app.Activity#onPause()} callback to:</p> + +<ul> + <li>Stop animations or other ongoing actions that could consume CPU.</li> + <li>Commit unsaved changes, but only if users expect such changes to be permanently saved when +they leave (such as a draft email).</li> + <li>Release system resources, such as broadcast receivers, handles to sensors (like +GPS), or any resources that may affect battery life while your activity is paused and the user +does not need them.</li> +</ul> + +<p>For example, if your application uses the {@link android.hardware.Camera}, the +{@link android.app.Activity#onPause()} method is a good place to release it.</p> + +<pre> +@Override +public void onPause() { + super.onPause(); // Always call the superclass method first + + // Release the Camera because we don't need it when paused + // and other activities might need to use it. + if (mCamera != null) { + mCamera.release() + mCamera = null; + } +} +</pre> + +<p>Generally, you should <strong>not</strong> use {@link android.app.Activity#onPause()} to store +user changes (such as personal information entered into a form) to permanent storage. The only time +you should persist user changes to permanent storage within {@link android.app.Activity#onPause()} +is when you're certain users expect the changes to be auto-saved (such as when drafting an email). +However, you should avoid performing CPU-intensive work during {@link +android.app.Activity#onPause()}, such as writing to a database, because it can slow the visible +transition to the next activity (you should instead perform heavy-load shutdown operations during +{@link android.app.Activity#onStop onStop()}).</p> + +<p>You should keep the amount of operations done in the {@link android.app.Activity#onPause +onPause()} method relatively simple in order to allow for a speedy transition to the user's next +destination if your activity is actually being stopped.</p> + +<p class="note"><strong>Note:</strong> When your activity is paused, the {@link +android.app.Activity} instance is kept resident in memory and is recalled when the activity resumes. +You don’t need to re-initialize components that were created during any of the callback methods +leading up to the Resumed state.</p> + + + +<h2 id="Resume">Resume Your Activity</h2> + +<p>When the user resumes your activity from the Paused state, the system calls the {@link +android.app.Activity#onResume()} method.</p> + +<p>Be aware that the system calls this method every time your activity comes into the foreground, +including when it's created for the first time. As such, you should implement {@link +android.app.Activity#onResume()} to initialize components that you release during {@link +android.app.Activity#onPause()} and perform any other initializations that must occur each time the +activity enters the Resumed state (such as begin animations and initialize components only used +while the actiivty has user focus).</p> + +<p>The following example of {@link android.app.Activity#onResume()} is the counterpart to +the {@link android.app.Activity#onPause()} example above, so it initializes the camera that's +released when the activity pauses.</p> + +<pre> +@Override +public void onResume() { + super.onResume(); // Always call the superclass method first + + // Get the Camera instance as the activity achieves full user focus + if (mCamera == null) { + initializeCamera(); // Local method to handle camera init + } +} +</pre> + + + + + + + diff --git a/docs/html/training/basics/activity-lifecycle/recreating.jd b/docs/html/training/basics/activity-lifecycle/recreating.jd new file mode 100644 index 0000000..941f1fd --- /dev/null +++ b/docs/html/training/basics/activity-lifecycle/recreating.jd @@ -0,0 +1,177 @@ +page.title=Recreating an Activity +parent.title=Managing the Activity Lifecycle +parent.link=index.html + +trainingnavtop=true +previous.title=Stopping and Restarting an Activity +previous.link=stopping.html + +@jd:body + +<div id="tb-wrapper"> + <div id="tb"> + + <h2>This lesson teaches you to</h2> + <ol> + <li><a href="#SaveState">Save Your Activity State</a></li> + <li><a href="#RestoreState">Restore Your Activity State</a></li> + </ol> + + <h2>You should also read</h2> + <ul> + <li><a href="{@docRoot}training/basics/supporting-devices/screens.html">Supporting +Different Screens</a></li> + <li><a +href="{@docRoot}guide/topics/resources/runtime-changes.html">Handling Runtime Changes</a></li> + <li><a href="{@docRoot}guide/topics/fundamentals/activities.html">Activities</a> + </li> + </ul> + + </div> +</div> + +<p>There are a few scenarios in which your activity is destroyed due to normal app behavior, such as +when the user presses the <em>Back</em> button or your activity signals its own destruction by +calling {@link android.app.Activity#finish()}. The system may also destory your activity if it's +currently stopped and hasn't been used in a long time or the foreground activity requires more +resources so the system must shut down background processes to recover memory.</p> + +<p>When your activity is destroyed because the user presses <em>Back</em> or the activity finishes +itself, the system's concept of that {@link android.app.Activity} instance is gone forever because +the behavior indicates the activity is no longer needed. However, if the system destroys +the activity due to system constraints (rather than normal app behavior), then althought the actual +{@link android.app.Activity} instance is gone, the system remembers that it existed such that if +the user navigates back to it, the system creates a new instance of the activity using a set of +saved data that describes the state of the activity when it was destroyed. The saved data that the +system uses to restore the previous state is called the "instance state" and is a collection of +key-value pairs stored in a {@link android.os.Bundle} object.</p> + +<p class="caution"><strong>Caution:</strong> Your activity will be destroyed and recreated each time +the user rotates the screen. When the screen changes orientation, the system destroys and recreates +the foreground activity because the screen configuration has changed and your activity might need to +load alternative resources (such as the layout).</p> + +<p>By default, the system uses the {@link android.os.Bundle} instance state to saves information +about each {@link android.view.View} object in your activity layout (such as the text value entered +into an {@link android.widget.EditText} object). So, if your activity instance is destroyed and +recreated, the state of the layout is automatically restored to its previous state. However, your +activity might have more state information that you'd like to restore, such as member variables that +track the user's progress in the activity.</p> + +<p>In order for you to add additional data to the saved instance state for your activity, there's an +additional callback method in the activity lifecycle that's not shown in the illustration from +previous lessons. The method is {@link android.app.Activity#onSaveInstanceState +onSaveInstanceState()} and the system calls it when the user is leaving your activity. When the +system calls this method, it passes the {@link android.os.Bundle} object that will be saved in the +event that your activity is destroyed unexpectedly so you can add additional information to it. Then +if the system must recreate the activity instance after it was destroyed, it passes the same {@link +android.os.Bundle} object to your activity's {@link android.app.Activity#onRestoreInstanceState +onRestoreInstanceState()} method and also to your {@link android.app.Activity#onCreate onCreate()} +method.</p> + +<img src="{@docRoot}images/training/basics/basic-lifecycle-savestate.png" /> +<p class="img-caption"><strong>Figure 2.</strong> As the system begins to stop your activity, it +calls {@link android.app.Activity#onSaveInstanceState onSaveInstanceState()} (1) so you can specify +additional state data you'd like to save in case the {@link android.app.Activity} instance must be +recreated. +If the activity is destroyed and the same instance must be recreated, the system passes the state +data defined at (1) to both the {@link android.app.Activity#onCreate onCreate()} method +(2) and the {@link android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} method +(3).</p> + + + +<h2 id="SaveState">Save Your Activity State</h2> + +<p>As your activity begins to stop, the system calls {@link android.app.Activity#onSaveInstanceState +onSaveInstanceState()} so your activity can save state information with a collection of key-value +pairs. The default implementation of this method saves information about the state of the activity's +view hierarchy, such as the text in an {@link android.widget.EditText} widget or the scroll position +of a {@link android.widget.ListView}.</p> + +<p>To save additional state information for your activity, you must +implement {@link android.app.Activity#onSaveInstanceState onSaveInstanceState()} and add +key-value pairs to the {@link android.os.Bundle} object. For example:</p> + +<pre> +static final String STATE_SCORE = "playerScore"; +static final String STATE_LEVEL = "playerLevel"; +... + +@Override +public void onSaveInstanceState(Bundle savedInstanceState) { + // Save the user's current game state + savedInstanceState.putInt(STATE_SCORE, mCurrentScore); + savedInstanceState.putInt(STATE_LEVEL, mCurrentLevel); + + // Always call the superclass so it can save the view hierarchy state + super.onSaveInstanceState(savedInstanceState); +} +</pre> + +<p class="caution"><strong>Caution:</strong> Always call the superclass implementation of {@link +android.app.Activity#onSaveInstanceState onSaveInstanceState()} so the default implementation +can save the state of the view hierarchy.</p> + + + +<h2 id="RestoreState">Restore Your Activity State</h2> + +<p>When your activity is recreated after it was previously destroyed, you can recover your saved +state from the {@link android.os.Bundle} that the system +passes your activity. Both the {@link android.app.Activity#onCreate onCreate()} and {@link +android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} callback methods receive +the same {@link android.os.Bundle} that containes the instance state information.</p> + +<p>Because the {@link android.app.Activity#onCreate onCreate()} method is called whether the +system is creating a new instance of your activity or recreating a previous one, you must check +whether the state {@link android.os.Bundle} is null before you attempt to read it. If it is null, +then the system is creating a new instance of the activity, instead of restoring a previous one +that was destroyed.</p> + +<p>For example, here's how you can restore some state data in {@link android.app.Activity#onCreate +onCreate()}:</p> + +<pre> +@Override +protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); // Always call the superclass first + + // Check whether we're recreating a previously destroyed instance + if (savedInstanceState != null) { + // Restore value of members from saved state + mCurrentScore = savedInstanceState.getInt(STATE_SCORE); + mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL); + } else { + // Probably initialize members with default values for a new instance + } + ... +} +</pre> + +<p>Instead of restoring the state during {@link android.app.Activity#onCreate onCreate()} you +may choose to implement {@link +android.app.Activity#onRestoreInstanceState onRestoreInstanceState()}, which the system calls +after the {@link android.app.Activity#onStart()} method. The system calls {@link +android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} only if there is a saved +state to restore, so you do not need to check whether the {@link android.os.Bundle} is null:</p> + +<pre> +public void onRestoreInstanceState(Bundle savedInstanceState) { + // Always call the superclass so it can restore the view hierarchy + super.onRestoreInstanceState(savedInstanceState); + + // Restore state members from saved instance + mCurrentScore = savedInstanceState.getInt(STATE_SCORE); + mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL); +} +</pre> + +<p class="caution"><strong>Caution:</strong> Always call the superclass implementation of {@link +android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} so the default implementation +can restore the state of the view hierarchy.</p> + +<p>To learn more about recreating your activity due to a +restart event at runtime (such as when the screen rotates), read <a +href="{@docRoot}guide/topics/resources/runtime-changes.html">Handling Runtime Changes</a>.</p> + diff --git a/docs/html/training/basics/activity-lifecycle/starting.jd b/docs/html/training/basics/activity-lifecycle/starting.jd new file mode 100644 index 0000000..cc7e473 --- /dev/null +++ b/docs/html/training/basics/activity-lifecycle/starting.jd @@ -0,0 +1,290 @@ +page.title=Starting an Activity +parent.title=Managing the Activity Lifecycle +parent.link=index.html + +trainingnavtop=true +next.title=Pausing and Resuming an Activity +next.link=pausing.html + +@jd:body + + +<div id="tb-wrapper"> + <div id="tb"> + + <h2>This lesson teaches you to</h2> +<ol> + <li><a href="#lifecycle-states">Understand the Lifecycle Callbacks</a></li> + <li><a href="#launching-activity">Specify Your App's Launcher Activity</a></li> + <li><a href="#Create">Create a New Instance</a></li> + <li><a href="#Destroy">Destroy the Activity</a></li> +</ol> + + <h2>You should also read</h2> + <ul> + <li><a href="{@docRoot}guide/topics/fundamentals/activities.html">Activities</a></li> + </ul> + +<h2>Try it out</h2> + +<div class="download-box"> + <a href="http://developer.android.com/shareables/training/ActivityLifecycle.zip" +class="button">Download the demo</a> + <p class="filename">ActivityLifecycle.zip</p> +</div> + + </div> +</div> + +<p>Unlike other programming paradigms in which apps are launched with a {@code main()} method, the +Android system initiates code in an {@link android.app.Activity} instance by invoking specific +callback methods that correspond to specific stages of its +lifecycle. There is a sequence of callback methods that start up an activity and a sequence of +callback methods that tear down an activity.</p> + +<p>This lesson provides an overview of the most important lifecycle methods and shows you how to +handle the first lifecycle callback that creates a new instance of your activity.</p> + + + +<h2 id="lifecycle-states">Understand the Lifecycle Callbacks</h2> + +<p>During the life of an activity, the system calls a core set of lifecycle methods in +a sequence similar to a step pyramid. That is, each stage of the +activity lifecycle is a separate step on the pyramid. As the system creates a new activity instance, +each callback method moves the activity state one step toward the top. The top of the pyramid is the +point at which the activity is running in the foreground and the user can interact with it.</p> + +<p>As the user begins to leave the activity, the system calls other methods that move the activity +state back down the pyramid in order to dismantle the activity. In some cases, the activity will +move only part way down the pyramid and wait (such as when the user switches to another app), from +which point the activity can move back to the top (if the user returns to the activity) and +resume where the user left off.</p> + + +<img src="{@docRoot}images/training/basics/basic-lifecycle.png" /> +<p class="img-caption"><strong>Figure 1.</strong> A simplified illustration of the Activity +lifecycle, expressed as a step pyramid. This shows how, for every callback used to take +the activity a step toward the Resumed state at the top, there's a callback method +that takes the activity a step down. The activity can also return to the resumed state from the +Paused and Stopped state.</p> + + +<p>Depending on the complexity of your activity, you probably don't need to implement all the +lifecycle methods. However, it's important that you understand each one and implement those that +ensure your app behaves the way users expect. Implementing your activity lifecycle methods properly +ensures your app behaves well in several ways, including that it:</p> +<ul> + <li>Does not crash if the user receives a phone call or switches to another app +while using your app.</li> + <li>Does not consume valuable system resources when the user is not actively using +it.</li> + <li>Does not loose the user's progress if they leave your app and return to it at a +later time.</li> + <li>Does not crash of loose the user's progress when the screen rotates between +landscape and portrait orientation.</li> +</ul> + +<!-- +<p class="table-caption"><strong>Table 1.</strong> Activity lifecycle state pairs and callback +methods.</p> +<table> + <tr> + <th scope="col">Lifecycle State</th> + <th scope="col">Startup Method</th> + <th scope="col">Teardown Method</th> + </tr> + <tr> + <td>Created / Destroyed</td> + <td>{@link android.app.Activity#onCreate onCreate()}</td> + <td>{@link android.app.Activity#onDestroy()}</td> + </tr> + <tr> + <td>Started / Stopped</td> + <td>{@link android.app.Activity#onStart()}</td> + <td>{@link android.app.Activity#onStop()}</td> + </tr> + <tr> + <td>Resumed / Resumed</td> + <td>{@link android.app.Activity#onResume()}</td> + <td>{@link android.app.Activity#onPause()}</td> + </tr> +</table> +--> + +<p>As you'll learn in the following lessons, there are several situtations in which an activity +transitions between different states that are illustrated in figure 1. However, only three of +these states can be static. That is, the activity can exist in one of only three states for an +extended period of time:</p> +<dl> + <dt>Resumed</dt> + <dd>In this state, the activity is in the foreground and the user can interact with it. +(Also sometimes referred to as the "running" state.)</dd> + <dt>Paused</dt> + <dd>In this state, the activity is partially obscured by another activity—the +other activity that's in the foreground is semi-transparent or doesn't cover the entire screen. The +paused activity does not receive user input and cannot execute any code. + <dt>Stopped</dt> + <dd>In this state, the activity is completely hidden and not visible to the user; it is +considered to be in the background. While stopped, the activity instance and all its state +information such as member variables is retained, but it cannot execute any code.</dd> +</dl> + +<p>The other states (Created and Started) are transient and the system quickly moves from them to +the next state by calling the next lifecycle callback method. That is, after the system calls +{@link android.app.Activity#onCreate onCreate()}, it quickly calls {@link +android.app.Activity#onStart()}, which is quickly followed by {@link +android.app.Activity#onResume()}.</p> + +<p>That's it for the basic activity lifecycle. Now you'll start learning about some of the +specific lifecycle behaviors.</p> + + + +<h2 id="launching-activity">Specify Your App's Launcher Activity</h2> + +<p>When the user selects your app icon from the Home screen, the system calls the {@link +android.app.Activity#onCreate onCreate()} method for the {@link android.app.Activity} in your app +that you've declared to be the "launcher" (or "main") activity. This is the activity that serves as +the main entry point to your app's user interface.</p> + +<p>You can define which activity to use as the main activity in the Android manifest file, <a +href="{@docRoot}guide/topics/manifest/manifest-intro.html">{@code AndroidManifest.xml}</a>, which is +at the root of your project directory.</p> + +<p>The main activity for your app must be declared in the manifest with an <a +href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code +<intent-filter>}</a> that includes the {@link +android.content.Intent#ACTION_MAIN MAIN} action and +{@link android.content.Intent#CATEGORY_LAUNCHER LAUNCHER} category. For example:</p> + +<pre> +<activity android:name=".MainActivity" android:label="@string/app_name"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> +</activity> +</pre> + +<p class="note"><strong>Note:</strong> When you create a new Android project with the Android SDK +tools, the default project files include an {@link android.app.Activity} class that's declared in +the manifest with this filter.</p> + +<p>If either the {@link android.content.Intent#ACTION_MAIN MAIN} action or +{@link android.content.Intent#CATEGORY_LAUNCHER LAUNCHER} category are not declared for one of your +activities, then your app icon will not appear in the Home screen's list of apps.</p> + + + +<h2 id="Create">Create a New Instance</h2> + +<p>Most apps include several different activities that allow the user to perform different actions. +Whether an activity is the main activity that's created when the user clicks your app icon or a +different activity that your app starts in response to a user action, the system creates +every new instance of {@link android.app.Activity} by calling its {@link +android.app.Activity#onCreate onCreate()} method.</p> + +<p>You must implement the {@link android.app.Activity#onCreate onCreate()} method to perform basic +application startup logic that should happen only once for the entire life of the activity. For +example, your implementation of {@link android.app.Activity#onCreate onCreate()} should define the +user interface and possibly instantiate some class-scope variables.</p> + +<p>For example, the following example of the {@link android.app.Activity#onCreate onCreate()} +method shows some code that performs some fundamental setup for the activity, such as +declaring the user interface (defined in an XML layout file), defining member variables, +and configuring some of the UI.</p> + +<pre> +TextView mTextView; // Member variable for text view in the layout + +@Override +public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // Set the user interface layout for this Activity + // The layout file is defined in the project res/layout/main_activity.xml file + setContentView(R.layout.main_activity); + + // Initialize member TextView so we can manipulate it later + mTextView = (TextView) findViewById(R.id.text_message); + + // Make sure we're running on Honeycomb or higher to use ActionBar APIs + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { + // For the main activity, make sure the app icon in the action bar + // does not behave as a button + ActionBar actionBar = getActionBar(); + actionBar.setHomeButtonEnabled(false); + } +} +</pre> + +<p class="caution"><strong>Caution:</strong> Using the {@link android.os.Build.VERSION.SDK_INT} to +prevent older system's from executing new APIs works in this way on Android 2.0 (API level +5) and higher only. Older versions will encounter a runtime exception.</p> + +<p>Once the {@link android.app.Activity#onCreate onCreate()} finishes execution, the system +calls the {@link android.app.Activity#onStart()} and {@link android.app.Activity#onResume()} methods +in quick succession. Your activity never resides in the Created or Started states. Technically, the +activity becomes visible to the user when {@link android.app.Activity#onStart()} is called, but +{@link android.app.Activity#onResume()} quickly follows and the activity remains in the Resumed +state until something occurs to change that, such as when a phone call is received, the user +navigates to another activity, or the device screen turns off.</p> + +<p>In the other lessons that follow, you'll see how the other start up methods, {@link +android.app.Activity#onStart()} and {@link android.app.Activity#onResume()}, are useful during your +activity's lifecycle when used to resume the activity from the Paused or Stopped states.</p> + +<p class="note"><strong>Note:</strong> The {@link android.app.Activity#onCreate onCreate()} +method includes a parameter called <code>savedInstanceState</code> that's discussed in the +latter lesson about <a href="recreating.html">Recreating an Activity</a>.</p> + + +<img src="{@docRoot}images/training/basics/basic-lifecycle-create.png" /> +<p class="img-caption"><strong>Figure 2.</strong> Another illustration of the activity lifecycle +structure with an emphasis on the three main callbacks that the system calls in sequence when +creating a new instance of the activity: {@link android.app.Activity#onCreate onCreate()}, {@link +android.app.Activity#onStart()}, and {@link android.app.Activity#onResume()}. Once this sequence of +callbacks complete, the activity reaches the Resumed state where users can interact with the +activity until they switch to a different activity.</p> + + + + + + + +<h2 id="Destroy">Destroy the Activity</h2> + +<p>While the activity's first lifecycle callback is {@link android.app.Activity#onCreate +onCreate()}, it's very last callback is {@link android.app.Activity#onDestroy}. The system calls +this method on your activity as the final +signal that your activity instance is being completely removed from the system memory.</p> + +<p>Most apps don't need to implement this method because local class references are destroyed +with the activity and your activity should perform most cleanup during {@link +android.app.Activity#onPause} and {@link android.app.Activity#onStop}. However, if your +activity includes background threads that you created during {@link +android.app.Activity#onCreate onCreate()} or other other long-running resources that could +potentially leak memory if not properly closed, you should kill them during {@link +android.app.Activity#onDestroy}.</p> + +<pre> +@Override +public void onDestroy() { + super.onDestroy(); // Always call the superclass + + // Stop method tracing that the activity started during onCreate() + android.os.Debug.stopMethodTracing(); +} +</pre> + +<p class="note"><strong>Note:</strong> The system calls {@link android.app.Activity#onDestroy} +after it has already called {@link android.app.Activity#onPause} and {@link +android.app.Activity#onStop} in all situations except one: when you call {@link +android.app.Activity#finish()} from within the {@link android.app.Activity#onCreate onCreate()} +method. In some cases, such as when your activity operates as a temporary decision maker to +launch another activity, you might call {@link android.app.Activity#finish()} from within {@link +android.app.Activity#onCreate onCreate()} to destory the activity. In this case, the system +immediately calls {@link android.app.Activity#onDestroy} without calling any of the other +lifecycle methods.</p> diff --git a/docs/html/training/basics/activity-lifecycle/stopping.jd b/docs/html/training/basics/activity-lifecycle/stopping.jd new file mode 100644 index 0000000..7dfc6d3 --- /dev/null +++ b/docs/html/training/basics/activity-lifecycle/stopping.jd @@ -0,0 +1,193 @@ +page.title=Stopping and Restarting an Activity +parent.title=Managing the Activity Lifecycle +parent.link=index.html + +trainingnavtop=true +previous.title=Pausing and Resuming an Activity +previous.link=pausing.html +next.title=Recreating an Activity +next.link=recreating.html + +@jd:body + +<div id="tb-wrapper"> + <div id="tb"> + + <h2>This lesson teaches you to</h2> + <ol> + <li><a href="#Stop">Stop Your Activity</a></li> + <li><a href="#Start">Start/Restart Your Activity</a></li> + </ol> + + <h2>You should also read</h2> + <ul> + <li><a href="{@docRoot}guide/topics/fundamentals/activities.html">Activities</a> + </li> + </ul> + +<h2>Try it out</h2> + +<div class="download-box"> + <a href="http://developer.android.com/shareables/training/ActivityLifecycle.zip" +class="button">Download the demo</a> + <p class="filename">ActivityLifecycle.zip</p> +</div> + + </div> +</div> + +<p>Properly stopping and restarting your activity is an important process in the activity lifecycle +that ensures your users perceive that your app is always alive and doesn't loose their progress. +There are a few of key scenarios in which your activity is stopped and restarted:</p> + +<ul> + <li>The user opens the Recent Apps window and switches from your app to another app. The +activity in your app that's currently in the foreground is stopped. If the user returns to your +app from the Home screen launcher icon or the Recent Apps window, the activity restarts.</li> + <li>The user performs an action in your app that starts a new activity. The current activity +is stopped when the second activity is created. If the user then presses the <em>Back</em> +button, the first activity is restarted.</li> + <li>The user receives a phone call while using your app on his or her phone.</li> +</ul> + +<p>The {@link android.app.Activity} class provides two lifecycle methods, {@link +android.app.Activity#onStop()} and {@link android.app.Activity#onRestart()}, which allow you to +specifically handle how your activity handles being stopped and restarted. Unlike the paused state, +which identifies a partial UI obstruction, the stopped state guarantees that the UI is no longer +visible and the user's focus is in a separate activity (or an entirely separate app).</p> + +<p class="note"><strong>Note:</strong> Because the system retains your {@link android.app.Activity} +instance in system memory when it is stopped, it's possible that you don't need to implement the +{@link android.app.Activity#onStop()} and {@link android.app.Activity#onRestart()} (or even {@link +android.app.Activity#onStart()} methods at all. For most activities that are relatively simple, the +activity will stop and restart just fine and you might only need to use {@link +android.app.Activity#onPause()} to pause ongoing actions and disconnect from system resources.</p> + +<img src="{@docRoot}images/training/basics/basic-lifecycle-stopped.png" /> +<p class="img-caption"><strong>Figure 1.</strong> When the user leaves your activity, the system +calls {@link android.app.Activity#onStop onStop()} to stop the activity (1). If the user returns +while the activity is stopped, the system calls {@link android.app.Activity#onRestart onRestart()} +(2), quickly followed by {@link android.app.Activity#onStart onStart()} (3) and {@link +android.app.Activity#onResume()} (4). Notice that no matter what scenario causes the activity to +stop, the system always calls {@link android.app.Activity#onPause onPause()} before calling {@link +android.app.Activity#onStop onStop()}.</p> + + + +<h2 id="Stop">Stop Your Activity</h2> + +<p>When your activity receives a call to the {@link android.app.Activity#onStop()} method, it's no +longer visible and should release almost all resources that aren't needed while the user is not +using it. Once your activity is stopped, the system might destroy the instance if it needs to +recover system memory. In extreme cases, the system might simply kill your app process without +calling the activity's final {@link android.app.Activity#onDestroy()} callback, so it's important +you use {@link android.app.Activity#onStop()} to release resources that might leak memory.</p> + +<p>Although the {@link android.app.Activity#onPause onPause()} method is called before +{@link android.app.Activity#onStop()}, you should use {@link android.app.Activity#onStop onStop()} +to perform larger, more CPU intensive shut-down operations, such as writing information to a +database.</p> + +<p>For example, here's an implementation of {@link android.app.Activity#onStop onStop()} that +saves the contents of a draft note to persistent storage:</p> + +<!-- TODO: Find a better example for onStop, because this kind of thing should probably use a +separate thread but that's too complicated to show here. --> +<pre> +@Override +protected void onStop() { + super.onStop(); // Always call the superclass method first + + // Save the note's current draft, because the activity is stopping + // and we want to be sure the current note progress isn't lost. + ContentValues values = new ContentValues(); + values.put(NotePad.Notes.COLUMN_NAME_NOTE, getCurrentNoteText()); + values.put(NotePad.Notes.COLUMN_NAME_TITLE, getCurrentNoteTitle()); + + getContentResolver().update( + mUri, // The URI for the note to update. + values, // The map of column names and new values to apply to them. + null, // No SELECT criteria are used. + null // No WHERE columns are used. + ); +} +</pre> + +<p>When your activity is stopped, the {@link android.app.Activity} object is kept resident in memory +and is recalled when the activity resumes. You don’t need to re-initialize components that were +created during any of the callback methods leading up to the Resumed state. The system also +keeps track of the current state for each {@link android.view.View} in the layout, so if the user +entered text into an {@link android.widget.EditText} widget, that content is retained so you don't +need to save and restore it.</p> + +<p class="note"><strong>Note:</strong> Even if the system destroys your activity while it's stopped, +it still retains the state of the {@link android.view.View} objects (such as text in an {@link +android.widget.EditText}) in a {@link android.os.Bundle} (a blob of key-value pairs) and restores +them if the user navigates back to the same instance of the activity (the <a +href="recreating.html">next lesson</a> talks more about using a {@link android.os.Bundle} to save +other state data in case your activity is destroyed and recreated).</p> + + + +<h2 id="Start">Start/Restart Your Activity</h2> + +<p>When your activity comes back to the foreground from the stopped state, it receives a call to +{@link android.app.Activity#onRestart()}. The system also calls the {@link +android.app.Activity#onStart()} method, which happens every time your activity becomes visible +(whether being restarted or created for the first time). The {@link +android.app.Activity#onRestart()} method, however, is called only when the activity resumes from the +stopped state, so you can use it to perform special restoration work that might be necessary only if +the activity was previously stopped, but not destroyed.</p> + +<p>It's uncommon that an app needs to use {@link android.app.Activity#onRestart()} to restore +the activity's state, so there aren't any guidelines for this method that apply to +the general population of apps. However, because your {@link android.app.Activity#onStop()} +method should essentially clean up all your activity's resources, you'll need to re-instantiate them +when the activity restarts. Yet, you also need to instantiate them when your activity is created +for the first time (when there's no existing instance of the activity). For this reason, you +should usually use the {@link android.app.Activity#onStart()} callback method as the counterpart +to the {@link android.app.Activity#onStop()} method, because the system calls {@link +android.app.Activity#onStart()} both when it creates your activity and when it restarts the +activity from the stopped state.</p> + +<p>For example, because the user might have been away from your app for a long time before +coming back it, the {@link android.app.Activity#onStart()} method is a good place to verify that +required system features are enabled:</p> + +<pre> +@Override +protected void onStart() { + super.onStart(); // Always call the superclass method first + + // The activity is either being restarted or started for the first time + // so this is where we should make sure that GPS is enabled + LocationManager locationManager = + (LocationManager) getSystemService(Context.LOCATION_SERVICE); + boolean gpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); + + if (!gpsEnabled) { + // Create a dialog here that requests the user to enable GPS, and use an intent + // with the android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS action + // to take the user to the Settings screen to enable GPS when they click "OK" + } +} + +@Override +protected void onRestart() { + super.onRestart(); // Always call the superclass method first + + // Activity being restarted from stopped state +} +</pre> + + + + +<p>When the system destroys your activity, it calls the {@link android.app.Activity#onDestroy()} +method for your {@link android.app.Activity}. Because you should generally have released most of +your resources with {@link android.app.Activity#onStop()}, by the time you receive a call to {@link +android.app.Activity#onDestroy()}, there's not much that most apps need to do. This method is your +last chance to clean out resources that could lead to a memory leak, so you should be sure that +additional threads are destroyed and other long-running actions like method tracing are also +stopped.</p> + |