前言
基于 4.4 的追溯过程,因为是基于 txt 写的,所以可以复制出来再看
主题
在Android中,zygote是整个系统创建新进程的核心装置。从字面上看,zygote是受精卵的意思,它的主要工作就是进行细胞分裂。
zygote进程在内部会先启动Dalvik虚拟机,继而加载一些必要的系统资源和系统类,最后进入一种监听状态。在后续的运作中,当其他
系统模块(比如AMS)希望创建新进程时,只需向zygote进程发出请求,zygote进程监听到该请求后,会相应地“分裂”出新的进程,于是
这个新进程在初生之时,就先天具有了自己的Dalvik虚拟机以及系统资源。
系统启动伊始,zygote进程就会被 init 进程启动起来 init.rc 中启动 zygote 进程:
app_process 用于启动 Java 程序,它将生成一个 dalvik 虚拟机运行,让 Java 代码运行于虚拟机中
它的源码为 frameworks/base/cmds/app_process/app_main.cpp,生成的可执行文件为 Android 设备中的
/system/bin/app_process
app_process 的通常用于如下:
app_process [java-options] cmd-dir start-class-name [options]
其中各项功能如下:
java-options: 传递给虚拟机的参数选项
cmd-dir: java 程序所在路径
start-class-name: java 程序的类名称
[options]: 传递给 app_process 的参数选项,主要包括以下几项:
"--zygote": 是否为 zygote 进程
"--start-system-server": 是否为启动 system_server 的进程
"--application": 是否启动用程序
"--nice-name=": 指定进程的名称
流程总结:
frameworks\base\cmds\app_process\app_main.cpp
///
// 执行程序时的参数:
// /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
main()
// 先构造了一个 AppRuntime 对象,即 AppRuntime runtime;而后把进程名改成“zygote”,并利用 runtime 对象,
// 把工作转交给 java 层的 ZygoteInit 类处理。
AppRuntime runtime;
// 会跳过-Xzygote,i的位置对应 /system/bin
int i = runtime.addVmArguments(argc, argv);
if (zygote)
{
// 这个 AppRuntime 类继承于 AndroidRuntime 类,却没有重载其 start(...) 函数,所以 main() 函数中调用
// 的 runtime.start(...) 其实走的是 AndroidRuntime 的 start(...),而且传入了类名参数,即字符串——
// “ com.android.internal.os.ZygoteInit ”
// frameworks\base\core\jni\AndroidRuntime.cpp
// 这个函数就是调用 com.android.internal.os.ZygoteInit 类的 main() 静态函数
runtime.start("com.android.internal.os.ZygoteInit", startSystemServer ? "start-system-server" : "");
AndroidRuntime::start//(const char* className, const char* options)
///
// 初始化 JNI 接口, 因为后面用到的 FindClass() 之类的类
jni_invocation.Init(NULL);
/
// 启动虚拟机
if (startVm(&mJavaVM, &env) != 0)
AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv)
{
// 获得属性文件里面一此虚拟机设备的属性
property_get("dalvik.vm.checkjni", propBuf, "");
。。。。
// 启动 dalvik 虚拟机
JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs)
}
// 注册 Android 系统需要的 jni 函数
if (startReg(env) < 0)
AndroidRuntime::startReg//(JNIEnv* env)
// 注册一些重要的 jni 接口
if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0)
// 将传入的类名字符串参数辗转传给 FindClass("com.android.internal.os.ZygoteInit")
char* slashClassName = toSlashClassName(className);
jclass startClass = env->FindClass(slashClassName);
// 加载 ZygoteInit 类
// 【这是很关键的一步,就在这一步,控制权就转移到Java层次了】
// 调用 com.android.internal.os.ZygoteInit 这个类的静态 main() 方法
// AppRuntime 的 start() 最后会加载 Java 层次的 ZygoteInit 类,并利用 JNI 技术的
// CallStaticVoidMethod()调用其静态的 main() 函数
env->CallStaticVoidMethod(startClass, startMeth, strArray);
// frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static void main//(String argv[])
{
try{
///
// 在 init.rc 中已经创建了
// service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
// class main
// socket zygote stream 660 root system // 这个服务的 socket 选项表明,它需要一个名为“zygote”的“流型(stream)”socke
// onrestart write /sys/android_power/request_state wake
// onrestart write /sys/power/state on
// onrestart restart media
// onrestart restart netd
// onrestart restart surfaceflinger
// 具体创建流程见 Android Init.c 分析.c
// init 进程在新 fork 出的 zygote 进程里,是如何将 socket 的文件描述符记录记录
// 在“ANDROID_SOCKET_zygote”环境变量的,这里将会进行监听这个 socket
registerZygoteSocket();
//
// 预加载一些类,这些类记录在 frameworks/base/preloaded-classes 文本文件里
preload();
// 预加载一些系统资源
// 基本上有两大类资源:
// 1)一类和图片有关(preloaed_drawables)
// 2)另一类和颜色有关(preloaded_color_state_lists)
preloadResources();
/
// 启动整个 Android 系统的系统服务
// 接下来就是启动 Android 的重头戏了,此时 ZygoteInit 的 main() 函数会调用 startSystemServer(),
// 该函数用于启动整个 Android 系统的系统服务。其大体做法是先 fork 一个子进程,然后在子进程中做一些
// 初始化动作,继而执行 SystemServer 类的 main() 静态函数。需要注意的是,startSystemServer() 并不是
// 在函数体内直接调用 Java 类的 main() 函数的,而是通过抛异常的方式,在 startSystemServer() 之外加以处理的。
if (argv[1].equals("start-system-server")) {
startSystemServer();
private static boolean startSystemServer//() throws MethodAndArgsCaller, RuntimeException
// fork 出系统服务对应的进程
pid = Zygote.forkSystemServer(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids, parsedArgs.debugFlags, null, parsedArgs.permittedCapabilities, parsedArgs.effectiveCapabilities);
// 这里在 fork 的子进程中执行的, 即 SystemServer 进程中
if (pid == 0)
{
// 对新 fork 出的系统进程,执行 handleSystemServerProcess(), 让这个新进程成为真正的系统进程(SystemServer进程)
handleSystemServerProcess(parsedArgs);
// 因为当前已经不是运行在 zygote 进程里了,所以 zygote 里的那个监听 socket 就应该关闭了。这就是 closeServerSocket() 的意义
closeServerSocket();
// 此时的 remainingArgs 就是 ”com.android.server.SystemServer”
RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs);
public static final void zygoteInit//(int targetSdkVersion, String[] argv) throws ZygoteInit.MethodAndArgsCaller
// 在新fork出的系统进程里,需要重新定向系统输出流
redirectLogStreams();
// 设置新创建的应用进程的时区和键盘布局等通用信息
commonInit();
// 接下来调用的 nativeZygoteInit() 是个 JNI 函数,在 AndroidRuntime.cpp 文件中可以看到
// 内部会启动线程池,用于 Binder 通信
nativeZygoteInit();
applicationInit(targetSdkVersion, argv);
//
// 【其中的invokeStaticMain()一句最为关键,它承担向外抛出“特殊异常”的作用】
invokeStaticMain(args.startClass, args.startArgs);
// 抛出异常后,会跳转到下面代码的 catch (MethodAndArgsCaller caller) 继续运行,在那里调用 caller.run() 会进入下面
// 代码的 run() 函数
// 【使用抛出异常启动原因】可以清函数调用栈
throw new ZygoteInit.MethodAndArgsCaller(m, argv);
}
///
// 正常情况下子进程这一段代代码不会被执行
// 而父进程因为没有抛出异常,所以会执行在这里进行死循环,进行循环监听状态
// 每当 Activity Manager Service 向它发出“启动新应用进程”的命令时,它又会 fork
// 一个子进程,并在子进程里抛出一个异常,这样子进程还是会跳转到 catch 一句
// Log.i(TAG, "Accepting command socket connections");
runSelectLoop();
// while循环中,不断调用 selectReadable()
while (true) {
// 该函数是个native函数,对应C++层的 com_android_internal_os_ZygoteInit_selectReadable()
index = selectReadable(fdArray);
do {
// 主体函数就是一个 select() 负责监视若干文件描述符的变化情况,我们常见的变化情况有:读、写、异常等等
// 最后三个参数都为 NULL,表示该 select() 操作只打算监视文件描述符的“读变化”,而且如果没有可读的文件,
// select() 就维持阻塞状态
err = select (nfds, &fdset, NULL, NULL, NULL);
} while (err < 0 && errno == EINTR);
// 假设 ActivityManagerService 发来一个创建 Activity 组件请求,处理到这里就会创建一个新的应用进程
done = peers.get(index).runOnce();
// 我们知道,当AMS需要启动一个新进程时,会调用类似下面的句子
// Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
// app.processName, uid, uid, gids, debugFlags, mountExternal,
// app.info.targetSdkVersion, app.info.seinfo, null);
// 包括 ActivityThread 类名等重要信息的参数,最终就会通过 socket 传递给 zygote。
// 从 socket 中读取参数数据, 写数据的是 AMS(Activity Manager Server)
args = readArgumentList();
// 内部调用 fork() 出一个子进程
pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal,
parsedArgs.seInfo, parsedArgs.niceName);
if (pid == 0) {
/
// 抛出异常,让子进程能跳出循环,执行自己程序的 main 函数
ZygoteInit.invokeStaticMain(cloader, className, mainArgs);
}
}
}
// 在这里捕捉子进程抛出来的异常
catch (MethodAndArgsCaller caller) {
// 这里接收上面 startSystemServer() 函数内部抛出的异常,相当于从那里直接 goto 到这里,中间的程序不会执行了
// runSelectLoop() 里面也会抛出,如 ActivityManagerService 请求 zygote 创建 Actiivty 组件时, 也会 fork 个子进程抛异常
// 有一点需要说明一下,fork 出的 SystemServer 进程在跳转到 catch 语句后,会执行 SystemServer 类
// 的 main() 函数,而其他情况下,fork 出的应用进程在跳转的 catch 语句后,则会执行 ActivityThread 类
// 的 main() 函数。这个 ActivityThread 对于应用程序而言非常重要 【使用抛出异常启动原因】可以清函数调用栈
caller.run();// 为什么会执行到 main ? 【原因在抛出异常位置有说,经过了中间类】因为使用的是多线程机制, run() 是找多线程运行的意思,而不是执行 run() 函数
// 在异常处理中会调用 run() 就是这里的,因为在这里实现的 Runnable 多线程接口
public static class MethodAndArgsCaller extends Exception implements Runnable// Runnable 是多线程的意思吧
} // 在下面的异常捕获中运行的 caller.run() 会运行到这里
public void run() {
// 在这里执行要执行的类的 main() 函数,为什么是 main() 函数,那就上面抛出时设置的
mMethod.invoke(null, new Object[] { mArgs });
///
// 这里执行的是 SystemServer 类 的 main() 函数
public static void main//(String[] args)
{
// 调用 loadLibrary() 加载 HAL 库,位于文件 onload.cpp
// 会调用 onload.cpp 的 JNI_OnLoad(), 注册各个硬件访问子服务
System.loadLibrary("android_servers");
// 调用 ServerThread.initAndLoop(), 注册系统的关键服务,如 ActivityManagerService,PackageManagerService 等等
ServerThread thr = new ServerThread();
thr.initAndLoop();
///
// 创建主线程消息队列
Looper.prepareMainLooper();
power = new PowerManagerService();
ServiceManager.addService(Context.POWER_SERVICE, power);
// 会等待 PackageManagerService 启动后注册服务 ActivityManagerService
Slog.i(TAG, "Activity Manager");
context = ActivityManagerService.main(factoryTest);
Slog.i(TAG, "Package Manager");
pm = PackageManagerService.main(context, installer,
factoryTest != SystemServer.FACTORY_TEST_OFF,
onlyCore);
// 注册服务 ActivityManagerService
ActivityManagerService.setSystemProcess();
Slog.i(TAG, "User Service");
ServiceManager.addService(Context.USER_SERVICE,
UserManagerService.getInstance());
Slog.i(TAG, "System Content Providers");
ActivityManagerService.installSystemProviders();
Slog.i(TAG, "Window Manager");
wm = WindowManagerService.main(context, power, display, inputManager,
wmHandler, factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL,
!firstBoot, onlyCore);
ServiceManager.addService(Context.WINDOW_SERVICE, wm);
// 从这里启动 launcher 的 Activity 组件
ActivityManagerService.self().systemReady(new Runnable() {。。。});
ActivityManagerService::systemReady()
mStackSupervisor.resumeTopActivitiesLocked();
ActivityStack::resumeTopActivityLocked()
// 这里调用函数 topRunningActivityLocked 返回的是当前系统 Activity 堆栈
// 最顶端的 Activity,由于此时还没有 Activity 被启动过,因此,返回值为 null,
// 即 next 变量的值为 null,于是就调用 mService.startHomeActivityLocked 函数
if (next == null) {
// There are no more activities! Let's just start up the
// Launcher...
ActivityOptions.abort(options);
/// M: Power off alarm feature:
/// If mAlarmBoot is TRUE, that means this is alarm boot-up
/// We will skip to resume home activity until the Alarm activity is destroyed. @{
if (PowerOffAlarmUtility.isAlarmBoot()) {
Slog.v(TAG, "Skip to resume home activity!!");
return false;
}
/// @}
if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: No more activities go home");
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
return mStackSupervisor.resumeHomeActivity(prev);
ActivityStackSupervisor::resumeHomeActivity()
return mService.startHomeActivityLocked(mCurrentUser);
ActivityManagerService::startHomeActivityLocked()
Intent intent = getHomeIntent();
Intent getHomeIntent() {
Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
intent.setComponent(mTopComponent);
if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
/
// 这里就是 Launcher 组件的属性
intent.addCategory(Intent.CATEGORY_HOME);
}
return intent;
}
// 通过 resolveActivityInfo() 向 PackageManagerService 查询到带 CATEGORY_HOME 属性的 Launcher
// 程序信息
ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
// 然后启动他
mStackSupervisor.startHomeActivity(intent, aInfo);
ActivityStackSupervisor::startHomeActivity()
// 移动到栈顶
moveHomeToTop();
///
// 调用 ActivityManagerService::startActivityLocked() 启动 Launcher 程序
// 【startActivityLoked() 详见 Android 源码情景分析:16.2 应用程序的显示过程】
startActivityLocked(null, intent, null, aInfo, null, null, 0, 0, 0, null, 0, null, false, null);
}
// 循环等待消息队列
Looper.loop();
}
}
}
}