Android系统启动流程
-
启动电源以及系统启动
当电源按下时引导芯片代码从预定义的地方(固化在ROM)开始执行。加载引导程序BootLoader到RAM,然后执行
-
引导程序 BootLoader
引导程序BootLoader 是在Android操作系统开始运行前的一个小程序,它的主要作用是把系统OS拉起来并运行
-
Linux 内核启动
当内核启动时,设置缓存、被保护存储器、计划列表、加载驱动。当内核完成系统设置时,它首先在系统文件中寻找 init.rc 文件,并启动init进程
-
init 进程启动
初始化和启动属性服务,并启动 Zygote 进程
-
Zygote 进程启动
创建Java虚拟机并为java虚拟机注册 JNI 方法,创建服务器端 Socket,启动 SystemServer 进程
-
SystemServer 进程启动
启动 Binder 线程池和SystemServiceManager,并且启动各种系统服务
-
Launcher 启动
被SystemServer进程启动的AMS会启动Launcher,Launcher启动后会将已安装应用的快捷图标显示到界面上
init 进程启动流程
-
入口函数: system/core/init/init.cpp—>main()函数
关注点:
a. 在开始时创建和挂载启动所需的文件目录,其中挂载tmpfs、devpts、proc、sysfs、selinuxfs共5种系统文件
b. 调用 property_init() 函数对属性服务进行初始化
c. 调用 signal_handler_init() 函数设置子进程信号处理函数(system/core/init/signal_handler.cpp),主要用于防止 init 进程的子进程成为僵尸进程
d. 调用 start_property_service() 函数启动属性服务
e. 调用 parser.ParseConfig("/init.rc") 解析 init.rc 配置文件
f. 调用 restart_processes() 重启死去的进程
僵尸进程与危害:在Linux中,父进程使用 fork 创建子进程,在子进程终止之后,如果父进程并不知道子进程已经终止了,这时子进程虽然已经退出了,但是在系统进程表中还为它保留了一定的信息(比如进程号、退出状态、运行时间等),这个子进程就被称为僵尸进程。系统的进程表是一项有限资源,如果系统进程表被僵尸进程耗尽的话,系统就可能无法创建新的进程了
-
解析 init.rc
init.rc 是由 Android 初始化语言(Android Init Language)编写的脚本,这种语言主要包含五种类型语句据:Action、Command、Service、Option和import
Action 类型语句采用 ActionParser 来进行解析
Service 类型语句采用 ServiceParser (system/core/init/service.cpp)来进行解析
-
init 启动 Zygote 服务
Android 系统启动(init,zygote) - feibin筱飞 - 博客园
-
属性服务
Windows 平台上有一个注册表管理器,注册表的内容采用键值对的形式来记录用户、软件的一些使用信息。即使系统或者软件重启,其还是能够根据之前注册表中的记录,进行相应的初始化工作。Android也提供了一个类似的机制,叫做属性服务
init 进程启动总结
(1) 创建和挂载启动所需的目录文件
(2) 初始化和启动属性服务
(3) 解析 init.rc 配置文件并启动 Zygote 进程
Zygote 进程启动过程
-
入口: 调用 app_main.cpp 的 main 函数中的AppRuntime的start方法来启动 Zygote 进程
app_main.cpp(main函数)
-
if(strcmp(arg, "--zygote") == 0){ zygote = true}: 如果当前运行在Zygote进程中,则将 zygote 设置为true
-
else if(strcmp(arg, "--start-system-server") == 0){startSystemServer = true}: 如果当前运行在 SystemServer 进程中,则将 startSystemServer 设置为 true
-
if(zygote){runtime.start("com.android.internal.os.ZygoteInit", args, zygote)}: 如果 zygote 为true则表示在 Zygote进程中,就会调用 AppRuntime的start函数
AndroidRuntime.cpp(start函数)
-
if(startVm(&mJavaVM, &env, zygote) != 0){return ;}: 调用startVm函数来创建 Java 虚拟机
-
if(startReg(env) < 0){}: 调用 startReg 函数为 Java 虚拟机注册 JNI 方法
-
calssNameStr = env ->NewStringUTF(className): className值为com.android.internal.os.ZygoteInit
-
char* slashClassName = toSlashClassName(className): 将 className 的 “.” 替换为 “/”
-
jclass startClass = env -> FindClass(slashClassName): 根据 slashClassName找到 ZygoteInit
-
jmethodID startMeth = env -> GetStaticMethodID(startClass, "main", "([Ljava/lang/String;)V"): 找到 ZygoteInit 的 main 方法
-
env -> CallStaticVoidMethod(startClass, startMeth, strArray): 通过JNI调用 ZygoteInit 的 main 方法
-
-
ZygoteInit中的main方法
通过 JNI 调用 ZygoteInit 的 main 方法后就进入了 Java 框架层,此前的代码是没有任何代码进入 Java 框架层的,换句话说 Zygote 开创了 Java 框架层
-
zygoteServer.registerServerSocket(socketName): 创建一个 Server 端的 Socket,socketName 的值为 "zygote",用于等待ActivitryManagerService 请求 Zygote 来创建新的应用程序进程
-
preload(bootTimingsTraceLog): 预加载类和资源
-
startSystemServer(abiList, socketName, zygoteServer): 启动 SystemServer 进程,这样系统服务也会由 SystemServer 进程启动起来
-
zygoteServer.runSelectLoop(abList): 调用 ZygoteServer 的 runSelectLoop 方法来等待 AMS 请求创建新的应用程序进程
ZygoteInit 的 main 方法主要做了4件事:
(1). 创建一个 Server 端的 Socket
(2). 预加载类和资源
(3).启动 SystemServer 进程
(4).等待 AMS 请求创建新的应用程序进程
-
Zygote 进程启动总结
(1) 创建 AppRuntime 并调用 start 方法,启动 Zygote 进程
(2) 创建 Java 虚拟机并为 java 虚拟机注册 JNI 方法
(3) 通过 JNI 调用 ZygoteInit 的 main 函数进入 Zygote 的 Java 框架层
(4) 通过 registerZygoteSocket 方法创建服务器端 Socket,并通过 runSelectLopp 方法等待 AMS 的请求来创建新的应用程序进程
(5) 启动 SystemServer 进程
SystemServer 处理过程
SystemServer 进程主要用于创建系统服务,AMS、WMS和PMS都是由它创建的
-
入口: ZygoteInit的 startSystemServer方法
-
zygoteServer.closeServerSocket(): SystemServer 进程复制了 Zygote进程的地址空间,因此也会得到Zygote进程创建的Socket,这个Socket 对于 SystemServer 没有用处,因此会先关闭该Socket
-
handleSystemServerProcess(): 启动 SystemServer 进程
-
cl = createPathClassLoader(SystemServerClasspath, parsedArgs.targetSdkVersion): 创建 PathClassLoader
-
ZygoteInit.zygoteInt(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl): 调用ZygoteInit的zygoteInit方法
-
-
ZygoteInit的 zygoteInit() 方法
ZygoteInit.nativeZygoteInit(): 调用native 层的代码,启动Binder线程池,这样SystemServer进程就可以使用Binder与其他进程进行通信了
-
进入SystemServer的main() 方法
-
在RuntimeInit.java中调用了 applicationInit()方法
-
在 applicationInit()方法中主要调用了 invokeStaticMain()
-
cl = Class.forName(className, true, classLoader): className为con.android.server.SystemServer,通过反射返回的 cl 为 SystemServer类
-
m = cl.getMethode("main", new Class[]{String[].class}): 找到SystemServer中的 main 方法
-
throw new Zygote.MethodAndArgsCaller(m, argv): 将找到的 main 方法传入该异常中并抛出该异常,捕获该异常的代码在 ZygoteInit.java 的 main方法中,这个main方法会调用 SystemServer的main方法
-
-
-
SystemServer的main() 方法
-
System.loadLibrary("android_servers"):加载动态库 libandroid_servers.so
-
mSystemServiceManager = new SystemServiceManager(mSystemContext):创建 SystemServerManager,它会对系统服务进行创建、启动和生命周期管理
-
startBootstrapServices():用SystemServiceManager 启动了 ActivityManagerService、PowerManagerService、PackageManagerService等服务
-
startOtherServices():启动 DropBoxMangerService、BatteryService、UsageStatsService和WebViewUpdateService
官方把系统服务分为了三种类型:引导服务、核心服务和其他服务,这些服务的父类均为 SystemService
-
SystemServer 进程总结
(1) 启动 Binder 线程池,这样就可以与其他进程进行通信
(2) 创建 SystemServiceManager,其用于对系统的服务进行创建、启动和生命周期管理
(3) 启动各种系统服务
Launcher 启动过程
-
Launcher 概述
系统启动的最后一步是启动一个应用程序用来显示系统中已经安装的应用程序,这个应用程序就叫做Launcher,作用主要有以下两点:
(1). 作为 Android 系统的启动器,用于启动应用程序
(2). 作为 Android 系统的桌面,用于显示和管理应用程序的快捷图标或者其他桌面组件
-
Launcher 启动过程
SystemServer 进程在启动的过程中会启动 PackageManagerService,PackageManagerService启动后会将系统中的应用程序安装完成。在此前已经启动的AMS 会将 Launcher 启动起来
-
启动Launcher的入口为AMS的 systemReady 方法,它在SystemServer的startOtherServices方法中被调用
-
systemReady 方法还总调用了 ActivityStackSupervisor 的 resumeFocusedStackTopActivityLocked方法
-
resumeFocusedStackTopActivityLocked方法会调用ActivityStack 的 resumeTopActivityUncheckedLocked方法(ActivityStack对象是用来描述Activity堆栈的)
-
resumeTopActivityInnerLocked(prev, options) —>ActivityStackSupervisor.resumeHomeStackTask()
-
resumeHomeStackTask() —> AMS的startHomeActivityLocked()
-
if(mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL && mTopAction == null): mFactoryTest 代表系统的运行模式,系统的运行模式分为三种,分别是工厂模式、低级工厂模式和高级工厂模式;mTopAction 则用来描述第一个被启动 Activity 组件的 Action,它的默认值为 Intent.ACTION_MAIN
-
Intent intent = getHomeIntent(): 创建 Launcher 启动所需的 Intent
-
if(app == null) || app.instr == null): 判断符合Action为 Intent.ACTION_MAIN、Category 为 Intent.CATEGORY_HOME的应用程序是否已经启动,如果没有启动则走下一步
-
mActivityStarter.startHomeActivityLocked(intent, aInfo, myReason): 启动Launcher
mSupervisor.moveHomeStackTaskToTop(reason): 将launcher放入HomeStack中,HomeStack是在AcitvityStackSupervisor中定义存储Launcher的变量。接着调用startActivityLocked方法来启动 Launcher
-
-
-
Launcher 中应用图标显示过程
packages/apps/Launcher3/src/com/android/launcher3/Launcher.java—> onCreate() 方法
-
LauncherAppStore app = LauncherAppState.getInstance(): 获取LauncherAppState 实例
-
mModel = app.setLauncher(this):调用 setLauncher方法并将Launcher对象传入
mMode.initialize(launcher): 会将传入的 Callbacks(launcher),封装成一个弱引用对象
-
@Thunk static final HandlerThread sWorkerThread = nwe HandlerThread("launcher-loader"): 创建具有消息循环的线程HandlerThread对象
-
@Thunk static final Handler sWorker = new Handler(sWorkerThread.getLooper): 创建了Handler,并且传入 HandlerThread的Looper,这里Handler的作用就是向 HandlerThread 发送消息
-
mLoaderTask = new LoaderTask(mApp, isLaunching): 创建 LoaderTask
-
sWorker.post(mLoaderTask): 将 LoaderTask 作为消息发送给 HandlerThread
LauncherModerl.java —LoaderTask类实现了Runnable接口
loadWorkspace(): 加载工作区信息
bindWorkspace(mPageToBindFirst): 绑定工作区信息
loadAllApps():加载系统已经安装的应用程序信息
callbacks.bindAllApplications(added) ——> mAppsView.setApps(apps)
setApps方法会将包含应用信息的列表 apps 设置给 mApps,这个mApps 是 AlphabeticalAppsList类型的对象
-
接着查看AllAppsContainerView 的 onFinishInflate 方法
-
mAppsRecyclerView = findViewById(R.id.apps_list_view): 得到 AllAppsRecyclerView 用来显示 App 列表
-
mAppsRecyclerView.setApps(mApps): 将此前的 mApps 设置进去
-
mAppsRecyclerView.setAdapter(mAdapter): 设置Adapter,这样显示应用程序快捷图标的列表就会显示在屏幕上
-
-



