文章初始给大家推荐一篇文章https://blog.csdn.net/xlnaan/article/details/80904309#commentBox
上篇文章已经分析到开机动画的两种播放形式了https://blog.csdn.net/we1less/article/details/116464874
首先以android()方式播放
android() AOSP/frameworks/base/cmds/bootanimation/BootAnimation.cpp
bool BootAnimation::android()
{
{
…
checkExit();
} while (!exitPending());
…
return false;
}
这里可以看到在开机动画播放的循环当中以checkExit()判断终止循环播放
void BootAnimation::checkExit() {
// Allow surface flinger to gracefully request shutdown
char value[PROPERTY_VALUE_MAX];
property_get(EXIT_PROP_NAME, value, “0”);
int exitnow = atoi(value);
if (exitnow) {
requestExit();
mCallbacks->shutdown();
}
}
关于这个requestExit() 和exitPending()可以参考https://blog.csdn.net/llping2011/article/details/9706599 大致意思就是调用requestExit() ExitexitPending()就会返回true
可以在这看出 退出循环的标志就是 EXIT_PROP_NAME 的值 默认是0
static const char EXIT_PROP_NAME[] = “service.bootanim.exit”;
可以查询一下这个属性到底在哪做过设置
godv@godv-OptiPlex-7070:~/godv/AOSP/android-8.1.0_r1/frameworks$ grep “service.bootanim.exit” ./ -rn
./native/services/surfaceflinger/SurfaceFlinger_hwc1.cpp:341: property_set(“service.bootanim.exit”, “1”);
./native/services/surfaceflinger/StartPropertySetThread.cpp:33: property_set(“service.bootanim.exit”, “0”);
./native/services/surfaceflinger/SurfaceFlinger.cpp:388: property_set(“service.bootanim.exit”, “1”);
./base/cmds/bootanimation/BootAnimation.cpp:93:static const char EXIT_PROP_NAME[] = “service.bootanim.exit”;
./base/cmds/bootanimation/FORMAT.md:77:the system property service.bootanim.exit
to a nonzero string.)
./base/services/core/java/com/android/server/wm/WindowManagerService.java:3509: SystemProperties.set(“service.bootanim.exit”, “1”);
可以看出 service.bootanim.exit 这个属性在 SurfaceFlinger.cpp:388 和 WindowManagerService.java:3509 出现过
开机动画停止过程:
1.应用启动后,调用到activityThread中的handleResumeActivity,这个方法会发送一个Idler消息
if (!r.onlyLocalRequest) {
r.nextIdle = mNewActivities;
mNewActivities = r;
if (localLOGV) Slog.v(
TAG, "Scheduling idle handler for " + r);
Looper.myQueue().addIdleHandler(new Idler());
}
2.Idler消息中通过 am.activityIdle调用到activityManagerServer中的activityIdle方法
if (a.activity != null && !a.activity.mFinished) {
try {
am.activityIdle(a.token, a.createdConfig, stopProfiling);
a.createdConfig = null;
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
3.frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
ActivityManagerService中会调用mStackSupervisor.activityIdleInternalLocked的方法
ActivityRecord r =
mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout /,
false / processPausingActivities */, config);
4.activityIdleInternalLocked通过checkFinishBootingLocked方法调用postFinishBooting–>enableScreenAfterBoot();
if (isFocusedStack(r.getStack()) || fromTimeout) {
booting = checkFinishBootingLocked();
}
private boolean checkFinishBootingLocked() {
final boolean booting = mService.mBooting;
boolean enableScreen = false;
mService.mBooting = false;
if (!mService.mBooted) {
mService.mBooted = true;
enableScreen = true;
}
if (booting || enableScreen) {
mService.postFinishBooting(booting, enableScreen);
}
return booting;
}
void enableScreenAfterBoot() {
void enableScreenAfterBoot() {
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
SystemClock.uptimeMillis());
mWindowManager.enableScreenAfterBoot();
synchronized (this) {
updateEventDispatchingLocked();
}
}
5.frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
通过enableScreenAfterBoot就回到了WindowManagerService,WindowManagerService中的enableScreenAfterBoot–>performEnableScreen
停止动画的代码就在performEnableScreen中,同时设置SystemProperties和surfaceFlinger 中的service.bootanim.exit为1,
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) {
Slog.i(TAG_WM, “******* 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);
data.recycle();
}
} catch (RemoteException ex) {
Slog.e(TAG_WM, “Boot completed: SurfaceFlinger is dead!”);
}