Android系统启动流程

一、引言

在分析Android系统架构的文章中,我们只是静态分析了Android系统架构,虽然可以了解Android架构地层次和功能,但不足以了解Android整个系统运行时各层次之间的信息传递和交互,即不能真正看穿Android的运行机理,故还需进一步学习。

所以新开一篇文章结合Android 8.0源码来讲述Android系统启动流程。

二、Android系统启动流程

这是一张Android系统启动的流程图(来自gityuan)。

根据上图,整个过程可分为以下几个阶段:

  1. Boot Loader阶段:设备加电后,首先运行的是Boot Loader程序。Boot Loader主要负责硬件初始化和设备的引导操作。
  2. Kernel阶段:当Boot Loader完成初始化操作后,它会将控制权交给内核。内核是Android系统的核心组件,负责管理系统资源、调度进程等。在这个阶段,内核会加载文件系统和驱动程序,为最终系统的启动做好准备。
  3. Init进程阶段:在Kernel阶段完成后,Init进程就会被启动。Init进程是用户空间的第一个进程,负责启动系统中其他所有的进程。在这个阶段,Init进程会依次执行init.rc脚本中定义的各项任务,包括挂载文件系统、启动服务等。
  4. Zygote进程阶段:在Init进程启动完成后,Android系统会创建一个名为Zygote的进程,他是所有Java应用程序的孵化器。Zygote进程会预加载大量的Java类和资源,以提高应用程序的启动速度。当用户启动新的应用程序时,Zygote进程会复制自身并生成新的虚拟机实例,然后加载对应应用程序的代码并执行。
  5. System Server阶段:在Zygote进程启动完成后,System Server进程就会被启动。System Server是整个Android系统中非常重要的一个进程,负责启动并管理多种系统服务,例如Activity Manager、Window Manager、PackageManager等。在这个阶段,用户才可以看到开始界面,开始使用手机。
  6. Launcher启动阶段:在System Server启动完成后,系统会开始启动Android应用程序。在这个阶段,启动器会展示所有已安装的应用程序,用户可以选择启动所需应用程序。

2.1 Boot Loader阶段

当手机处于关机状态时,长按Power键开机,引导芯片开始从固化在ROM 里的预设代码开始执行,将引导程序(Boot Loader)加载到 RAM中并执行,主要任务是将操作系统加载到内存中并建立好操作系统运行的环境,然后将控制权转移到操作系统内核。

2.2 Kernel阶段

Kernel阶段会启动Kernel的swapper进程(pid=0),该进程又称为idle进程,是Kernel开创的第一个进程,用于初始化进程管理、内存管理,加载驱动等相关工作,以及启动kthreadd进程(pid=2),该进程是Linux系统的内核进程,是所有内核进程的鼻祖,会创建内核工作线程kworkder,软中断线程ksoftirqd,thermal等内核守护进程。Kernel完成这些工作后,会在系统文件中寻找init.rc文件,并启动init进程。

2.3 Init进程阶段

init进程(pid=1)是Android系统中用户空间的第一个进程,是所有用户进程的鼻祖。init源码在system/core/init/init.cpp路径下,关键代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
int main(int argc, char** argv) {
......
// 添加环境变量
add_environment("PATH", _PATH_DEFPATH);
......

if (is_first_stage) {
......
// 创建和挂载启动所需要的文件目录
mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755");
......
// 初始化Kernel的日志
InitKernelLogging(argv);
......
}
......
// 对属性服务进行初始化
property_init();

......
// 设置子进程信号处理,如果子进程异常退出,init进程会调用该函数中设定的信号处理函数来进行处理
signal_handler_init();
......
//启动属性服务
start_property_service();
......

if (bootscript.empty()) {
//解析 init.rc配置文件
parser.ParseConfig("/init.rc");
......
} else {
......
}

......

while (true) {
//重启死去的进程
}

return 0;
}

而在解析init.rcsystem/core/rootdir/init.rc)过程中会孵化zygote进程。

