Merge "docs: Add 101 class on activity lifecycle including ZIP for sample app" into ics-mr1

This commit is contained in:
Scott Main
2012-04-19 19:04:51 -07:00
committed by Android (Google) Code Review
23 changed files with 6475 additions and 1 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

View File

@@ -0,0 +1,635 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>ActiveLayerIndex</key>
<integer>0</integer>
<key>ApplicationVersion</key>
<array>
<string>com.omnigroup.OmniGrafflePro</string>
<string>138.33.0.157554</string>
</array>
<key>AutoAdjust</key>
<true/>
<key>BackgroundGraphic</key>
<dict>
<key>Bounds</key>
<string>{{0, 0}, {576, 733}}</string>
<key>Class</key>
<string>SolidGraphic</string>
<key>ID</key>
<integer>2</integer>
<key>Style</key>
<dict>
<key>shadow</key>
<dict>
<key>Draws</key>
<string>NO</string>
</dict>
<key>stroke</key>
<dict>
<key>Draws</key>
<string>NO</string>
</dict>
</dict>
</dict>
<key>CanvasOrigin</key>
<string>{0, 0}</string>
<key>ColumnAlign</key>
<integer>1</integer>
<key>ColumnSpacing</key>
<real>36</real>
<key>CreationDate</key>
<string>2012-03-20 17:38:46 -0700</string>
<key>Creator</key>
<string>Billy Rutledge</string>
<key>DisplayScale</key>
<string>1 0/72 in = 1 0/72 in</string>
<key>GraphDocumentVersion</key>
<integer>8</integer>
<key>GraphicsList</key>
<array>
<dict>
<key>Bounds</key>
<string>{{257, 117}, {282, 231}}</string>
<key>Class</key>
<string>ShapedGraphic</string>
<key>FontInfo</key>
<dict>
<key>Color</key>
<dict>
<key>b</key>
<string>0</string>
<key>g</key>
<string>0</string>
<key>r</key>
<string>0</string>
</dict>
<key>Font</key>
<string>DroidSans-Bold</string>
<key>Size</key>
<real>10</real>
</dict>
<key>ID</key>
<integer>200</integer>
<key>Magnets</key>
<array>
<string>{1, 1}</string>
<string>{1, -1}</string>
<string>{-1, -1}</string>
<string>{-1, 1}</string>
<string>{0, 1}</string>
<string>{0, -1}</string>
<string>{1, 0}</string>
<string>{-1, 0}</string>
<string>{-0.5, -0.233518}</string>
<string>{-0.491442, 0.260063}</string>
<string>{0.507118, -0.224086}</string>
<string>{0.507118, 0.267179}</string>
<string>{-0.27431, -0.474028}</string>
<string>{0.27978, -0.478478}</string>
<string>{0.293938, 0.543044}</string>
<string>{-0.286232, 0.553804}</string>
</array>
<key>Shape</key>
<string>Rectangle</string>
<key>Style</key>
<dict>
<key>fill</key>
<dict>
<key>Color</key>
<dict>
<key>b</key>
<string>0.628571</string>
<key>g</key>
<string>0.768599</string>
<key>r</key>
<string>1</string>
</dict>
<key>FillType</key>
<integer>2</integer>
<key>GradientAngle</key>
<real>90</real>
<key>GradientColor</key>
<dict>
<key>b</key>
<string>0.236788</string>
<key>g</key>
<string>0.532236</string>
<key>r</key>
<string>0.990271</string>
</dict>
</dict>
<key>shadow</key>
<dict>
<key>Color</key>
<dict>
<key>a</key>
<string>0.35</string>
<key>b</key>
<string>0</string>
<key>g</key>
<string>0</string>
<key>r</key>
<string>0</string>
</dict>
<key>Fuzziness</key>
<real>2.3972222805023193</real>
<key>ShadowVector</key>
<string>{0, 1}</string>
</dict>
<key>stroke</key>
<dict>
<key>Color</key>
<dict>
<key>b</key>
<string>0.131021</string>
<key>g</key>
<string>0.363196</string>
<key>r</key>
<string>0.725948</string>
</dict>
<key>CornerRadius</key>
<real>3</real>
</dict>
</dict>
<key>Text</key>
<dict>
<key>Text</key>
<string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
{\colortbl;\red255\green255\blue255;}
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
\f0\b\fs24 \cf0 Fragment B}</string>
<key>VerticalPad</key>
<integer>0</integer>
</dict>
</dict>
<dict>
<key>Bounds</key>
<string>{{163, 117}, {92, 231}}</string>
<key>Class</key>
<string>ShapedGraphic</string>
<key>FontInfo</key>
<dict>
<key>Color</key>
<dict>
<key>b</key>
<string>0</string>
<key>g</key>
<string>0</string>
<key>r</key>
<string>0</string>
</dict>
<key>Font</key>
<string>DroidSans-Bold</string>
<key>Size</key>
<real>10</real>
</dict>
<key>ID</key>
<integer>1203</integer>
<key>Magnets</key>
<array>
<string>{1, 1}</string>
<string>{1, -1}</string>
<string>{-1, -1}</string>
<string>{-1, 1}</string>
<string>{0, 1}</string>
<string>{0, -1}</string>
<string>{1, 0}</string>
<string>{-1, 0}</string>
<string>{-0.5, -0.233518}</string>
<string>{-0.491442, 0.260063}</string>
<string>{0.507118, -0.224086}</string>
<string>{0.507118, 0.267179}</string>
<string>{-0.27431, -0.474028}</string>
<string>{0.27978, -0.478478}</string>
<string>{0.293938, 0.543044}</string>
<string>{-0.286232, 0.553804}</string>
</array>
<key>Shape</key>
<string>Rectangle</string>
<key>Style</key>
<dict>
<key>fill</key>
<dict>
<key>Color</key>
<dict>
<key>b</key>
<string>1</string>
<key>g</key>
<string>0.874135</string>
<key>r</key>
<string>0.71718</string>
</dict>
<key>FillType</key>
<integer>2</integer>
<key>GradientAngle</key>
<real>90</real>
<key>GradientColor</key>
<dict>
<key>b</key>
<string>1</string>
<key>g</key>
<string>0.662438</string>
<key>r</key>
<string>0.464468</string>
</dict>
</dict>
<key>shadow</key>
<dict>
<key>Color</key>
<dict>
<key>a</key>
<string>0.35</string>
<key>b</key>
<string>0</string>
<key>g</key>
<string>0</string>
<key>r</key>
<string>0</string>
</dict>
<key>Fuzziness</key>
<real>2.3972222805023193</real>
<key>ShadowVector</key>
<string>{0, 1}</string>
</dict>
<key>stroke</key>
<dict>
<key>Color</key>
<dict>
<key>b</key>
<string>0.93512</string>
<key>g</key>
<string>0.472602</string>
<key>r</key>
<string>0.333854</string>
</dict>
<key>CornerRadius</key>
<real>3</real>
</dict>
</dict>
<key>Text</key>
<dict>
<key>Text</key>
<string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
{\colortbl;\red255\green255\blue255;}
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
\f0\b\fs24 \cf0 Fragment A}</string>
<key>VerticalPad</key>
<integer>0</integer>
</dict>
</dict>
<dict>
<key>Bounds</key>
<string>{{24, 168}, {92, 152}}</string>
<key>Class</key>
<string>ShapedGraphic</string>
<key>FontInfo</key>
<dict>
<key>Color</key>
<dict>
<key>b</key>
<string>0</string>
<key>g</key>
<string>0</string>
<key>r</key>
<string>0</string>
</dict>
<key>Font</key>
<string>DroidSans-Bold</string>
<key>Size</key>
<real>10</real>
</dict>
<key>ID</key>
<integer>157</integer>
<key>Magnets</key>
<array>
<string>{1, 1}</string>
<string>{1, -1}</string>
<string>{-1, -1}</string>
<string>{-1, 1}</string>
<string>{0, 1}</string>
<string>{0, -1}</string>
<string>{1, 0}</string>
<string>{-1, 0}</string>
<string>{-0.5, -0.233518}</string>
<string>{-0.491442, 0.260063}</string>
<string>{0.507118, -0.224086}</string>
<string>{0.507118, 0.267179}</string>
<string>{-0.27431, -0.474028}</string>
<string>{0.27978, -0.478478}</string>
<string>{0.293938, 0.543044}</string>
<string>{-0.286232, 0.553804}</string>
</array>
<key>Shape</key>
<string>Rectangle</string>
<key>Style</key>
<dict>
<key>fill</key>
<dict>
<key>Color</key>
<dict>
<key>b</key>
<string>1</string>
<key>g</key>
<string>0.874135</string>
<key>r</key>
<string>0.71718</string>
</dict>
<key>FillType</key>
<integer>2</integer>
<key>GradientAngle</key>
<real>90</real>
<key>GradientColor</key>
<dict>
<key>b</key>
<string>1</string>
<key>g</key>
<string>0.662438</string>
<key>r</key>
<string>0.464468</string>
</dict>
</dict>
<key>shadow</key>
<dict>
<key>Color</key>
<dict>
<key>a</key>
<string>0.35</string>
<key>b</key>
<string>0</string>
<key>g</key>
<string>0</string>
<key>r</key>
<string>0</string>
</dict>
<key>Fuzziness</key>
<real>2.3972222805023193</real>
<key>ShadowVector</key>
<string>{0, 1}</string>
</dict>
<key>stroke</key>
<dict>
<key>Color</key>
<dict>
<key>b</key>
<string>0.93512</string>
<key>g</key>
<string>0.472602</string>
<key>r</key>
<string>0.333854</string>
</dict>
<key>CornerRadius</key>
<real>3</real>
</dict>
</dict>
<key>Text</key>
<dict>
<key>Text</key>
<string>{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
{\colortbl;\red255\green255\blue255;}
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
\f0\b\fs24 \cf0 Fragment A}</string>
<key>VerticalPad</key>
<integer>0</integer>
</dict>
</dict>
<dict>
<key>Bounds</key>
<string>{{11.96, 141.616}, {117.52, 224.884}}</string>
<key>Class</key>
<string>ShapedGraphic</string>
<key>ID</key>
<integer>1202</integer>
<key>ImageID</key>
<integer>2</integer>
<key>Magnets</key>
<array>
<string>{0, 1}</string>
<string>{0, -1}</string>
<string>{1, 0}</string>
<string>{-1, 0}</string>
</array>
<key>Shape</key>
<string>Rectangle</string>
<key>Style</key>
<dict>
<key>fill</key>
<dict>
<key>Draws</key>
<string>NO</string>
</dict>
<key>shadow</key>
<dict>
<key>Draws</key>
<string>NO</string>
</dict>
<key>stroke</key>
<dict>
<key>Draws</key>
<string>NO</string>
</dict>
</dict>
</dict>
<dict>
<key>Bounds</key>
<string>{{140, 95}, {422.773, 277}}</string>
<key>Class</key>
<string>ShapedGraphic</string>
<key>ID</key>
<integer>1201</integer>
<key>ImageID</key>
<integer>1</integer>
<key>Magnets</key>
<array>
<string>{0, 1}</string>
<string>{0, -1}</string>
<string>{1, 0}</string>
<string>{-1, 0}</string>
</array>
<key>Shape</key>
<string>Rectangle</string>
<key>Style</key>
<dict>
<key>fill</key>
<dict>
<key>Draws</key>
<string>NO</string>
</dict>
<key>shadow</key>
<dict>
<key>Draws</key>
<string>NO</string>
</dict>
<key>stroke</key>
<dict>
<key>Draws</key>
<string>NO</string>
</dict>
</dict>
</dict>
</array>
<key>GridInfo</key>
<dict/>
<key>GuidesLocked</key>
<string>NO</string>
<key>GuidesVisible</key>
<string>YES</string>
<key>HPages</key>
<integer>1</integer>
<key>ImageCounter</key>
<integer>3</integer>
<key>ImageLinkBack</key>
<array>
<dict/>
<dict/>
</array>
<key>ImageList</key>
<array>
<string>image2.png</string>
<string>image1.png</string>
</array>
<key>KeepToScale</key>
<false/>
<key>Layers</key>
<array>
<dict>
<key>Lock</key>
<string>NO</string>
<key>Name</key>
<string>Layer 1</string>
<key>Print</key>
<string>YES</string>
<key>View</key>
<string>YES</string>
</dict>
</array>
<key>LayoutInfo</key>
<dict>
<key>Animate</key>
<string>NO</string>
<key>circoMinDist</key>
<real>18</real>
<key>circoSeparation</key>
<real>0.0</real>
<key>layoutEngine</key>
<string>dot</string>
<key>neatoSeparation</key>
<real>0.0</real>
<key>twopiSeparation</key>
<real>0.0</real>
</dict>
<key>LinksVisible</key>
<string>NO</string>
<key>MagnetsVisible</key>
<string>NO</string>
<key>MasterSheets</key>
<array/>
<key>ModificationDate</key>
<string>2012-03-20 17:52:44 -0700</string>
<key>Modifier</key>
<string>Billy Rutledge</string>
<key>NotesVisible</key>
<string>NO</string>
<key>Orientation</key>
<integer>2</integer>
<key>OriginVisible</key>
<string>NO</string>
<key>PageBreaks</key>
<string>YES</string>
<key>PrintInfo</key>
<dict>
<key>NSBottomMargin</key>
<array>
<string>float</string>
<string>41</string>
</array>
<key>NSLeftMargin</key>
<array>
<string>float</string>
<string>18</string>
</array>
<key>NSPaperSize</key>
<array>
<string>coded</string>
<string>BAtzdHJlYW10eXBlZIHoA4QBQISEhAdOU1ZhbHVlAISECE5TT2JqZWN0AIWEASqEhAx7X05TU2l6ZT1mZn2WgWQCgRgDhg==</string>
</array>
<key>NSRightMargin</key>
<array>
<string>float</string>
<string>18</string>
</array>
<key>NSTopMargin</key>
<array>
<string>float</string>
<string>18</string>
</array>
</dict>
<key>PrintOnePage</key>
<false/>
<key>ReadOnly</key>
<string>NO</string>
<key>RowAlign</key>
<integer>1</integer>
<key>RowSpacing</key>
<real>36</real>
<key>SheetTitle</key>
<string>Canvas 1</string>
<key>SmartAlignmentGuidesActive</key>
<string>YES</string>
<key>SmartDistanceGuidesActive</key>
<string>YES</string>
<key>UniqueID</key>
<integer>1</integer>
<key>UseEntirePage</key>
<false/>
<key>VPages</key>
<integer>1</integer>
<key>WindowInfo</key>
<dict>
<key>CurrentSheet</key>
<integer>0</integer>
<key>ExpandedCanvases</key>
<array>
<dict>
<key>name</key>
<string>Canvas 1</string>
</dict>
</array>
<key>Frame</key>
<string>{{837, 167}, {1214, 1013}}</string>
<key>ListView</key>
<true/>
<key>OutlineWidth</key>
<integer>142</integer>
<key>RightSidebar</key>
<false/>
<key>ShowRuler</key>
<true/>
<key>Sidebar</key>
<true/>
<key>SidebarWidth</key>
<integer>120</integer>
<key>VisibleRegion</key>
<string>{{-252, -63}, {1079, 859}}</string>
<key>Zoom</key>
<real>1</real>
<key>ZoomValues</key>
<array>
<array>
<string>Canvas 1</string>
<real>1</real>
<real>1</real>
</array>
</array>
</dict>
<key>saveQuickLookFiles</key>
<string>YES</string>
</dict>
</plist>

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

