【Android】之【系统启动】
创始人
2025-06-01 11:51:21
0

一、流程总览

系统启动->BootLoader->Linux内核->init -> zygote -> systemserver->Launcher

① 启动电源以及系统启动

当电源按下时引导芯片代码开始从预定义的地方(固化在ROM)开始执行。加载引导程序Bootloader到RAM,然后执行。

② 引导程序BootLoader

引导程序BootLoader是在Android操作系统开始运行前的一个小程序,它的主要作用是把系统OS拉起来并运行。

③ Linux内核启动

内核启动时,设置缓存、被保护存储器、计划列表、加载驱动。当内核完成系统设置,它首先在系统文件中寻找init.rc文件,并启动init进程。

④ init进程启动

解析init.rc配置文件,初始化和启动属性服务,并且启动Zygote进程。

⑤ Zygote进程启动

创建JavaVM并为JavaVM注册JNI,创建服务端Socket,启动SystemServer进程。

⑥ SystemServer进程启动

启动Binder线程池和SystemServiceManager,并且启动各种系统服务。

⑦ Launcher启动

被SystemServer进程启动的ActivityManagerService会启动Launcher,Launcher启动后会将已安装应用的快捷图标显示到界面上。
在这里插入图片描述

在这里插入图片描述

二、模块解析

Init进程

init是一个进程,确切地说,它是Linux系统中用户空间的第一个进程。由于Android是基于Linux内核的,所以init也是Android系统中用户空间的第一个进程,它的进程号是1。作为天字第一号的进程,init被赋予了很多极其重要的工作职责,简单概括为

1、创建和挂载启动所需的文件目录。
2、初始化和启动Linux属性服务。
3、解析init.rc配置文件,首先开启ServiceManager和MediaServer等关键进程。
4、init进程fork启动Zygote服务进程。

将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进程

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进程}}
}

SystemServer进程

ZygoteInit.javastartSystemServer();init1init2 启动一个ServerThreadSystemServer.javaServerThread的run函数//系统各种重要服务都在这里启动startBootstrapServices();startCoreServices(); //AMS LightsService BatteryService UsageStatsService ...startOtherServices();

三、App 启动过程

这里以启动微信为例子说明

  1. Launcher 通知 AMS 要启动微信了,并且告诉AMS要启动的是哪个页面也就是首页是哪个页面。
  2. AMS 收到消息告诉 Launcher 知道了,并且把要启动的页面记下来。
  3. Launcher 进入Paused状态,告诉 AMS,你去找微信吧。

上述就是 Launche r和 AMS 的交互过程

  1. AMS 检查微信是否已经启动了也就是是否在后台运行,如果是在后台运行就直接启动,如果不是,AMS
    会在新的进程中创建一个ActivityThread 对象,并启动其中的 main 函数。
  2. 微信启动后告诉 AMS,启动好了。
  3. AMS 通过之前的记录找出微信的首页,告诉微信应该启动哪个页面。
  4. 微信按照AMS通知的页面去启动就启动成功了。

四、Activity启动过程

Activity 启动过程是由 ActivityMangerService(AMS) 来启动的,底层 原理是 Binder实现的 最终交给 ActivityThread 的 performActivity 方法来启动它

ActivityThread 大概可以分为以下五个步骤

  1. 通过 ActivityClientRecoed 对象获取 Activity 的组件信息
  2. 通过 Instrument 的 newActivity 使用类加载器创建 Activity 对象
  3. 检验 Application 是否存在,不存在的话,创建一个,保证 只有一个 Application
  4. 通过 ContextImpl 和 Activity 的 attach 方法来完成一些初始化操作
  5. 调用 onCreate方法。

五、参考

  • Android系统启动篇
  • Android 操作系统架构开篇
  • Android系统启动流程

相关内容

热门资讯

美国总统特朗普关税政策的法律对... 美国总统特朗普关税政策的法律对头们要求法院在特朗普政府上诉期间暂停实施关税。
芯朋微将于6月18日召开股东大... 金融界6月2日消息,芯朋微发布公告,将于2025年6月18日召开第1次临时股东大会,网络投票同日进行...
“开盒”游戏害了多少孩子?看这... 5月29日,在最高人民法院“六一”儿童节公众开放日活动上,由最高人民法院新闻局、民一庭、人民法院出版...
原创 一... 近期,伴随着中国积极推行国际调解机制的浪潮,历史冤家柬埔寨与泰国却在边境地区上演了一场短暂却引发广泛...
2025深圳最新购房政策汇总! 深圳最新的购房政策是如何的? 今日小编为大家整理 2025年深圳买房政策汇总 大家一起来看看 一、...
南昌南斯友好路两家“海湾石油”... 今天(2日)上午 多名消费者向《都市现场》反映 他们在南昌南斯友好路上的两家“海湾石油” 预付充值了...
曝拜仁与莱奥密谈!AC米兰索要... 足坛转会市场再起波澜!德甲巨无霸拜仁慕尼黑,这次将目光投向了亚平宁半岛,盯上了AC米兰的王牌边锋——...
曼联2500万甩卖“铁腰”,那... 提起苏格兰中场斯科特·麦克托米奈,如今的足坛可谓是无人不知,无人不晓。但就在2024年夏天,当曼联以...
行驶中推送广告、恶意更新隐私政... 深蓝汽车法务部今日(6 月 2 日)发布声明提出,部分网络内容发布 “深蓝汽车在行驶过程中推送广告严...
德国银行高管:美政府政策频繁变... 根据德国《商报》6月2日刊发的专访文章,德国国家开发银行复兴信贷银行董事会主席斯特凡·温特尔斯指出,...