應用進程的啟動流程

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

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。