1. 开机各阶段
makefile
```shell
boot_progress|bootAnimation:|wm_boot_animation_done
boot_progress_start: 6914 标志着kernel启动完成。Zygote开始启动 此时界面还是现实开机静态图片
BootAnimation: BootAnimationStartTiming start time: 15202ms 界面开始开机动画
boot_progress_preload_start: 9509 Zygote开始加载资源
boot_progress_preload_end: 12251 Zygote加载资源结束
boot_progress_system_run: 12619 SystemServer开始启动
boot_progress_pms_start: 13424 PMS开始启动
boot_progress_pms_system_scan_start: 13482 PMS扫描/system目录下的安装包
boot_progress_pms_data_scan_start: 15598 PMS扫描/data目录下的安装包
boot_progress_pms_scan_end: 15633 PMS扫描结束
boot_progress_pms_ready: 16225 PMS初始化完毕
boot_progress_ams_ready: 22036 AMS就绪
android.intent.category.HOME: 先启动"Android正在启动" FallbackHome。
boot_progress_enable_screen: 24814 AMS启动完成后开始激活屏幕,从此以后
屏幕才能响应用户的触摸
wm_boot_animation_done: 27995 开机动画结束,这一步用户能直观感受到开
机结束
ACTION_LOCKED_BOOT_COMPLETED: Android7.0之后才有,在解锁前就会发出。
ActivityTaskManager: START u0 {act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10000100 cmp=com.android.launcher3/.Launcher} from uid 0, pid 0 启动launcher
```
wm_boot_animation_done : 开机动画结束,一般统计到这个时间点。
可以过滤 SystemServerTiming 看子服务启动时间。
Zygote32Timing 查看 zygote 加载各资源消耗的时间, 主要是 preloaded-classes 耗时。
2. Android 启动过程
-
bootloader 启动 kernel
-
kernel 启动后,首先启动 init 进程
-
system\core\init\Init.cpp 在里面搭建系统运行环境,并解析启动init.rc。在init.zygote*.rc中启动 app_process(即zygote进程)。app_progress 入口在app_main.cpp。 里面启动ZygoteInit 和RuntimeInit。
-
ZygoteInit 里面启动 SystemServer,并用ZygoteServer注册一个socket,死循环等待AMS的信息来创建应用进程。
3. SystemServer 启动过程
-
设置时间、时区、语言等
-
startBootstrapServices:读配置,启动开机必备的服务:AMS、PMS等等
startCoreServices:其他重要服务,DropBox、电池、应用使用情况服务等
startOtherServices:通知、蓝牙、wifi等设备相关服务。
-
在AMS的systemReady 中调用startHomeActivityLocked 启动launcher。
-
Launcher启动后,会在ActivityThread.handleResumeActivity中通过Idler 最终通过 finishBooting(里面设置sys.boot_completed 属性为1) 调用UserController.sendBootCompleted。这里涉及各种开机相关广播,在对credential-encrypted storage解锁后,BOOT_COMPLETED在UserController.finishUserUnlockedCompleted 中发出。
4. 几种开机广播
ACTION_LOCKED_BOOT_COMPLETED 表示解锁之前的 Direct Boot Mode 启动完成
ACTION_BOOT_COMPLETED 我们平时监听的开机广播
开机广播发送时机
go
```shell
在Launcher启动时的handleResumeActivity,
ActivityTaskManagerService.activityIdle:
ActivityStackSupervisor.activityIdleInternalLocked:
checkFinishBootingLocked: 检查是否初始化完成,需要所有启动应用的主线程是空闲的
ActivityManagerService.finishBooting:
UserController.sendBootCompleted
finishUserBoot
ACTION_LOCKED_BOOT_COMPLETED 发送;
maybeUnlockUser
unlockUserCleared
finishUserUnlocking:发送 SYSTEM_USER_UNLOCK_MSG 信息,finishUserUnlocked
finishUserUnlockedCompleted:ACTION_BOOT_COMPLETED 这里发送开机广播
ActivityTaskManagerService.postFinishBooting:
```
launcher 启动后, 调用到 ActivityThread.handleResumeActivity()
yaml
```java
@Override
public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
String reason) {
... ...
// 往 loop 中添加了一条空闲消息
Looper.myQueue().addIdleHandler(new Idler());
}
private class Idler implements MessageQueue.IdleHandler {
2470 @Override
2471 public final boolean queueIdle() {
2472 ActivityClientRecord a = mNewActivities;
2473 boolean stopProfiling = false;
2474 if (mBoundApplication != null && mProfiler.profileFd != null
2475 && mProfiler.autoStopProfiler) {
2476 stopProfiling = true;
2477 }
2478 if (a != null) {
2479 mNewActivities = null;
// 这里交给了 ActivityClient
2480 final ActivityClient ac = ActivityClient.getInstance();
2481 ActivityClientRecord prev;
2482 do {
2483 if (localLOGV) Slog.v(
2484 TAG, "Reporting idle of " + a +
2485 " finished=" +
2486 (a.activity != null && a.activity.mFinished));
2487 if (a.activity != null && !a.activity.mFinished) {
2488 ac.activityIdle(a.token, a.createdConfig, stopProfiling);
2489 a.createdConfig = null;
2490 }
2491 prev = a;
2492 a = a.nextIdle;
2493 prev.nextIdle = null;
2494 } while (a != null);
2495 }
2496 if (stopProfiling) {
2497 mProfiler.stopProfiling();
2498 }
2499 return false;
2500 }
2501 }
```
Looper.myQueue().addIdleHandler(new Idler());
往 loop 中添加了一条空闲消息,这个消息主要通知 ActivityTaskManagerService 当前 Activity 空闲了,这个时候可以去做一些其他的事情,比如执行上一个 Activity 的 onStop( ), onDestroy( ) ......
还有开机广播, 接着就来看看ActivityTaskManagerService.activityIdle():
arduino
```java
/** Reports the main thread is idle after the activity is resumed. */
50 public void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
51 try {
52 getActivityClientController().activityIdle(token, config, stopProfiling);
53 } catch (RemoteException e) {
54 e.rethrowFromSystemServer();
55 }
56 }
```
这里交给了 ActivityClientController 中的 activityIdle 来处理
java
```java
public void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
141 final long origId = Binder.clearCallingIdentity();
142 try {
143 synchronized (mGlobalLock) {
144 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "activityIdle");
145 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
146 if (r == null) {
147 return;
148 }
// 这里其实还是回到了 ActivityTaskSupervisor
149 mTaskSupervisor.activityIdleInternal(r, false /* fromTimeout */,
150 false /* processPausingActivities */, config);
151 if (stopProfiling && r.hasProcess()) {
152 r.app.clearProfilerIfNeeded();
153 }
154 }
155 } finally {
156 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
157 Binder.restoreCallingIdentity(origId);
158 }
159 }
```
yaml
``java
void activityIdleInternal(ActivityRecord r, boolean fromTimeout,
1578 boolean processPausingActivities, Configuration config) {
1579 if (DEBUG_ALL) Slog.v(TAG, "Activity idle: " + r);
1580
1581 if (r != null) {
1582 if (DEBUG_IDLE) Slog.d(TAG_IDLE, "activityIdleInternal: Callers="
1583 + Debug.getCallers(4));
1584 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
1585 r.finishLaunchTickingLocked();
1586 if (fromTimeout) {
1587 reportActivityLaunched(fromTimeout, r, INVALID_DELAY, -1 /* launchState */);
1588 }
1589
1590 // This is a hack to semi-deal with a race condition
1591 // in the client where it can be constructed with a
1592 // newer configuration from when we asked it to launch.
1593 // We'll update with whatever configuration it now says
1594 // it used to launch.
1595 if (config != null) {
1596 r.setLastReportedGlobalConfiguration(config);
1597 }
1598
1599 // We are now idle. If someone is waiting for a thumbnail from
1600 // us, we can now deliver.
1601 r.idle = true;
1602
1603 // Check if able to finish booting when device is booting and all resumed activities
1604 // are idle.
// 1.检查是否初始化完成,需要所有启动应用的主线程是空闲的
1605 if ((mService.isBooting() && mRootWindowContainer.allResumedActivitiesIdle())
1606 || fromTimeout) {
1607 checkFinishBootingLocked();
1608 }
1609
1610 // When activity is idle, we consider the relaunch must be successful, so let's clear
1611 // the flag.
1612 r.mRelaunchReason = RELAUNCH_REASON_NONE;
1613 }
1614
1615 if (mRootWindowContainer.allResumedActivitiesIdle()) {
1616 if (r != null) {
1617 mService.scheduleAppGcsLocked();
1618 mRecentTasks.onActivityIdle(r);
1619 }
1620
1621 if (mLaunchingActivityWakeLock.isHeld()) {
1622 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
1623 if (VALIDATE_WAKE_LOCK_CALLER &&
1624 Binder.getCallingUid() != Process.myUid()) {
1625 throw new IllegalStateException("Calling must be system uid");
1626 }
1627 mLaunchingActivityWakeLock.release();
1628 }
1629 mRootWindowContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
1630 }
1631
1632 // Atomically retrieve all of the other things to do.
// 2. 处理 stop 和 destory 的 activity
1633 processStoppingAndFinishingActivities(r, processPausingActivities, "idle");
1634
1635 if (DEBUG_IDLE) {
1636 Slogf.i(TAG, "activityIdleInternal(): r=%s, mStartingUsers=%s", r, mStartingUsers);
1637 }
1638
1639 if (!mStartingUsers.isEmpty()) {
1640 final ArrayList<UserState> startingUsers = new ArrayList<>(mStartingUsers);
1641 mStartingUsers.clear();
1642 // Complete user switch.
1643 for (int i = 0; i < startingUsers.size(); i++) {
1644 UserState userState = startingUsers.get(i);
1645 Slogf.i(TAG, "finishing switch of user %d", userState.mHandle.getIdentifier());
1646 mService.mAmInternal.finishUserSwitch(userState);
1647 }
1648 }
1649
1650 mService.mH.post(() -> mService.mAmInternal.trimApplications());
1651 }
1652
```
上面的逻辑主要分为 3块, 其中 2 中是处理 Activity 的生命周期。
1 中就会去发送开机广播
``
mService.isBooting()
这里返回 true, 在ActivityManagerService.systemReady()
里赋的值
mRootWindowContainer.allResumedActivitiesIdle()
这里就是判断启动过的 Activity 主线程是否全是空闲的,如果不是空闲,就会一直等,直到所有都是空闲的才会在这里往下执行。(这也就是为什么有时候系统开机广播会在开机之后几分钟才发送)
再往下看看 checkFinishBootingLocked()
yaml
```java
1560 /**
1561 * Called when all resumed tasks/root-tasks are idle.
1562 */
1563 @GuardedBy("mService")
1564 private void checkFinishBootingLocked() {
1565 final boolean booting = mService.isBooting();
1566 boolean enableScreen = false;
// 置为 false
1567 mService.setBooting(false);
1568 if (!mService.isBooted()) {
1569 mService.setBooted(true);
1570 enableScreen = true;
1571 }
1572 if (booting || enableScreen) {
//
1573 mService.postFinishBooting(booting, enableScreen);
1574 }
1575 }
1576
```
注意这里的 booting 和 booted, 通过 booting 来判断,执行一次就会被设置为 false.
也就是方法只会执行一次。
yaml
```java
frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
5181 void postFinishBooting(boolean finishBooting, boolean enableScreen) {
5182 mH.post(() -> {
5183 if (finishBooting) {
// 这里会执行 ActivityManagerService 的finishBooting
5184 mAmInternal.finishBooting();
5185 }
5186 if (enableScreen) {
// 这里中间通过转发下,会执行到 WindowManagerService的enableScreenAfterBoot()
5187 mInternal.enableScreenAfterBoot(isBooted());
5188 }
5189 });
5190 }
5191
```
ini
```java
final void finishBooting() {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
synchronized (this) {
if (!mBootAnimationComplete) {
mCallFinishBooting = true;
return;
}
mCallFinishBooting = false;
}
... ...
}
@Override
public void bootAnimationComplete() {
final boolean callFinishBooting;
synchronized (this) {
callFinishBooting = mCallFinishBooting;
mBootAnimationComplete = true;
}
if (callFinishBooting) {
finishBooting();
}
}
```
这里的mBootAnimationComplete默认是false,直接就给返回了,如果不返回就会去执行发送开机广播了
开机动画: bootAnimationComplete()
, 这里将 mBootAnimationComplete
置为 true
还是会去执行 finishBooting()
bootAnimationComplete()
什么时候执行呢?
WindowManagerService.enableScreenAfterBoot()
yaml
```java
public void enableScreenAfterBoot() {
3834 synchronized (mGlobalLock) {
3835 ProtoLog.i(WM_DEBUG_BOOT, "enableScreenAfterBoot: mDisplayEnabled=%b "
3836 + "mForceDisplayEnabled=%b mShowingBootMessages=%b mSystemBooted=%b. "
3837 + "%s",
3838 mDisplayEnabled, mForceDisplayEnabled, mShowingBootMessages, mSystemBooted,
3839 new RuntimeException("here").fillInStackTrace());
3840 if (mSystemBooted) {
3841 return;
3842 }
3843 mSystemBooted = true;
3844 hideBootMessagesLocked();
3845 // If the screen still doesn't come up after 30 seconds, give
3846 // up and turn it on.
3847 mH.sendEmptyMessageDelayed(H.BOOT_TIMEOUT, 30 * 1000);
3848 }
3849
3850 mPolicy.systemBooted();
3851
3852 performEnableScreen();
3853 }
private void performEnableScreen() {
... ...
try {
mActivityManager.bootAnimationComplete();
} catch (RemoteException e) {
}
... ...
```
enableScreenAfterBoot()
只会执行一次,但是 performEnableScreen()
可能会执行多次,内部会每隔 200ms 去查询动画是否完成,如果完成了,就会执行ActivityManagerService.bootAnimationComplete()
又执行回去,也就是再回去`ActivityManagerService.finishBooting():
arduino
```java
final void finishBooting() {
... ...
mUserController.sendBootCompleted(... ...);
... ...
}
```
又转到UserController
类中去了,这是ActivityManagerService
的一个帮助类,先来看下它的调用链:
rust
```shell
UserController:
sendBootCompleted() -> finishUserBoot() -> maybeUnlockUser() -> unlockUserCleared() -> finishUserUnlocking -> handler 发送 SYSTEM_USER_UNLOCK_MSG 消息 -> finishUserUnlocked() -> finishUserUnlockedCompleted()
```
java
```java
private void finishUserUnlockedCompleted(UserState uss) {
... ...
final Intent bootIntent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
bootIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
bootIntent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT
| Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
| Intent.FLAG_RECEIVER_OFFLOAD);
// Widget broadcasts are outbound via FgThread, so to guarantee sequencing
// we also send the boot_completed broadcast from that thread.
final int callingUid = Binder.getCallingUid();
final int callingPid = Binder.getCallingPid();
FgThread.getHandler().post(() -> {
mInjector.broadcastIntent(bootIntent, null,
new IIntentReceiver.Stub() {
@Override
public void performReceive(Intent intent, int resultCode, String data,
Bundle extras, boolean ordered, boolean sticky, int sendingUser)
throws RemoteException {
Slog.i(UserController.TAG, "Finished processing BOOT_COMPLETED for u"
+ userId);
mBootCompleted = true;
}
}, 0, null, null,
new String[]{android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
AppOpsManager.OP_NONE, null, true, false, MY_PID, SYSTEM_UID,
callingUid, callingPid, userId);
});
}
```
这里先是封装了Intent.ACTION_BOOT_COMPLETED
这个广播意图,同时还传了一个android.Manifest.permission.RECEIVE_BOOT_COMPLETED
权限,然后转交给UserController.Injector.broadcastIntent():
arduino
```java
protected int broadcastIntent(Intent intent, String resolvedType,
IIntentReceiver resultTo, int resultCode, String resultData,
Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
boolean ordered, boolean sticky, int callingPid, int callingUid, int realCallingUid,
int realCallingPid, int userId) {
// TODO b/64165549 Verify that mLock is not held before calling AMS methods
synchronized (mService) {
return mService.broadcastIntentLocked(null, null, intent, resolvedType, resultTo,
resultCode, resultData, resultExtras, requiredPermissions, appOp, bOptions,
ordered, sticky, callingPid, callingUid, realCallingUid, realCallingPid,
userId);
}
}
```
这里又调用到ActivityManagerService.broadcastIntentLocked()
,到这里就不在往下看了,后面就是去执行发送广播的逻辑。
对于有些广播接收不到,比如报如下错误:
W BroadcastQueue: Background execution not allowed:
******************
类似这类错误,就可以在BroadcastQueue
这个类里面找到抛这个异常的地方,然后基于抛这个异常的判断看看怎么去处理