1.注册(init.rc)
service bootanim /system/bin/bootanimation
class core
user graphics
# group graphics audio ####
group graphics media audio ####
disabled
oneshot
2.启动
void SurfaceFlinger::startBootAnim() {//启动开机动画
#ifdef MTK_AOSP_ENHANCEMENT
// dynamic disable/enable boot animation
checkEnableBootAnim();
#else
// start boot animation
property_set("service.bootanim.exit", "0");
property_set("ctl.start", "bootanim");
#endif
}
void SurfaceFlinger::bootFinished()//关闭开机动画
{
const nsecs_t now = systemTime();
const nsecs_t duration = now - mBootTime;
ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
mBootFinished = true;
// wait patiently for the window manager death
const String16 name("window");
sp<IBinder> window(defaultServiceManager()->getService(name));
if (window != 0) {
window->linkToDeath(static_cast<IBinder::DeathRecipient*>(this));
}
// 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.
property_set("service.bootanim.exit", "1");
#ifdef MTK_AOSP_ENHANCEMENT
// boot time profiling
ALOG(LOG_INFO,"boot","BOOTPROF:BootAnimation:End:%ld", long(ns2ms(systemTime())));
bootProf(0);
SFWatchDog::getInstance()->setThreshold(500);
#endif
}
3.动画加载
BootAnimation_main.cpp
int main(int argc, char** argv)
{
#if defined(HAVE_PTHREADS)
setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_DISPLAY);
#endif
char value[PROPERTY_VALUE_MAX];
property_get("debug.sf.nobootanimation", value, "0");
int noBootAnimation = atoi(value);
if(noBootAnimation != 0) {
ALOGI_IF(noBootAnimation, "boot animation disabled");
}
XLOGD("[BootAnimation %s %d]noBootAnimation=%d",__FUNCTION__,__LINE__,noBootAnimation);
if (!noBootAnimation) {
sp<ProcessState> proc(ProcessState::self());
ProcessState::self()->startThreadPool();
// create the boot animation object
bool setBoot = true;
bool setRotated = false;
bool sePaly = true;
if(argc > 1){
if(!strcmp(argv[1],"shut"))
setBoot = false;
}
if(argc > 2){
if(!strcmp(argv[2],"nomp3"))
sePaly = false;
}
if(argc > 3){
if(!strcmp(argv[3],"rotate"))
setRotated = true;
}
XLOGD("[BootAnimation %s %d]setBoot=%d,sePaly=%d,setRotated=%d",__FUNCTION__,__LINE__,setBoot,sePaly,setRotated);
char volume[PROPERTY_VALUE_MAX];
property_get("persist.sys.mute.state", volume, "-1");
int nVolume = -1;
nVolume = atoi(volume);
XLOGD("[BootAnimation %s %d]nVolume=%d",__FUNCTION__,__LINE__,nVolume);
if(nVolume == 0 || nVolume == 1 ){
sePaly = false;
}
XLOGD("before new BootAnimation...");
XLOGD("[BootAnimation %s %d]before new BootAnimation...",__FUNCTION__,__LINE__);
sp<BootAnimation> boot = new BootAnimation(setBoot,sePaly,setRotated);
XLOGD("joinThreadPool...");
XLOGD("[BootAnimation %s %d]before joinThreadPool...",__FUNCTION__,__LINE__);
IPCThreadState::self()->joinThreadPool();
XLOGD("exit boot animation...");
XLOGD("[BootAnimation %s %d]after joinThreadPool...",__FUNCTION__,__LINE__);
}
XLOGD("[BootAnimation %s %s %d]end",__FILE__,__FUNCTION__,__LINE__);
return 0;
BootAnimation.cpp
bool BootAnimation::threadLoop()
{
bool r;
// We have no bootanimation file, so we use the stock android logo
// animation.
sp<MediaPlayer> mediaplayer;
char* resourcePath = initAudioPath();
status_t mediastatus = NO_ERROR;
if (resourcePath != NULL) {
XLOGD("sound file path: %s", resourcePath);
mediaplayer = new MediaPlayer();
mediastatus = mediaplayer->setDataSource(NULL, resourcePath, NULL);
if (mediastatus == NO_ERROR) {
mediaplayer->setAudioStreamType(AUDIO_STREAM_BOOT);
mediastatus = mediaplayer->prepare();
}
if (mediastatus == NO_ERROR) {
mediastatus = mediaplayer->start();
}
}
if (mZip == NULL) {
r = android();//安卓原始动画
} else {
if (!bMTKMovie) {
XLOGD("threadLoop() movie()");
r = movie();
} else {
XLOGD("threadLoop() MTKmovie()");
r = MTKmovie();
}
}
if (resourcePath != NULL) {
if (mediastatus == NO_ERROR) {
mediaplayer->stop();
mediaplayer->disconnect();
mediaplayer.clear();
}
}
eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
eglDestroyContext(mDisplay, mContext);
eglDestroySurface(mDisplay, mSurface);
mFlingerSurface.clear();
mFlingerSurfaceControl.clear();
eglTerminate(mDisplay);
IPCThreadState::self()->stopProcess();
return r;
}
红色部分就是Android具体加载动画的地方,当service.bootanim.exit为1的时候退出动画