做为一名 Android 程序员,你有没有想过:那么复杂的 Android 系统,它是怎样运行起来的,咱们的 App 又是怎样被 Android 系统加载后呈如今屏幕上的呢?Android 系统的启动是一个比较复杂的过程,涉及到了一些咱们没有接触过的知识,本文将基于 Android Nougat 最新的代码上讲述 Android 系统的启动流程。html
当按下电源键(加电)或者系统重启(复位)的时候,引导芯片会从 ROM(这里通常指 Flash ROM,即闪存)中预约义的位置将 Bootloader 载入到 RAM 中,接着,Bootloader 将会把 Linux 内核载入到 RAM 中并启动。java
Bootloader 是在系统内核运行以前运行的一段小程序,也是系统运行的第一个程序,它的主要做用是:linux
Linux 内核启动过程当中会建立 init 进程,init 进程是用户空间的第一个进程(pid=1),对应的可执行程序的源文件文件为 /system/core/init/Init.cpp,它的 main 方法以下:android
int main(int argc, char** argv) {
if (!strcmp(basename(argv[0]), "ueventd")) {
return ueventd_main(argc, argv);
}
if (!strcmp(basename(argv[0]), "watchdogd")) {
return watchdogd_main(argc, argv);
}
umask(0);
add_environment("PATH", _PATH_DEFPATH);
bool is_first_stage = (argc == 1) || (strcmp(argv[1], "--second-stage") != 0);
// 建立文件并挂载
if (is_first_stage) {
mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755");
mkdir("/dev/pts", 0755);
mkdir("/dev/socket", 0755);
mount("devpts", "/dev/pts", "devpts", 0, NULL);
#define MAKE_STR(x) __STRING(x)
mount("proc", "/proc", "proc", 0, "hidepid=2,gid=" MAKE_STR(AID_READPROC));
mount("sysfs", "/sys", "sysfs", 0, NULL);
}
open_devnull_stdio();
klog_init();
klog_set_level(KLOG_NOTICE_LEVEL);
NOTICE("init %s started!\n", is_first_stage ? "first stage" : "second stage");
if (!is_first_stage) {
// Indicate that booting is in progress to background fw loaders, etc.
close(open("/dev/.booting", O_WRONLY | O_CREAT | O_CLOEXEC, 0000));
// 初始化属性相关资源
property_init();
process_kernel_dt();
process_kernel_cmdline();
export_kernel_boot_props();
}
...
// 启动属性服务
start_property_service();
const BuiltinFunctionMap function_map;
Action::set_function_map(&function_map);
Parser& parser = Parser::GetInstance();
parser.AddSectionParser("service",std::make_unique<ServiceParser>());
parser.AddSectionParser("on", std::make_unique<ActionParser>());
parser.AddSectionParser("import", std::make_unique<ImportParser>());
// 解析init.rc配置文件
parser.ParseConfig("/init.rc");
...
while (true) {
if (!waiting_for_exec) {
am.ExecuteOneCommand();
restart_processes();
}
int timeout = -1;
if (process_needs_restart) {
timeout = (process_needs_restart - gettime()) * 1000;
if (timeout < 0)
timeout = 0;
}
if (am.HasMoreCommands()) {
timeout = 0;
}
bootchart_sample(&timeout);
epoll_event ev;
int nr = TEMP_FAILURE_RETRY(epoll_wait(epoll_fd, &ev, 1, timeout));
if (nr == -1) {
ERROR("epoll_wait failed: %s\n", strerror(errno));
} else if (nr == 1) {
((void (*)()) ev.data.ptr)();
}
}
return 0;
}
复制代码
init 进程的职责主要有四个:ios
这里重点看第一点,init.rc 是一个配置文件,它由 Android 初始化语言编写,zygote 进程和 servicemanager 进程都是由 init 进程解析 init.rc 中特定的语句启动的,好比,启动 zygote 进程的代码格式以下:c++
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
class main
priority -20
user root
group root readproc
socket zygote stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart audioserver
onrestart restart cameraserver
onrestart restart media
onrestart restart netd
onrestart restart wificond
writepid /dev/cpuset/foreground/tasks
复制代码
事实上,在 system/core/rootdir 目录下,有多个 init.rc 文件,在不一样的硬件环境下,相应的 init.rc 文件会被导入,好比在 64 位操做系统中,上面启动 zygote 进程的代码是从 init.zygote64.rc 文件中导入的。git
我在文章借助 AIDL 理解 Android Binder 机制——Binder 前因后果中讲到“Binder 通讯模型和通讯过程”的时候提到过 ServerManager,它是 Binder IPC 的核心,是上下文的管理者,Binder 服务端必须先向 ServerManager 注册才可以为客户端提供服务,Binder 客户端在与服务端通讯以前须要从 ServerManager 中查找并获取 Binder 服务端的引用。然而 ServerManager 在向 Binder 驱动申请成为上下文管理者的时候又涉及到了 Binder IPC 过程,这时候应该怎么处理呢?程序员
servicemanager 进程是由 init 进程经过解析 init.rc 文件来启动的,对应的代码以下:小程序
service servicemanager /system/bin/servicemanager
class core
user system
group system
critical
onrestart restart healthd
onrestart restart zygote
onrestart restart media
onrestart restart surfaceflinger
onrestart restart drm
复制代码
servicemanager 进程对应可执行程序的源文件为 framework/native/cmds/servicemanager/service_manager.c,简化后的代码以下:数组
int main(int argc, char **argv) {
struct binder_state *bs;
// 打开binder驱动,申请 128k 字节大小的内存空间
bs = binder_open(128*1024);
...
// 成为上下文管理者
if (binder_become_context_manager(bs)) {
return -1;
}
// 验证 selinux 权限,判断进程是否有权注册或查看指定服务
selinux_enabled = is_selinux_enabled();
sehandle = selinux_android_service_context_handle();
selinux_status_open(true);
if (selinux_enabled > 0) {
if (sehandle == NULL) {
abort();
}
if (getcon(&service_manager_context) != 0) {
abort();
}
}
...
// 进入无限循环,处理 client 端发来的请求
binder_loop(bs, svcmgr_handler);
return 0;
}
复制代码
这里重点关注两点,首先,在申请了一块大小为 128k 的内存空间并验证 selinux 权限后,接着调用 framework/native/cmds/servicemanager/binder.c 中的 binder_become_context_manager 方法:
int binder_become_context_manager(struct binder_state *bs) {
// 经过ioctl,发送 BINDER_SET_CONTEXT_MGR 指令
return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0);
}
复制代码
而后,调用 binder_loop 方法进入循环来处理 client 发来的请求,注意第二个参数是一个方法体,用于处理各类状态回调:
int svcmgr_handler(struct binder_state *bs, struct binder_transaction_data *txn, struct binder_io *msg, struct binder_io *reply) {
struct svcinfo *si;
uint16_t *s;
size_t len;
uint32_t handle;
uint32_t strict_policy;
int allow_isolated;
...
strict_policy = bio_get_uint32(msg);
s = bio_get_string16(msg, &len);
...
switch(txn->code) {
case SVC_MGR_GET_SERVICE:
case SVC_MGR_CHECK_SERVICE:
// 获取服务名
s = bio_get_string16(msg, &len);
// 根据名称查找相应服务
handle = do_find_service(bs, s, len, txn->sender_euid, txn->sender_pid);
bio_put_ref(reply, handle);
return 0;
case SVC_MGR_ADD_SERVICE:
// 获取服务名
s = bio_get_string16(msg, &len);
handle = bio_get_ref(msg);
allow_isolated = bio_get_uint32(msg) ? 1 : 0;
// 注册指定服务
if (do_add_service(bs, s, len, handle, txn->sender_euid,
allow_isolated, txn->sender_pid))
return -1;
break;
}
}
复制代码
servicemanager 进程在启动过程的工做内容以下:
经过解析 init.rc 文件, zygote 进程对应的可执行程序的源文件为 frameworks/base/cmds/app_process/App_main.cpp,它的 main 方法以下:
int main(int argc, char* const argv[])
{
...
AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
...
Vector<String8> args;
if (!className.isEmpty()) {
args.add(application ? String8("application") : String8("tool"));
runtime.setClassNameAndArgs(className, argc - i, argv + i);
} else {
maybeCreateDalvikCache();
if (startSystemServer) {
args.add(String8("start-system-server"));
}
char prop[PROP_VALUE_MAX];
if (property_get(ABI_LIST_PROPERTY, prop, NULL) == 0) {
LOG_ALWAYS_FATAL("app_process: Unable to determine ABI list from property %s.",
ABI_LIST_PROPERTY);
return 11;
}
String8 abiFlag("--abi-list=");
abiFlag.append(prop);
args.add(abiFlag);
for (; i < argc; ++i) {
args.add(String8(argv[i]));
}
}
if (!niceName.isEmpty()) {
runtime.setArgv0(niceName.string());
set_process_name(niceName.string());
}
if (zygote) {
// 调用 AppRuntime 父类 AndroidRuntime 的 start 方法建立 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.");
return 10;
}
}
复制代码
调用 frameworks/base/core/jni/AndroidRuntime.cpp 的 start 方法:
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
...
/* start the virtual machine */
JniInvocation jni_invocation;
jni_invocation.Init(NULL);
JNIEnv* env;
// 启动 DVM
if (startVm(&mJavaVM, &env, zygote) != 0) {
return;
}
onVmCreated(env);
// 注册 JNI 方法
if (startReg(env) < 0) {
ALOGE("Unable to register all android natives\n");
return;
}
jclass stringClass;
jobjectArray strArray;
jstring classNameStr;
stringClass = env->FindClass("java/lang/String");
assert(stringClass != NULL);
// 建立数组
strArray = env->NewObjectArray(options.size() + 1, stringClass, NULL);
assert(strArray != NULL);
// 从 app_main 的 main 函数得知 className 为 com.android.internal.os.ZygoteInit
classNameStr = env->NewStringUTF(className);
assert(classNameStr != NULL);
env->SetObjectArrayElement(strArray, 0, classNameStr);
for (size_t i = 0; i < options.size(); ++i) {
jstring optionsStr = env->NewStringUTF(options.itemAt(i).string());
assert(optionsStr != NULL);
env->SetObjectArrayElement(strArray, i + 1, optionsStr);
}
char* slashClassName = toSlashClassName(className);
jclass startClass = env->FindClass(slashClassName);
if (startClass == NULL) {
ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
/* keep going */
} 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);
if (env->ExceptionCheck())
threadExitUncaughtException(env);
}
}
...
}
复制代码
经过 JNI 的方式进入 frameworks/base/core/java/com/android/internal/os/ZygoteInit.java:
public static void main(String argv[]) {
...
try {
...
// 注册Zygote用的Socket
registerZygoteSocket(socketName);
...
// 预加载类和资源
preload();//2
...
if (startSystemServer) {
// 启动SystemServer进程
startSystemServer(abiList, socketName);
}
Log.i(TAG, "Accepting command socket connections");
// 等待客户端请求
runSelectLoop(abiList);
closeServerSocket();
} catch (MethodAndArgsCaller caller) {
caller.run();
} catch (RuntimeException ex) {
Log.e(TAG, "Zygote died with exception", ex);
closeServerSocket();
throw ex;
}
}
复制代码
ZygoteInit.java 的 registerZygoteSocket 方法:
private static void registerZygoteSocket(String socketName) {
if (sServerSocket == null) {
int fileDesc;
final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;
try {
String env = System.getenv(fullSocketName);
fileDesc = Integer.parseInt(env);
} catch (RuntimeException ex) {
throw new RuntimeException(fullSocketName + " unset or invalid", ex);
}
try {
FileDescriptor fd = new FileDescriptor();
fd.setInt$(fileDesc);
// 建立 Socket 客户端
sServerSocket = new LocalServerSocket(fd);
} catch (IOException ex) {
throw new RuntimeException(
"Error binding to local socket '" + fileDesc + "'", ex);
}
}
}
复制代码
ZygoteInit.java 的 startSystemServer 方法:
private static boolean startSystemServer(String abiList, String socketName) throws MethodAndArgsCaller, RuntimeException {
...
/* Hardcoded command line to start the system server */
// SystemServer 启动参数
String args[] = {
"--setuid=1000",
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1032,3001,3002,3003,3006,3007,3009,3010",
"--capabilities=" + capabilities + "," + capabilities,
"--nice-name=system_server",
"--runtime-args",
"com.android.server.SystemServer",
};
ZygoteConnection.Arguments parsedArgs = null;
int pid;
try {
parsedArgs = new ZygoteConnection.Arguments(args);
ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
// 调用 Zygote.java fock 出新线程,名字叫 system_server
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.debugFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
// pid 为 0 则为 fock 出来的子线程
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
// 启动 SystemServer 进程
handleSystemServerProcess(parsedArgs);
}
return true;
}
复制代码
frameworks/base/core/java/com/android/internal/os/Zygote.java 的 forkAndSpecialize 方法:
public static int forkAndSpecialize(int uid, int gid, int[] gids, int debugFlags, int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose, String instructionSet, String appDataDir) {
VM_HOOKS.preFork();
// 调用 Native 层的方法 fock 出子线程
int pid = nativeForkAndSpecialize(uid, gid, gids, debugFlags, rlimits,
mountExternal, seInfo, niceName, fdsToClose, instructionSet, appDataDir);
// Enable tracing as soon as possible for the child process.
if (pid == 0) {// fock 出来的子线程中执行
Trace.setTracingEnabled(true);
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "PostFork");
}
VM_HOOKS.postForkCommon();
return pid;
}
复制代码
ZygoteInit.java 的 runSelectLoop 方法:
private static void runSelectLoop(String abiList) throws MethodAndArgsCaller {
ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
// sServerSocket 对象就是刚才在 registerZygoteSocket 方法中建立的服务端 Socket
fds.add(sServerSocket.getFileDescriptor());
peers.add(null);
// 循环读取状态
while (true) {
StructPollfd[] pollFds = new StructPollfd[fds.size()];
for (int i = 0; i < pollFds.length; ++i) {
pollFds[i] = new StructPollfd();
pollFds[i].fd = fds.get(i);
pollFds[i].events = (short) POLLIN;
}
try {
Os.poll(pollFds, -1);
} catch (ErrnoException ex) {
throw new RuntimeException("poll failed", ex);
}
for (int i = pollFds.length - 1; i >= 0; --i) {
// 读取的状态不是客户端链接或者数据请求时,进入下一次循环
if ((pollFds[i].revents & POLLIN) == 0) {
continue;
}
if (i == 0) {// i = 0 表示跟客户端 Socket 链接上了
ZygoteConnection newPeer = acceptCommandPeer(abiList);
peers.add(newPeer);
fds.add(newPeer.getFileDesciptor());
} else {// i > 0 表示接收到客户端 Socket 发送过来的请求
// runOnce 方法建立一个新的应用程序进程
boolean done = peers.get(i).runOnce();
if (done) {
peers.remove(i);
fds.remove(i);
}
}
}
}
}
复制代码
frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java 的 runOnce 方法:
boolean runOnce() throws ZygoteInit.MethodAndArgsCaller {
String args[];
Arguments parsedArgs = null;
FileDescriptor[] descriptors;
try {
// 读取 socket 客户端发送过来的参数列表
args = readArgumentList();
descriptors = mSocket.getAncillaryFileDescriptors();
} catch (IOException ex) {
// EOF reached.
closeSocket();
return true;
}
...
try {
// 将 socket 客户端传递过来的参数,解析成 Arguments 对象格式
parsedArgs = new Arguments(args);
...
// 一样调用 Zygote.java 的 forkAndSpecialize 方法 fock 出子进程
pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
parsedArgs.niceName, fdsToClose, parsedArgs.instructionSet,
parsedArgs.appDataDir);
} catch (Exception e) {
...
}
try {
if (pid == 0) {
// 子进程执行
IoUtils.closeQuietly(serverPipeFd);
serverPipeFd = null;
// 进入子进程流程
handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);
return true;
} else {
// 父进程执行
IoUtils.closeQuietly(childPipeFd);
childPipeFd = null;
return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs);
}
} finally {
IoUtils.closeQuietly(childPipeFd);
IoUtils.closeQuietly(serverPipeFd);
}
}
复制代码
从 App_main 开始,zygote 启动过程的时序图以下:
能够看到,这个过程当中 zygote 首先启动了 AndroidRuntime 并经过它反射调用了 ZygoteInit.main() 方法,由此进入了 Java 的世界,所以 zygote 是 Java 层的第一个进程,也是其余 Java 进程的始祖,其余 Java 进程的建立必须依赖 zygote。
zygote 进程的任务分别是:
接下来分别讲解 system_server 进程的启动过程和 system_server 进程的执行过程。
在上一小节中咱们已经知道,zygote 进程在启动的过程当中会经过 startSystemServer 方法 fock 出了一个叫 system_server 的进程,而后再该方法内执行了 handleSystemServerProcess 方法:
private static void handleSystemServerProcess( ZygoteConnection.Arguments parsedArgs) throws ZygoteInit.MethodAndArgsCaller {
/** 因为 fock 出来的 system_server 进程会复制 zygote 进程的地址空间,所以它也获得了 zygote 进程中的 Socket,这个 Socket 对它来讲并没有用处,这里将其关闭 **/
closeServerSocket();
...
if (parsedArgs.invokeWith != null) {
...
} else {
ClassLoader cl = null;
if (systemServerClasspath != null) {
cl = createSystemServerClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);
Thread.currentThread().setContextClassLoader(cl);
}
// 出现新的类 RuntimeInit,调用了它的 zygoteInit 方法
RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
}
}
复制代码
frameworks/base/core/java/com/android/internal/os/RuntimeInit.java 的 zygoteInit 方法:
public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) throws ZygoteInit.MethodAndArgsCaller {
if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote");
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "RuntimeInit");
redirectLogStreams();
commonInit();
/** 经过 Native 层中 AndroidRuntime.cpp 的 JNI 方法最终调用 app_main.cpp 的 onZygoteInit 方法 启动 Binder 线程池, 使 system_server 进程可使用 Binder 与其余进程通讯 **/
nativeZygoteInit();
// 继续往下调用
applicationInit(targetSdkVersion, argv, classLoader);
}
复制代码
RuntimeInit 的 applicationInit 方法:
private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) throws ZygoteInit.MethodAndArgsCaller {
...
invokeStaticMain(args.startClass, args.startArgs, classLoader);
}
复制代码
RuntimeInit 的 invokeStaticMain 方法:
private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader) throws ZygoteInit.MethodAndArgsCaller {
Class<?> cl;
try {
/** className 为 ZygoteInit.java 中 startSystemServer 方法 传递过来的 "com.android.server.SystemServer",这里经过反射获得 SystemServer 类 **/
cl = Class.forName(className, true, classLoader);
} catch (ClassNotFoundException ex) {
throw new RuntimeException(
"Missing class when invoking static main " + className, ex);
}
Method m;
try {
// 找到 SystemServer 类的 main 方法
m = cl.getMethod("main", new Class[] { String[].class });
} catch (NoSuchMethodException ex) {
throw new RuntimeException(
"Missing static main on " + className, ex);
} catch (SecurityException ex) {
throw new RuntimeException(
"Problem getting static main on " + className, ex);
}
int modifiers = m.getModifiers();
if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
throw new RuntimeException(
"Main method is not public and static on " + className);
}
/** 将 main 方法包装在 ZygoteInit.MethodAndArgsCaller 类中并做为异常抛出 捕获异常的地方在上一小节中 ZygoteInit.java 的 main 方法 **/
throw new ZygoteInit.MethodAndArgsCaller(m, argv);
}
复制代码
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java 的 main 方法:
public static void main(String argv[]) {
...
closeServerSocket();
} catch (MethodAndArgsCaller caller) {
// 接收到 caller 对象后调用它的 run 方法
caller.run();
} catch (RuntimeException ex) {
Log.e(TAG, "Zygote died with exception", ex);
closeServerSocket();
throw ex;
}
}
复制代码
ZygoteInit 的 MethodAndArgsCaller 类是一个 Exception 类,同时也实现了 Runnable 接口:
public static class MethodAndArgsCaller extends Exception implements Runnable {
private final Method mMethod;
private final String[] mArgs;
public MethodAndArgsCaller(Method method, String[] args) {
mMethod = method;
mArgs = args;
}
public void run() {
try {
// 调用传递过来的 mMethod
mMethod.invoke(null, new Object[] { mArgs });
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex);
} catch (InvocationTargetException ex) {
...
}
}
}
复制代码
这样,system_server 进程便启动起来并进入了 SystemServer.java 的 main 方法。
这里须要思考一下,为何须要抛出异常到 ZygoteInit 中执行?官方解释就是抛出异常的时候 Android 虚拟机会清空该进程堆内存中的栈帧,所以前面一系列启动 system_server 进程的过程当中方法调用过程就被清除了,节省了堆栈的空间,使 ZygoteInit.java 的 main 方法处于全部 Java 进程的方法栈中的栈顶。另外,从最新 Android Pie 的代码中看,这个过程已经变成在每一步中将包装好的 MethodAndArgsCaller 对象做为返回值返回,最后在 ZygoteInit 执行对象的 call 方法,这样每一个方法都执行了返回过程,天然在堆栈中对应的栈帧也被弹出栈了。
查看 frameworks/base/services/java/com/android/server/SystemServer.java 的源码:
/** * The main entry point from zygote. */
public static void main(String[] args) {
// 调用 run 方法
new SystemServer().run();
}
复制代码
private void run() {
...
// 加载 libandroid_servers.so
System.loadLibrary("android_servers");
...
// 建立 SystemServiceManager
mSystemServiceManager = new SystemServiceManager(mSystemContext);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
...
try {
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartServices");
// 启动引导服务
startBootstrapServices();
// 启动核心服务
startCoreServices();
// 启动其余服务
startOtherServices();
} catch (Throwable ex) {
...
} finally {
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
...
}
复制代码
能够看到,在 run 方法中,主要执行了启动引导服务、核心服务和其余服务的任务,这些服务加起来一共有 80 多个,它们对应这个各类不一样的功能,部分服务以下:
引导服务 | 做用 |
---|---|
Installer | 系统安装apk时的一个服务类,启动完成Installer服务以后才能启动其余的系统服务 |
ActivityManagerService | 负责四大组件的启动、切换、调度。 |
PowerManagerService | 计算系统中和Power相关的计算,而后决策系统应该如何反应 |
LightsService | 管理和显示背光LED |
DisplayManagerService | 用来管理全部显示设备 |
UserManagerService | 多用户模式管理 |
SensorService | 为系统提供各类感应器服务 |
PackageManagerService | 用来对apk进行安装、解析、删除、卸载等等操做 |
核心服务 | 做用 |
---|---|
BatteryService | 管理电池相关的服务 |
UsageStatsService | 收集用户使用每个APP的频率、使用时常 |
WebViewUpdateService | WebView更新服务 |
其余服务 | 做用 |
---|---|
CameraService | 摄像头相关服务 |
AlarmManagerService | 全局定时器管理服务 |
InputManagerService | 管理输入事件 |
WindowManagerService | 窗口管理服务 |
VrManagerService | VR模式管理服务 |
BluetoothService | 蓝牙管理服务 |
NotificationManagerService | 通知管理服务 |
DeviceStorageMonitorService | 存储相关管理服务 |
LocationManagerService | 定位管理服务 |
AudioService | 音频相关管理服务 |
... | ... |
system_server 进程在启动过程当中完成的工做分别是:
在上一节 frameworks/base/services/java/com/android/server/SystemServer.java 的 main 方法中,有一句:
private void startOtherServices() {
...
// 调用 AMS 的 systemReady 方法
mActivityManagerService.systemReady(new Runnable() {
@Override
public void run() {
...
}
}
...
}
复制代码
继续跟踪: frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java:
public void systemReady(final Runnable goingCallback) {
...
synchronized (this) {
...
// 调用 ActivityStackSupervisor 的 resumeFocusedStackTopActivityLocked 方法
mStackSupervisor.resumeFocusedStackTopActivityLocked();
mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
}
}
复制代码
frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java:
boolean resumeFocusedStackTopActivityLocked(ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
if (targetStack != null && isFocusedStack(targetStack)) {
// 调用 ActivityStack 的 resumeTopActivityUncheckedLocked 方法
return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
if (r == null || r.state != RESUMED) {
mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
}
return false;
}
复制代码
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
if (mStackSupervisor.inResumeTopActivity) {
return false;
}
boolean result = false;
try {
// Protect against recursion.
mStackSupervisor.inResumeTopActivity = true;
if (mService.mLockScreenShown == ActivityManagerService.LOCK_SCREEN_LEAVING) {
mService.mLockScreenShown = ActivityManagerService.LOCK_SCREEN_HIDDEN;
mService.updateSleepIfNeededLocked();
}
// 调用 resumeTopActivityInnerLocked 方法
result = resumeTopActivityInnerLocked(prev, options);
} finally {
mStackSupervisor.inResumeTopActivity = false;
}
return result;
}
复制代码
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
...
// 回到 ActivityStackSupervisor 的 resumeHomeStackTask 方法
return isOnHomeDisplay() && mStackSupervisor.resumeHomeStackTask(returnTaskType, prev, "prevFinished");
...
}
复制代码
frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java:
boolean resumeHomeStackTask(int homeStackTaskType, ActivityRecord prev, String reason) {
...
if (r != null && !r.finishing) {
mService.setFocusedActivityLocked(r, myReason);
return resumeFocusedStackTopActivityLocked(mHomeStack, prev, null);
}
// 再次回到 AMS 的 startHomeActivityLocked 方法
return mService.startHomeActivityLocked(mCurrentUser, myReason);
}
复制代码
boolean startHomeActivityLocked(int userId, String reason) {
if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
&& mTopAction == null) {
return false;
}
// 获取 Intent
Intent intent = getHomeIntent();
ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
if (aInfo != null) {
intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
aInfo = new ActivityInfo(aInfo);
aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
ProcessRecord app = getProcessRecordLocked(aInfo.processName,
aInfo.applicationInfo.uid, true);
if (app == null || app.instrumentationClass == null) {
intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
// 使用 mActivityStarter 启动 app,这里再也不详细跟踪
mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
}
} else {
Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
}
return true;
}
复制代码
getHomeIntent 方法:
Intent getHomeIntent() {
Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
intent.setComponent(mTopComponent);
intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
// 添加 android.intent.category.HOME
intent.addCategory(Intent.CATEGORY_HOME);
}
return intent;
}
复制代码
能够看到,最后经过一个隐式 Intent 使用 Intent.FLAG_ACTIVITY_NEW_TASK 模式启动了一个带 Intent.CATEGORY_HOME 标签的 Activity,而带有 Intent.CATEGORY_HOME 标签的 Activity 正是 Launcher App,它的 AndroidManifest 文件以下:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.launcher3">
<uses-sdk android:targetSdkVersion="23" android:minSdkVersion="16"/>
...
<application android:allowBackup="@bool/enable_backup" android:backupAgent="com.android.launcher3.LauncherBackupAgentHelper" android:hardwareAccelerated="true" android:icon="@mipmap/ic_launcher_home" android:label="@string/app_name" android:largeHeap="@bool/config_largeHeap" android:restoreAnyVersion="true" android:supportsRtl="true" >
<activity android:name="com.android.launcher3.Launcher" android:launchMode="singleTask" android:clearTaskOnLaunch="true" android:stateNotNeeded="true" android:theme="@style/Theme" android:windowSoftInputMode="adjustPan" android:screenOrientation="nosensor" android:configChanges="keyboard|keyboardHidden|navigation" android:resumeWhilePausing="true" android:taskAffinity="" android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.MONKEY"/>
</intent-filter>
</activity>
...
</application>
</manifest>
复制代码
Launcher 启动后会将全部已安装的应用图标展现在一个网格布局的 RecyclerView 里面,这时候用户就能够经过点击这些图标来启动相应的 app 了。
整个过程的时序图以下:
关于 Launcher 如何将 App 图标显示出来等更多工做细节,能够参考Android M Launcher3主流程源码浅析 和 Android系统启动流程(四)Launcher启动过程与系统启动流程这两篇文章。
最后,从总体上来看 Android 系统的启动流程:
原来,一个复杂的 Android 系统就这么被运行起来了,碍于本人有限的水平,描述这个过程其实也还简化了不少操做,下面这个图比较全面地总结了这个流程:
系列文章
按下电源键后居然发生了这一幕 —— Android 系统启动流程分析(本文)
App 居然是这样跑起来的 —— Android App/Activity 启动流程分析
屏幕上内容到底是怎样画出来的 —— Android View 工做原理详解
参考文章
若是你对文章内容有疑问或者有不一样的意见,欢迎留言,咱们一同探讨。