从代码中可以看出init进程阶段主要做了以下事情:

  1. 创建和挂载启动所需要的文件目录
  2. 初始化和启动属性服务
  3. 解析init.rc配置文件并孵化zygote进程

2.4 Zygote进程阶段

Android系统中,DVMART、应用程序进程以及运行系统的关键服务的SystemServer进程都是由Zygote进程创建的,我们也将它称为孵化器。它通过fork(复制进程)来创建应用进程和SystemServer进程,由于Zygote进程在启动时会创建DVM或者ART,因此通过fork而创建的应用程序进程和SystemServer进程可以在内部获取一个DVM或者ART的实例副本。

通过解析init.rc配置文件可以知道init启动Zygote时主要是调用app_main.cppmain方法(之后再分析),所在路径为frameworks/base/cmds/app_process/app_main.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
int main(int argc, char* const argv[])
{
......
while (i < argc) {
const char* arg = argv[i++];
if (strcmp(arg, "--zygote") == 0) {
//如果当前运行在zygote进程中,则将zygote设置为true
zygote = true;
niceName = ZYGOTE_NICE_NAME;
} else if (strcmp(arg, "--start-system-server") == 0) {
//如果当前运行在SystemServer进程中,则将startSystemServer设置为true
startSystemServer = true;
} else if (strcmp(arg, "--application") == 0) {
application = true;
} else if (strncmp(arg, "--nice-name=", 12) == 0) {
niceName.setTo(arg + 12);
} else if (strncmp(arg, "--", 2) != 0) {
className.setTo(arg);
break;
} else {
--i;
break;
}
}

......

if (zygote) {
//启动Zygote进程
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
} else if (className) {
runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
} else {
fprintf(stderr, "Error: no class name or --zygote supplied.\n");
app_usage();
LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
}
}

zygote进程都是通过fork自身来创建子进程的,这样Zygote进程以及它的子进程都可以进入app_main.cppmain函数,因此为了区分main函数运行在哪个进程中,对argc进行了判断。

接下来查看runtime.start()这个方法,这个方法属于AppRuntime类,而这个类又继承AndroidRuntime,路径为/frameworks/base/core/jni/AndroidRuntime.cpp,位于第994行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
......

/* 启动java虚拟机 */
JniInvocation jni_invocation;
jni_invocation.Init(NULL);
JNIEnv* env;
if (startVm(&mJavaVM, &env, zygote) != 0) {
return;
}
onVmCreated(env);

//为java虚拟机注册JNI方法
if (startReg(env) < 0) {
ALOGE("Unable to register all android natives\n");
return;
}
......
//className为com.android.internal.os.ZygoteInit
classNameStr = env->NewStringUTF(className);
......
//将全限定类名className转成路径
char* slashClassName = toSlashClassName(className);
//通过slashClassName找到ZygoteInit
jclass startClass = env->FindClass(slashClassName);
if (startClass == NULL) {
ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
} else {
//找到ZygoteInit的main方法
jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
"([Ljava/lang/String;)V");
if (startMeth == NULL) {
ALOGE("JavaVM unable to find main() in '%s'\n", className);
/* keep going */
} else {
//通过JNI调用ZygoteInit的main方法
env->CallStaticVoidMethod(startClass, startMeth, strArray);
......
}

首先通过startVm方法创建java虚拟机,然后通过startReg方法为Java虚拟机注册JNI方法,将className转成路径后,即找到ZygoteInit类所在位置,然后通过GetStaticMethodID获取main方法,最后通过CallStaticVoidMethod方法启动ZygoteInit

值得注意的是,这里是通过JNI调用ZygoteInitmain方法,查看ZygoteInit也可以发现是java语言编写的。当前Zygote的运行逻辑在Native层中,通过JNI调用java代码后,Zygote就进入到了java框架层!

