在Android系統中,Activity和Service是應用程序的核心組件,它們組合在一塊兒構成了一個完整的應用程序,應用程序框架層提供了一套完整的機制來協助應用程序啓動這些Activity和Service,以及提供Binder機制幫助它們相互間進行通訊。java
有兩種操做會引起Activity的啓動,一種用戶點擊應用程序圖標時,Launcher會爲咱們啓動應用程序的主Activity;應用程序的默認Activity啓動起來後,它又能夠在內部經過調用startActvity接口啓動新的Activity,依此類推,每個Activity均可以在內部啓動新的Activity。經過這種連鎖反應,按需啓動Activity,從而完成應用程序的功能。android
Activity的啓動方式有兩種,一種是顯式的,一種是隱式的,隱式啓動可使得Activity之間的藕合性更加鬆散,所以,這裏只關注隱式啓動Activity的方法。web
下面讓咱們首先經過一終流程圖來看一下 Activity 的生命週期是怎樣的,你們應該都很熟悉這張圖吧app
我來對這張流程作個簡單的解釋框架
1.啓動Activity:系統會先調用onCreate方法,而後調用onStart方法,最後調用onResume,Activity進入運行狀態。ide
2.當前Activity被其餘Activity覆蓋其上或被鎖屏:系統會調用onPause方法,暫停當前Activity的執行。spa
3.當前Activity由被覆蓋狀態回到前臺或解鎖屏:系統會調用onResume方法,再次進入運行狀態。code
4.當前Activity轉到新的Activity界面或按Home鍵回到主屏,自身退居後臺:系統會先調用onPause方法,而後調用onStop方法,進入停滯狀態。orm
5.用戶後退回到此Activity:系統會先調用onRestart方法,而後調用onStart方法,最後調用onResume方法,再次進入運行狀態。xml
6.當前Activity處於被覆蓋狀態或者後臺不可見狀態,即第2步和第4步,系統內存不足,殺死當前Activity,然後用戶退回當前Activity:再次調用onCreate方法、onStart方法、onResume方法,進入運行狀態。
7.用戶退出當前Activity:系統先調用onPause方法,而後調用onStop方法,最後調用onDestory方法,結束當前Activity。
接着經過一個實例來看一下 Activity 的整個生命週期,閒話少說,都在代碼裏了...
src\cn\lion\activitytest
1. MainActivity.java
package cn.lion.activitytest; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; public class MainActivity extends Activity{ private final static String LOG_TAG = "cn.lion.activitytest.MainActivity"; private Button startButton = null; private int param = 1; //Activity建立時被調用 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); startButton = (Button)findViewById(R.id.button_start); startButton.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View v){ Intent intent = new Intent("cn.lion.activitytest.subactivity"); startActivity(intent); } }); Log.i(LOG_TAG, "MainActivity onCreate() called"); } //Activity建立或者從後臺從新回到前臺時被調用 @Override protected void onStart(){ super.onStart(); Log.i(LOG_TAG, "MainActivity onStart() called"); } //Activity從後臺從新回到前臺時被調用 @Override protected void onRestart(){ super.onRestart(); Log.i(LOG_TAG, "MainActivity onRestart() called"); } //Activity建立或者從被覆蓋、後臺從新回到前臺時被調用 @Override protected void onResume(){ super.onResume(); Log.i(LOG_TAG, "MainActivity onResume() called"); } //Activity被覆蓋到下面或者鎖屏時被調用 @Override protected void onPause() { super.onPause(); Log.i(LOG_TAG, "MainActivity onPause() called"); //有可能在執行完onPause或onStop後,系統資源緊張將Activity殺死,因此有必要在此保存持久數據 } //退出當前Activity或者跳轉到新Activity時被調用 @Override protected void onStop() { super.onStop(); Log.i(LOG_TAG, "MainActivity onStop() called"); } //退出當前Activity時被調用,調用以後Activity就結束了 @Override protected void onDestroy() { super.onDestroy(); Log.i(LOG_TAG, "MainActivity onDestory() called"); } //Activity窗口得到或失去焦點時被調用,在onResume以後或onPause以後 @Override public void onWindowFocusChanged(boolean hasFocus){ super.onWindowFocusChanged(hasFocus); Log.i(LOG_TAG, "MainActivity onWindowFocusChanged() called"); } /** * Activity被系統殺死時被調用. * 例如:屏幕方向改變時,Activity被銷燬再重建;當前Activity處於後臺,系統資源緊張將其殺死. * 另外,當跳轉到其餘Activity或者按Home鍵回到主屏時該方法也會被調用,系統是爲了保存當前View組件的狀態. * 在onPause以前被調用. */ @Override protected void onSaveInstanceState(Bundle outState) { outState.putInt("param", param); Log.i(LOG_TAG, " MainActivity onSaveInstanceState() called. put param: " + param); super.onSaveInstanceState(outState); } /** * Activity被系統殺死後再重建時被調用. * 例如:屏幕方向改變時,Activity被銷燬再重建;當前Activity處於後臺,系統資源緊張將其殺死,用戶又啓動該Activity. * 這兩種狀況下onRestoreInstanceState都會被調用,在onStart以後. */ @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { param = savedInstanceState.getInt("param"); Log.i(LOG_TAG, "MainActivity onRestoreInstanceState() called. get param: " + param); super.onRestoreInstanceState(savedInstanceState); } }
2. SubActivity.java
package cn.lion.activitytest; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; public class SubActivity extends Activity{ private final static String LOG_TAG = "cn.lion.activitytest.SubActivity"; private Button finishButton = null; private int param = 2; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.sub); finishButton = (Button)findViewById(R.id.button_finish); finishButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { finish(); } }); Log.i(LOG_TAG, "Sub Activity onCreate() called"); } //Activity建立或者從後臺從新回到前臺時被調用 @Override protected void onStart(){ super.onStart(); Log.i(LOG_TAG, "SubActivity onStart() called"); } //Activity從後臺從新回到前臺時被調用 @Override protected void onRestart(){ super.onRestart(); Log.i(LOG_TAG, "SubActivity onRestart() called"); } //Activity建立或者從被覆蓋、後臺從新回到前臺時被調用 @Override protected void onResume(){ super.onResume(); Log.i(LOG_TAG, "SubActivity onResume() called"); } //Activity被覆蓋到下面或者鎖屏時被調用 @Override protected void onPause() { super.onPause(); Log.i(LOG_TAG, "SubActivity onPause() called"); //有可能在執行完onPause或onStop後,系統資源緊張將Activity殺死,因此有必要在此保存持久數據 } //退出當前Activity或者跳轉到新Activity時被調用 @Override protected void onStop() { super.onStop(); Log.i(LOG_TAG, "SubActivity onStop() called"); } //退出當前Activity時被調用,調用以後Activity就結束了 @Override protected void onDestroy() { super.onDestroy(); Log.i(LOG_TAG, "SubActivity onDestory() called"); } //Activity窗口得到或失去焦點時被調用,在onResume以後或onPause以後 @Override public void onWindowFocusChanged(boolean hasFocus){ super.onWindowFocusChanged(hasFocus); Log.i(LOG_TAG, "SubActivity onWindowFocusChanged() called"); } /** * Activity被系統殺死時被調用. * 例如:屏幕方向改變時,Activity被銷燬再重建;當前Activity處於後臺,系統資源緊張將其殺死. * 另外,當跳轉到其餘Activity或者按Home鍵回到主屏時該方法也會被調用,系統是爲了保存當前View組件的狀態. * 在onPause以前被調用. */ @Override protected void onSaveInstanceState(Bundle outState) { outState.putInt("param", param); Log.i(LOG_TAG, " SubActivity onSaveInstanceState() called. put param: " + param); super.onSaveInstanceState(outState); } /** * Activity被系統殺死後再重建時被調用. * 例如:屏幕方向改變時,Activity被銷燬再重建;當前Activity處於後臺,系統資源緊張將其殺死,用戶又啓動該Activity. * 這兩種狀況下onRestoreInstanceState都會被調用,在onStart以後. */ @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { param = savedInstanceState.getInt("param"); Log.i(LOG_TAG, "SubActivity onRestoreInstanceState() called. get param: " + param); super.onRestoreInstanceState(savedInstanceState); } }
res\values
strings.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">ActivityTest</string> <string name="action_settings">Settings</string> <string name="hello_world">Hello world!</string> <string name="sub_activity">SubActivity</string> <string name="start">Start-subActivity</string> <string name="finish">Finish-activity</string> </resources>
res\layout
1. activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:gravity="center"> <Button android:id="@+id/button_start" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:text="@string/start" > </Button> </LinearLayout>
2. sub.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:gravity="center"> <Button android:id="@+id/button_finish" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:text="@string/finish" > </Button> </LinearLayout>
接着一步一步來對這個簡單的應用進行操做,而後看一下它的執行結果(注意下面的 Log 信息是通過過濾器過濾的,我定義了一個只顯示 cn.lion.activitytest* 類型信息的過濾器...)
1. 程序啓動後的顯示界面
Log 打印的信息以下
2. 點擊上圖的 Start-subActivity 按鈕後,界面跳轉以下
Log 的追加打印的信息以下
3. 點擊上圖的 Finish-activity 按鈕後,界面跳轉以下
Log 追加打印的信息以下
不管是經過點擊應用程序圖標來啓動Activity,仍是經過Activity內部調用startActivity接口來啓動新的Activity,都要藉助於應用程序框架層的ActivityManagerService服務進程。Service也是由ActivityManagerService進程來啓動的。在Android應用程序框架層中,ActivityManagerService是一個很是重要的接口,它不但負責啓動Activity和Service,還負責管理Activity和Service。
Android應用程序框架層中的ActivityManagerService啓動Activity的過程大體以下圖所示:
下面簡要介紹一下啓動的過程:
Step 1. 不管是經過Launcher來啓動Activity,仍是經過Activity內部調用startActivity接口來啓動新的Activity,都經過Binder進程間通訊進入到ActivityManagerService進程中,而且調用ActivityManagerService.startActivity接口;
Step 2. ActivityManagerService調用ActivityStack.startActivityMayWait來作準備要啓動的Activity的相關信息;
Step 3. ActivityStack通知ApplicationThread要進行Activity啓動調度了,這裏的ApplicationThread表明的是調用ActivityManagerService.startActivity接口的進程,對於經過點擊應用程序圖標的情景來講,這個進程就是Launcher了,而對於經過在Activity內部調用startActivity的情景來講,這個進程就是這個Activity所在的進程了;
Step 4. ApplicationThread不執行真正的啓動操做,它經過調用ActivityManagerService.activityPaused接口進入到ActivityManagerService進程中,看看是否須要建立新的進程來啓動Activity;
Step 5. 對於經過點擊應用程序圖標來啓動Activity的情景來講,ActivityManagerService在這一步中,會調用startProcessLocked來建立一個新的進程,而對於經過在Activity內部調用startActivity來啓動新的Activity來講,這一步是不須要執行的,由於新的Activity就在原來的Activity所在的進程中進行啓動;
Step 6. ActivityManagerServic調用ApplicationThread.scheduleLaunchActivity接口,通知相應的進程執行啓動Activity的操做;
Step 7. ApplicationThread把這個啓動Activity的操做轉發給ActivityThread,ActivityThread經過ClassLoader導入相應的Activity類,而後把它啓動起來。