系统启动->BootLoader->Linux内核->init -> zygote -> systemserver->Launcher
当电源按下时引导芯片代码开始从预定义的地方(固化在ROM)开始执行。加载引导程序Bootloader到RAM,然后执行。
引导程序BootLoader是在Android操作系统开始运行前的一个小程序,它的主要作用是把系统OS拉起来并运行。
内核启动时,设置缓存、被保护存储器、计划列表、加载驱动。当内核完成系统设置,它首先在系统文件中寻找init.rc文件,并启动init进程。
解析init.rc配置文件,初始化和启动属性服务,并且启动Zygote进程。
创建JavaVM并为JavaVM注册JNI,创建服务端Socket,启动SystemServer进程。
启动Binder线程池和SystemServiceManager,并且启动各种系统服务。
被SystemServer进程启动的ActivityManagerService会启动Launcher,Launcher启动后会将已安装应用的快捷图标显示到界面上。
init是一个进程,确切地说,它是Linux系统中用户空间的第一个进程。由于Android是基于Linux内核的,所以init也是Android系统中用户空间的第一个进程,它的进程号是1。作为天字第一号的进程,init被赋予了很多极其重要的工作职责,简单概括为:
将init的工作流程精简为以下四点:
1、解析两个配置文件,其中,将分析对init.rc文件的解析。
2、执行各个阶段的动作,创建Zygote的工作就是在其中的某个阶段完成的。
3、调用property_init初始化属性相关的资源,并且通过property_start_service启动属性服务。
4、init进入一个无限循环,并且等待一些事情的发生。重点关注init如何处理来自socket和来自属性服务器相关的事情。
init进程的入口函数是main(system/core/init/init.c)
[–>init.c]
main(){//解析init.rc配置文件parse_config_file("/init.rc");//初始化和属性相关的资源property_init();}
[–>init.rc]
import /init.${ro.zygote}.rc init.zygote64.rcservice zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-serverclass mainsocket zygote stream 660 root systemonrestart write /sys/android_power/request_state wakeonrestart write /sys/power/state ononrestart restart mediaonrestart restart netd
Zygote的中文翻译为“受精卵”,是生命的开始,从字面意思,我们大致可以领会到它在Android系统中的地位。Dalvik/ART,应用程序进程以及运行系统的关键服务SystemServer都是由Zygote进程创建的,所以一般也称它为孵化器。Zygote需要做很多工作,归纳起来大致有如下几条:
(1)创建Dalvik/ART(启动VM虚拟机)
startVm property_get("dalvik.vm.heapsize", heapsizeOptsBuf+4, "16m"); 设置虚拟机heapsize,默认为16MB。绝大多数厂商都会修改这个值,一般是32MB。 heapsize不能设置过小,否则在操作大尺寸的图片时无法分配所需内存。 这里有一个问题,即heapsize既然是系统级的属性,那么能否根据不同应用程序的需求来进行动 态调整?我开始也考虑过能否实现这一构想,不过希望很快就破灭了。对这一问题,我们将在拓展部分深入讨论。
(2)从Native层进入到Java框架层。也就是说Zygote开创了Java框架层,这一步是通过Native层通过JNI方式调用ZygoteInit类的main方法来实现。Zygote的路径为:frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
(3)ZygoteInit的main方法中会创建一个Service端的Socket,名称为“zygote”,用于等待AMS请求Zygote创建新的应用程序进程。
(4)ZygoteInit的main方法中还会通过fork方式创建并启动SystemServer进程
总结下关键的几个步骤:
1、启动VM虚拟机。
2、创建Zygote的Socket服务端。
3、加载预加载的类到内存。
4、加载Android通用的资源比如color、drawable等。
5、加载JNI注册、lib库等等资源。
6、fork出SystemServer进程。
7、开启循环监听客户端的请求。
Zygote是由init进程根据init.rc文件中的配置项而创建的。zygote最初的名字叫“app_process”,这个名字是在Android.mk文件中被指定的,但app_process在运行过程中,通过Linux下的pctrl系统调用将自己的名字换成了“zygote”,所以我们通过ps命令看到的进程名是“zygote”。
它的原型app_process所对应的源文件是App_main.cpp,代码如下所示
[–>App_main.cpp]
static const char ZYGOTE_NICE_NAME[] = "zygote";int main(int argc, char* const argv[]){set_process_name(niceName.string());//设置本进程名为zygote,这正是前文所讲的“换名把戏”。if (zygote) {runtime.start("com.android.internal.os.ZygoteInit", args);}
}
Zygote的这个main函数虽很简单,但其重要功能却是由AppRuntime的start来完成的。下面,我们就来具体分析这个AppRuntime。
[–>AndroidRuntime.cpp]
void AndroidRuntime::start(const char*className, const bool startSystemServer)
{//className的值是"com.android.internal.os.ZygoteInit"//startSystemServer的值是true//① 创建虚拟机if(startVm(&mJavaVM, &env) != 0)goto bail;/*startVmproperty_get("dalvik.vm.heapsize", heapsizeOptsBuf+4, "16m");设置虚拟机heapsize,默认为16MB。绝大多数厂商都会修改这个值,一般是32MB。heapsize不能设置过小,否则在操作大尺寸的图片时无法分配所需内存。这里有一个问题,即heapsize既然是系统级的属性,那么能否根据不同应用程序的需求来进行动态调整?我开始也考虑过能否实现这一构想,不过希望很快就破灭了。对这一问题,我们将在拓展部分深入讨论。*///②注册JNI函数if(startReg(env) < 0) {goto bail;} //找到ZygoteInit类的static main函数的jMethodId。startMeth = env->GetStaticMethodID(startClass, "main","([Ljava/lang/String;)V");....../*③通过JNI调用Java函数,注意调用的函数是main,所属的类是com.android.internal.os.ZygoteInit,传递的参数是“com.android.internal.os.ZygoteInit true”,调用ZygoteInit的main函数后,Zygote便进入了Java世界!也就是说,Zygote是开创Android系统中Java世界的盘古。*/
}
Welcome to Java World
[–>ZygoteInit.java]
public static void main(String argv[]) {try {SamplingProfilerIntegration.start();//①注册Zygote用的socketregisterZygoteSocket();//②预加载类和资源preloadClasses();preloadResources();......//强制一次垃圾收集gc();//我们传入的参数满足if分支if (argv[1].equals("true")) {startSystemServer();//③启动system_server进程}}
}
ZygoteInit.javastartSystemServer();init1init2 启动一个ServerThreadSystemServer.javaServerThread的run函数//系统各种重要服务都在这里启动startBootstrapServices();startCoreServices(); //AMS LightsService BatteryService UsageStatsService ...startOtherServices();
这里以启动微信为例子说明
上述就是 Launche r和 AMS 的交互过程
Activity 启动过程是由 ActivityMangerService(AMS) 来启动的,底层 原理是 Binder实现的 最终交给 ActivityThread 的 performActivity 方法来启动它
ActivityThread 大概可以分为以下五个步骤