继续查看ZygoteInit,所在位置为frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public static void main(String argv[]) {
......

try {
......
//创建一个server端的socket,socketName的值为zygote
zygoteServer.registerServerSocket(socketName);

if (!enableLazyPreload) {
......
//预加载类和资源
preload(bootTimingsTraceLog);
......
} else {
Zygote.resetNicePriority();
}

......

if (startSystemServer) {
//启动systemServer进程
startSystemServer(abiList, socketName, zygoteServer);
}

Log.i(TAG, "Accepting command socket connections");
//等待AMS请求
zygoteServer.runSelectLoop(abiList);
zygoteServer.closeServerSocket();
} catch (Zygote.MethodAndArgsCaller caller) {
caller.run();
} catch (Throwable ex) {
Log.e(TAG, "System zygote died with exception", ex);
zygoteServer.closeServerSocket();
throw ex;
}
}

首先通过registerServerSocket方法来创建一个名为zygoteServer端的socket,用于等待ActivityManagerService请求Zygote来创建新的应用程序进程。然后预加载类和资源。启动systemServer进程之后,通过runSelectLoop方法等待AMS请求创建新的应用程序进程。

总结一下整个Zygote进程阶段主要的任务:

  1. 创建AndroidRuntime并调用其start方法,启动Zygote进程。
  2. 创建java虚拟机并注册JNI方法。
  3. 通过JNI调用ZygoteInitmain方法,使ZygoteNative层进入到java框架层。
  4. 通过registerServerSocket方法创建服务器端Socket,并通过runSelectLoop方法等待AMS请求来创建新的应用程序进程。
  5. 启动SystemServer进程。

2.5 System Server阶段

SystemServer启动代码仍在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
private static boolean startSystemServer(String abiList, String socketName, ZygoteServer zygoteServer)
throws Zygote.MethodAndArgsCaller, RuntimeException {
......

try {
......

/* 从Zygote进程中fork出SystemServer进程 */
pid = Zygote.forkSystemServer(
......);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}

/* For child process */
//子进程是否运行在SystemServer进程中
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
//关闭Zygote进程创建的Socket
zygoteServer.closeServerSocket();
//启动SystemServer进程
handleSystemServerProcess(parsedArgs);
}

return true;
}

由于SystemServer进程fork了Zygote进程,所以该进程也会得到Zygote进程创建的Socket,这个Socket对于SystemServer进程没有用处,所以需要关闭。最后通过handleSystemServerProcess方法启动SystemServer进程。

接下来查看handleSystemServerProcess方法,其代码位于同样的路径下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
private static void handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs)
throws Zygote.MethodAndArgsCaller {

......

if (parsedArgs.invokeWith != null) {
......
} else {
ClassLoader cl = null;
if (systemServerClasspath != null) {
//创建PathClassLoader
cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);

Thread.currentThread().setContextClassLoader(cl);
}

//调用zygoteInit方法
ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
}

}

继续跟踪zygoteInit方法,其代码还是位于同样的路径下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
throws Zygote.MethodAndArgsCaller {
if (RuntimeInit.DEBUG) {
Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
}

Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
RuntimeInit.redirectLogStreams();

RuntimeInit.commonInit();
//启动Binder线程池
ZygoteInit.nativeZygoteInit();
//进入SystemServer的main方法
RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}

nativeZygoteInit方法顾名思义是native层的方法,用来启动Binder线程池(需要先了解JNI,这里先不解释),这样SystemServer进程就可以使用Binder与其他进程进行通信了。applicationInit方法则是用于进入到SystemServermain方法,对应方法所在路径为/frameworks/base/core/java/com/android/internal/os/RuntimeInit.java

1
2
3
4
5
6
protected static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
throws Zygote.MethodAndArgsCaller {
......
// Remaining arguments are passed to the start class's static main
invokeStaticMain(args.startClass, args.startArgs, classLoader);
}

