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的常规父子进程操作
}
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