From be2f4edd2ca2b4ba9bbed7262719064ca55b54ff Mon Sep 17 00:00:00 2001 From: Scott Main Date: Mon, 2 Apr 2012 12:56:42 -0700 Subject: docs: Add 101 class on activity lifecycle including ZIP for sample app Change-Id: Id2659ebe15094dad10da4d9bdefed527984fccd9 --- .../training/basics/activity-lifecycle/index.jd | 74 ++++++ .../training/basics/activity-lifecycle/pausing.jd | 152 +++++++++++ .../basics/activity-lifecycle/recreating.jd | 177 +++++++++++++ .../training/basics/activity-lifecycle/starting.jd | 290 +++++++++++++++++++++ .../training/basics/activity-lifecycle/stopping.jd | 193 ++++++++++++++ 5 files changed, 886 insertions(+) create mode 100644 docs/html/training/basics/activity-lifecycle/index.jd create mode 100644 docs/html/training/basics/activity-lifecycle/pausing.jd create mode 100644 docs/html/training/basics/activity-lifecycle/recreating.jd create mode 100644 docs/html/training/basics/activity-lifecycle/starting.jd create mode 100644 docs/html/training/basics/activity-lifecycle/stopping.jd (limited to 'docs/html/training') 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 000000000000..d278f042e839 --- /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 + +
+
+ + +

Dependencies and prerequisites

+ + + +

You should also read

+ + + +

Try it out

+ +
+ Download the demo +

ActivityLifecycle.zip

+
+ +
+
+ +

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).

+ +

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.

+ +

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.

+ +

Lessons

+ +
+
Starting an Activity
+
Learn the basics about the activity lifecycle, how the user can launch your app, and how +to perform basic activity creation.
+
Pausing and Resuming an Activity
+
Learn what happens when your activity is paused (partially obscured) and resumed and what you +should do during these state changes.
+
Stopping and Restarting an Activity
+
Learn what happens when the user completely leaves your activity and returns to it.
+
Recreating an Activity
+
Learn what happens when your activity is destroyed and how you can rebuild the activity +state when necessary.
+
+ 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 000000000000..216d55e1d87a --- /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 + +
+
+ +

This lesson teaches you to

+
    +
  1. Pause Your Activity
  2. +
  3. Resume Your Activity
  4. +
+ +

You should also read

+ + +

Try it out

+ +
+ Download the demo +

ActivityLifecycle.zip

+
+ +
+
+ +

During normal app use, the foreground activity is sometimes obstructed by other +visual components that cause the activity to pause. 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.

+ +

However, once the activity is fully-obstructed and not visible, it stops (which is +discussed in the next lesson).

+ +

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.

+ +

Note: 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.

+ + +

Figure 1. 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).

+ + +

Pause Your Activity

+ +

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:

+ + + +

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.

+ +
+@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;
+    }
+}
+
+ +

Generally, you should not 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()}).

+ +

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.

+ +

Note: 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.

+ + + +

Resume Your Activity

+ +

When the user resumes your activity from the Paused state, the system calls the {@link +android.app.Activity#onResume()} method.

+ +

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).

+ +

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.

+ +
+@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
+    }
+}
+
+ + + + + + + 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 000000000000..941f1fd11c37 --- /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 + +
+
+ +

This lesson teaches you to

+
    +
  1. Save Your Activity State
  2. +
  3. Restore Your Activity State
  4. +
+ +

You should also read

+ + +
+
+ +

There are a few scenarios in which your activity is destroyed due to normal app behavior, such as +when the user presses the Back 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.

+ +

When your activity is destroyed because the user presses Back 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.

+ +

Caution: 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).

+ +

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.

+ +

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.

+ + +

Figure 2. 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).

+ + + +

Save Your Activity State

+ +

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}.

+ +

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:

+ +
+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);
+}
+
+ +

