啓動前:
1,init進程是所有Linux程序的起點,會啓動ServiceManager,fork一些守護進程,也是Zygote的父進程,通過解析init.rc孵化出Zygote進程。
2,Zygote是所有Java進程的父進程,所有的APP進程都是由Zygote進程fork出的(因爲每個APP都是運行在各自的虛擬機中,APP每次運行都要重新初始化和啓動虛擬機,很耗費時間,Zygote會把已經運行的虛擬機代碼和內存信息共享,這樣可以預加載資源和類,從而縮短啓動時間,所以是fork進程,而不是新建進程),Zygote初始化後,會註冊一個等待接受消息的socket,OS層會採用socket進行IPC通信。
3,SystemSever進程是Zygote孵化出的第一個進程,負責啓動和管理整個Framework,如AMS,PMS等服務。
4,launcher進程是Zygote進程孵化的第一個APP進程。Launcher繼承Activity,也是一個界面。
先從Launcher啓動一個APP說起:
咱們的手機桌面也是一個APP,這個APP就叫Launcher,可以說是其他APP的入口和管理者,當我們點擊APP圖標後,會發生以下幾件事兒:
1,Launcher捕獲點擊事件(在Launcher所在線程進行)。
Launcher.onClick->Launcher.onClickAppShortcut->Launcher.startAppShortcutOrInfoActivity(獲取APP安裝時PMS解析AndroidManifest.xml文件的信息)->Launcher.startActivitySafely
2,Launcher通知AMS要啓動一個新Activity(也就是目標APP的入口Activity)。
Activity.startActivity->Activity.startActivityForResult->Instrumentation.exeStartActivity()->AMP.startActivity
簡單說這是個跨進程通信過程就是AMP利用Binder進行通信,通過Binder對象的transact方法傳輸到AMS.
重要實現是Instrumentation.exeStartActivity()方法,其中傳入的contextThread是一個IBinder對象,即ApplicationThread的本地對象,是通過ActivityThread.getApplicationThread()獲取到的。ActivityManagerNative.getDefault()返回的是AMS的代理對象AMP。這兒我們就是把自己的Binder對象(contextThread)傳遞給了AMS,用來完成ActivityThread與AMS的通信。
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
//省略部分代碼
try {
//...
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
//檢查啓動Activity的結果(拋出異常,例如清單文件未註冊Activity)
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
}
3,AMS先校驗Activity的正確性,如是否註冊,如果正確會暫存當前activity的信息,然後AMS通知Launcher程序pause Activity(在AMS所在進程執行,即SystemSever進程)
AMS.startActivity->AMS.startActivityAsUser->ActicityStackSupervisor.startActivityMayWait->ActicityStackSupervisor.startActivityLocked(校驗參數,創建ActivityRecord,每啓動一個activity就會創建一個對於的ActivityRecord對象,等)->ActicityStackSupervisor.startActivityUnchecked->ActivityStack.startActivityLocked(判斷是否需要創建一個新的任務來啓動Activity)->ActivityStack.resumeTopActivityLocked(獲取棧頂activity,通知Launcher應pause掉該activity)->ActivityStack.startPausingLocked->ApplicationThreadProxy.schedulePauseActivity
4,Launcher會pause掉棧頂Activity,在該Activity不可見時,並通知AMS已經paused(在Launcher所在進程執行)
ApplicationThread.schedulePauseActivity->ActivityThread.queueOrSendMessage->Handler.handleMessage->ActivityThread.handlePauseActivity->ActivityManagerProxy.activityPaused
5,AMS檢查activity所在進程是否存在,如果存在,則直接通知這個進程啓動Activity,不存在就調用Process.start創建一個進程(在AMS進程執行)
AMS.activityPaused->ActivityStack.activityPaused->ActivityStack.completePausedLocked->ActivityStack.resumeTopActivityLocked->ActivityStack.startSpecificActivityLocked(檢查進程是否已存在)->AMS.startProcessLocked ->Process.start(是Zygote進程fork出的新的APP進程,通過反射執行ActivityThread的main方法)
在startSpecificActivityLocked方法中檢查進程是否存在,若存在則直接調用第7步的realStartActivityLocked方法啓動activity。
6,創建ActivityThread實例,進行初始化操作。將該進程綁定到AMS,並保存當前進程對應的主線程。綁定Application,如果Application不存在,則調用LoadedApk.makeApplication創建一個新的Application對象。之後進入Loop循環。(在APP進程執行)
ActivityThread.main->ActivityThread.attach(false)(false聲明不是系統進程,該方法將當前進程綁定到了AMS)->AMP.attchApplication
public final class ActivityThread {
final ApplicationThread mAppThread = new ApplicationThread();
public static void main(String[] args) {
// 初始化主線程的消息隊列
Looper.prepareMainLooper();
//創建當前進程的主線程
ActivityThread thread = new ActivityThread();
//將主線程綁定到AMS
thread.attach(false);
//保存主線程的handler
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
// 開啓消息循環
Looper.loop();
}
private void attach(boolean system) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) { // 是否爲系統進程
android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
UserHandle.myUserId());
RuntimeInit.setApplicationObject(mAppThread.asBinder());
// 獲得 AMS 的代理對象
final IActivityManager mgr = ActivityManagerNative.getDefault();
mgr.attachApplication(mAppThread);
}
}
}
// ActivityManagerProxy 的 attachApplication 方法
public void attachApplication(IApplicationThread app) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeStrongBinder(app.asBinder());
mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0);
reply.readException();
data.recycle();
reply.recycle();
}
現在APP的新進程創建完畢了,也有了自己的主線程,接下來就要啓動activity了。
7,AMS處理APP進程發出的創建進程完成的通信請求,通知APP啓動目標Activity(在AMS進程執行)
AMS.attchApplication(通過Binder.getCallingPid獲取了APP進程ID,AMS綁定本地ApplicationThread對象,後續通過ApplicationThreadProxy進行通信)->AMS.attachApplicationLocked(在該方法AMS通過thread.bindApplication綁定Application)->ActivityStackSupervisor.attachApplicationLocked->ActivityStackSupervisor.realStartActivityLocked(真正要啓動activity了)->ApplicationThreadProxy.scheduleLaunchActivity (AMS通過ATP通知APP進程啓動Activity)
8,加載目標Activity類,如MainActivity,調用該類的onCreate方法(在APP進程執行)
ApplicationThread.scheduleLaunchActivity(ApplicationThread發消息給AT)->ActivityThread.queueOrSendMessage->H.handleMessage (AT的Handler來處理接收到的LAUNCH_ACTIVITY的消息)->ActivityThread.handleLaunchActivity->ActivityThread.performLaunchActivity->Instrumentation.newActivity->Instrumentation.callActivityOnCreate->MainActivity.onCreate
備註:
AMS(ActivityManagerService):服務端對象,負責系統中所以Activity的生命週期。在SystemServer進程開啓時,會初始化AMS。
Instrumentation:負責調用Activity和Application的生命週期,每個activy內部都有該對象的引用。
AMN(ActivityManagerNative):運行在server端(SystemServer進程)。實現了Binder類,具體功能由子類AMS實現。
AMP(ActivityManagerProxy):AMS的client端代理,AMP和AMS通過Binder通信。
ActivityThread:運行在UI線程(主線程),APP的真正入口,因爲提供了static main()函數,是我們常說的主線程。
ApplicationThread:是Activity的內部類,是一個Binder類,用來實現AMS和ActivityThread之間的交互,實現跨進程通信。
ApplicationThreadProxy:ApplicationThread 在服務端的代理。AMS就是通過該代理與ActivityThread進行通信的。
ActivityStackSupervisor:負責所有Activity棧的管理。
其他:
1、新的Activity類是通過類加載器方式即通過反射的方式生成的,在mInstrumentation.newActivity()方法中:
(Activity)cl.loadClass(className).newInstance();
最後調用mInstrumentation.callActivityOnCreate(),該方法會顯示調用Activtiy的onStart()方法。
2,之後調用方法是:
ActivityThread.performResumeActivity()-> Activity.performResume()-> Instrumentation.callActivityOnResume()-> Activity.onResume()
在onResume之後開始繪製界面。
3,說個閒話,如果想讓自己的APP做Launcher,就在註冊配置文件添加
<category android:name="android.intent.category.HOME"/>
<category android:name="android.intent.category.DEFAULT"/>
參考: