1page.title=停止并重新开始Activity 2page.tags=Activity生命周期 3helpoutsWidget=true 4 5trainingnavtop=true 6 7@jd:body 8 9<div id="tb-wrapper"> 10 <div id="tb"> 11 12 <h2>本课程将向您展示如何</h2> 13 <ol> 14 <li><a href="#Stop">停止Activity</a></li> 15 <li><a href="#Start">开始/重新开始Activity</a></li> 16 </ol> 17 18 <h2>您还应阅读</h2> 19 <ul> 20 <li><a href="{@docRoot}guide/components/activities.html">Activity</a> 21 </li> 22 </ul> 23 24<h2>试一试</h2> 25 26<div class="download-box"> 27 <a href="http://developer.android.com/shareables/training/ActivityLifecycle.zip" class="button">下载演示</a> 28 <p class="filename">ActivityLifecycle.zip</p> 29</div> 30 31 </div> 32</div> 33 34<p>正确停止和重新开始Activity是Activity生命周期中的重要过程,其可确保您的用户知晓应用始终保持Activity状态并且不会丢失进度。有几种Activity停止和重新开始的关键场景: 35 36</p> 37 38<ul> 39 <li>用户打开“最近应用”窗口并从您的应用切换到另一个应用。当前位于前台的您的应用中的Activity将停止。 40如果用户从主屏幕启动器图标或“最近应用”窗口返回到您的应用,Activity会重新开始。 41</li> 42 <li>用户在您的应用中执行开始新Activity的操作。当第二个Activity创建好后,当前Activity便停止。 43如果用户之后按了<em>返回</em>按钮,第一个Activity会重新开始。 44</li> 45 <li>用户在其手机上使用您的应用的同时接听来电。</li> 46</ul> 47 48<p>{@link android.app.Activity} 课程提供两种生命周期方法:{@link 49android.app.Activity#onStop()} 和 {@link android.app.Activity#onRestart()},这些方法允许您专门处理正在停止和重新开始的Activity。 50不同于识别部分 UI 阻挡的暂停状态,停止状态保证 UI 不再可见,且用户的焦点在另外的Activity(或完全独立的应用)中。 51 52</p> 53 54<p class="note"><strong>注意:</strong>因为系统在停止时会将您的 {@link android.app.Activity} 55实例保留在系统内存中,您根本无需实现 56{@link android.app.Activity#onStop()} 和 {@link android.app.Activity#onRestart()}或甚至{@link 57android.app.Activity#onStart()} 方法。对于大多数相对简单的Activity而言, Activity将停止并重新开始,并且您可能只需使用 {@link 58android.app.Activity#onPause()} 暂停正在进行的操作,并从系统资源断开连接。 59</p> 60 61<img src="{@docRoot}images/training/basics/basic-lifecycle-stopped.png" /> 62<p class="img-caption"><strong>图 1.</strong>用户离开Activity时,系统会调用 {@link android.app.Activity#onStop onStop()} 停止Activity(1)。 63如果用户在Activity停止时返回,系统会调用 {@link android.app.Activity#onRestart onRestart()} 64(2),紧接着调用 {@link android.app.Activity#onStart onStart()} (3) 和 {@link 65android.app.Activity#onResume()} (4)。 66注意:无论什么场景导致Activity停止,系统始终会在调用 {@link 67android.app.Activity#onStop onStop()} 之前调用 {@link android.app.Activity#onPause onPause()}。 68</p> 69 70 71 72<h2 id="Stop">停止Activity</h2> 73 74<p>当您的Activity收到 {@link android.app.Activity#onStop()} 方法的调用时,它不再可见,并且应释放几乎所有用户不使用时不需要的资源。 75 76一旦您的Activity停止,如果需要恢复系统内存,系统可能会销毁该实例。 77在极端情况下,系统可能会仅终止应用进程,而不会调用Activity的最终 {@link android.app.Activity#onDestroy()} 回调,因此您使用 {@link android.app.Activity#onStop()} 释放可能泄露内存的资源非常重要。 78 79</p> 80 81<p>尽管 {@link android.app.Activity#onPause onPause()} 方法在 82{@link android.app.Activity#onStop()}之前调用,您应使用 {@link android.app.Activity#onStop onStop()} 83执行更大、占用更多 CPU 的关闭操作,比如向数据库写入信息。 84</p> 85 86<p>例如,此处是将草稿笔记内容保存在永久存储中的 {@link android.app.Activity#onStop onStop()} 的实现: 87</p> 88 89<!-- TODO: Find a better example for onStop, because this kind of thing should probably use a 90separate thread but that's too complicated to show here. --> 91<pre> 92@Override 93protected void onStop() { 94 super.onStop(); // Always call the superclass method first 95 96 // Save the note's current draft, because the activity is stopping 97 // and we want to be sure the current note progress isn't lost. 98 ContentValues values = new ContentValues(); 99 values.put(NotePad.Notes.COLUMN_NAME_NOTE, getCurrentNoteText()); 100 values.put(NotePad.Notes.COLUMN_NAME_TITLE, getCurrentNoteTitle()); 101 102 getContentResolver().update( 103 mUri, // The URI for the note to update. 104 values, // The map of column names and new values to apply to them. 105 null, // No SELECT criteria are used. 106 null // No WHERE columns are used. 107 ); 108} 109</pre> 110 111<p>当您的Activity停止时, {@link android.app.Activity} 对象将驻留在内存中并在Activity继续时被再次调用。 112您无需重新初始化在任何导致进入“继续”状态的回调方法过程中创建的组件。 113系统还会在布局中跟踪每个 {@link android.view.View} 的当前状态,如果用户在 {@link android.widget.EditText} 小工具中输入文本,该内容会保留,因此您无需保存即可恢复它。 114 115 116</p> 117 118<p class="note"><strong>注意:</strong>即使系统在Activity停止时销毁了Activity,它仍会保留 {@link android.os.Bundle}(键值对的二进制大对象)中的 {@link android.view.View} 对象(比如 {@link 119android.widget.EditText} 中的文本),并在用户导航回Activity的相同实例时恢复它们 (<a href="recreating.html">下一堂课</a> 讲述更多有关在您的Activity被销毁且重新创建的情况下使用 {@link android.os.Bundle} 保存其他数据状态的知识)。 120 121 122</p> 123 124 125 126<h2 id="Start">开始/重新开始Activity</h2> 127 128<p>当您的Activity从停止状态返回前台时,它会接收对 129{@link android.app.Activity#onRestart()} 的调用。系统还会在每次您的Activity变为可见时调用 {@link 130android.app.Activity#onStart()} 方法(无论是正重新开始还是初次创建)。 131但是,只会在Activity从停止状态继续时调用 {@link 132android.app.Activity#onRestart()} 方法,因此您可以使用它执行只有在Activity之前停止但未销毁的情况下可能必须执行的特殊恢复工作。 133 134</p> 135 136<p>应用需要使用 {@link android.app.Activity#onRestart()} 恢复Activity状态的情况并不常见,因此没有适用于一般应用群体的任何方法指导原则。 137 138但是,因为您的 {@link android.app.Activity#onStop()} 139方法应基本清理所有Activity的资源,您将需要在Activity重新开始时重新实例化它们。 140但是,您还需要在您的Activity初次创建时重新实例化它们(没有Activity的现有实例)。 141出于此原因,您应经常使用 {@link android.app.Activity#onStart()} 回调方法作为 142 {@link android.app.Activity#onStop()} 方法的对应部分,因为系统会在它创建您的Activity以及从停止状态重新开始Activity时调用 {@link 143android.app.Activity#onStart()} 。 144 145</p> 146 147<p>例如,因为用户可能在回到它之前已离开应用很长时间, {@link android.app.Activity#onStart()} 方法是确认所需系统功能已启动的理想选择: 148 149</p> 150 151<pre> 152@Override 153protected void onStart() { 154 super.onStart(); // Always call the superclass method first 155 156 // The activity is either being restarted or started for the first time 157 // so this is where we should make sure that GPS is enabled 158 LocationManager locationManager = 159 (LocationManager) getSystemService(Context.LOCATION_SERVICE); 160 boolean gpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); 161 162 if (!gpsEnabled) { 163 // Create a dialog here that requests the user to enable GPS, and use an intent 164 // with the android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS action 165 // to take the user to the Settings screen to enable GPS when they click "OK" 166 } 167} 168 169@Override 170protected void onRestart() { 171 super.onRestart(); // Always call the superclass method first 172 173 // Activity being restarted from stopped state 174} 175</pre> 176 177 178 179 180<p>当系统销毁您的Activity时,它会调用您的 {@link android.app.Activity} 的 {@link android.app.Activity#onDestroy()} 181方法。因为您通常应已使用 {@link android.app.Activity#onStop()} 释放大多数您的资源,到您接收对 {@link 182android.app.Activity#onDestroy()} 的调用时,大多数应用无需做太多操作。 183此方法是您清理可导致内存泄露的资源的最后一种方法,因此您应确保其他线程被销毁且其他长期运行的操作(比如方法跟踪)也会停止。 184 185 186</p> 187 188