停止和重啟activity在activity的生命周期中很重要,它能讓用戶感覺你的app總是激活的而且不會丟失他們的進度。activity在下面的這些情況會停止和重啟:
-
用戶打開常用app窗口然后從你的app切換到其他app。你的app中的activity現在就在后台了而且停止了。如果用戶從主屏的啟動圖標或者最近使用的app窗口返回到你的app,這個activity就會重啟。
-
用戶在你的程序中執行了一個操作來啟動一個新的activity。當前的activity在第二個activity創建時就會停止了。如果用戶點擊了返回按鈕,第一個activity就重啟了。
-
用戶在使用你的app時接到電話。
注意:因為當activity停止時系統在系統內存中保留了實例,可能不需要實現onStop()和onRestart()甚至onStart()方法。對於大多數activity來說相對簡單,activity會很好的停止和重啟,你只需要使用onPause()來暫停正在執行的操作和斷開與系統資源的連接。
圖1.當用戶離開activity,系統會調用onStop()來停止activity。如果activity停止后用戶返回,系統會調用onRestart(),然后緊接着onStart()和onResume()。注意不管是什么情況導致activity要停止,系統總是會在調用onStop()前調用onPause()。
停止Activity
當activity被調用onStop()方法后,它不在可見並且需要釋放用戶不使用的絕大多數資源。一旦activity停止了,系統可能會在清理內存時銷毀實例。在極端的情況下,系統可能不調用onDestroy()直接殺掉app進程,所有用onStop()來釋放資源防止內存泄漏很重要。
雖然在onStop()之前調用了onPause()方法,你應該使用onStop()來處理大部分消耗CPU的操作,比如寫入信息到數據庫。
這里有一個實現onStop()的例子,它把筆記草稿保存的永久的存儲中:
@Override protected void onStop() { super.onStop(); // Always call the superclass method first // 保存筆記草稿,因為activity將要停止 // 我們要保證當前的筆記進度不丟失 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. ); }
當activity停止后,activity對象保存在內存中,當activity恢復時會被再調用。不需要在任何的回調方法中重新初始化組件來回到Resumed狀態。系統也記錄了layout中每個View的狀態,所以如果用戶在EditText控件中輸入了文字,這些內容會被保留,所以你不需要保存和還原它。
注意:雖然系統在activity停止時銷毀了它,但是仍然在Bundle(一系列的鍵值對)中保存這View對象(比如EditText中的文字)的狀態然后在用戶切換回原來的activity時恢復他們。(后面會講更多的關於使用Bundle在activity銷毀和再創建時保存狀態數據)
開始/重啟Activity
當activity從停止狀態返回到前台,它收到onRestrart()調用。系統也會調用onStart()方法,每次activity變成可見時都會調用(不管時被重啟還是第一次創建)。這個onRestart()方法,只有在activity從停止狀態恢復時才會調用,所以你可以用它做一些特殊的恢復操作只要activity之前被停止了並且沒有銷毀。
app使用onRestart()來恢復activity的狀態不常見, 所以沒有使用這個方作作為app入口的講解。但是,因為onStop()方法本質上清理掉了activity的資源,你需要在activity重啟的時候需要重新實例化他們。第一次創建的時候也需要實例化他們(當沒有存在的實例時)。由於這個原因,你應該使用onStart()方法對應onStop()方法,因為系統在創建activity和從停止狀態重啟時都會調用onStart()。
例如,由於用戶在回來app之前已經沒有進入app很長時間了,onStart()方法是一個查看系統功能是否可用的好地方:
@Override protected void onStart() { super.onStart(); // Always call the superclass method first // activity可能是重啟也可能是第一次啟動 // 所以在這里我們應該確保GPS功能可用 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 }
當系統銷毀activity時,調用activity的onDestroy()方法。由於已經在onStop()中釋放了大部分資源,在收到onDestroy()調用時,大多數app不需要做什么了。這個方法時清理資源防止內存泄漏的最后機會,所以需要確保被添加的線程被銷毀了還有長時間運行的操作(比如追蹤方法)也被停止了。