先别急着被这个标题吓到,我知道“源码分析”这四个字听起来就像是要把人埋在几千页的C++代码里出不来。但说实话,Android的启动流程其实就像是一个精密的交响乐团演出,每一个环节都有它的“乐手”在等着登台。我们今天不啃那些枯燥的定义,而是像剥洋葱一样,从最底下的内核开始,一层层往上走,直到看到你家手机桌面那个熟悉的图标亮起来。
第一章:开机那一刻,内核在忙什么?
当你按下电源键,Android手机并不是立刻就开始“启动”的。那一刻,硬件世界刚刚从沉睡中醒来,而真正接管这一切的是Linux内核。
1.1 从复位信号到内核加载
想象一下,你的手机SoC(系统级芯片)就像一个人的大脑。当你按下电源键,电源管理芯片(PMIC)会发出一个复位信号。这个信号会告诉CPU:“嘿,醒醒,该干活了。”
此时,CPU执行的第一条指令通常存储在只读存储器(ROM)中,比如BootROM。这段代码是固化的,无法修改。它的任务很简单但至关重要:验证并加载Bootloader。
BootROM (在ROM中)
↓ 验证签名
Bootloader (如U-Boot)
↓ 初始化硬件
Linux Kernel
↓ 挂载根文件系统
Init进程
Bootloader的作用就像是翻译官。它负责初始化关键的硬件——内存控制器、屏幕、电池、存储等等,然后把Linux内核从闪存(eMMC或UFS)中读取到内存里,并传递给内核。
1.2 内核的初始化与根文件系统的挂载
一旦内核被加载,它就进入了start_kernel()函数。这是内核的入口点。接下来的事情非常忙碌:
- 设备驱动初始化:内核会探测和初始化硬件驱动。
- 内存管理建立:建立分页机制,为后续进程分配内存。
- 挂载根文件系统:这是最关键的一步。内核需要找到根文件系统(通常是ext4、f2fs等格式),然后将其挂载到根目录
/。
根文件系统中包含了一个关键的可执行文件:/init。
你可以这样理解:内核负责把“舞台”搭好,然后把“导演”请上台。这个“导演”就是init进程。
第二章:Init进程——Android的“老祖宗”
在Linux世界里,PID 1的进程非常重要,它是所有其他进程的祖先。在Android中,这个PID 1的进程就是我们熟知的init。
2.1 Init进程的职责
init进程不仅仅是启动服务那么简单,它是一个守护进程(Daemon),负责:
- 解析启动脚本:读取
/init.rc和/init.<device>.rc等配置文件。 - 创建和重启服务:根据配置启动各种系统服务。
- 处理Zygote:触发Zygote进程的启动,这是Android应用进程的孵化器。
- 属性服务:提供系统属性查询接口。
2.2 启动脚本解析:init.rc的秘密
打开init.rc文件,你会看到类似这样的语法:
# 定义一个服务
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
# 指定服务的启动参数
class main
priority -20
user root
group root readproc
socket zygote stream 660 root system
onrestart restart healthd
onrestart restart audioserver
onrestart restart media
onrestart restart surfaceflinger
onrestart restart inputflinger
onrestart restart drm
onrestart restart cameraserver
onrestart restart keystore
这段代码的意思是:创建一个名为zygote的服务,执行路径是/system/bin/app_process,并携带特定的参数。同时,这个服务属于main类,以root用户身份运行,并创建了一个名为zygote的socket。
init进程会不断循环解析这些脚本,一旦条件满足(比如class main的服务都启动完成),它就会继续往下执行。
2.3 Init进程的源代码位置
如果你想深入看init的源码,主要代码在:
system/core/init/
核心文件包括:
init.cpp:主入口点service.cpp:服务管理parser.cpp:脚本解析property_service.cpp:属性服务
第三章:Zygote——应用进程的“孵化器”
当init进程启动了Zygote服务后,Android的就真正进入了应用世界。Zygote是Android中一个非常特殊的进程,它被称为“孵化者”。
3.1 为什么需要Zygote?
你可能想过一个问题:如果每个App都要从头启动,那得多慢啊?
没错,这就是Zygote存在的原因。Zygote进程启动时,会预加载大量的公共类库、系统资源,甚至预创建一些基础对象。当需要启动一个新的App时,Android不需要从零开始创建一个Java虚拟机,而是通过拷贝(Fork) Zygote的方式来快速生成新进程。
这就像是从一个已经准备好的“模板”复制一个,而不是从零开始建造一栋房子。
3.2 Zygote的启动流程
Zygote进程是由app_process可执行文件启动的。让我们看看app_process的源码逻辑:
// app_main.cpp ( frameworks/base/cmds/app_process/app_main.cpp )
int main(int argc, char* const argv[])
{
AppRuntime runtime;
// ... 解析参数 ...
if (zygote) {
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
} else if (className) {
runtime.start(className, args, zygote);
}
}
AppRuntime继承自AndroidRuntime,它的start方法最终会调用Java层的ZygoteInit.main()。
3.3 ZygoteInit.main()的核心逻辑
进入Java层,ZygoteInit的main方法是关键:
// frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static void main(String argv[]) {
ZygoteServer zygoteServer = new ZygoteServer();
// 1. 注册Zygote Socket
ZygoteHooks.startZygoteNoThreadCreation();
final Runnable caller;
try {
// 预加载类和资源
preload(bootTimingsTraceLog);
// 2. 如果是系统服务器模式,启动SystemServer
if (startSystemServer) {
Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
if (r != null) {
r.run();
return;
}
}
// 3. 进入循环,等待应用启动请求
caller = zygoteServer.runSelectLoop(abiList);
} catch (Throwable ex) {
// 异常处理
}
// 4. 启动系统服务的后续工作
if (caller != null) {
caller.run();
}
}
这里有几个关键步骤:
1. 预加载(Preload)
Zygote会加载大量的公共类,如java.lang.String、android.view.View等,以及资源文件。这一步非常耗时,但为了后续App的快速启动,值得。
2. 启动SystemServer
Zygote会Fork出一个子进程来运行SystemServer。SystemServer负责启动Android的核心系统服务,如ActivityManagerService、PackageManagerService等。
3. 进入Socket监听循环
Zygote会监听一个Unix Domain Socket(通常是/dev/socket/zygote)。当其他进程(如AMS)需要启动新App时,会通过这个Socket发送请求。Zygote接收到请求后,会Fork出新的进程并执行App的入口类。
3.4 Fork的秘密
fork()系统调用是Unix/Linux中创建进程的核心。在Android中,Zygote使用fork()来创建应用进程。
pid_t fork(void);
当fork()被调用时,操作系统会创建一个新的进程,新进程是原进程的副本。但在Android中,Zygote使用了一个优化:Copy-on-Write(写时复制)。
这意味着,当Zygote Fork出子进程时,子进程共享父进程的内存页。只有当子进程试图修改某页内存时,才会真正复制该页。这大大节省了内存和启动时间。
第四章:SystemServer——系统服务的“大管家”
SystemServer进程是Android系统中最重要的进程之一。它启动了几乎所有的核心服务。
4.1 SystemServer的启动
从ZygoteInit中,我们看到了forkSystemServer()的调用。这个方法会Fork出一个新进程,并执行SystemServer的main方法。
// frameworks/base/core/java/com/android/server/SystemServer.java
public static void main(String[] args) {
new SystemServer().run();
}
private void run() {
// 1. 初始化系统上下文
SystemServerInitThreadPool.get();
// 2. 启动引导服务
startBootstrapServices(t);
// 3. 启动核心服务
startCoreServices(t);
// 4. 启动其他服务
startOtherServices(t);
// 5. 启动虚拟系统服务(如多用户支持)
startVirtualSystemServices(t);
}
4.2 关键服务的启动顺序
SystemServer启动的服务是有严格顺序的,因为有些服务依赖于其他服务。
引导服务(Bootstrap Services):
SystemServiceManager:服务管理器,负责创建和启动其他服务。ActivityManagerService(AMS):管理应用的生命周期和任务。PackageManagerService(PMS):管理应用的安装、卸载和信息。PowerManagerService:管理电源和唤醒锁。DisplayManagerService:管理显示设备。
核心服务(Core Services):
BatteryService:电池状态管理。UsageStatsService:使用统计。WebViewUpdateService:WebView更新。
其他服务(Other Services):
WindowManagerService:窗口管理。InputManagerService:输入事件管理。SensorService:传感器管理。
4.3 服务启动的代码模式
每个服务的启动模式大致相同:
private void startBootstrapServices(SystemServerInitThreadPool t) {
// 启动Installer,用于安装APK
mInstaller = mSystemServiceManager.startService(Installer.class);
// 启动DeviceIdentifiersPolicyService
mSystemServiceManager.startService(DeviceIdentifiersPolicyService.class);
// 启动Power服务
mSystemServiceManager.startService(POWER_SERVICE);
// 启动PackageManagerService
mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
ServiceManager.addService(Context.PACKAGE_SERVICE, mPackageManagerService);
// 启动ActivityManagerService
ActivityManagerService.main(mSystemContext);
ServiceManager.addService(Context.ACTIVITY_SERVICE, ActivityManager.getService());
// ... 更多服务
}
注意SystemServiceManager.startService()的调用。这个类负责实例化服务并调用其onStart()方法。
第五章:ActivityManagerService——应用调度的“指挥官”
现在,我们已经走到了Android系统服务的最核心部分:ActivityManagerService(AMS)。
AMS是Android中最重要的系统服务之一,它负责管理所有应用程序的生命周期、任务栈和进程调度。
5.1 AMS的启动与初始化
AMS在SystemServer的startBootstrapServices()阶段被启动。它的main()方法是一个静态方法,用于创建单例:
// frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public static final void main(File systemDir, String systemConfig) {
// 创建AMS实例
ActivityManagerService am = new ActivityManagerService(systemDir);
ActivityManagerService.setSelf(am, systemConfig);
// 启动AMS
am.start();
// 创建OS Binder线程池
Process.setArgumentPolicy();
// 添加AMS到ServiceManager
ServiceManager.addService(Context.ACTIVITY_SERVICE, am, /*allowIsolated=*/ true,
DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO);
}
5.2 AMS如何启动一个App?
这是最关键的问题:当你点击一个App图标时,AMS做了什么?
让我们模拟一个完整的启动流程:
步骤1:AMS接收启动请求
当Launcher(桌面应用)点击App图标时,它会发送一个意图(Intent)给AMS。
步骤2:AMS检查进程是否存在
AMS会检查目标App的进程是否已经存在。如果存在,就直接激活;如果不存在,就需要启动新进程。
步骤3:发起Fork请求给Zygote
// ActivityManagerService.java 中的 startProcessLocked 方法
private final void startProcessLocked(ProcessRecord app, String hostingType,
String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
// 计算启动时间和内存限制
long startTime = SystemClock.uptimeMillis();
// 调用Process.start(),这是一个本地方法
Process.ProcessStartResult startResult = Process.start(entryPoint, app.processName, uid, uid,
gids, runtimeFlags, zygotePolicyFlags, maxNumApps, childSeinfo,
abiOverride, entryPointArgs, mountExternal, seInfo, app.info.targetSdkVersion,
app.info.appId, app.uid, app.staticAppDataSharedLibs, app.startTaskRootOptions,
app.useLowMemoryProfiler, app.instrumentationClass != null, app.info.allowBackup,
app.info.instrumentationName, app.info.processName, app.info.backupKey,
app.info.uid, app.info.targetSdkVersion, app.info.dataDir, app.info.nativeLibraryDir,
isolated, app.info.populatedTheme,
app.info.optimizeInfo, app.requiredAbi, app.info.installerPackageName,
app.startChildZygote, app.instructionSets, app.info.description,
app.processName.getApplicationInfo().descriptionRes, app.taskAffinity,
app.info.splitNames, app.cpuAbiOverride, app.info.usesNonSdkApi,
app.info.pixelPerfect);
// 检查启动结果
if (startResult.usingColdStart) {
// 冷启动
}
}
步骤4:Zygote收到请求并Fork
Zygote监听Socket,收到AMS的请求后,会Fork出一个新进程。
// ZygoteServer.java 中的 runSelectLoop 方法
private Runnable runSelectLoop(String abiList) {
while (true) {
// 等待Socket数据
int index = selectReadyChannels();
if (index < 0) {
continue;
}
// 读取请求
String args[] = readArgumentList();
// Fork进程
return handleChildProc(args, descriptors, pipeFd, fdsToClose, fdsToIgnore,
abiList, isDefaultZygote);
}
}
步骤5:新进程执行App的入口
Fork后的进程会执行ActivityThread.main()方法,这是App的入口点。
// ActivityThread.java
public static void main(String[] args) {
// 创建主线程的Looper
Looper.prepareMainLooper();
// 创建ActivityThread实例
ActivityThread thread = new ActivityThread();
thread.attach(false);
// 如果是系统进程,加载SystemProperties
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
// 进入消息循环
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
第六章:ActivityThread——App的“主心骨”
ActivityThread是Android应用中最重要的类之一。它是每个App的主线程管理类,负责处理所有UI相关的事件。
6.1 ActivityThread的初始化
在main()方法中,ActivityThread会完成以下初始化:
- 创建Handler:用于处理主线程的消息。
- 绑定到AMS:通过
attach()方法建立与AMS的连接。 - 初始化Application:创建并初始化App的Application对象。
private void attach(boolean system) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
// 非系统进程,绑定到AMS
android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
UserHandle.myUserId());
final IActivityManager mgr = ActivityManager.getService();
try {
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
// 注册ContentProvider
// ...
}
}
6.2 消息循环的处理
ActivityThread通过Looper.loop()进入消息循环,处理各种消息:
- BIND_APPLICATION:绑定Application
- CREATE_SERVICE:创建Service
- EXECUTE_TRANSACTION:执行Activity、Service、Broadcast的生命周期回调
- PAUSE_ACTIVITY:暂停Activity
- RESUME_ACTIVITY:恢复Activity
”`java public final class ActivityThread {
// 主线程Handler
final H mH = new H();
class H extends Handler {
public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToMsg(msg.what));
switch (msg.what) {
case BIND_APPLICATION:
// 处理Application绑定
AppBindData data = msg.obj;
handleBindApplication(data);
break;
case CREATE_SERVICE:
//
