1.基礎:Linux進程的啟動(兩種策略)
- 子進程繼承父進程的執行環境
if((pid == fork()< 0)){
//error
}else if(pid == 0){
//child process
}else{
//parent process
}
- 自主配置子進程的執行環境
//child process
execve(path,……);
2.Android應用進程的啟動
(1)誰發起的進程啟動
(2)誰真正啟動的應用
3.觸發進程的啟動
- AMS中判斷進程是否啟動的邏輯
ProcessRecord app = getProcessRecordLocked(……);
if(app!=null && app.thread!=null){
//1.進程已啟動 2.已啟動的進程完成了向AMS的報告
return;
}
startProcessLoced(r.processName);
在AMS端有三項關于app重要判斷
…… startProcessLoced(r.processName){
if(app != null && app.pid != null){
if(app.thread == null){
//
return app;
}
}
}
startProcessLoced()的具體工作:
- 打開本地Socket
- 通過Socket發送參數列表(其中就有"ActivityThread"這個名字)
發送之后,就開始等待結果: - Zygote返回創建好的進程的PID
Zygote受到該請求后如何處理?
//Zygote的loop在一直循環,等待有Socket請求,終于等到了
boolean runOnce(){
//1.讀取受到的參數列表String args;
//2.Zygote的常規父子進程操作
}
AMS-Zygote-Ap在進程創建時的交互.jpg
app.thread將會被AMS保存至ProcessRecord中
上述“ 向AMS的報告 ”過程需要 AP進程和AMS的跨進程通信
- AMS與AP的交互
AMS (IApplicationThread) | AP(IActivityManager)
注意,AP的binder是通過ServiceManager查到的,但是這里有一個疑問,AMS是怎么得到AP的binder句柄的?因為Ap并沒有向SM注冊(AP也不是服務不可能去注冊)
答案是:AP啟動的時候,不僅向AMS報告了app.thread,而且向AMS傳遞了IApplicationThread
4.誰真正啟動的應用
//
5.AP啟動過程:ActivityThread
public static void main(String[] args){
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attch(false);
//1.重要:與AMS通信過程
//2.重要:ViewRootImpl創建過程
//3.Instrumentation創建過程
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
6.組件什么時候啟動
以應用Service為例:
(1)如果請求啟動應用Service時,AMS查詢到啟所在進程已經啟動,那么就直接啟動該Service
(2)如果請求啟動應用Service時,AMS查詢到:
- app == null
則向Zygote發出創建進程的請求(攜帶進程的名字"ActivityThread); - app.pid == 0
說明Zygote還沒有向AMS返回創建進程的結果 - app.thread == null
說明Ap雖然已經創建,但是還沒有向AMS登記。
在第二種情況下,應用Service會被暫存入mPendingSevice,等到(2)的過程成功執行之后,再從mPendingService取出(并且remove),然后執行Service