【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系统启动流程

相关内容

热门资讯

家装预付资金安全困局如何破解,... 家装预付资金安全困局如何破解 专家提出:建立“先验收后付款”装修资金存管制度 预交数万元甚至数十万元...
工行安康解放路支行积极开展《反... 为深入贯彻落实《国家金融监督管理总局安康监管分局办公室关于开展<反有组织犯罪法>宣传活动的通知》要求...
重庆公布育儿补贴制度实施方案 原标题:每孩每年3600元 重庆公布育儿补贴制度实施方案 11月21日,记者了解到,市卫生健康委、市...
十五运会组委会在深总结本届赛事... 深圳新闻网2025年11月22日讯(深圳报业集团记者 林炜航)11月21日,十五运会组委会在深圳市民...
中国军视网:日本妄言击沉福建舰... 本文转自【中国军视网】; 日本首相高市早苗发表涉台错误言论,公然挑战一个中国原则,甚至还有日本无知政...
重磅!东莞长安50万㎡产城发布... 在当下竞争激烈的市场环境中,中小企业如何突破成本压力,找到一片既能扎根成长又能眺望未来的理想栖息地?...
毕马威:政策、资本等多维着力 ... 由毕马威联合长三角G60科创走廊创新研究中心主办的“长三角高端装备新质领袖榜单发布仪式”于11月21...
河曲县开展驻村帮扶工作政策业务... 来源:河曲县融媒体中心 近日,我县组织开展驻村帮扶工作政策业务集中培训,进一步提升驻村帮扶干部...
羽绒服涨价与猪肉降价有关?经济... 中央气象台发布统计信息,14日至17日,我国今年下半年首轮大范围寒潮天气即将自西向东影响我国,多地降...
周勇,任上落马 11月21日,中央纪委国家监委网站发布通报: 国家能源集团乌海能源党委书记、董事长周勇涉嫌严重违纪违...