Android开关机动画/铃音是如何播放的?

来源:互联网 发布:qq三国奥义天赋点算法 编辑:程序博客网 时间:2024/05/22 09:03
1. 开关机动画的启动

Android系统在init.rc中定义了很多Service,具体定义格式可以参考《Android Platform Developer’s Guide》中的“Android Init Language”。init.rc中定义的Service将会被init进程创建,其中已经定义的服务就包含了开机动画.

每一项服务必须在/init.rc中定义Android系统启动时,init守护进程将解析init.rc和启动属性服务,属性“ctl.start”和“ctl.stop”是用来启动和停止服务的。一旦收到设置“ctrl.start”属性的请求,属性服务将使用该属性值作为服务名找到该服务,启动该服务。这项服务的启动结果将会放入“ init.svc.<服务名>“属性中 。客户端应用程序可以轮询那个属性值,以确定结果。

servicebootanim /system/bin/bootanimation    usergraphics    groupgraphics    disabled    oneshot//定义了一个bootanim的服务,对应执行/system/bin/bootanimation//disabled 表示init进程创建只是创建它,但不立刻执行//oneshot 表示该服务只执行一次

当android系统boot时,开始加载动画和开机铃声,其代码位于

//源文件SurfaceFlinger.cpp

status_tSurfaceFlinger::readyToRun(){    // start boot animation service    property_set("ctl.start", "bootanim");//}

当Android完成boot后,关闭动画和开机铃声,代码位于

//源文件SurfaceFlinger.cpp

voidSurfaceFlinger::bootFinished(){    //stop bootanim service    property_set("ctl.stop", "bootanim");}

在Android系统中,长按Power键默认会弹出对话框让你选择“飞行模式”,“静音”,“关机”等功能。

选择”关机“,弹出“设备将要关机”选择对话框。可以选择“是”关机,和“否”返回系统。

从代码中我们可以看出,如果选择上述对话框的“关机”选项之后,将会调用ShutdownThread.java的shutdown方法来关机。shutdown方法的第二个参数标识是否弹出询问对话框。

 ShutdownThread代码位于

frameworks/base/core/java/com/android/internal/app/ShutdownThread.java

shutdown方法中有如下代码

publicstatic void shutdown(final Context context, boolean confirm){    ….    beginShutdownSequence(context);    ….}beginShutdownSequence(context)-》startBootAnimation():   privatestatic void startBootAnimation(){        if (bPlayaudio) {            SystemProperties.set("ctl.start","bootanim:shutmp3");            Log.d(TAG, "bootanim:shutmp3" );        } else {            SystemProperties.set("ctl.start","bootanim:shutnomp3");            Log.d(TAG, "bootanim:shutnomp3" );       }    }
从上述分析可知,开关机动画的启动/停止都会设置ctl.start bootanim property来,最终通过bootanimation service来实现的。

这样就转入 bootanimation这个service来真正处理开关机动画和铃声。

注:可以用setprop ctl.startbootanim:shut 命令动态启动bootanimation service

 

2. bootanimationservice详解

bootanimationservice 的代码所在位置:/frameworks/base/cmds/bootanimation, 主要有两个文件:

bootanimation_main.cpp

bootAnimation.cpp

 bootanimation_main.cpp是主入口文件:

int main(intargc, char** argv){       // ...        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;              }        // ...        sp<BootAnimation>boot = new BootAnimation(setBoot,sePaly,setRotated);        XLOGD("joinThreadPool...");        IPCThreadState::self()->joinThreadPool();        XLOGD("exit bootanimation...");    }    return 0;}
其主要的功能是根据传进来的参数决定是是要播放开机还是关机动画/铃音,并且启动BootAnimation:

BootAnimation.cpp集成自Thread,在创建时会调用readyToRun()->threadLoop():

status_tBootAnimation::readyToRun() {……………………………………mAndroidAnimation = false;       if(bBootOrShutDown){    status_terr = mZip.open("/data/local/bootanimation.zip");    if(err != NO_ERROR) {       err =mZip.open("/system/media/bootanimation.zip");       if (err != NO_ERROR) {           mAndroidAnimation = true;       }    }       }else {           if(!bShutRotate){              status_terr = mZip.open("/data/local/shutanimation.zip");          if (err != NO_ERROR) {              err= mZip.open("/system/media/shutanimation.zip");              if (err != NO_ERROR) {                  mAndroidAnimation = true;              }              }           }       }return NO_ERROR;}
readyToRun() 方法判断/system/media/bootanimation.zip(shutanimaion.zip)是否存在,如果存在,则将 mAndroidAnimation 设置false,这个变量决定threadLoop中调用android()还是movie()来具体实现动画的播放。
boolBootAnimation::threadLoop(){        //  …................       if(!bBootOrShutDown){              pSoundFileName="/data/local/shutaudio.mp3";              pBackupSoundFileName="/system/media/shutaudio.mp3";       } else {              pSoundFileName="/data/local/bootaudio.mp3";         pBackupSoundFileName="/system/media/bootaudio.mp3";       }           …...............           mediastatus =mediaplayer->setDataSource(pBackupSoundFileName, NULL);           mediaplayer->setAudioStreamType(AudioSystem::BOOT);           mediastatus = mediaplayer->prepare();           mediaplayer->setAudioStreamType(AudioSystem::BOOT);           mediastatus =mediaplayer->prepare();           mediaplayer->setVolume(0.28,0.28);           mediastatus =mediaplayer->start();             …..........................           if (mAndroidAnimation)          r = android();            } else {           r = movie();           }}
threadLoop首先判断system/media/bootaudio.mp3(shutaudio.mp3)文件是否存在,如果存在则调用mediaplayer的接口播放(setdatasoruce,prepare,setvolume,start)。

然后根据 mAndroidAnimation 变量调用android()/movie(). 如果system/media/shutanimation.zip/bootanimation.zip存在的话,调用movie(),该接口会解析zip文件中的desc.txt文件,根据txt文件中的配置来播放动画。