Caution: Always call the superclass implementation of {@link +android.app.Activity#onSaveInstanceState onSaveInstanceState()} so the default implementation +can save the state of the view hierarchy.

+ + + +

Restore Your Activity State

+ +

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.

+ +

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.

+ +

For example, here's how you can restore some state data in {@link android.app.Activity#onCreate +onCreate()}:

+ +
+@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
+    }
+    ...
+}
+
+ +

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:

+ +
+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);
+}
+
+ +

Caution: Always call the superclass implementation of {@link +android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} so the default implementation +can restore the state of the view hierarchy.

+ +

To learn more about recreating your activity due to a +restart event at runtime (such as when the screen rotates), read Handling Runtime Changes.

+ 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 000000000000..cc7e473b5d9c --- /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 + + +
+
+ +

This lesson teaches you to

+
    +
  1. Understand the Lifecycle Callbacks
  2. +
  3. Specify Your App's Launcher Activity
  4. +
  5. Create a New Instance
  6. +
  7. Destroy the Activity
  8. +
+ +

You should also read

+ + +

Try it out

+ +
+ Download the demo +

ActivityLifecycle.zip

+
+ +
+
+ +

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.

+ +

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.

+ + + +

Understand the Lifecycle Callbacks

+ +

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.

+ +

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.

+ + + +

Figure 1. 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.

+ + +

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:

+ + + + +

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:

+
+
Resumed
+
In this state, the activity is in the foreground and the user can interact with it. +(Also sometimes referred to as the "running" state.)
+
Paused
+
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. +
Stopped
+
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.
+
+ +

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()}.

+ +

That's it for the basic activity lifecycle. Now you'll start learning about some of the +specific lifecycle behaviors.

+ + + +

Specify Your App's Launcher Activity

+ +

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.

+ +

You can define which activity to use as the main activity in the Android manifest file, {@code AndroidManifest.xml}, which is +at the root of your project directory.

+ +

The main activity for your app must be declared in the manifest with an {@code +<intent-filter>} that includes the {@link +android.content.Intent#ACTION_MAIN MAIN} action and +{@link android.content.Intent#CATEGORY_LAUNCHER LAUNCHER} category. For example:

+ +
+<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>
+
+ +

Note: 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.

+ +

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.

+ + + +

Create a New Instance

+ +

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.

+ +

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.

+ +

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.

+ +
+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);
+    }
+}
+
+ +

Caution: 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.

+ +

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.

+ +

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.

+ +

Note: The {@link android.app.Activity#onCreate onCreate()} +method includes a parameter called savedInstanceState that's discussed in the +latter lesson about Recreating an Activity.

+ + + +

Figure 2. 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.

+ + + + + + + +

Destroy the Activity

+ +

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.

+ +

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}.

+ +
+@Override
+public void onDestroy() {
+    super.onDestroy();  // Always call the superclass
+    
+    // Stop method tracing that the activity started during onCreate()
+    android.os.Debug.stopMethodTracing();
+}
+
+ +

Note: 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.

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 000000000000..7dfc6d322aa9 --- /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 + +
+
+ +

This lesson teaches you to

+
    +
  1. Stop Your Activity
  2. +
  3. Start/Restart Your Activity
  4. +
+ +

You should also read

+ + +

Try it out

+ +
+ Download the demo +

ActivityLifecycle.zip

+
+ +
+
+ +

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:

+ + + +

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).

+ +

Note: 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.

+ + +

Figure 1. 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()}.

+ + + +

Stop Your Activity

+ +

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.

+ +

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.

+ +

For example, here's an implementation of {@link android.app.Activity#onStop onStop()} that +saves the contents of a draft note to persistent storage:

+ + +
+@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.
+            );
+}
+
+ +

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.

+ +

Note: 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 next lesson talks more about using a {@link android.os.Bundle} to save +other state data in case your activity is destroyed and recreated).

+ + + +

Start/Restart Your Activity

+ +

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.

+ +

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.

+ +

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:

+ +
+@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    
+}
+
+ + + + +

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.

+ -- cgit v1.2.3-59-g8ed1b