前言
对于Android系统的启动,从手机直观上看,大概经历几个步骤:
- 按下开机键
- 出现启动动画
- 稍等若干秒,出现锁屏界面
- 解锁之后,进入桌面
这篇文章就从源码的角度出发,揭露这些环节发生时,系统都是如何操作的。
一、系统启动
1.1 Linux 系统的启动
了解Android系统启动之前,先简要描述一下Linux系统的启动过程:
-
内核的引导。
- 当系统开机之后,BIOS会进行开机自检
- 运行Bootloader
- 首先读入 /boot 目录下的内核文件,启动init进程
-
运行 init。
- 读取 /etc/inittab 文件, 启动各种系统服务
- 在Ubuntu系统中,init进程会读取 /etc/init.d /etc/init /etc/rcS.d 目录中的文件来启动系统服务
-
系统初始化。
-
建立终端 。
-
用户登录系统
1.2 Android系统的启动
按照官方描述,Android系统架构共分五层,自上到下依次为:
- 应用层 - apps
- 应用框架层 - Framework
- 系统运行库层- Native Libraries
- 硬件抽象层 - HAL
- Linux内核层
既然采用了Linux内核,那么Android系统的起始动作跟Linux无异,但由于Android手机属于嵌入式设备,并没有使用BIOS,取而代之的是 Bootloader —— 系统启动加载器,由Bootloader加载内核,再由内核启动init 进程。
二、第一个进程-init
2.1 初始化
作为内核启动后创建的第一个进程,init的进程号为1 ,源码位于/System/core/init.cpp , 其中main函数,负责一些初始化工作,将代码简化后,大致如下:
int main(int argc, char** argv) {
// 初始化Kernel日志
InitKernelLogging(argv);
LOG(INFO) << "init second stage started!";
//初始化属性服务
property_init();
// 设置关于SELinux的内容
SelinuxSetupKernelLogging();
SelabelInitialize();
SelinuxRestoreContext();
// 创建epoll句柄
epoll_fd = epoll_create1(EPOLL_CLOEXEC);
//监控子进程异常的信号处理函数
sigchld_handler_init();
//启动属性服务
start_property_service();
//解析init.rc文件,以便后续启动系统服务。
LoadBootScripts(am, sm);
epoll_event ev;
// 等待I/O事件
int nr = TEMP_FAILURE_RETRY(epoll_wait(epoll_fd, &ev, 1, epoll_timeout_ms));
return 0;
}
2.2 解析init.rc
在上面一节的main函数中,有个LoadBootScripts函数,用来解析init.rc。
static void LoadBootScripts(ActionManager& action_manager, ServiceList& service_list) {
Parser parser = CreateParser(action_manager, service_list);
//获取ro.boot.init_rc配置,如果不存在则读取 /init.rc 文件
std::string bootscript = GetProperty("ro.boot.init_rc", "");
if (bootscript.empty()) {
parser.ParseConfig("/init.rc");
if (!parser.ParseConfig("/system/etc/init")) {
late_import_paths.emplace_back("/system/etc/init");
}
if (!parser.ParseConfig("/product/etc/init")) {
late_import_paths.emplace_back("/product/etc/init");
}
if (!parser.ParseConfig("/odm/etc/init")) {
late_import_paths.emplace_back("/odm/etc/init");
}
if (!parser.ParseConfig("/vendor/etc/init")) {
late_import_paths.emplace_back("/vendor/etc/init");
}
} else {
parser.ParseConfig(bootscript);
}
}
init.rc 是由Android Init Language 定义的配置文件,由init进程解析用来执行命令或者创建系统核心服务等。
init.rc包含4种状态类别
- Actions
- Commands
- Services
- Options
下面列举一些在init.rc中进行的操作:
- 创建目录
mkdir /data/local/tmp 0771 shell shell
mkdir /data/local/traces 0777 shell shell
mkdir /data/data 0771 system system
mkdir /data/app-private 0771 system system
mkdir /data/app-ephemeral 0771 system system
-
启动服务
service ueventd /sbin/ueventd class core critical seclabel u:r:ueventd:s0 shutdown critical service console /system/bin/sh class core console disabled user shell group shell log readproc seclabel u:r:shell:s0 setenv HOSTNAME console 其中还引入了其他rc文件,其中有一个非常重要的就是 import /init.${ro.zygote}.rc , 这个服务就是大名鼎鼎的 Zygote, 内容为:
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server class main priority -20 user root group root readproc reserved_disk 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启动Zygote
根据上节所述, rc文件的解析会调用到 parser.ParseConfig ,接下来就是对所有服务的添加工作,代码简化后如下:
bool Parser::ParseConfig(const std::string& path, size_t* parse_errors) { return ParseConfigFile(path, parse_errors); } bool Parser::ParseConfigFile(const std::string& path, size_t* parse_errors) { config_contents->push_back('\n'); // TODO: fix parse_config. ParseData(path, *config_contents, parse_errors); return true; } void Parser::ParseData(const std::string& filename, const std::string& data, size_t* parse_errors) { for (;;) { switch (next_token(&state)) { case T_EOF: return; case T_NEWLINE: jstate.line++; section_parser->ParseSection(std::move(args), filename, state.line); section_parser->EndSection(); } } } Result<Success> ServiceParser::EndSection() { if (service_) { service_list_->AddService(std::move(service_)); } return Success(); } void ServiceList::AddService(std::unique_ptr<Service> service) { services_.emplace_back(std::move(service)); } std::vector<std::unique_ptr<Service>> services_;可以看出当实例化一个Server之后,会加入services_的链表中。
继续分析。
init.rc中有一个操作是 class_start , 它对应的实现在 buildins.cpp 中
{"class_start", {1, 1, {false, do_class_start}}},do_class_start及后续操作简化如下 :
Result<Success> do_class_start(const BuiltinArguments& args) {
for (const auto& service : ServiceList::GetInstance()) {
auto result = service->StartIfNotDisabled();
}
return Success();
}
Result<Success> Service::StartIfNotDisabled() {
return Start();
}
Result<Success> Service::Start() {
pid_t pid = -1;
if (namespace_flags_) {
pid = clone(nullptr, nullptr, namespace_flags_ | SIGCHLD, nullptr);
} else {
pid = fork();
}
if (pid == 0) {
if (!ExpandArgsAndExecv(args_)) {
PLOG(ERROR) << "cannot execve('" << args_[0] << "')";
}
}
return Success();
}
我们可以清楚的看到,do_class_start实际上就是遍历ServiceList获取每一个要创建的服务,调用service->start(), 最终使用fork() 在子进程中 执行execv函数来启动服务。
而这, 其中就包括Zygote。
三、Zygote-程序孵化器
Zygote的职责有很多,大体上可以的可以分为:
- 创建虚拟机ART : 负责给app提供运行时环境
- 创建SystemServer: 负责管理各种Framework层的Service
- 创建APP
3.1 main函数
int main(int argc, char* const argv[])
{
//创建虚拟机
AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
// Parse runtime arguments. Stop at first unrecognized option.
bool zygote = false;
bool startSystemServer = false;
bool application = false;
++i; // Skip unused "parent dir" argument.
while (i < argc) {
const char* arg = argv[i++];
if (strcmp(arg, "--zygote") == 0) {
zygote = true;
niceName = ZYGOTE_NICE_NAME;
} else if (strcmp(arg, "--start-system-server") == 0) {
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) {
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.");
}
}
根据代码列出main函数的逻辑:
-
创建虚拟机
-
由于后续Zygote会fork出若干子进程,所以会根据参数判断当前进程的类型:
- --zygote: zygote父进程
- -start-system-server: SystemServer进程
- --application: APP进程
-
启动虚拟机: runtime.start
3.2 虚拟机的启动
根据前文描述,在Zygote的main函数中,执行了Runtime的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;
startVm(&mJavaVM, &env, zygote) ;
char* slashClassName = toSlashClassName(className != NULL ? className : "");
jclass startClass = env->FindClass(slashClassName);
jmethodID startMeth = env->GetStaticMethodID(startClass, "main", "([Ljava/lang/String;)V");
env->CallStaticVoidMethod(startClass, startMeth, strArray);
free(slashClassName);
ALOGD("Shutting down VM\n");
if (mJavaVM->DetachCurrentThread() != JNI_OK)
ALOGW("Warning: unable to detach main thread\n");
if (mJavaVM->DestroyJavaVM() != 0)
ALOGW("Warning: VM did not shut down cleanly\n");
}
- startVm() : 启动虚拟机,创建Java运行时环境。
- 通过运行时提供的JNI,接口执行 className 中的 main 方法,className为com.android.internal.os.ZygoteInit
经过上面的过程,正式将代码的执行环境从C++ 切换到了 Java环境, 下面我们分析ZygoteInit.main()
3.3 ZygoteInit
由上文可知,ZygoteInit 类是虚拟机世界调用的第一个Java 类,我们一起来看看它都做了什么。
首选来看 main 方法, 简化后的伪代码如下:
public static void main(String argv[]) {
// 注册一个命名socket
ZygoteServer zygoteServer = new ZygoteServer();
zygoteServer.registerServerSocketFromEnv(socketName);
//预加载
preload(bootTimingsTraceLog);
// 执行一次gc
gcAndFinalize();
// fork SystemServer进程
Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
r.run();
// 循环等待事件。
zygoteServer.runSelectLoop(abiList);
// 关闭socket
zygoteServer.closeServerSocket();
}
-
registerServerSocketFromEnv
在main函数的起始处注册了一个命名socket,了解linux编程的同学应该都知道,这是一个进程间通信的方式,而通信的另一方就是 负责管理和创建APP的 ActivityManagerSevice 。
通过命令
netstat -na可以看到这里创建的socket
unix 2 [ ACC ] STREAM LISTENING 25970 /dev/socket/zygote
-
preload: 预加载操作,主要的功能包括:
- 加载基础的Java类,类的列表存储在 /system/etc/preloaded-classes 文件中
- 加载基础资源,包括preloadDrawables 和 preloadColorStateLists
- 加载HAL层、OpenGL、libandroid.so等底层库
我们可以在启动时 通过Logcat过滤Zygote日志,查看preload的过程:
09-06 08:38:05.352 800 800 I Zygote : Lazily preloading resources. 09-06 08:38:05.352 800 800 D Zygote : begin preload 09-06 08:38:05.352 800 800 I Zygote : Installing ICU cache reference pinning... 09-06 08:38:05.352 800 800 I Zygote : Preloading ICU data... 09-06 08:38:05.357 800 800 I Zygote : Preloading classes... 09-06 08:38:05.612 800 800 I Zygote : ...preloaded 6535 classes in 255ms. 09-06 08:38:05.742 800 800 I Zygote : Preloading resources... 09-06 08:38:05.768 800 800 I Zygote : ...preloaded 64 resources in 26ms. 09-06 08:38:05.770 800 800 I Zygote : ...preloaded 41 resources in 2ms. 09-06 08:38:05.966 800 800 I Zygote : Preloading shared libraries... 09-06 08:38:05.973 800 800 I Zygote : Uninstalled ICU cache reference pinning... 09-06 08:38:05.973 800 800 I Zygote : Installed AndroidKeyStoreProvider in 0ms. 09-06 08:38:05.977 800 800 I Zygote : Warmed up JCA providers in 3ms. 09-06 08:38:05.977 800 800 D Zygote : end preload -
gcAndFinalize() : 封装了System.gc(),主动执行一次GC操作
-
forkSystemServer() : 创建SystemServer进程,下文会详细介绍
-
runSelectLoop() : 监听SocketServer,循环读取消息
代码如下:
Runnable runSelectLoop(String abiList) {
ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
fds.add(mServerSocket.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;
}
Os.poll(pollFds, -1);
for (int i = pollFds.length - 1; i >= 0; --i) {
if ((pollFds[i].revents & POLLIN) == 0) {
continue;
}
if (i == 0) {
ZygoteConnection newPeer = acceptCommandPeer(abiList);
peers.add(newPeer);
fds.add(newPeer.getFileDesciptor());
} else {
ZygoteConnection connection = peers.get(i);
final Runnable command = connection.processOneCommand(this);
}
}
}
}
runSelectLoop主要做的工作包括:
- 使用Os.poll的方式,监听ZygoteServer创建的Socket [ poll 是linux网络多路复用的一种,其他还有select,epoll]。
- 不断监听新创建的socket
- 如果接收到消息,调用 processOneCommand 执行
四、 SystemServer
4.1 创建
由上文可知,SystemServer的创建时由ZygoteInit来完成的 ,伪代码如下:
private static Runnable forkSystemServer(String abiList, String socketName,
ZygoteServer zygoteServer) {
// 准备SystemServer 的参数
String args[] = {
"--setuid=1000",
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1024,1032,1065,3001,3002,3003,3006,3007,3009,3010",
"--capabilities=" + capabilities + "," + capabilities,
"--nice-name=system_server",
"--runtime-args",
"--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
"com.android.server.SystemServer",
};
int pid;
// fork SystemServer 进程
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.runtimeFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
/* For child process */
if (pid == 0) {
// 处理SystemServer进程
return handleSystemServerProcess(parsedArgs);
}
return null;
}
参数解析:
- setuid ,setgid : 设置UID和GID为1000, 我们可以通过查看 /proc/pid/status,来查看SystemServer的UID GID的值
- nice-name : 修改进程名为 system_server
- com.android.server.SystemServer: 设置SystemServer进程对应的Java类
常用UID:
#define AID_ROOT 0 /* traditional unix root user */
#define AID_SYSTEM 1000 /* * system server anches. */
#define AID_SHELL 2000 /* adb and debug shell user */
// 用户层APP的UID大于 10000
4.2 准备
handleSystemServerProcess:
private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) {
//修改进程名为 system_server
if (parsedArgs.niceName != null) {
Process.setArgV0(parsedArgs.niceName);
}
//
final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
performSystemServerDexOpt(systemServerClasspath);
prepareSystemServerProfile(systemServerClasspath);
ClassLoader cl = null;
cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);
Thread.currentThread().setContextClassLoader(cl);
return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
- Process.setArgV0 : 修改进程名为 system_server
blueline:/ $ ps -ef |grep system_server
system 1161 794 5 08:38:03 ? 02:17:13 system_server
-
performSystemServerDexOpt : 获取SYSTEMSERVERCLASSPATH变量,并进行DexOpt操作。
根据env命令可得该环境变量包含以下Jar文件:
SYSTEMSERVERCLASSPATH=/system/framework/services.jar:/system/framework/ethernet-service.jar:/system/framework/wifi-service.jar:/system/framework/com.android.location.provider.jar获取Jar文件后,调用DexOpt操作,继续追踪代码,最终调用 installd 服务的 run_dex2oat 操作。
-
prepareSystemServerProfile : 根据环境变量 生成相应目录下的 prof 文件。
- createPathClassLoader: 创建PathClassLoader
- ZygoteInit.zygoteInit : 准备工作结束之后,执行zygoteInit
4.2 运行
上文分析到SystemServer进行一些准备工作,最后调用了zygoteInit
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
if (RuntimeInit.DEBUG) {
Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
}
RuntimeInit.commonInit();
ZygoteInit.nativeZygoteInit();
return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
这里的工作有三个
- RuntimeInit.commonInit(): 主要是进行了Java异常相关的初始化 .
protected static final void commonInit() {
LoggingHandler loggingHandler = new LoggingHandler();
Thread.setUncaughtExceptionPreHandler(loggingHandler);
Thread.setDefaultUncaughtExceptionHandler(new KillApplicationHandler(loggingHandler));
}
- ZygoteInit.nativeZygoteInit(): Native函数,对应onZygoteInit,创建native线程池,作用是用于Binder通信。
void onZygoteInit()
{
sp<ProcessState> proc = ProcessState::self();
proc->startThreadPool();
}
-
RuntimeInit.applicationInit: 通过PathClassLoader和className ,通过反射调用SystemServer.main函数。
protected static Runnable applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) { Class<?> cl; // className = com.android.server.SystemServer cl = Class.forName(className, true, classLoader); Method m = cl.getMethod("main", new Class[] { String[].class }); return m.invoke(null, new Object[] { mArgs }); }
4.3 SystemServer.main
简化后的代码:
static void main(String[] args) {
new SystemServer().run();
}
private void run() {
// Increase the number of binder threads in system_server
BinderInternal.setMaxThreads(sMaxBinderThreads);
Looper.prepareMainLooper();
Looper.getMainLooper().setSlowLogThresholdMs(
SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS);
// 加载 android_servers库
System.loadLibrary("android_servers");
// 初始化 SystemContext
createSystemContext();
// 创建 SystemServiceManager
mSystemServiceManager = new SystemServiceManager(mSystemContext);
mSystemServiceManager.setStartInfo(mRuntimeRestart,
mRuntimeStartElapsedTime, mRuntimeStartUptime);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
startBootstrapServices();
startCoreServices();
startOtherServices();
SystemServerInitThreadPool.shutdown();
// Loop forever.
Looper.loop();
}
-
BinderInternal.setMaxThreads(sMaxBinderThreads) : 设置Binder线程池支持的最大线程数,sMaxBinderThreads= 31;
可以通过ps -T -p 来查看SystemServer Binder线程池中的线程,可以看到线程的名称是用Binder:pid_count来命名的.
//shell命令
blueline:/ $ ps -T -p 9835 |grep Binder
system 9835 9860 9742 4849920 301604 0 0 S Binder:9835_1
system 9835 9861 9742 4849920 301604 0 0 S Binder:9835_2
system 9835 9970 9742 4849920 301604 0 0 S Binder:9835_3
system 9835 10098 9742 4849920 301604 0 0 S Binder:9835_4
system 9835 10139 9742 4849920 301604 0 0 S Binder:9835_5
system 9835 10267 9742 4849920 301604 0 0 S Binder:9835_6
system 9835 10356 9742 4849920 301604 0 0 S Binder:9835_7
system 9835 10398 9742 4849920 301604 0 0 S Binder:9835_8
system 9835 12364 9742 4849920 301604 0 0 S Binder:9835_9
- Looper.prepareMainLooper() : 创建一个主线程的looper
- SystemServiceManager: 负责对所有系统服务的管理,包括 创建、启动 等等。
- startBootstrapServices(); startCoreServices() ; startOtherServices();
分别负责启动 Boot、Core、Other 三种类型的 Services
4.4 各种Services的启动
上节说到 SystemServer 的末尾启动了 系统的Services,包括三种类型,Boot、Core、Other,共100+, 这里我们拿 BootServiceManager中的 Installd 来举例说明其创建和启动过程。
// SystemServiceManager为 SystemServer创建的服务管理对象
Installer installer = mSystemServiceManager.startService(Installer.class);
//SystemServiceManager.java:
public <T extends SystemService> T startService(Class<T> serviceClass) {
final String name = serviceClass.getName();
final T service;
Constructor<T> constructor = serviceClass.getConstructor(Context.class);
service = constructor.newInstance(mContext);
startService(service);
return service;
}
// 由ArrayList来存储所有启动的service
private final ArrayList<SystemService> mServices = new ArrayList<SystemService>();
public void startService(@NonNull final SystemService service) {
// Register it.
mServices.add(service);
service.onStart();
}
// Installer.java
public class Installer extends SystemService {
@Override
public void onStart() {
connect();
}
private void connect() {
// ServiceManager 是系统服务涉及的另一个重要的类
IBinder binder = ServiceManager.getService("installd");
// 监听服务销毁,触发时重连
binder.linkToDeath(new DeathRecipient() {
@Override
public void binderDied() {
connect();
}
}, 0);
// Installer中的 Binder服务实例
mInstalld = IInstalld.Stub.asInterface(binder);
}
}
由上面的代码可以看到,启动一个Installer SystemService的过程大致为:
- 通过传入的Class调用构造方法创建一个Installer的实例,然后将实例加入一个ArrayList中
- 调用installer中的onstart方法,进而调用connect()方法
- connect中出现了一个 ServiceManager ,并调用getService 取得了 binder实例
- 调用linkToDeath,意思是监听服务的死亡,如果死亡就会回调, 然后再回调中重新走次connect操作.
- 将binder实例转换成 mInstalld 。
4.5 ServiceManager
ServiceManager部分关键代码:
public final class ServiceManager {
private static IServiceManager sServiceManager;
private static HashMap<String, IBinder> sCache = new HashMap<String, IBinder>();
private static IServiceManager getIServiceManager() {
// Find the service manager
sServiceManager = ServiceManagerNative
.asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
return sServiceManager;
}
public static IBinder getService(String name) {
IBinder service = sCache.get(name);
if (service != null) {
return service;
} else {
return Binder.allowBlocking(rawGetService(name));
}
}
public static void addService(String name, IBinder service, boolean allowIsolated, int dumpPriority) {
getIServiceManager().addService(name, service, allowIsolated, dumpPriority);
}
}
ServiceManager是服务管理中另一个重要的类, 主要管理的类型是 Binder , 它由几个重要的操作:
- getIServiceManager:获得对应的native端实例
- getService : 获取当前Binder Service
- addService : 将BinderService 加入到Binder列表中,由ServiceManagerNative管理。
4.6 小结
在SystemServer这一章中涉及了几个重要的类,且命名看起来相似度很高,不好区分,简单的总结一下:
- SystemServer : 由Zygote fork出的子进程,作为容纳所有系统服务的'容器'
- SystemService : 作为抽象类, 每一个系统服务都实现了SystemService
- SystemServiceManager : 管理SystemService类型的服务,使用ArrayList数据结构
- ServiceManager: 负责管理Binder服务 , 每一个系统服务都包含至少一个Binder实例,而Binder主要解决进程间的通信。
- ServiceManagerNative: ServiceManager的本地类,又C++实现。
五、 SystemUI
在开头我们讲过,我们开机看到的第一个应用是 锁屏界面 (实际上是开机动画,这里暂不做讲解), 那么它又是如果启动的呢?答案是SystemUI
5.1 SystemUI的启动
private void startOtherServices() {
...
mActivityManagerService.systemReady(() -> {
startSystemUi(context, windowManagerF);
}
...
}
static final void startSystemUi(Context context, WindowManagerService windowManager) {
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.android.systemui",
"com.android.systemui.SystemUIService"));
intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
//Slog.d(TAG, "Starting service: " + intent);
context.startServiceAsUser(intent, UserHandle.SYSTEM);
windowManager.onSystemUiStarted();
}
startOtherServices有一段代码, 在等待mActivityManagerService服务准备完毕之后,调用startSystemUI, 而在startSystemUi中 看到了 作为应用开发中比较熟悉的 startServiceAsUser 方法,启动的服务就是 SystemUI ,包名为com.android.systemui
5.2 锁屏服务启动
在启动SystemUI之后,启动了一系列UI组件,其中包括了 StatusBar ,看一下StatusBar中的代码
public class StatusBar extends SystemUI {
@Override
public void start() {
startKeyguard();
}
}
最终我们找到了 startKeyguard , 而这个Keyguard ,锁屏服务了。
六 总结
这篇文章,我们讲述了总按下开机键到启动锁屏服务的整个流程,这里简单归纳一下:
- 开机,启动Bootloader
- 加载Linux内核,启动Init进程
- 解析init.rc,启动Zygote进程
- Zygote创建SystemServer
- SystemServer初始化系统服务,包括AcitvityManagerService ,PackageManagerService等等
- AcitvityManagerService初始化完成,回调启动SystemUI服务
- SystemUI调用startKeyguard , 显示锁屏。
参考
- 《Android进阶解密》
- 贴出的系统源码,大部分基于Android9.0
\