1. 触发进程启动
应用进程的启动通常由以下场景触发:
-
用户点击桌面图标:启动主Activity。
-
启动其他组件:如Service、BroadcastReceiver、ContentProvider。
-
跨进程调用:其他应用通过Binder调用需创建新进程。
核心入口为 ActivityManagerService (AMS),负责统一调度进程生命周期。
2. AMS分配进程与权限校验
当组件需要启动时,AMS执行以下关键步骤:
-
进程检查:
-
若目标应用进程已存在(如后台保活),直接复用。
-
若不存在,进入创建流程。
-
-
权限校验:
-
检查调用方权限(如
START_ACTIVITY权限)。 -
验证目标组件的
AndroidManifest声明(如<activity>的exported属性)。
-
-
进程分配决策:
-
根据
android:process属性决定是否创建独立进程(默认与包名相同)。
-
3. 向Zygote发起进程创建请求
AMS通过Socket通信向Zygote发起进程创建:
-
构造启动参数:
-
目标类名:
android.app.ActivityThread。 -
应用信息:包名、用户ID、APK路径等。
-
虚拟机参数:堆大小、JNI库路径等。
-
-
Socket通信:
-
AMS通过
LocalSocket向Zygote进程(/dev/socket/zygote)发送请求数据。 -
Zygote主线程通过
ZygoteServer.runSelectLoop()接收请求。
-
4. Zygote fork子进程
Zygote收到请求后,执行以下操作:
-
解析参数:
-
验证UID/GID权限,确保安全隔离。
-
-
fork子进程:
-
调用
fork()创建子进程,继承Zygote预加载的类、资源及虚拟机状态。
-
-
子进程特化:
-
关闭无用资源:如父进程的Socket连接。
-
设置进程名:
com.example.app(通过Process.setArgV0())。 -
调用
ActivityThread.main():进入应用进程主逻辑。
-
5. 应用进程初始化
子进程执行ActivityThread.main(),完成以下初始化:
-
绑定到AMS:
-
通过
attachApplication()将进程信息注册到AMS,建立Binder通信链路(IApplicationThread)。
-
-
创建Application对象(由AMS发送bindApplication后调用):
-
反射创建目标应用类(
android.app.Application)。 -
调用
Application.onCreate()生命周期。
-
-
启动目标组件:
-
AMS通过Binder通知应用进程启动目标组件(如Activity的
onCreate())。 -
主线程初始化
Looper,进入消息循环(Looper.loop())。
-
Q1:为什么Android用Zygote fork进程而不是直接启动新进程?
-
答:Zygote预加载公共资源(类、主题、库),fork可继承这些资源,节省内存和启动时间。
Q2:应用进程如何绑定到AMS?
-
答:通过
ActivityThread.attach()发送Binder句柄(IApplicationThread)给AMS,AMS通过此接口控制应用进程的生命周期。
Q3:AMS和zygote通信为什么不采用binder机制?
答:
-
1.Binder依赖ServiceManager注册:Binder通信需要服务端(Zygote)先在ServiceManager中注册Binder对象,客户端(AMS)才能通过ServiceManager获取其引用。然而,Zygote和ServiceManager均由Init进程启动,二者属于并行启动的独立进程,无法保证Zygote在启动时ServiceManager已就绪。若Zygote尝试注册Binder时ServiceManager尚未初始化完成,将导致注册失败,AMS无法通过Binder与Zygote通信。
-
2.Socket的独立性:Socket通信不依赖ServiceManager,Zygote启动后直接监听Socket请求,无需等待其他服务初始化,避免了时序依赖问题。
Android应用进程启动流程解析
2573

被折叠的 条评论
为什么被折叠?