View File

@@ -1,7 +1,7 @@
<ul>
<li>
<span class="heading">
<span class="en">Android Training</span>
<span class="en">Basic Training</span>
</span>
<ul>
@@ -10,6 +10,124 @@
</a>
</li>
<li class="toggle-list">
<div><a href="<?cs var:toroot ?>training/basics/firstapp/index.html">
<span class="en">Building Your First App<span class="new">&nbsp;new!</span></span>
</a></div>
<ul>
<li><a href="<?cs var:toroot ?>training/basics/firstapp/creating-project.html">
<span class="en">Creating an Android Project</span>
</a>
</li>
<li><a href="<?cs var:toroot ?>training/basics/firstapp/running-app.html">
<span class="en">Running Your Application</span>
</a>
</li>
<li><a href="<?cs var:toroot ?>training/basics/firstapp/building-ui.html">
<span class="en">Building a Simple User Interface</span>
</a>
</li>
<li><a href="<?cs var:toroot ?>training/basics/firstapp/starting-activity.html">
<span class="en">Starting Another Activity</span>
</a>
</li>
</ul>
</li>
<li class="toggle-list">
<div><a href="<?cs var:toroot ?>training/basics/activity-lifecycle/index.html">
<span class="en">Managing the Activity Lifecycle<span class="new">&nbsp;new!</span></span>
</a></div>
<ul>
<li><a href="<?cs var:toroot ?>training/basics/activity-lifecycle/starting.html">
<span class="en">Starting an Activity</span>
</a>
</li>
<li><a href="<?cs var:toroot ?>training/basics/activity-lifecycle/pausing.html">
<span class="en">Pausing and Resuming an Activity</span>
</a>
</li>
<li><a href="<?cs var:toroot ?>training/basics/activity-lifecycle/stopping.html">
<span class="en">Stopping and Restarting an Activity</span>
</a>
</li>
<li><a href="<?cs var:toroot ?>training/basics/activity-lifecycle/recreating.html">
<span class="en">Recreating an Activity</span>
</a>
</li>
</ul>
</li>
<li class="toggle-list">
<div><a href="<?cs var:toroot ?>training/basics/supporting-devices/index.html">
<span class="en">Supporting Different Devices<span class="new">&nbsp;new!</span></span>
</a></div>
<ul>
<li><a href="<?cs var:toroot ?>training/basics/supporting-devices/languages.html">
<span class="en">Supporting Different Languages</span>
</a>
</li>
<li><a href="<?cs var:toroot ?>training/basics/supporting-devices/screens.html">
<span class="en">Supporting Different Screens</span>
</a>
</li>
<li><a href="<?cs var:toroot ?>training/basics/supporting-devices/platforms.html">
<span class="en">Supporting Different Platform Versions</span>
</a>
</li>
</ul>
</li>
<li class="toggle-list">
<div><a href="<?cs var:toroot ?>training/basics/intents/index.html">
<span class="en">Interacting with Other Apps<span class="new">&nbsp;new!</span></span>
</a></div>
<ul>
<li><a href="<?cs var:toroot ?>training/basics/intents/sending.html">
<span class="en">Sending the User to Another App</span>
</a>
</li>
<li><a href="<?cs var:toroot ?>training/basics/intents/result.html">
<span class="en">Getting a Result from the Activity</span>
</a>
</li>
<li><a href="<?cs var:toroot ?>training/basics/intents/filters.html">
<span class="en">Allowing Other Apps to Start Your Activity</span>
</a>
</li>
</ul>
</li>
<li class="toggle-list">
<div><a href="<?cs var:toroot ?>training/basics/location/index.html">
<span class="en">Making Your App Location Aware<span class="new">&nbsp;new!</span></span>
</a></div>
<ul>
<li><a href="<?cs var:toroot ?>training/basics/location/locationmanager.html">
<span class="en">Using the Location Manager</span>
</a>
</li>
<li><a href="<?cs var:toroot ?>training/basics/location/currentlocation.html">
<span class="en">Obtaining the Current Location</span>
</a>
</li>
<li><a href="<?cs var:toroot ?>training/basics/location/geocoding.html">
<span class="en">Displaying a Location Address</span>
</a>
</li>
</ul>
</li>
</ul>
</li>
<li>
<span class="heading">
<span class="en">Advanced Training</span>
</span>
<ul>
<li class="toggle-list">
<div><a href="<?cs var:toroot ?>training/multiscreen/index.html">
<span class="en">Designing for Multiple Screens</span>

Binary file not shown.

View File

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

View File

@@ -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>
&#64;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 dont 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>
&#64;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>

View File

@@ -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";
...
&#64;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>
&#64;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>

View File

@@ -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&mdash;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
&lt;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>
&lt;activity android:name=".MainActivity" android:label="&#64;string/app_name">
&lt;intent-filter>
&lt;action android:name="android.intent.action.MAIN" />
&lt;category android:name="android.intent.category.LAUNCHER" />
&lt;/intent-filter>
&lt;/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
&#64;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>
&#64;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>

View File

@@ -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>
&#64;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 dont 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>
&#64;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"
}
}
&#64;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>