? ? ? ? 这篇文章主要来聊聊系统开机广播是什么时候发送的,在上一篇android10 launcher启动流程聊了launcher启动,最后调用到ActivityThread.handleResumeActivity()将launcher界面显示出来,即将要聊到的开机广播就是沿着这条线继续往下走:
@Override
public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
String reason) {
... ...
Looper.myQueue().addIdleHandler(new Idler());
}
private class Idler implements MessageQueue.IdleHandler {
@Override
public final boolean queueIdle() {
... ...
if (a != null) {
mNewActivities = null;
IActivityTaskManager am = ActivityTaskManager.getService();
ActivityClientRecord prev;
do {
if (localLOGV) Slog.v(
TAG, "Reporting idle of " + a +
" finished=" +
(a.activity != null && a.activity.mFinished));
if (a.activity != null && !a.activity.mFinished) {
try {
//这里会执行到ActivityTaskManagerService.activityIdle()
am.activityIdle(a.token, a.createdConfig, stopProfiling);
a.createdConfig = null;
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
prev = a;
a = a.nextIdle;
prev.nextIdle = null;
} while (a != null);
}
... ...
return false;
}
}
在执行handleResumeActivity()的最后,通过Looper.myQueue().addIdleHandler(new Idler())往looper中添加了一条空闲消息,这个消息主要通知ActivityTaskManagerService当前Activity空闲了,这个时候就可以去做一些其他的事情,比如执行上一个Activity的onStop()、onDestroy,还有这里要说到的开机广播,接着就来看看ActivityTaskManagerService.activityIdle():
@Override
public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
... ...
final ActivityRecord r = mStackSupervisor.activityIdleInternalLocked(token,
false /* fromTimeout */, false /* processPausingActivities */, config);
... ...
}
将处理转交给ActivityStackSupervisor.activityIdleInternalLocked()来处理了:
final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
boolean processPausingActivities, Configuration config) {
... ...
ActivityRecord r = ActivityRecord.forTokenLocked(token);
if (r != null) {
... ...
// Check if able to finish booting when device is booting and all resumed activities
// are idle.
//1 检查是否初始化完成,需要所有启动应用的主线程是空闲的
if ((mService.isBooting() && mRootActivityContainer.allResumedActivitiesIdle())
|| fromTimeout) {
booting = checkFinishBootingLocked();
}
}
... ...
// 获取所有需要stop的activity
final ArrayList<ActivityRecord> stops = processStoppingActivitiesLocked(r,
true /* remove */, processPausingActivities);
NS = stops != null ? stops.size() : 0;
if ((NF = mFinishingActivities.size()) > 0) {
finishes = new ArrayList<>(mFinishingActivities);
mFinishingActivities.clear();
}
... ...
// 2 执行所有该stop的activity
for (int i = 0; i < NS; i++) {
r = stops.get(i);
final ActivityStack stack = r.getActivityStack();
if (stack != null) {
if (r.finishing) {
stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false,
"activityIdleInternalLocked");
} else {
stack.stopActivityLocked(r);
}
}
}
// 3 执行所有该destroy的activity
for (int i = 0; i < NF; i++) {
r = finishes.get(i);
final ActivityStack stack = r.getActivityStack();
if (stack != null) {
activityRemoved |= stack.destroyActivityLocked(r, true, "finish-idle");
}
}
... ...
return r;
}
?这里执行的逻辑主要分为三块,其中第2、3点是处理Activity的生命周期,第1点里面就会去发送开机广播,mService.isBooting()这里返回的true,在ActivityManagerService.systemReady()里赋的值,mRootActivityContainer.allResumedActivitiesIdle()这里就是判断启动过的Activity主线程是否全是空闲的,如果有不是空闲,就会一直等,直达所有都是空闲的才会在这里往下执行,这也就是为什么有时候系统开机广播会在开机之后几分钟才发送,往下ActivityStackSupervisor.checkFinishBootingLocked():
private boolean checkFinishBootingLocked() {
final boolean booting = mService.isBooting();
boolean enableScreen = false;
mService.setBooting(false);
if (!mService.isBooted()) {
mService.setBooted(true);
enableScreen = true;
}
if (booting || enableScreen) {
mService.postFinishBooting(booting, enableScreen);
}
return booting;
}
注意这里booting和booted,上面是通过booting来判断的,这里执行一次后就会设置为false,也就是这个方法只会执行一次,接着就会执行ActivityTaskManagerService.postFinishBooting():
void postFinishBooting(boolean finishBooting, boolean enableScreen) {
mH.post(() -> {
if (finishBooting) {
//这里会去执行ActivityManagerService的finishBooting()
mAmInternal.finishBooting();
}
if (enableScreen) {
//这里中间通过转发下,会执行到WindowManagerService的enableScreenAfterBoot()
mInternal.enableScreenAfterBoot(isBooted());
}
});
}
这里先来看下ActivityManagerService.finishBooting():
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()是什么时候执行的呢?这里我们先回到ActivityTaskManagerService.postFinishBooting()函数,接着来看他的第二个函数,也就是会执行WindowManagerService.enableScreenAfterBoot():
public void enableScreenAfterBoot() {
synchronized (mGlobalLock) {
... ...
if (mSystemBooted) {
return;
}
mSystemBooted = true;
... ...
}
performEnableScreen();
}
private void performEnableScreen() {
... ...
try {
mActivityManager.bootAnimationComplete();
} catch (RemoteException e) {
}
... ...
}
enableScreenAfterBoot()只会执行一次,但是performEnableScreen()可能会执行多次,内部会每隔200ms去查询动画是否完成,如果完成了,就会执行ActivityManagerService.bootAnimationComplete(),原来如此,这是又执行回去,也就是再回去ActivityManagerService.finishBooting():
final void finishBooting() {
... ...
mUserController.sendBootCompleted(... ...);
... ...
}
又转到UserController类中去了,这是ActivityManagerService的一个帮助类,先来看下它的调用链:
UserController:
sendBootCompleted() ——> finishUserBoot() ——> maybeUnlockUser() ——> unlockUserCleared()
——> finishUserUnlocking() ——> handler发SYSTEM_USER_UNLOCK_MSG消息 ——> finishUserUnlocked()
——> finishUserUnlockedCompleted()
所以我们这里就直接来看UserController.finishUserUnlockedComplete():
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():
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这个类里面找到抛这个异常的地方,然后基于抛这个异常的判断看看怎么去处理,这里就不在多说了。好了,这篇文章就到这了。
|