invokeStaticMain方法的代码如下(位于相同路径下):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
throws Zygote.MethodAndArgsCaller {
Class<?> cl;

try {
//通过反射得到SystemServer类
cl = Class.forName(className, true, classLoader);
} catch (ClassNotFoundException ex) {
......
}

Method m;
try {
//找到SystemServer的main方法
m = cl.getMethod("main", new Class[] { String[].class });
} catch (NoSuchMethodException ex) {
......
} catch (SecurityException ex) {
......
}

......
//抛出异常,这里抛出异常中调用了SystemServer的main方法
throw new Zygote.MethodAndArgsCaller(m, argv);
}

主要是获取SystemServermain方法,并传入MethodAndArgsCaller异常中,捕获该异常的代码在ZygoteInit.javamain方法中(第766行),这个main方法会调用SystemServermain方法。

1
2
3
4
5
6
7
8
9
try{
......
} catch (Zygote.MethodAndArgsCaller caller) {
caller.run();
} catch (Throwable ex) {
Log.e(TAG, "System zygote died with exception", ex);
zygoteServer.closeServerSocket();
throw ex;
}

当捕获到MethodAndArgsCaller异常时,就会调用MethodAndArgsCallerrun方法,路径为/frameworks/base/core/java/com/android/internal/os/Zygote.java,代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public static class MethodAndArgsCaller extends Exception
implements Runnable {
/** method to call */
private final Method mMethod;

/** argument array */
private final String[] mArgs;

public MethodAndArgsCaller(Method method, String[] args) {
mMethod = method;
mArgs = args;
}

public void run() {
try {
mMethod.invoke(null, new Object[] { mArgs });
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex);
} catch (InvocationTargetException ex) {
Throwable cause = ex.getCause();
if (cause instanceof RuntimeException) {
throw (RuntimeException) cause;
} else if (cause instanceof Error) {
throw (Error) cause;
}
throw new RuntimeException(ex);
}
}
}

因为我们将SystemServermain方法作为参数传入了MethodAndArgsCaller异常中,所以mMethod.invoke即是SystemServermain方法的invoke,即SystemServermain方法被调用。

所以为什么不直接在invokeStaticMain方法中调用SystemServermain方法呢,反而是要通过抛出异常来调用?

答:因为在Zygote启动SystemServer进程后,SystemServer进程做了很多准备工作,这使得SystemServermain方法看起来不像是SystemServer进程的入口方法。而抛出异常的处理会清除所有的设置过程需要的堆栈帧,会使得SystemServermain方法看起来像是SystemServer进程的入口方法。

SystemServermain方法对应代码路径为/frameworks/base/services/java/com/android/server/SystemServer.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
public static void main(String[] args) {
new SystemServer().run();
}
......

private void run() {
try {
......
//创建消息Looper
Looper.prepareMainLooper();
//加载动态库libandroid_servers.so
System.loadLibrary("android_servers");
performPendingShutdown();

//创建系统的Context
createSystemContext();

//创建SystemServiceManager
mSystemServiceManager = new SystemServiceManager(mSystemContext);
mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
// Prepare the thread pool for init tasks that can be parallelized
SystemServerInitThreadPool.get();
} finally {
traceEnd(); // InitBeforeStartServices
}

try {
traceBeginAndSlog("StartServices");
//启动引导服务
startBootstrapServices();
//启动核心服务
startCoreServices();
//启动其他服务
startOtherServices();
SystemServerInitThreadPool.shutdown();
} catch (Throwable ex) {
......
} finally {
traceEnd();
}
......

// Loop forever.
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}

首先会创建消息Looper、加载库、创建系统context,然后创建SystemServiceManager来对系统服务进行创建、启动和生命周期管理。然后会启动各种服务,包括ActivityManagerServicePackageManagerServiceWindowManagerService等服务。最后Looper循环等待接收消息。

总结一下整个System Server进程阶段的主要任务:

  1. 启动Binder线程池。
  2. 创建SystemServiceManager,用于对系统服务进行创建、启动和生命周期管理。
  3. 启动各种系统服务。

2.6 Launcher进程阶段

