在开机动画执行的循环里,都会调用checkExit来检查是否要退出开机动画
//frameworks\base\cmds\bootanimation
bool BootAnimation::android() {
//......
do {
checkExit();
} while (!exitPending());//调用requestExit之后,exitPending()返回true,退出循环
//......
来看一下checkExit方法
//frameworks\base\cmds\bootanimation
void BootAnimation::checkExit() {
char value[PROPERTY_VALUE_MAX];
property_get(EXIT_PROP_NAME, value, "0");
int exitnow = atoi(value);
if (exitnow) {
requestExit();
mCallbacks->shutdown();
}
}
其中 EXIT_PROP_NAME为 service.bootanim.exit,当检测到该属性的值不为0时,就调用 requestExit 退出动画。系统是在WindowManagerService中的performEnableScreen方法中,设置了该属性
private void performEnableScreen() {
synchronized (mGlobalLock) {
//......
if (!mBootAnimationStopped) {
Trace.asyncTraceBegin(TRACE_TAG_WINDOW_MANAGER, "Stop bootanim", 0);
// stop boot animation
// formerly we would just kill the process, but we now ask it to exit so it
// can choose where to stop the animation.
SystemProperties.set("service.bootanim.exit", "1");
mBootAnimationStopped = true;
}
//......
try {
IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
if (surfaceFlinger != null) {
ProtoLog.i(WM_ERROR, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");
Parcel data = Parcel.obtain();
data.writeInterfaceToken("android.ui.ISurfaceComposer");
surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION, // BOOT_FINISHED
data, null, 0); //这里最终调用到surfaceFlinger中,也会设置service.bootanim.exit这个值
data.recycle();
}
} catch (RemoteException ex) {
ProtoLog.e(WM_ERROR, "Boot completed: SurfaceFlinger is dead!");
}
}
//......
}
来分析一下 performEnableScreen 的调用栈。在performEnableScreen 的三个地方,分别加了打印信息
1,在3432行添加:
android.util.Log.d("test1","performEnableScreen1 mDisplayEnabled:"+mDisplayEnabled+",mForceDisplayEnabled:" +mForceDisplayEnabled+",mShowingBootMessages:"+mShowingBootMessages+",mSystemBooted:"+mSystemBooted,new Exception());
2,在3463行添加:
android.util.Log.d("test1","performEnableScreen2:",new Exception());
3,在3477 行添加:
android.util.Log.d("test1","performEnableScreen3:",new Exception());
调用栈信息如下
03-11 16:49:15.662 445 479 D test1 : performEnableScreen1 mDisplayEnabled:false,mForceDisplayEnabled:false,mShowingBootMessages:false,mSystemBooted:true
03-11 16:49:15.662 445 479 D test1 : java.lang.Exception
03-11 16:49:15.662 445 479 D test1 : at com.android.server.wm.WindowManagerService.performEnableScreen(WindowManagerService.java:3432)
03-11 16:49:15.662 445 479 D test1 : at com.android.server.wm.WindowManagerService.enableScreenAfterBoot(WindowManagerService.java:3381)
03-11 16:49:15.662 445 479 D test1 : at com.android.server.wm.ActivityTaskManagerService$LocalService.enableScreenAfterBoot(ActivityTaskManagerService.java:6468)
03-11 16:49:15.662 445 479 D test1 : at com.android.server.wm.ActivityTaskManagerService.lambda$postFinishBooting$7$ActivityTaskManagerService(ActivityTaskManagerService.java:5658)
03-11 16:49:15.662 445 479 D test1 : at com.android.server.wm.-$$Lambda$ActivityTaskManagerService$hgT7_BsCohDVg6qQfaw5Xpx0-yQ.run(Unknown Source:6)
03-11 16:49:15.662 445 479 D test1 : at android.os.Handler.handleCallback(Handler.java:938)
03-11 16:49:15.662 445 479 D test1 : at android.os.Handler.dispatchMessage(Handler.java:99)
03-11 16:49:15.662 445 479 D test1 : at android.os.Looper.loop(Looper.java:223)
03-11 16:49:15.662 445 479 D test1 : at android.os.HandlerThread.run(HandlerThread.java:67)
03-11 16:49:15.662 445 479 D test1 : at com.android.server.ServiceThread.run(ServiceThread.java:44)
03-11 16:49:15.674 445 479 D test1 : performEnableScreen1 mDisplayEnabled:false,mForceDisplayEnabled:false,mShowingBootMessages:false,mSystemBooted:true
03-11 16:49:15.674 445 479 D test1 : java.lang.Exception
03-11 16:49:15.674 445 479 D test1 : at com.android.server.wm.WindowManagerService.performEnableScreen(WindowManagerService.java:3432)
03-11 16:49:15.674 445 479 D test1 : at com.android.server.wm.WindowManagerService.access$1100(WindowManagerService.java:317)
03-11 16:49:15.674 445 479 D test1 : at com.android.server.wm.WindowManagerService$H.handleMessage(WindowManagerService.java:4991)
03-11 16:49:15.674 445 479 D test1 : at android.os.Handler.dispatchMessage(Handler.java:106)
03-11 16:49:15.674 445 479 D test1 : at android.os.Looper.loop(Looper.java:223)
03-11 16:49:15.674 445 479 D test1 : at android.os.HandlerThread.run(HandlerThread.java:67)
03-11 16:49:15.674 445 479 D test1 : at com.android.server.ServiceThread.run(ServiceThread.java:44)
03-11 16:49:15.684 445 479 D test1 : performEnableScreen2:
03-11 16:49:15.684 445 479 D test1 : java.lang.Exception
03-11 16:49:15.684 445 479 D test1 : at com.android.server.wm.WindowManagerService.performEnableScreen(WindowManagerService.java:3463)
03-11 16:49:15.684 445 479 D test1 : at com.android.server.wm.WindowManagerService.access$1100(WindowManagerService.java:317)
03-11 16:49:15.684 445 479 D test1 : at com.android.server.wm.WindowManagerService$H.handleMessage(WindowManagerService.java:4991)
03-11 16:49:15.684 445 479 D test1 : at android.os.Handler.dispatchMessage(Handler.java:106)
03-11 16:49:15.684 445 479 D test1 : at android.os.Looper.loop(Looper.java:223)
03-11 16:49:15.684 445 479 D test1 : at android.os.HandlerThread.run(HandlerThread.java:67)
03-11 16:49:15.684 445 479 D test1 : at com.android.server.ServiceThread.run(ServiceThread.java:44)
03-11 16:49:15.690 445 479 D test1 : performEnableScreen1 mDisplayEnabled:false,mForceDisplayEnabled:false,mShowingBootMessages:false,mSystemBooted:true
03-11 16:49:15.690 445 479 D test1 : java.lang.Exception
03-11 16:49:15.690 445 479 D test1 : at com.android.server.wm.WindowManagerService.performEnableScreen(WindowManagerService.java:3432)
03-11 16:49:15.690 445 479 D test1 : at com.android.server.wm.WindowManagerService.access$1100(WindowManagerService.java:317)
03-11 16:49:15.690 445 479 D test1 : at com.android.server.wm.WindowManagerService$H.handleMessage(WindowManagerService.java:4991)
03-11 16:49:15.690 445 479 D test1 : at android.os.Handler.dispatchMessage(Handler.java:106)
03-11 16:49:15.690 445 479 D test1 : at android.os.Looper.loop(Looper.java:223)
03-11 16:49:15.690 445 479 D test1 : at android.os.HandlerThread.run(HandlerThread.java:67)
03-11 16:49:15.690 445 479 D test1 : at com.android.server.ServiceThread.run(ServiceThread.java:44)
03-11 16:49:15.944 445 479 D test1 : performEnableScreen1 mDisplayEnabled:false,mForceDisplayEnabled:false,mShowingBootMessages:false,mSystemBooted:true
03-11 16:49:15.944 445 479 D test1 : java.lang.Exception
03-11 16:49:15.944 445 479 D test1 : at com.android.server.wm.WindowManagerService.performEnableScreen(WindowManagerService.java:3432)
03-11 16:49:15.944 445 479 D test1 : at com.android.server.wm.WindowManagerService.access$1100(WindowManagerService.java:317)
03-11 16:49:15.944 445 479 D test1 : at com.android.server.wm.WindowManagerService$H.handleMessage(WindowManagerService.java:5114)
03-11 16:49:15.944 445 479 D test1 : at android.os.Handler.dispatchMessage(Handler.java:106)
03-11 16:49:15.944 445 479 D test1 : at android.os.Looper.loop(Looper.java:223)
03-11 16:49:15.944 445 479 D test1 : at android.os.HandlerThread.run(HandlerThread.java:67)
03-11 16:49:15.944 445 479 D test1 : at com.android.server.ServiceThread.run(ServiceThread.java:44)
03-11 16:49:15.947 445 479 D test1 : performEnableScreen3:
03-11 16:49:15.947 445 479 D test1 : java.lang.Exception
03-11 16:49:15.947 445 479 D test1 : at com.android.server.wm.WindowManagerService.performEnableScreen(WindowManagerService.java:3477)
03-11 16:49:15.947 445 479 D test1 : at com.android.server.wm.WindowManagerService.access$1100(WindowManagerService.java:317)
03-11 16:49:15.947 445 479 D test1 : at com.android.server.wm.WindowManagerService$H.handleMessage(WindowManagerService.java:5114)
03-11 16:49:15.947 445 479 D test1 : at android.os.Handler.dispatchMessage(Handler.java:106)
03-11 16:49:15.947 445 479 D test1 : at android.os.Looper.loop(Looper.java:223)
03-11 16:49:15.947 445 479 D test1 : at android.os.HandlerThread.run(HandlerThread.java:67)
03-11 16:49:15.947 445 479 D test1 : at com.android.server.ServiceThread.run(ServiceThread.java:44)
**可以看出:
分别来看一下这三个调用的地方
1,ActivityTaskManagerService的 5658行即postFinishBooting
在FallbackHome resume的时候,会添加一个 IdleHandler
@Override
public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
String reason) {
//......
Looper.myQueue().addIdleHandler(new Idler());
}
没有Message消息时,执行此IdleHandler
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 {
am.activityIdle(a.token, a.createdConfig, stopProfiling);
a.createdConfig = null;
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
//......
进而调用到ActivityTaskManagerService的activityIdle函数中,调用栈如下
activityIdle Name:com.android.settings.FallbackHome
03-11 16:49:15.628 445 1059 D test1 : java.lang.Exception
03-11 16:49:15.628 445 1059 D test1 : at com.android.server.wm.ActivityTaskManagerService.activityIdle(ActivityTaskManagerService.java:1807)
03-11 16:49:15.628 445 1059 D test1 : at android.app.IActivityTaskManager$Stub.onTransact(IActivityTaskManager.java:1920)
03-11 16:49:15.628 445 1059 D test1 : at android.os.Binder.execTransactInternal(Binder.java:1159)
03-11 16:49:15.628 445 1059 D test1 : at android.os.Binder.execTransact(Binder.java:1123)
通过一步步的调用,最终调用到postFinishBooting,调用信息如下
activityIdle
mStackSupervisor.activityIdleInternal(r, false /* fromTimeout */,false /* processPausingActivities */, config);
checkFinishBootingLocked
mService.postFinishBooting(booting, enableScreen);
mInternal.enableScreenAfterBoot(isBooted());
mWindowManager.enableScreenAfterBoot();
performEnableScreen();
2,WindowManagerService 的 4991行
在4991行是接收到ENABLE_SCREEN的消息,然后执行performEnableScreen
case ENABLE_SCREEN: {
performEnableScreen();
break;
}
在enableScreenIfNeeded 方法中发送消息
@Override
public void enableScreenIfNeeded() {
synchronized (mGlobalLock) {
enableScreenIfNeededLocked();
}
}
void enableScreenIfNeededLocked() {
//......
if (mDisplayEnabled) {
return;
}
if (!mSystemBooted && !mShowingBootMessages) {
return;
}
mH.sendEmptyMessage(H.ENABLE_SCREEN);
}
enableScreenIfNeeded 在PhoneWindowManager中被调用
private void finishScreenTurningOn() {
//......
if (enableScreen) {
try {
mWindowManager.enableScreenIfNeeded();
} catch (RemoteException unhandled) {
}
}
}
在所有的windows都绘制完成之后,发送MSG_WINDOW_MANAGER_DRAWN_COMPLETE消息,最终调用到finishScreenTurningOn
3,WindowManagerService的5114行
调用checkBootAnimationCompleteLocked ,如果开机完成则调用performEnableScreen
case CHECK_IF_BOOT_ANIMATION_FINISHED: {
final boolean bootAnimationComplete;
synchronized (mGlobalLock) {
ProtoLog.i(WM_DEBUG_BOOT, "CHECK_IF_BOOT_ANIMATION_FINISHED:");
bootAnimationComplete = checkBootAnimationCompleteLocked();
}
if (bootAnimationComplete) {
performEnableScreen();
}
break;
}