1. 什么是Activity?
- Activity作為Android四大組件之一,它有着舉足輕重的地位,每一個Activity都會獲得一個用於繪制其用戶界面的窗口,Activity是一個view對象的容器,通過Window類的setContentView()方法添加到Activity上,最終提供與用戶交互的界面;
- Activity是上下文對象 Context的子類, 並且實現了Window.callback,KeyEvent.callback 這兩個接口,因此 Activity 可以響應和處理用戶與窗口的交互事件,以及鍵盤相關的輸入事件;
- 一個Android應用通常由一個或者多個Activity 組成;如果是多個Activity,一般會指定應用中的某個 Activity 為“主” Activity,即首次啟動應用時呈現給用戶的那個 Activity。 而且每個Activity 通過使用Intent(意圖)均可啟動另一個Activity,這里使用的是IPC機制。 每次啟動一個新的Activity 啟動時,前一 Activity 便會停止,但系統會在回退桟中保留該 Activity,而新啟動的Activity可以放如該棧頂也可以設置其啟動方式放入新的回退桟,這就和Activity四種啟動方式有關了。
附上一張圖,對Activity有一個更直觀和全面的認識:

對Activity有了一個比較直觀的認識后,我們自然想到的是怎么使用它,其實對於Activity google對其封裝的還是挺厲害,開發者使用時主要就是繼承Activity,通過setContentView()方法設置布局界面,然后重寫它的幾個生命周期函數;而跳轉新的Acitivty更簡單,通過一個Intent然后調用startActivity方法即可;
2. Activity生命周期
其實對於Activity最重要的就是搞清楚它的各個生命周期函數,只有這樣我們才能知道Activity在各個生命周期階段需要做什么事,那些事不適合做,這對於編寫高質量的App是至關重要的;
Activity是通過回退桟來管理的,此時Activity可呈現出四種狀態:
(1) 當Activity位於回退棧桟頂時,此時將顯示在屏幕上,用戶可與之交互,此時Activity處於運行狀態;
(2) 當Activity失去了焦點但依然可見(如棧頂Activity尺寸小沒有完全覆蓋屏幕,或者棧頂Activity是透明的),此時Activity處於暫停狀態;
(3) 當Activity被新的Activity或者應用完全遮住(新Activity不透明),因此Activity已經對用戶不可見,此時Activity處於停止狀態;
(4) 當Activity被完全退出或者App進程完全退出時,Activity將會回調onDestory方法,之后Activity將被銷毀,Activity將處於銷毀狀態;
下面我們主要闡述Activity的生命周期:
同樣我們先附上圖(來自Android官方文檔):

1. 首先對Activity主要生命周期函數做介紹:
(1) onCreate
Activity生命周期的第一個方法,表示Activity正在被創建,在該方法中通過setContentView 方法加載xml編寫的布局文件,然后通過findByViewId方法獲取控件;
onCreate()方法在Activity整個生命周期中只會調用一次,所以該方法中就可以做一些大致只需要做一次的工作,如:一些變量的初始化,資源的加載,初始化控件以及事件的綁定等;
由於此時view還沒有加載出來,因此該方法中不能開啟動畫的;
注:onCreate()的官方文檔注釋,建議 setContentView()、findViewById() 在 onCreate() 中調用,但在onStart()中調用 setContentView()、findViewById() 功能也是正常的,只是不建議,並且很少會這樣做;
(2) onStart
Activity正在啟動,此時Activity已經看見,但是沒有展現在前台,沒有獲取到焦點,當然也就不能與用戶交互;
因為該方法是Activity重新回到前台時第一個回調的方法,因此在該方法里我們可以去檢查某些必須的系統特性是否可用,比如網絡是否在連接, GPS是否打開等類似的功能;
該方法中我們通常初始化一些變量,當然這些變量必須是在Activity處於前台的時候才能夠被響應;
(3) onResume
Activity可見可交互;
如果Activity是重新打開,此時就需要在該方法中重新實例化在onPause()中釋放的資源;
初始化在前台顯示時需要的資源,如:動畫、播放視頻,此外建議在onResume()中打開獨占設備,比如相機,之所以在該方法中打開是因為當打開新的Activity時,首先會onPause掉舊Activity,然后在onCreate, onStart, onResume新Activity,如果之前舊Activity已經打開了獨占設備(相機), 那此時onPause舊Activity時就可以釋放掉獨占設備(相機),那么打開的新Activity就能夠使用獨占設備(相機)了;
(4) onPause
Activity已經暫停,可見但不在前台,因此也不可交互;
該方法中需要持久化用戶數據、停止動畫,暫停正在播放的視頻等不太耗時的操作;
釋放部分占用的系統資源(尤其是獨占設備),如:相機, GPS等,設置有時會讓該Activity斷開網絡連接,因為這些工作會大幅度占用系統資源,增加電耗或者流量消耗;
因為打開新的Activity前回去回調舊Activity的onPause方法,因此onPause方法中不能做太耗時的操作(如,數據庫讀寫,IO操作),否則調新的 Activity 在切換時可能會出現卡頓現象,這是用戶不想看到的;
耗時的清理工作應該放在onStop方法中;
(5) onStop
Activity即將停止,此時當然不可見;
耗時的清理工作應該放在onStop方法中;
Activity 在此狀態時仍然存在於內存中,如果在系統內存不夠時,系統接下來很快會銷毀掉該Activity,在極端情況下,直接 kill Activity 且不執行onDestroy()函數。所以務必在onStop()函數中就清理掉可能引起內存泄露的資源,當然更極端的時系統內存已嚴重不足,導致系統無法保留該進程的情況下,onStop() 可能都不會被執行;
(6) onDestory
Activity即將被銷毀,
很多情況下 Activity 是不需要定義這個函數,因為在onPause()和onStop()中,大多數的清理工作都已經完成了。但是,如果在onCreate()中定義了后台線程,或者可能引起內存泄露的代碼,那就需要在onDestroy()中清理,如,靜態對象持有其他Activity的引用,廣播注銷等操作;
(7) onRestart
Activity正在被重新啟動
在原Activity沒有銷毀時重新要回到該Activity時會回調該方法,緊接着會回調onStart方法,一般在該方法中恢復用戶數據;
其實Activity生命周期函數可以看成是成對的,onCreate和onDestory成對,onStart和onStop成對,onResume和onPause成對,這在上述每個回調函數的介紹中也可以看出來

2. 下面闡述幾種比較常見的情況:
(1) 單個A Activity啟動回調流程
onCreate
onStart
onResume
(2) 當用戶按下home鍵時
onPause
onStop
(3) 當用戶再次回到原Activity時
onRestart
onStart
onResume
(4) 在A Activity的基礎上,打開新的B Activity,此時需要注意的問題是B Activity的大小和透明度
a. B Activity完全覆蓋A Activity,並且B Activity是不透明的:
A Activity: onPause
B Activity: onCreate --> on Start --> onResume
A Activity : onStop
b. B Activity因為尺寸小沒有完全覆蓋A Activity,或者B Activity是透明的, 此時A Activity的onStop方法是不會被執行的
A Activity: onPause
B Activity: onCreate --> on Start --> onResume
(5) 當用戶按back鍵時
onPause
onStop
onDestory
筆者水平有限,如有錯誤,歡迎指正,謝謝!