系统启动的最后一步是启动一个应用程序来显示系统中已经安装的应用程序,这个应用程序就是Launcher,通俗来讲就是Android系统的桌面,它是Zygote进程孵化的第一个APP。Launcher在启动过程中会请求PackageManagerService返回系统中已经安装的应用程序的信息,并将这些信息封装成一个快捷图标列表显示在系统屏幕上,用户可以通过点击图标来启动相应的应用程序。

Launcher通过startOtherServices启动,启动入口为AMSsystemReady方法(第1646行),所在路径为frameworks/base/services/java/com/android/server/SystemServer.java

1
2
3
4
5
6
7
8
9
10
11
12
private void startOhterServices(){
......
mActivityManagerService.systemReady(() -> {
Slog.i(TAG, "Making services ready");
traceBeginAndSlog("StartActivityManagerReadyPhase");
mSystemServiceManager.startBootPhase(
SystemService.PHASE_ACTIVITY_MANAGER_READY);
......
}
......
}

查看AMSsystemReady方法代码,所在路径为/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

1
2
3
4
5
6
7
8
public void systemReady(final Runnable goingCallback, BootTimingsTraceLog traceLog) {
......
synchronized(this) {
......
mStackSupervisor.resumeFocusedStackTopActivityLocked();
mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
}
}

调用了ActivityStackSupervisorresumeFocusedStackTopActivityLocked方法,所在路径为/frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java

1
2
3
4
5
6
7
8
9
10
11
12
boolean resumeFocusedStackTopActivityLocked() {
return resumeFocusedStackTopActivityLocked(null, null, null);
}

boolean resumeFocusedStackTopActivityLocked(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
if (targetStack != null && isFocusedStack(targetStack)) {
return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
......
return false;
}

这里使用了重载,最终都是调用第二个方法,里面调用是ActivityStackresumeTopActivityUncheckedLocked方法,所在路径为/frameworks/base/services/core/java/com/android/server/am/ActivityStack.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
......
try {
// Protect against recursion.
mStackSupervisor.inResumeTopActivity = true;
result = resumeTopActivityInnerLocked(prev, options);
} finally {
mStackSupervisor.inResumeTopActivity = false;
}

mStackSupervisor.checkReadyForSleepLocked();

return result;
}

该方法主要是调用了resumeTopActivityInnerLocked方法(在同一个文件中,第2305行)。

1
2
3
4
5
6
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
......
return isOnHomeDisplay() &&
mStackSupervisor.resumeHomeStackTask(returnTaskType, prev, "prevFinished");
......
}

关键的地方是调用了ActivityStackSupervisorresumeHomeStackTask方法,所在路径为frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java

1
2
3
4
5
6
7
8
boolean resumeHomeStackTask(ActivityRecord prev, String reason) {
......
if (r != null && !r.finishing) {
moveFocusableActivityStackToFrontLocked(r, myReason);
return resumeFocusedStackTopActivityLocked(mHomeStack, prev, null);
}
return mService.startHomeActivityLocked(mCurrentUser, myReason);
}

关键的地方是调用了ActivityServicestartHomeActivityLocked方法,所在路径为frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
boolean startHomeActivityLocked(int userId, String reason) {
//判断工厂模式和mTopAction值,符合要求则继续执行
if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
&& mTopAction == null) {
return false;
}
//创建Launcher启动所需要的Intent
Intent intent = getHomeIntent();
//使用Intent对应的Activity信息
ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
if (aInfo != null) {
// 设置Intent的组件为解析得到的Activity组件
intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
// 创建新的ActivityInfo对象,并将applicationInfo设置为相应用户ID下的应用程序信息
aInfo = new ActivityInfo(aInfo);
aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
// 获取指定名称和UID的进程记录
ProcessRecord app = getProcessRecordLocked(aInfo.processName, Info.applicationInfo.uid, true);
// 如果进程记录不存在或进程记录没有关联的instrumentation
if (app == null || app.instr == null) {
// 设置Intent标志包含FLAG_ACTIVITY_NEW_TASK,表示在新任务中启动Home活动
intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
final String myReason = reason + ":" + userId + ":" + resolvedUserId;
// 启动Launcher
mActivityStarter.startHomeActivityLocked(intent, aInfo, myReason);
}
} else {
Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
}

