1、BootLoader 加载引导程序
在 Android 系统启动时,CPU 首先执行存储在 ROM 中的引导程序 BootLoader。BootLoader 读取其中的配置信息和参数,并将控制权交给下一阶段的引导程序。
2、加载 Linux 内核 Kernel
接着,BootLoader 加载 Linux 内核 Kernel,并将控制权交给内核。此时,内核开始初始化系统并加载必要的驱动程序模块。
3、启动 init 进程
内核完成基本系统初始化后,会启动 init 进程,它是 Android 系统中的第一个用户空间进程,负责启动系统中的各个服务和应用程序。
在 init 进程中,会执行 init.rc 脚本文件,该文件定义了系统启动时需要执行的命令。例如,以下命令会启动 ril-daemon 进程,用于处理与基带通信相关的事务:
service ril-daemon /system/bin/rild
socket rild stream 660 root radio
oneshot
4、启动 Zygote 进程
init 进程会启动 Zygote 进程,它是一个特殊的进程,负责启动其他进程的虚拟机。当应用程序首次被启动时,Zygote 进程会创建一个新的虚拟机,并在其中运行该应用程序。
在 init 进程中,会执行 /system/bin/app_process 命令,该命令会启动 Zygote 进程。具体来说,该命令会执行 com.android.internal.os.ZygoteInit 类的 main() 方法:
public static void main(String[] argv) {
ZygoteServer zygoteServer = new ZygoteServer();
if (argv.length == 2 && argv[1].equals("start-system-server")) {
zygoteServer.registerServerSocket("android-system", ZygoteServer.ABSTRACT_SOCKET_NAME);
Runnable r = zygoteServer.runSelectLoop(String.valueOf(Process.myUid()));
Thread thr = new Thread(r, "ZygoteStartSystemServer");
thr.start();
} else {
zygoteServer.registerServerSocket(ZygoteServer.PRIMARY_SOCKET_NAME, null);
zygoteServer.runSelectLoop(null);
}
}
在 main() 方法中,会创建一个 ZygoteServer 对象,并调用其 startServer() 方法,创建一个 LocalServerSocket 对象,以便其他进程可以通过 UNIX 域套接字与该进程通信。如果启动 System Server 进程,会将参数 "start-system-server" 传递给 Zygote 进程,此时 Zygote 进程会创建一个名为 "android-system" 的 UNIX 域套接字。
5、启动 System Server 进程
SystemServer 是 Android 系统中最重要的进程之一,负责管理系统服务,如网络连接、电源管理、传感器等,以及与应用程序进行通信。SystemServer 进程也由 Zygote 进程启动.
SystemServer 的启动主要包括以下几个步骤:
1、从 Zygote 进程中复制资源
SystemServer 进程从 Zygote 进程中继承了一些重要的资源,如类加载器、内存映射等。
在 Zygote 进程中,我们可以看到以下代码段:
class ZygoteInit {
// ...
public static void main(String argv[]) {
// ...
preload();
// ...
}
/**
* Preload resources and initialize the native library.
*/
private static void preload() {
// ...
sClassLoaders = ClassLoaderFactory.createClassLoader(null, BOOT_CLASSPATH, sDexPaths);
// ...
}
// ...
}
在 preload() 方法中,Zygote 进程会创建一个 ClassLoader,用于加载 Android 系统中的 Java 类。注意到 sClassLoaders 是一个静态变量,因此可以在其他进程中使用。
SystemServer 进程在启动时,会通过 ZygoteInit 的静态方法 forkSystemServer() 创建一个新的进程,并在其中调用 ZygoteInit.main() 方法。在这个新的进程中,SystemServer 进程会调用 ZygoteInit.preload() 方法,以获取 Zygote 进程中的资源。具体来说,SystemServer 进程会继承 Zygote 进程中的 ClassLoader、内存映射等资源。
2、启动系统服务
SystemServer 进程负责启动 Android 系统中的各种服务,如 ActivityManagerService、WindowManagerService、PackageManagerService 等。这些服务在启动时,需要完成一些初始化工作,如创建对象、注册监听器等。
以 ActivityManagerService 为例,我们可以看到以下代码段:
javaCopy code
class ActivityManagerService extends IActivityManager.Stub {
// ...
public static void main(String[] args) {
// ...
ActivityManagerService service = new ActivityManagerService(context, factory);
service.start();
// ...
}
public void start() {
// ...
mActivityTaskManager = new ActivityTaskManagerService(this);
// ...
}
// ...
}
在 main() 方法中,ActivityManagerService 进程会创建一个新的 ActivityManagerService 对象,并调用 start() 方法启动服务。在 start() 方法中,ActivityManagerService 进程会创建一个新的 ActivityTaskManagerService 对象,并将其保存在 mActivityTaskManager 成员变量中。
3、运行应用程序
Android 应用程序通常运行在自己的进程中。当用户启动一个应用程序时,SystemServer 进程会根据应用程序的包名,启动一个新的进程,并在其中运行应用程序的主入口 Activity。
以启动 Settings 应用程序为例,init 进程会启动 Zygote 进程。Zygote 进程是一个特殊的进程,它负责启动其他进程的虚拟机。当应用程序首次被启动时,Zygote 进程会创建一个新的虚拟机,并在其中运行该应用程序。在 Zygote 进程启动时,它会执行以下代码:
private static void preload() {
// Preload classes commonly used by the system.
preloadClasses();
preloadResources();
}
该方法会预加载 Android 系统常用的类和资源,以提高后续进程启动的速度。
接着,Zygote 进程会执行以下代码创建一个新的虚拟机:
public static void main(String[] argv) {
// ...省略部分代码...
// Set thread priority to maximum to avoid interference from other
// system services.
Process.setThreadPriority(Process.THREAD_PRIORITY_FOREGROUND);
// ...省略部分代码...
ZygoteServer zygoteServer = new ZygoteServer(isPrimary);
if (startSystemServer) {
Runnable r = zygoteServer.zygoteInit(args);
if (r != null) {
r.run();
return;
}
} else {
zygoteServer.runSelectLoop(!abiList.isEmpty());
}
// ...省略部分代码...
}
其中,ZygoteServer 是 Zygote 进程的核心类,负责创建和管理虚拟机,并启动应用程序进程。
在 ZygoteServer 的 zygoteInit 方法中,会初始化 Android 系统服务和资源,并创建 SystemServer 进程:
javaCopy code
private Runnable zygoteInit(String[] argv) {
// ...省略部分代码...
// Load the config from the environment.
String configStr = System.getenv("ANDROID_SOCKET_zygote_secondary");
if (configStr != null) {
socketName = configStr;
isPrimaryZygote = false;
}
// ...省略部分代码...
// Register the server socket.
try {
// ...省略部分代码...
} catch (IOException ex) {
throw new RuntimeException("Error binding to socket", ex);
}
// ...省略部分代码...
if (configStr != null) {
try {
// ...省略部分代码...
} catch (IOException ex) {
throw new RuntimeException("Error binding to socket", ex);
}
}
// ...省略部分代码...
if (isPrimaryZygote) {
// ...省略部分代码...
preload();
}
// ...省略部分代码...
// Start profiling if requested.
if (profilingInfo != null) {
startMethodTracing(profilingInfo);
}
// ...省略部分代码...
if (startSystemServer) {
return forkSystemServer();
} else {
// ...省略部分代码...
}
// ...省略部分代码...
}
在 forkSystemServer 方法中,会创建一个新的进程,并在其中启动 SystemServer 进程:
private Runnable forkSystemServer() {
return new Runnable() {
@Override
public void run() {
try {
ZygoteConnection.applyDebuggerSystemProperty();
// ZygoteServer 用于接收来自 Zygote 的连接请求
ZygoteServer zygoteServer = new ZygoteServer(mSocket);
// forkSystemServer() 方法会在新进程中启动 SystemServer 进程
ZygoteServer.ServerSocketSession session;
while (true) {
session = zygoteServer.acceptCommandPeer();
Runnable r = forkSystemServer(session, zygoteServer);
if (r != null) {
r.run();
}
}
} catch (Throwable ex) {
Log.e(TAG, "System zygote died with exception", ex);
throw ex;
} finally {
IoUtils.closeQuietly(mSocket);
}
}
};
}
当 Zygote 进程被启动时,它会执行如下的 Java 代码:
scssCopy code
public class ZygoteInit {
public static void main(String argv[]) {
...
// register zygote socket
registerZygoteSocket(socketName);
// preload classes and resources
preload();
// start system server
startSystemServer();
...
}
}
当 Zygote 进程被启动时,它会执行如下的 Java 代码:
scssCopy code
public class ZygoteInit {
public static void main(String argv[]) {
...
// register zygote socket
registerZygoteSocket(socketName);
// preload classes and resources
preload();
// start system server
startSystemServer();
...
}
}
这段代码中,registerZygoteSocket(socketName) 注册了一个 Unix 域套接字,用于应用程序进程连接到 Zygote 进程请求创建新进程。preload() 方法会预加载一些 Android 系统核心类和资源,以提高后续进程启动的速度。startSystemServer() 方法则是启动 System Server 进程,其中的核心代码如下:
scssCopy code
public class SystemServer {
public static void main(String[] args) {
...
// create system context
createSystemContext();
// start system services
startBootstrapServices();
startCoreServices();
// start system ui
startSystemUi();
...
}
}
在 startBootstrapServices() 方法中,会启动一些基础服务,如 PackageManagerService 和 ActivityManagerService,这些服务是所有应用程序都需要依赖的。在 startCoreServices() 方法中,会启动更多的系统服务,如网络连接服务、电源管理服务、传感器服务等。而在 startSystemUi() 方法中,会启动系统 UI 进程,负责显示用户界面。
当用户启动一个应用程序时,Zygote 进程会根据应用程序的包名(如 com.example.app)来生成一个类似于 /data/app/com.example.app-1/base.apk 的应用程序目录,并将该目录加入应用程序进程的 CLASSPATH 中。应用程序进程会继承 Zygote 进程的部分资源,如类加载器、内存映射等,从而加快应用程序的启动速度。
应用程序进程启动后,会执行应用程序的入口方法,如下所示:
csharpCopy code
public class MyApplication extends Application {
public void onCreate() {
...
}
}
在 onCreate() 方法中,应用程序可以进行一些初始化操作,如注册广播接收器、初始化全局变量等。接着,应用程序就可以启动各种 Activity、Service、BroadcastReceiver 等组件了。
至此,Android 系统启动流程就基本完成了。整个过程是一个由底层向上层逐步初始化的过程,从引导程序 BootLoader 到 Linux 内核 Kernel,再到 init 进程、Zygote 进程和 System Server 进程,最后到用户应用程序进程。在整个过程中,系统服务和资源被逐步启动和分配,从而使得应用程序可以正常运行。