Activity
Activity作爲Android的四大組件之一,可見其地位非同尋常,官網介紹:
移動應用體驗與桌面體驗的不同之處在於,用戶與應用的互動並不總是在同一位置開始,而是經常以不確定的方式開始。例如,如果您從主屏幕打開電子郵件應用,可能會看到電子郵件列表,如果您通過社交媒體應用啓動電子郵件應用,則可能會直接進入電子郵件應用的郵件撰寫界面。
Activity類的目的就是促進這種範式的實現。當一個應用調用另一個應用時,調用方應用會調用另一個應用中的 Activity,而不是整個應用。通過這種方式,Activity 充當了應用與用戶互動的入口點。您可以將 Activity 實現爲Activity類的子類。
下面是關於Activity類的文檔說明:
更多詳情可見官方API文檔:Activity類
Activity類是 Android 應用的關鍵組件,而 Activity 的啓動和組合方式則是該平臺應用模型的基本組成部分。在編程範式中,應用是通過main()
方法啓動的,而 Android 系統與此不同,它會調用與其生命週期特定階段相對應的特定回調方法來啓動 Activity實例中的代碼。
擴展:Activity / ActionBarActivity / AppCompatActivity的區別:
Activity
是大佬就不用說啦,後面這兩個(ActionBarActivity / AppCompatActivity)
都是爲了低版本兼容而提出來的,它們都在v7包下, ActionBarActivity已被廢棄,從名字就知道,ActionBarActivity在5.0後,被Google棄用了,AppCompatActivity
其實是ActionBarActivity
的替代,默認帶標題。而我們現在在Android Studio創建一個Activity默認繼承的會是:AppCompatActivity
! 當然你也可以改成Activity
,沒什麼影響的,看個人喜好。
在開發Android應用過程中,通常Activity(活動)是與用戶交互的接口,它提供了一個用戶完成相關操作的窗口。當我們在開發中創建Activity後,通過調用setContentView(View)方法來給該Activity指定一個佈局界面,而這個界面就是提供給用戶交互的接口。Android系統中是通過Activity棧的方式來管理Activity的,而Activity自身則是通過生命週期的方法來管理自己的創建與銷燬,So,下面我將講一下關於Activity的生命週期。
Activity的生命週期
先上圖,官方給出的Activity 生命週期的簡化圖:
當用戶瀏覽、退出和返回到Android應用時,應用中的 Activity 實例會在其生命週期的不同狀態間轉換。Activity 類會提供許多回調,這些回調會讓 Activity 知曉某個狀態已經更改:系統正在創建、停止或恢復某個 Activity,或者正在銷燬該 Activity 所在的進程。
爲了在 Activity 生命週期的各個階段之間導航轉換,Activity 類提供六個核心回調:
onCreate()
、onStart()
、onResume()
、onPause()
、onStop()
和onDestroy()
。當 Activity 進入新狀態時,系統會調用其中每個回調。
-
onCreate()
代碼必須實現此回調
,它會在系統首次創建 Activity 時觸發。Activity 會在創建後進入“已創建”狀態。它是生命週期第一個調用的方法,在該方法中做一些初始化的操作,如通過setContentView設置界面佈局的資源,初始化所需要的組件信息等,這些基本應用啓動邏輯在 Activity 的整個生命週期中只應發生一次。 -
onStart()
當上面的onCreate()
方法執行完成之後,Activity會 進入“已開始”狀態,系統會調用此回調。表示Activity正在啓動,這是在 Activity 即將對用戶可見之前調用的,此時的Activity已處於可見狀態,只是還沒有在前臺顯示,因此無法與用戶進行交互。
onStart()
方法會非常快速地完成,Activity 不會一直處於“已開始”狀態。一旦此回調結束,Activity 便會進入“已恢復”狀態,系統將調用onResume()
方法。 -
onResume()
Activity 會在進入“已恢復”狀態時來到前臺,然後系統調用onResume()
回調,此時Activity 處於 Activity 堆棧的頂層,也可以說明Activity已在前臺可見,並具有用戶輸入焦點,可與用戶交互了。這是應用與用戶互動的狀態,應用會一直保持這種狀態,直到某些事件發生,讓焦點遠離應用。此類事件包括接到來電、用戶導航到另一個 Activity,或設備屏幕關閉。
當Activity停止後(onPause()
方法或者onStop()
方法被調用),重新回到前臺時也會調用onResume()
方法,因此我們也可以在onResume()
方法中初始化一些資源,比如重新初始化
在onPause()
或者onStop()
方法中釋放的資源
。 -
onPause()
系統將此方法視爲用戶將要離開 Activity 的第一個標誌(儘管這並不總是意味着 Activity 會被銷燬)。此方法表示 Activity 不再位於前臺(儘管在用戶處於多窗口模式時 Activity 仍然可見)。
在 Android 7.0(API 級別 24)或更高版本中,有多個應用在多窗口模式下運行。無論何時,都只有一個應用(窗口)可以擁有焦點,因此係統會暫停所有其他應用。
onPause()
執行非常簡單,而且不一定要有足夠的時間來執行保存操作。因此,不應使用onPause()
來保存應用或用戶數據、進行網絡調用或執行數據庫事務。因爲在該方法完成之前,此類工作可能無法完成。相反,應在onStop()
期間執行高負載的關閉操作。 正常情況下,onStop()
方法會緊接着被回調的,但是有一種極端情況,onPause()
方法執行後直接執行了onResume()
方法,這可能是用戶操作使當前Activity退居後臺後,又迅速地再次回到到當前的Activity,此時onResume()
方法就會被回調。 -
onStop()
如果 Activity 不再對用戶可見,說明其已進入“已停止”狀態,因此係統將調用onStop()
回調。在onStop()
方法中,應用應釋放或調整在應用對用戶不可見時的無用資源。例如,應用可以暫停動畫效果,或從精確位置更新切換到粗略位置更新。使用onStop()
而非onPause()
可確保與界面相關的工作繼續進行,即使用戶在多窗口模式下查看您的 Activity 也能如此。 還可以 執行 CPU 相對密集的關閉操作。例如,如果無法找到更合適的時機來將信息保存到數據庫,可以在onStop()
期間執行此操作。
進入“已停止”狀態後,Activity 要麼返回與用戶互動,要麼結束運行並消失。如果 Activity 返回,系統將調用onRestart()
。如果 Activity 結束運行,系統將調用onDestroy()
。
備註:
AlertDialog和PopWindow是不會觸發上述
onPause()
和onStop()
兩個回調方法的。
- onRestart()
在Activity被停止後再次啓動時調用(即屏幕熄滅後再次回到app,按下home鍵後再次回到app),而後面會調用onStart()
方法。 - onDestroy()
銷燬 Activity 之前,系統會先調用onDestroy()
。系統調用此回調的原因:
1、Activity 即將結束(由於用戶徹底關閉 Activity 或由於系統爲 Activity 調用 finish())
2、由於配置變更(例如設備旋轉或多窗口模式),系統暫時銷燬 Activity
可以使用 isFinishing() 方法區分這兩種情況。
如果 Activity 即將結束,onDestroy()
是 Activity 收到的最後一個生命週期回調。如果由於配置變更而調用onDestroy()
,系統會立即新建 Activity 實例,然後在新配置中爲新實例調用onCreate()
。
onDestroy()
回調應釋放先前的回調(例如onStop()
)尚未釋放的所有資源。
注意:上面這些都是回調方法,我們不能夠去調用,我們能做的只是重寫方法裏面的內容,什麼時候去調用是由Activity所決定的。我們可以調用finish()方法,它可用於關閉某個Activity。
代碼驗證
第一個Activity:
public class MainActivity extends AppCompatActivity {
private static final String TAG = "Main";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button bt = findViewById(R.id.bt_main2);
bt.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(MainActivity.this, Main2Activity.class));
}
});
Log.d(TAG, "onCreate: ------> MainActivity進入“已創建”狀態!");
}
@Override
protected void onRestart() {
super.onRestart();
Log.d(TAG, "onRestart: ------> “已停止”狀態的MainActivity即將重啓!");
}
@Override
protected void onStart() {
super.onStart();
Log.d(TAG, "onStart: ------> MainActivity進入“已開始”狀態!");
}
@Override
protected void onResume() {
super.onResume();
Log.d(TAG, "onResume: ------> MainActivity進入“應用與用戶互動”狀態!");
}
@Override
protected void onPause() {
super.onPause();
Log.d(TAG, "onPause: ------> MainActivity進入“已暫停”狀態!");
}
@Override
protected void onStop() {
super.onStop();
Log.d(TAG, "onStop: ------> MainActivity進入“已停止”狀態!");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy: ------> MainActivity進入“已銷燬”狀態!");
}
}
第二個Activity:
public class Main2Activity extends AppCompatActivity {
private static final String TAG = "Main";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
Log.d(TAG, "onCreate: ------> Main2Activity進入“已創建”狀態!");
}
@Override
protected void onRestart() {
super.onRestart();
Log.d(TAG, "onRestart: ------> “已停止”狀態的Main2Activity即將重啓!");
}
@Override
protected void onStart() {
super.onStart();
Log.d(TAG, "onStart: ------> Main2Activity進入“已開始”狀態!");
}
@Override
protected void onResume() {
super.onResume();
Log.d(TAG, "onResume: ------> Main2Activity進入“應用與用戶互動”狀態!");
}
@Override
protected void onPause() {
super.onPause();
Log.d(TAG, "onPause: ------> Main2Activity進入“已暫停”狀態!");
}
@Override
protected void onStop() {
super.onStop();
Log.d(TAG, "onStop: ------> Main2Activity進入“已停止”狀態!");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy: ------> Main2Activity進入“已銷燬”狀態!");
}
}
驗證結果:
- 正常進入Activity,log日誌輸出:
- 點擊Back鍵正常退出Activity,log日誌輸出:
- 正常進入Activity,點擊Home鍵返回主界面,log日誌輸出:
- 點完Home鍵,重新進入Activity,log日誌輸出:
- 正常進入Activity,啓動另外一個Activity2,log日誌輸出:
- 進入另外一個Activity2後,點擊Back鍵再次回到Activity,log日誌輸出:
- 正常進入Activity,進入分屏模式,且失去焦點時,log日誌輸出:
- Activity退出分屏模式,獲取焦點進入全屏模式,log日誌輸出:
結論:
當Activity啓動時,會依次調用onCreate()
,onStart()
,onResume()
,也就是Activity已在前臺可見,並具有用戶輸入焦點,可與用戶交互了,而當Activity退到後臺時(不可見,點擊Home或者被新的Activity完全覆蓋),onPause()
和onStop()
會依次被調用。當Activity重新回到前臺(從手機主屏幕回到原Activity或者被覆蓋後又回到原Activity)時,onRestart()
,onStart()
,onResume()
會依次被調用。當Activity退出&銷燬時(點擊Back鍵),onPause()
,onStop()
,onDestroy()
會依次被調用,到此Activity的整個生命週期方法回調完成。
參考文章:
Android開發者:Activity簡介 https://developer.android.google.cn/guide/components/activities/intro-activities
4.1.1 Activity初學乍練 https://www.runoob.com/w3cnote/android-tutorial-activity.html
Android之Activity生命週期淺析(一) https://blog.csdn.net/javazejian/article/details/51932554