return true;
}

创建了一个Intent,并将mTopActionmTopData传入。mTopAction的值为Intent.ACTION_MAIN,并且如果系统运行模式低级工厂模式,则将intentCategory设置为android.intent.category.HOME(具体细节请跟进getHomeIntent方法查看)。在AndroidManifest文件(/packages/apps/Launcher3/AndroidManifest.xml)中查看intent-filter可以知道,能与该Intent匹配的是Launcher。之后就是判断Launcher是否已经启动,如果没有则调用ActivityStarterstartHomeActivityLocked方法启动,所在路径为/frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void startHomeActivityLocked(Intent intent, ActivityInfo aInfo, String reason) {
//将Launcher放入HomeStack中
mSupervisor.moveHomeStackTaskToTop(reason);
//启动Launcher
mLastHomeActivityStartResult = startActivityLocked(null /*caller*/, intent,
null /*ephemeralIntent*/, null /*resolvedType*/, aInfo, null /*rInfo*/,
null /*voiceSession*/, null /*voiceInteractor*/, null /*resultTo*/,
null /*resultWho*/, 0 /*requestCode*/, 0 /*callingPid*/, 0 /*callingUid*/,
null /*callingPackage*/, 0 /*realCallingPid*/, 0 /*realCallingUid*/,
0 /*startFlags*/, null /*options*/, false /*ignoreTargetSecurity*/,
false /*componentSpecified*/, mLastHomeActivityStartRecord /*outActivity*/,
null /*container*/, null /*inTask*/, "startHomeActivity: " + reason);
if (mSupervisor.inResumeTopActivity) {
mSupervisor.scheduleResumeTopActivities();
}
}

Launcher放入HomeStack中,HomeStack是在ActivityStackSupervisor中定义的用于存储Launcher的变量。接着调用startActivityLocked方法来启动Launcher

三、总结

以上只是简单的梳理了一遍Android系统启动的流程,整个过程为:设备开机后,处于Boot Loader阶段,加载并执行引导程序,为操作系统建立好环境之后,将控制权转移给操作系统内核,进入到kernel阶段。kernel阶段会启动swapper进程初始化进程管理、内存管理,加载驱动等相关工作,启动kthreadd进程,之后会启动init进程进入到init阶段。init阶段会创建和挂载启动所需要的文件目录,初始化和启动属性服务,之后启动zygote进程进入到zygote阶段。zygote阶段会创建java虚拟机并注册JNI方法,使ZygoteNative层进入到java框架层,创建服务器端Socket,用于消息通信,之后启动SystemServer进程进入到SystemServer阶段。SystemServer阶段会启动Binder线程池,创建SystemServiceManager管理系统服务,之后启动各种系统服务,其中包括Launcher,就是我们所常见的系统桌面。

然而,本篇文章省略了很多细节,并没有深入分析各个阶段的相关代码,并且在学习的过程中也遇到了一些没有了解过的东西,比如rc文件以及如何解析rc文件、 Binder通信、系统服务的管理、Activity的管理等。这些都需要积累一定的基础,进一步深入学习。


参考:

Android系统启动篇 | BATcoder - 刘望舒 (liuwangshu.cn)(Android系统启动系列篇)

Android 操作系统架构开篇 - Gityuan博客 | 袁辉辉的技术博客(找系统启动系列篇)

深入研究源码:Android10.0系统启动流程(一) - 知乎 (zhihu.com)(主页找系列篇)

Android系统启动流程 - 简书 (jianshu.com)

Android操作系统启动过程概览 - 知乎 (zhihu.com)

AOSPXRef

《Android进阶解密》


Android系统启动流程
http://example.com/2023/07/04/Android安全/Android系统启动流程/
作者
gla2xy
发布于
2023年7月4日
许可协议