編寫:kesenhoo - 原文: http://developer.android.com/training/basics/activity-lifecycle/stopping.html
恰當(dāng)?shù)耐V古c重啟我們的activity是很重要的,在activity生命周期中,他們能確保用戶感知到程序的存在并不會(huì)丟失他們的進(jìn)度。在下面一些關(guān)鍵的場(chǎng)景中會(huì)涉及到停止與重啟:
Activity類提供了onStop()與onRestart()方法來允許在activity停止與重啟時(shí)進(jìn)行調(diào)用。不同于暫停狀態(tài)的部分阻塞UI,停止?fàn)顟B(tài)是UI不再可見并且用戶的焦點(diǎn)轉(zhuǎn)移到另一個(gè)activity中.
Note: 因?yàn)橄到y(tǒng)在activity停止時(shí)會(huì)在內(nèi)存中保存Activity的實(shí)例,所以有時(shí)不需要實(shí)現(xiàn)onStop(),onRestart()甚至是onStart()方法. 因?yàn)榇蠖鄶?shù)的activity相對(duì)比較簡(jiǎn)單,activity會(huì)自己停止與重啟,我們只需要使用onPause()來停止正在運(yùn)行的動(dòng)作并斷開系統(tǒng)資源鏈接。
http://wiki.jikexueyuan.com/project/android-training-geek/images/basic-lifecycle-stopped.png" alt="basic-lifecycle-stopped" />
Figure 1. 上圖顯示:當(dāng)用戶離開我們的activity時(shí),系統(tǒng)會(huì)調(diào)用onStop()來停止activity (1). 這個(gè)時(shí)候如果用戶返回,系統(tǒng)會(huì)調(diào)用onRestart()(2), 之后會(huì)迅速調(diào)用onStart()(3)與onResume()(4). 請(qǐng)注意:無論什么原因?qū)е耡ctivity停止,系統(tǒng)總是會(huì)在onStop()之前調(diào)用onPause()方法。
當(dāng)activity調(diào)用onStop()方法, activity不再可見,并且應(yīng)該釋放那些不再需要的所有資源。一旦activity停止了,系統(tǒng)會(huì)在需要內(nèi)存空間時(shí)摧毀它的實(shí)例(和棧結(jié)構(gòu)有關(guān),通常back操作會(huì)導(dǎo)致前一個(gè)activity被銷毀)。極端情況下,系統(tǒng)會(huì)直接殺死我們的app進(jìn)程,并不執(zhí)行activity的onDestroy()回調(diào)方法, 因此我們需要使用onStop()來釋放資源,從而避免內(nèi)存泄漏。(這點(diǎn)需要注意)
盡管onPause()方法是在onStop()之前調(diào)用,我們應(yīng)該使用onStop()來執(zhí)行那些CPU intensive的shut-down操作,例如往數(shù)據(jù)庫(kù)寫信息。
例如,下面是一個(gè)在onStop()的方法里面保存筆記草稿到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.
);
}
activity已經(jīng)停止后,Activity對(duì)象會(huì)保存在內(nèi)存中,并在activity resume時(shí)被重新調(diào)用。我們不需要在恢復(fù)到Resumed state狀態(tài)前重新初始化那些被保存在內(nèi)存中的組件。系統(tǒng)同樣保存了每一個(gè)在布局中的視圖的當(dāng)前狀態(tài),如果用戶在EditText組件中輸入了text,它會(huì)被保存,因此不需要保存與恢復(fù)它。
Note: 即使系統(tǒng)會(huì)在activity stop時(shí)停止這個(gè)activity,它仍然會(huì)保存View對(duì)象的狀態(tài)(比如EditText中的文字) 到一個(gè)Bundle中,并且在用戶返回這個(gè)activity時(shí)恢復(fù)它們(下一小節(jié)會(huì)介紹在activity銷毀與重新建立時(shí)如何使用Bundle來保存其他數(shù)據(jù)的狀態(tài)).
當(dāng)activity從Stopped狀態(tài)回到前臺(tái)時(shí),它會(huì)調(diào)用onRestart().系統(tǒng)再調(diào)用onStart()方法,onStart()方法會(huì)在每次activity可見時(shí)都會(huì)被調(diào)用。onRestart()方法則是只在activity從stopped狀態(tài)恢復(fù)時(shí)才會(huì)被調(diào)用,因此我們可以使用它來執(zhí)行一些特殊的恢復(fù)(restoration)工作,請(qǐng)注意之前是被stopped而不是destrory。
使用onRestart()來恢復(fù)activity狀態(tài)是不太常見的,因此對(duì)于這個(gè)方法如何使用沒有任何的guidelines。然而,因?yàn)閛nStop()方法應(yīng)該做清除所有activity資源的操作,我們需要在重啟activtiy時(shí)重新實(shí)例化那些被清除的資源,同樣, 我們也需要在activity第一次創(chuàng)建時(shí)實(shí)例化那些資源。介于上面的原因,應(yīng)該使用onStart()作為onStop()所對(duì)應(yīng)方法。因?yàn)橄到y(tǒng)會(huì)在創(chuàng)建activity與從停止?fàn)顟B(tài)重啟activity時(shí)都會(huì)調(diào)用onStart()。也就是說,我們?cè)趏nStop里面做了哪些清除的操作,就該在onStart里面重新把那些清除掉的資源重新創(chuàng)建出來。
例如:因?yàn)橛脩艉芸赡茉诨氐竭@個(gè)activity之前已經(jīng)過了很長(zhǎng)一段時(shí)間,所以onStart()方法是一個(gè)比較好的地方來驗(yàn)證某些必須的系統(tǒng)特性是否可用。
@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
}
當(dāng)系統(tǒng)Destory我們的activity,它會(huì)為activity調(diào)用onDestroy()方法。因?yàn)槲覀儠?huì)在onStop方法里面做釋放資源的操作,那么onDestory方法則是我們最后去清除那些可能導(dǎo)致內(nèi)存泄漏的地方。因此需要確保那些線程都被destroyed并且所有的操作都被停止。