2019-08-13: 说说你对app(或进程)启动流程的理解?
liyilin-jack opened this issue · 7 comments
App 启动流程
App
启动流程 包括 bootloader
, Kernel
, init
,zygote
和system_server
.不过bootloader
, Kernel
已经偏操作系统内核和驱动方面了,不做细讲,这里从init
开始带大家深入理解App启动流程和顺序.
- 借鉴 代码GG|陆晓明流程图
init
init
是Linux用户的第一个进程,进程号是1
,说这个主要目的是引入我们话匣子zygote
,init
是如何创建zygote
以及init
属性服务是如何工作的呢?
代码很复杂,我也看不懂,你只要知道是通过init.rc
解析,然后执行各个阶段的动作,最后创建zygote
就行了,当然还要处理socket
属性服务方面的事情,因为涉及很多和Linux
系统相关的知识.作为应用开发就没必要太关注这个了.
zygote
当我上面没说,直接跳到zygote
,zygote
中文意思是受精卵
,他是Android
系统牵动Java
世界的纽带.而system_server
人如其名,系统中重要的server
都会驻留在Java
中.
zygote
和system_server
这两个进程分别是Java
世界的半边天,任何进程的死亡,都会导致Java
世界的Crash
.
zygote
最初名字是android_process
,这个名字是Android.mk
文件被指定的,它本身就是个Native
程序,和内核和驱动均无关.
我们不需要深究太多,只要了解一点,Zygote
觉的自己工作压力太大,于是通过startSystemServer
分裂system_server
作为Java
的世界服务.zygote
被命名为受精卵
一点都不过分,如果支持中文编码其实更适合盘古_女娲
system_server
ZygoteInt
调用 startSystemServer
创建 system_server
,system_server
通过 hsp
方法完成自己的使命,并抛出异常,最终调用SystemServer
引入 main
方法,main
方法加载 libandroid_server.so
并调用 native
的init1
函数,init1
函数通过JNI
调用init2
函数,init2
函数创建一个线程,用于加载各种service
,init1
函数最终加入Binder
通信系统
- 借鉴 邓凡平 流程图
参考资源
1. 深入理解 Android
2. App系统启动流程分析
3. App 启动过程(含 Activity 启动过程) | 安卓 offer 收割基
App的启动方式:
冷启动:当启动应用时,后台没有该应用的进程。这是系统会创建一个新的进程分配给该应用。这是app的冷启动。冷启动因为系统会分配一个新的进程给app,此时的app会创建Applocation,然后才回去创建MainActivity,最后显示在界面上。
热启动:当启动应用的时候,后台已经存在该应用的进程了,(列:按back和home应用虽然会退出但是应用的进程仍然在后台运行,可以进入任务列表查看)这个是热启动,因为热启动不会创建进程。所以app不会创建Applocation,只会初始化MainActivity。一个应用从创建到销毁只会执行一次Applocation。
应用的启动步骤:
(1) Launcher通过Binder进程间通信机制通知ActivityManagerService,它要启动一个Activity
(2) ActivityManagerService通过Binder进程间通信机制通知Launcher进入Paused状态
(3) Launcher通过Binder进程间通信机制通知ActivityManagerService,它已经准备就绪进入Paused状态,于是ActivityManagerService就创建一个新的进程,用来启动一个ActivityThread实例,即将要启动的Activity就是在这个ActivityThread实例中运行
(4) ActivityThread通过Binder进程间通信机制将一个ApplicationThread类型的Binder对象传递给ActivityManagerService,以便以后ActivityManagerService能够通过这个Binder对象和它进行通信
(5) ActivityManagerService通过Binder进程间通信机制通知ActivityThread,现在一切准备就绪,它可以真正执行Activity的启动操作了
应用启动流程涉及到的类和对象:
(1) Launcher:Launcher本质上也是一个应用程序,和我们的App一样,也是继承自Activity,实现了点击、长按等回调接口,来接收用户的输入。
(2) ActivityManagerServices:简称AMS,服务端对象,负责系统中所有Activity的生命周期。
(3) ActivityThread:App的真正入口。当开启App之后,会调用main()开始运行,开启消息循环队列,这就是传说中的UI线程或者叫主线程。与ActivityManagerServices配合,一起完成Activity的管理工作
(4) ApplicationThread:用来实现ActivityManagerService与ActivityThread之间的交互。在ActivityManagerService需要管理相关Application中的Activity的生命周期时,通过ApplicationThread的代理对象与ActivityThread通讯。
(5) ApplicationThreadProxy:是ApplicationThread在服务器端的代理,负责和客户端的ApplicationThread通讯。AMS就是通过该代理与ActivityThread进行通信的。
(6) Instrumentation:每一个应用程序只有一个Instrumentation对象,每个Activity内都有一个对该对象的引用。Instrumentation可以理解为应用进程的管家,ActivityThread要创建或暂停某个Activity时,都需要通过Instrumentation来进行具体的操作。
(7) ActivityStack:Activity在AMS的栈管理,用来记录已经启动的Activity的先后关系,状态信息等。通过ActivityStack决定是否需要启动新的进程。
(8) ActivityRecord:ActivityStack的管理对象,每个Activity在AMS对应一个ActivityRecord,来记录Activity的状态以及其他的管理信息。其实就是服务器端的Activity对象的映像。
(9) TaskRecord:AMS抽象出来的一个“任务”的概念,是记录ActivityRecord的栈,一个“Task”包含若干个ActivityRecord。AMS用TaskRecord确保Activity启动和退出的顺序。
App启动白屏或黑屏的原因:是因为已进入到Activity,但是未加载到布局文件,就先显示来windows窗口的背景。黑屏/白屏就是显示的windows背景(这个就是theme的设置)
App启动白屏或黑屏解决方案:
(1) 为Theme设置背景图(会给人一种快速加载的感觉)
<stylename="Theme.AppStartLoad"parent="android:Theme">
<itemname="android:windowBackground">@drawable/ipod_bg
<itemname="android:windowNoTitle">true
</style>(2) 为Theme设置透明属性(会给人较慢加载出来感觉)
<stylename="Theme.AppStartLoadTranslucent"parent="android:Theme">
<itemname="android:windowIsTranslucent">true
<itemname="android:windowNoTitle">true
</style>App的启动优化:
(1) Application的创建过程中尽量少的进行耗时操作
(2) 如果用到SharePreference,尽量在异步线程中操作
(3) 减少布局的层次,并且生命周期回调的方法中尽量减少耗时的操作
APP启动在项目中碰到过黑白屏的问题
为什么我的 APP 启动会白屏或者黑屏
有时候我们会发现,我们在启动我们自己的 APP 的时候,总是有那么点时间是白屏(黑屏),经过了白屏(黑屏)后才会进入我们的 APP。那么这是为什么呢?
有很多的初始化放到了 Application 中去完成了,那么这个时候刚打开程序的时候就会有个耗时,就会出现白屏的效果。
所以这里程序加载有个顺序,当打开一个 Activity 的时候,并且这个 Activity 所属的 Application 还没有运行,系统会首先为这个 Activity 创建一个进程,创建进程的时候就会调用 Application 的 onCreate 方法。进程的创建和 onCreate 内部的初始化是需要时间的,如果这个时候过长,没有任何反应的话,那么对于用户来说是不不知道的,用户还以为自己没有点到呢,所以很显然是不可能在原页面等待加载的,那么这个时候就有了 StartingWindow(PerviewWindow)的出现,StartingWindow 出现在应用程序进程创建并且初始化完成之前,是个临时的窗口,对应的 WindowType是 TYPE_APPLICATION_STARTING 作用就是告诉用户,系统已经收到我们的操作了,正在对程序进行初始化,只要初始化完毕后就会移除这个窗口。
所以其实我们看到的白屏或者黑屏就是 StartingWindow,那么为什么是白色或者黑色呢?我们一般都会给我们的 Application 和 Activity 设置 Theme,系统就会根据我们所设置的 Theme 来决定 StartingWindow 的颜色。我们都知道 Window 布局的顶层是 DecorView,而 StaringWindow 显示的是一个空的 DecorView,只是这个 DecorView 会应用我们的这个 Activity 所指定的 Theme。我们默认的 Theme 是 @android:style/Theme.Light 的话,这个时候就会产生白屏了。黑屏就是应用了 @android:style/Theme.Black,好了到这里我们就彻底明白为什么会出现白屏或者黑屏了。
App启动白屏或黑屏解决方案:
(1) 为Theme设置背景图(会给人一种快速加载的感觉)
<stylename="Theme.AppStartLoad"parent="android:Theme">
<itemname="android:windowBackground">@drawable/ipod_bg
<itemname="android:windowNoTitle">true
</style> (2) 为Theme设置透明属性(会给人较慢加载出来感觉)<stylename="Theme.AppStartLoadTranslucent"parent="android:Theme">
<itemname="android:windowIsTranslucent">true
<itemname="android:windowNoTitle">true
</style> App的启动优化:(1) Application的创建过程中尽量少的进行耗时操作
(2) 如果用到SharePreference,尽量在异步线程中操作
(3) 减少布局的层次,并且生命周期回调的方法中尽量减少耗时的操作
app的启动流程分析:https://www.jianshu.com/p/28281b54d318
首先放上我参考的文章,感觉写的不错。Android - Activity 启动过程
我先说一下我理解的一个应用启动的大致流程。
第一步我们点击桌面上一个应用图标,这个时候管理者会向系统服务进程发送一个指令:我要打开一个activity
;第二步既然要打开activity
,总要有个新的进程装载吧,那么系统服务向最牛的进程,算是系统进程吧,发送创建A
进程的请求,这个时候系统主进程会进行创建A
进程的工作,先判断要创建的A
进程是否存在,然后确定是否要创建A
进程;第三步创建好A
进程之后,A
进程向系统服务进程说,我已经被创建好了,你可以给我发送我运行需要的东西了,然后系统服务进程就会向A
进程发送指令,告诉A进程需要创建Application
和activity
等一系列操作。
上面一系列啰嗦的叙述,其中系统服务进程是system_serve
r进程,最牛的系统主进程是Zygote
进程,创建进程的操作是fock
操作,判断进程的唯一性是查看ActivityManagerService
中有没有A进程的ProcessRecord
(可以理解为每个进程的uid+process
)信息,创建A
进程的同时在A
进程中创建了ActivityThread
;进程A
中的ActivityThread
向system_server
进程的ActivityManagerService
发送A
进程创建好的指令,并把A
进程中的ApplicationThread
发给ActivityManagerService
,然后system_server
进程的ActivityManagerService
通过ApplicationThreadProxy
这个代理与进程中的ApplicationThread
沟通,进一步在A
进程中创建application
和activity
等
这过程太复杂了,里边涉及了好多的点。只能大致的说一下,我再继续研究一下,有新的发现和想法再补充上来
- 点击图标后Launcher进程会通过Binder机制向AMS发起打开Activity的请求【IPC->Binder】
- AMS会通过ActivityStarter处理Intent和Flag(启动模式相关的内容),然后通过Socket通知zygote进程【IPC->Socket】
- zygote进程会进行孵化(虚拟机和资源的复制),然后fork出新进程
- 然后zygote进程会通过invokeDynamicMain()方法调用到ActivityThread的main方法【ActivityThread】
public static void main(String[] args) { // 1. mainLooper Looper.prepareMainLooper(); // 2. 创建ActivityThread,执行attach ActivityThread thread = new ActivityThread(); thread.attach(false); // 3. Handler if (sMainThreadHandler == null) { sMainThreadHandler = thread.getHandler(); } // 4. loop() Looper.loop(); }
- main()中关于Handler相关的工作是:主线程Looper和Handler的创建、开启主线程Looper的消息循环
- main()另一工作就是创建ActivityThread对象,执行attach方法。【Application、ContentProvider】
- 先通过AMS执行bindApplication方法
- 内部会创建属于Application的ContextImpl对象,并且创建Application对象,建立两者的联系
- 创建ContentProvider,执行其onCreate()方法,并进行发布相关操作(前提是该app有ContentProvider)
- 执行Application的onCreate()方法
- 进程间通信IPC的Binder机制有哪些应用的场景?
- Binder 是基于 C/S 架构的
- IPC中Socket方式有哪些应用场景?
* - Application的Context上下文对象是在哪里初始化的?
- ActivityThread---handleBindApplication()(初始化)
- LoadedApk.makeApplication()
- Instrumentation.newApplication(Class,Context)
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
- Application.attach()
- Application.attachBaseContext()
- ContentProvider是在哪里创建、初始化和发布的?
- ActivityManagerService---attachApplicationLocked()(创建)AppBindData
- ApplicationThread---bindApplication()
- ActivityThread---handleBindApplication()(初始化)
- ActivityThread---installContentProviders()
- ActivityThread---installProvider()
- ActivityManagerService---publishContentProviders()(发布)
- ContentProvider的onCreate()和Application的onCreate()方法哪个先执行?
- ContentProvider的onCreate()
App 启动过程
一、整体了解
1、ActivityManagerService
简称 AMS,服务端对象,负责管理 Activity 生命周期。
2、ActivityThread
App 的入口,启动 App 后,会调用 ActivityThread.main(),开启 Looper、MessageQueue,与 ActivityManagerService 配合完成对 Activity 的管理。
3、ApplicationThread
实现 ActivityManagerService 与 ActivityThread 之间的交互,在 ActivityManagerService 需要管理 Application 中 Activity 的生命周期时,通过 ApplicationThread 代理对象和 ActivityThread 通信。
4、ApplicationThreadProxy
ApplicationThread 在服务端的代理对象,负责和客户端的 ApplicationThread 进行通信。
5、Instrumentation
每个应用程序只有一个 Instrumentation 对象,每个 Activity 内都有一个对该对象的引用,可以理解为应用进程的管家,ActivityThread 需要创建或者暂停某个 Activity 时,都需要通过 Instrumentation 进行操作。
6、ActivityStack
Activity 在 AMS 中的栈管理,用来记录已经启动的 Activity 的先后顺序、状态信息等,通过 ActivityStack 决定是否需要启动新的进程。
7、ActivityRecord
ActivityStack 管理的对象,每个 Activity 在 AMS 对应一个 ActivityRecord,用来记录 Activity 的状态以及其他管理信息,其实就是服务器端 Activity 对象的映射。
8、TaskRecord
AMS 抽象出来的一个任务的概念,是记录 ActivityRecord 的栈,一个 Task 包含若干个 ActivityRecord,AMS 通过 TaskRecord 确保 Activity 启动和退出的顺序。
二、Zygote
在 Linux 中,所有的进程都是由 init 进程直接或间接 fork 出来的,Zygote 进程也不例外。
手机开机后,Linux 内核加载完成后,会启动一个 init 进程。
每一个 App 其实都是:
- 一个独立的 Dalvik 虚拟机
- 一个独立的进程
所以,在系统中的第一个 Zygote 进程启动之后,再打开一个 App,其实就是开启一个新的进程。而为了实现资源共用和更快的启动速度,Android 系统开启新进程的方式是:通过 fork 第一个 Zygote 进程开启新进程,换句话说,其他应用所在的进程都是 Zygote 的子进程。
三、SystemServer
SystemServer 是一个进程,也是由 Zygote 进程 fork 出来的。
系统里比较重要的服务都是从这个进程里开启的,比如 ActivityManagerService、WindowManagerService、PackageManagerService 等。
Zygote 开启的时候会调用 ZygoteInit.main()
public static void main(String argv[]) {
ZygoteServer zygoteServer = new ZygoteServer();
// 标记 Zygote 开启
ZygoteHooks.startZygoteNoThreadCreation();
// Zygote 进入它自己的进程组
try {
Os.setpgid(0, 0);
} catch (ErrnoException ex) {
throw new RuntimeException("Failed to setpgid(0,0)", ex);
}
try {
// 上报 Zygote 开启时间到分裂时间,除非重新启动
if (!"1".equals(SystemProperties.get("sys.boot_completed"))) {
MetricsLogger.histogram(null, "boot_zygote_init",
(int) SystemClock.elapsedRealtime());
}
String bootTimeTag = Process.is64Bit() ? "Zygote64Timing" : "Zygote32Timing";
BootTimingsTraceLog bootTimingsTraceLog = new BootTimingsTraceLog(bootTimeTag,
Trace.TRACE_TAG_DALVIK);
bootTimingsTraceLog.traceBegin("ZygoteInit");
RuntimeInit.enableDdms();
// 开始 Zygote 初始化
SamplingProfilerIntegration.start();
boolean startSystemServer = false;
String socketName = "zygote";
String abiList = null;
boolean enableLazyPreload = false;
for (int i = 1; i < argv.length; i++) {
if ("start-system-server".equals(argv[i])) {
startSystemServer = true;
} else if ("--enable-lazy-preload".equals(argv[i])) {
enableLazyPreload = true;
} else if (argv[i].startsWith(ABI_LIST_ARG)) {
abiList = argv[i].substring(ABI_LIST_ARG.length());
} else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
socketName = argv[i].substring(SOCKET_NAME_ARG.length());
} else {
throw new RuntimeException("Unknown command line argument: " + argv[i]);
}
}
if (abiList == null) {
throw new RuntimeException("No ABI list supplied.");
}
zygoteServer.registerServerSocket(socketName);
// 在许多配置中, 避免急切的预加载资源和类文件
// 在许多事例中, 在第一次 fork 时会预加载一些优先级高的事情
if (!enableLazyPreload) {
bootTimingsTraceLog.traceBegin("ZygotePreload");
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
SystemClock.uptimeMillis());
preload(bootTimingsTraceLog);
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
SystemClock.uptimeMillis());
bootTimingsTraceLog.traceEnd(); // ZygotePreload
} else {
Zygote.resetNicePriority();
}
// 完成 Zygote 的初始化
SamplingProfilerIntegration.writeZygoteSnapshot();
// 做一个 GC 初始化,在启动之后进行清理
bootTimingsTraceLog.traceBegin("PostZygoteInitGC");
gcAndFinalize();
bootTimingsTraceLog.traceEnd(); // PostZygoteInitGC
bootTimingsTraceLog.traceEnd(); // ZygoteInit
// 禁止跟踪,以至于被 fork 的进程不能继承老的 Zygote
Trace.setTracingEnabled(false);
// Zygote 进程卸载根存储空间
Zygote.nativeUnmountStorageOnInit();
// 设置 seccomp 策略
Seccomp.setPolicy();
ZygoteHooks.stopZygoteNoThreadCreation();
if (startSystemServer) {
startSystemServer(abiList, socketName, zygoteServer);
}
Log.i(TAG, "Accepting command socket connections");
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;
}
}
// 为 fork SystemServer 进程准备参数
private static boolean startSystemServer(String abiList, String socketName, ZygoteServer zygoteServer)
throws Zygote.MethodAndArgsCaller, RuntimeException {
long capabilities = posixCapabilitiesAsBits(
OsConstants.CAP_IPC_LOCK,
OsConstants.CAP_KILL,
OsConstants.CAP_NET_ADMIN,
OsConstants.CAP_NET_BIND_SERVICE,
OsConstants.CAP_NET_BROADCAST,
OsConstants.CAP_NET_RAW,
OsConstants.CAP_SYS_MODULE,
OsConstants.CAP_SYS_NICE,
OsConstants.CAP_SYS_PTRACE,
OsConstants.CAP_SYS_TIME,
OsConstants.CAP_SYS_TTY_CONFIG,
OsConstants.CAP_WAKE_ALARM
);
// 没有容量的容器运行,避免设置它
if (!SystemProperties.getBoolean(PROPERTY_RUNNING_IN_CONTAINER, false)) {
capabilities |= posixCapabilitiesAsBits(OsConstants.CAP_BLOCK_SUSPEND);
}
// 硬编码开启 system server
String args[] = {
"--setuid=1000",
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,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);
// 请求 fork 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);
}
/* For child process */
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
zygoteServer.closeServerSocket();
handleSystemServerProcess(parsedArgs);
}
return true;
}
四、ActivityManagerService
简称 AMS,服务端对象,负责系统中所有 Activity 生命周期。
初始化时机:SystemServer 进程开启时。
public static void main(String[] args) {
new SystemServer().run();
}
public SystemServer() {
mFactoryTestMode = FactoryTest.getMode();
mRuntimeRestart = "1".equals(SystemProperties.get("sys.boot_completed"));
}
private void run() {
try {
traceBeginAndSlog("InitBeforeStartServices");
if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
Slog.w(TAG, "System clock is before 1970; setting to 1970.");
SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
}
String timezoneProperty = SystemProperties.get("persist.sys.timezone");
if (timezoneProperty == null || timezoneProperty.isEmpty()) {
Slog.w(TAG, "Timezone not set; setting to GMT.");
SystemProperties.set("persist.sys.timezone", "GMT");
}
if (!SystemProperties.get("persist.sys.language").isEmpty()) {
final String languageTag = Locale.getDefault().toLanguageTag();
SystemProperties.set("persist.sys.locale", languageTag);
SystemProperties.set("persist.sys.language", "");
SystemProperties.set("persist.sys.country", "");
SystemProperties.set("persist.sys.localevar", "");
}
// system server 不能多线程调用
Binder.setWarnOnBlocking(true);
Slog.i(TAG, "Entered the Android system server!");
int uptimeMillis = (int) SystemClock.elapsedRealtime();
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, uptimeMillis);
if (!mRuntimeRestart) {
MetricsLogger.histogram(null, "boot_system_server_init", uptimeMillis);
}
SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());
if (SamplingProfilerIntegration.isEnabled()) {
SamplingProfilerIntegration.start();
mProfilerSnapshotTimer = new Timer();
mProfilerSnapshotTimer.schedule(new TimerTask() {
@Override
public void run() {
SamplingProfilerIntegration.writeSnapshot("system_server", null);
}
}, SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL);
}
VMRuntime.getRuntime().clearGrowthLimit();
// system server 会一直运行,所以它需要高效使用其内存
VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
Build.ensureFingerprintProperty();
// 在 system server 中, 在没有显式指定用户的情况下,访问环境路径是会报错的
Environment.setUserRequired(true);
// 在 system server 中, 应该对任何输入包进行解压缩,避免抛出 BadParcelableException
BaseBundle.setShouldDefuse(true);
// 确保 binder 进行系统调用时能运行在前台
BinderInternal.disableBackgroundScheduling(true);
// 增加 system_server 中 binder 线程的数量
BinderInternal.setMaxThreads(sMaxBinderThreads);
android.os.Process.setThreadPriority(
android.os.Process.THREAD_PRIORITY_FOREGROUND);
android.os.Process.setCanSelfBackground(false);
Looper.prepareMainLooper();
// 初始化 native services(本地服务库)
System.loadLibrary("android_servers");
// 检查上次我们尝试关闭是否失败
performPendingShutdown();
// 初始化 system context
createSystemContext();
// 创建 system service manager
mSystemServiceManager = new SystemServiceManager(mSystemContext);
mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
// 准备 thread pool 并行初始化 tasks
SystemServerInitThreadPool.get();
} finally {
traceEnd(); // InitBeforeStartServices
}
// 开启服务
try {
traceBeginAndSlog("StartServices");
startBootstrapServices();
startCoreServices();
startOtherServices();
SystemServerInitThreadPool.shutdown();
} catch (Throwable ex) {
throw ex;
} finally {
traceEnd();
}
if (!mRuntimeRestart && !isFirstBootOrUpgrade()) {
int uptimeMillis = (int) SystemClock.elapsedRealtime();
MetricsLogger.histogram(null, "boot_system_server_ready", uptimeMillis);
final int MAX_UPTIME_MILLIS = 60 * 1000;
if (uptimeMillis > MAX_UPTIME_MILLIS) {
Slog.wtf(SYSTEM_SERVER_TIMING_TAG,
"SystemServer init took too long. uptimeMillis=" + uptimeMillis);
}
}
// 开启 Looper 循环
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
// 初始化上下文对象 mSystemContext
private void createSystemContext() {
// 创建 ActivityThread 对象,ActivityThread.systemMain() 会调用 ActivityThread.attach(),在 attach 中创建了 Application 对象,并调用了 Application.onCreate()
ActivityThread activityThread = ActivityThread.systemMain();
// mSystemContext 实际上是一个 ContextImpl 对象
mSystemContext = activityThread.getSystemContext();
// 设置默认主题
mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
final Context systemUiContext = activityThread.getSystemUiContext();
systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
}
private void startBootstrapServices() {
...
// 初始化 ActivityManagerService
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
mActivityManagerService.setInstaller(installer);
// Power manager 需要被提前创建因为其他服务需要它
mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
// 现在电源管理已经开始了,ActivityManagerService 负责电源管理功能
// 初始化电源管理
mActivityManagerService.initPowerManagement();
// 初始化 DisplayManagerService,在 package manager 之前 需要提供 Display manager
mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
// 开启 PackageManagerService
mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
...
}
这是系统进程开启时的流程,在这之后,会开启系统的 Launcher 程序,完成系统界面的加载与显示。
五、Android 系统里面的服务器和客户端
服务器端:所有 App 共用的系统服务,比如 ActivityManagerService、PackageManagerService、WindowManagerService 等,当某个 App 要进行某项操作时,要告诉这些系统服务。
客户端:某个 App。
App A 调用 startActivity 不能直接打开 App B 的某个页面,而是通过一系列调用,告诉 AMS 要打开 App B 的某个页面,AMS 会通知 Zygote 进程 fork 一个新进程,来开启 App B。
App 与 AMS 之间通过 Binder 进行 IPC 通信,AMS 与 Zygote 之间通过 Socket 进行通信。
AMS 的用途:
- 通知 Zygote 进程进行 fork 新进程
- 管理系统中所有 Activity 生命周期
六、Launcher
Launcher 本身也是一个应用程序。
七、Instrumentation 和 ActivityThread
每个 Activity 都持有 Instrumentation 对象的一个引用,但整个进程只会存在一个 Instrumentation 对象。
当 startActivityForResult() 调用之后,实际上还是调用了 mInstrumentation.execStartActivity()。
这个类里面的方法大多数和 Application 和 Activity 有关,这个类就是完成对 Application 和 Activity 初始化和生命周期的工具类。
AMS -> ActivityThread -> Instrumentation
八、AMS 与 ActivityThread 之间的 Binder 通信
startActivity()
-> startActivityForResult()
-> Instrumentation.execStartActivity() -> checkStartActivityResult()
-> ActivityManager.getService().startActivity()
-> ActivityManagerService.startActivity() -> startActivityAsUser()
-> ActivityStarter.startActivityMayWait() -> startActivityLocked() -> startActivity() -> startActivityUnchecked() -> resumeTargetStackIfNeeded()
-> ActivityStackSupervisor.resumeFocusedStackTopActivityLocked()
-> ActivityStack.resumeTopActivityUncheckedLocked() -> resumeTopActivityInnerLocked()
-> ActivityStackSupervisor.startSpecificActivityLocked() -> realStartActivityLocked()
-> ActivityThread.ApplicationThread.scheduleLaunchActivity() -> sendMessage() -> handleLaunchActivity() -> performLaunchActivity()
-> Instrumentation.callActivityOnCreate()
-> Activity.performCreate() -> onCreate()
ActivityManager.getService() 返回的就是 ActivityManagerService 的远程接口。
客户端:ActivityManagerProxy -> Binder驱动 -> ActivityManagerService:服务器
如果 AMS 想要通知 ActivityThread 做一些事情,还是通过 Binder 通信,不过是换成了 ApplicationThread 和 ApplicationThreadProxy。
ApplicationThreadProxy:服务器 -> Binder 驱动 -> 客户端:ApplicationThread
九、问答
1、一个 App 的程序入口到底是什么?
ActivityThread.main()。
2、整个 App 的主线程的消息循环是在哪里创建的?
是在 ActivityThread 初始化的时候,就已经创建消息循环了,所以在主线程里面创建 Handler 不需要指定 Looper,而如果在其他线程使用 Handler,则需要单独使用 Looper.prepare() 和 Looper.loop() 创建消息循环。
3、Application 是在什么时候创建的?onCreate()什么时候调用的?
也是在 ActivityThread.main() 的时候,再具体点,就是在 thread.attach(false) 的时候。
参考:APP启动过程