开机关机动画工作流程

一,开机画面切换过程

(1) Linux 系统启动,出现Linux小企鹅画面(由内核实现)。 (2) Android平台启动初始化,出现"A N D R I O D"文字字样画面。 (3) Android平台上层图形系统启动,出现含闪动的ANDROID字样的动画图片(start)。

二,(2)和(3)启动运行的过程

(1) Android 系统启动后,init.c中main()调用load_565rle_image()函数读取/initlogo.rle(一张565 rle压缩的位图),如果读取成功,则在/dev/graphics/fb0显示Logo图片;如果读取失败,则将/dev/tty0设为TEXT模式,并打开/dev/tty0,输出文本“A N D R I O D”字样。E8,E9已经将此部分会直接路过,E8直接注释此过程 相应代码如下:
        
  1. staticintconsole_init_action(intnargs,char**args)
  2. {
  3. intfd;
  4. chartmp[PROP_VALUE_MAX];
  5. if(console[0]){
  6. snprintf(tmp,sizeof(tmp),"/dev/%s",console);
  7. console_name=strdup(tmp);
  8. }
  9. fd=open(console_name,O_RDWR);
  10. if(fd>=0)
  11. have_console=1;
  12. close(fd);
  13. /*
  14. //查看init.h文件
  15. //#defineINIT_IMAGE_FILE"/initlogo.rle"
  16. //ADBSHELL查看根目录没有此张图片
  17. //加载initlogo.rle文件
  18. if(load_rle_image(INIT_IMAGE_FILE)){
  19. //此时fd是/dev/tty0对应的是输出端口
  20. //tty1表示输入端口,tty2貌似表示错误信息
  21. fd=open("/dev/tty0",O_WRONLY);//将/dev/tty0设为text模式
  22. if(fd>=0){
  23. constchar*msg;
  24. msg="\n"
  25. "\n"
  26. "\n"
  27. "\n"
  28. "\n"
  29. "\n"
  30. "\n"//consoleis40colsx30lines
  31. "\n"
  32. "\n"
  33. "\n"
  34. "\n"
  35. "\n"
  36. "\n"
  37. "\n"
  38. "ANDROID";
  39. write(fd,msg,strlen(msg));
  40. close(fd);//关闭接口
  41. }
  42. }
  43. */
  44. return0;
  45. }
相关代码:
        
  1. system/core/init/init.c
  2. system/core/init/init.h
  3. system/core/init/init.rc
  4. system/core/init/logo.c
*.rle文件的制作步骤:
        
  1. a.使用GIMP或者AdvancedBatchConverter软件,将图象转换为RAW格式;
  2. b.使用android自带的rgb2565工具,将RAW格式文件转换为RLE格式(如:rgb2565-rle<initlogo.raw>initlogo.rle)。
  3. 注:修改这几个地方的代码编译过后要重新烧写recovery,boot
(2),开机动画(闪动的ANDROID字样的动画图片) 我们最主要经常要修改的这是这部内容,这里包含两种动画类型: 1,第一种类似于Windows系统的滚动条,是由前景和背景两张PNG图片组成,对应原文件位于frameworks/base/core/res/assets/images/。前景图片(android-logo-mask.png)上的Android文字部分镂空,背景图片(android-logo-shine.png)则是简单的纹理。系统登录时,前景图片在最上层显示,程序代码(BootAnimation.android())控制背景图片连续滚动,透过前景图片文字镂空部分滚动显示背景纹理,从而实现动画效果。 图片1: 前景图片 图片2: 背景图片 2,制件开机动画包,开机动画服务程序启动以后会先在系统指定目录检查此包是否存在,如果存在,系统将执行此包中的动画,如果检查系统不存在此包,此时系统才会去按第一方式播放动画,这里包中的内容是通过一张一张图片连续播放来实现动画效果的,最后要生成一个类似bootanimation.zip的包 3,执行过程,init.c解析init.rc(其中定义服务:“service bootanim /system/bin/bootanimation”),bootanim服务由SurfaceFlinger.readyToRun()(property_set("ctl.start", "bootanim");)执行开机动画、bootFinished()(property_set("ctl.stop", "bootanim");)执行停止开机动画。 BootAnimation.h和BootAnimation.cpp文件放在了/frameworks/base/cmds/bootanimation目录下了,增加了一个入口文件bootanimation_main.cpp。Android.mk文件中可以看到,将开机动画从原来的SurfaceFlinger里提取出来了,生成可执行文件:bootanimation。 Android.mk代码如下: //=============Android.mk====================== LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES:= / bootanimation_main.cpp / BootAnimation.cpp # need "-lrt" on Linux simulator to pick up clock_gettime ifeq ($(TARGET_SIMULATOR),true) ifeq ($(HOST_OS),linux) LOCAL_LDLIBS += -lrt endif endif LOCAL_SHARED_LIBRARIES := / libcutils / libutils / libui / libcorecg / libsgl / libEGL / libGLESv1_CM / libmedia LOCAL_C_INCLUDES := / $(call include-path-for, corecg graphics) LOCAL_MODULE:= bootanimation include $(BUILD_EXECUTABLE) //========================================== 开机动画第一个入口:bootanimation_main.cpp int main(int argc, char** argv) { ….......... if (!noBootAnimation) { sp<ProcessState> proc(ProcessState::self()); ProcessState::self()->startThreadPool(); //初始化开机动画,开始播放开机动画.booted传下去的开机操作还是关机操作的参数 sp<BootAnimation> boot = new BootAnimation(booted); //初始化开机声音,开始播放开机声音.这个类是根据开机动画自定义的,可根据需求自行修改删除 sp<BootAnimationSound> bootsound = new BootAnimationSound(booted); IPCThreadState::self()->joinThreadPool(); } } 根据bootanimation_main.cpp将会初始化 BootAnimation类.下面我们来查看 BootAnimation.cpp文件.通过BootAnimation 构造函数来初始化 sbootanimation变量.根据sbootanimation来实现开关机播放不同的动画.判断开机还是关机可通过上面传过来的参数确定 BootAnimation::BootAnimation(bool shutdownAnimation) : Thread(false) { mSession = new SurfaceComposerClient(); mShutdownAnimation = shutdownAnimation; //权宜之计 if (mShutdownAnimation) { // 关机时播放的动画包 mSession->setOrientation(0, 0, 0); sprintf(sbootanimation, "/system/media/shutdownanimation.zip"); }else{ // 开机时播放的动画包 sprintf(sbootanimation, "/system/media/bootanimation.zip"); } } 此处可以看到 sbootanimation定义是一个zip包路径,通过这个我们可以知道,如果要通过第二种方法实现开关机动画可将制作的zip包放在/system/media/目录下文件名一致便可以了,后面会给出制作zip包的方法。如果是用第一种方法只需修改上面提到的两个图片即可。 mSession->setOrientation(0, 0, 0);此条语句是关机强制横屏,修改可通过第二个参数修改.值分别对应(0->0度,1->90度,2->180度,3->270度,)具体可修改查看效果 根据mAndroidAnimation的值来确定是播放第一种动画效果还是第二种动画效果 BootAnimation::threadLoop() if (mAndroidAnimation) { r = Android(); // 执行android字体闪动的图片 } else { r = movie(); // 执行bootanimation.zip中提供的动画图片 } ==> BootAnimation::Android()会加载"images/android-logo-mask.png"和"images/android-logo-shine.png" ==> BootAnimation::movie()会加载bootanimation.zip中的内容 这里是开机动画,下面是开机音乐的代码,流程跟开机动画类型 BootAnimationSound.cpp 和开机动画一样, 初始化bootsound变量,来实现开关机播放不同的音乐,判断开机还是关机可通过上面传过来的参数确定 BootAnimationSound::BootAnimationSound(bool booted) : Thread(false) { mShutdownAnimation = booted; if (mShutdownAnimation) { // 关机时播放的声音 sprintf(bootsound, "system/media/audio/ui/power_off.mp3"); }else{ // 开机时播放的声音 sprintf(bootsound, "system/media/audio/ui/power_on.mp3"); } } 通过bootsound我们知道要将你的音频文件放在system/media/audio/ui/目录即可播放声音了,具体实现播放声音的操作看下文,比较简单, playSound类实现播放声音的。 void BootAnimationSound::playSound() { MediaPlayer* mp = new MediaPlayer(); if (mp->setDataSource(bootsound, NULL) == NO_ERROR) { /*系统启动时声音从扬声器出来,而关机时如果插耳机则会从耳机出来,所以在 * 这里强制设定。但是,这个API 涉及许可,许可服务 PermissionController * 在 ActivityManagerService 启动,而ActivityManagerService 启动时间比 * SurfaceFlinger 和 Audio 都晚,从而导致开机时动画播放一段时间才有声 * 音。所以加了此判定。 * */ if(mShutdownAnimation) { mp->setAudioStreamType(AudioSystem::ENFORCED_AUDIBLE); }else{ sleep(2); } mp->prepare(); mp->start(); /* start 之后,设置音量才有效果。 start 之前设音量没有效果的。*/ mp->setVolume(0.4, 0.4); } else { LOGE("Failed to load CameraService sounds: system/media/audio/ui/power_on_off.ogg"); } } 代码比较简单,但还是一点要特别强调在设置开关机音量的时候,执行过mp->start();以后再执行mp->setVolume(0.4, 0.4);才会有效果,这是一个很神奇的一个问题,我们徐申龙徐工通过调试很久才找到这个很操蛋的问题,注意这点会给你节省不少时间, 最后别忘了在Android.mk文件还需要引入播放声音库 LOCAL_SHARED_LIBRARIES := \ libcutils \ libutils \ libbinder \ libui \ libskia \ libEGL \ libGLESv1_CM \ libgui \ libmedia 请注意,libmedia是新添加的; bootanimation.zip包的制做 第一步,我们将png图片转换成colormap:8bit 以缩小文件占用磁盘空间 (以下是ubuntu命令,不用linux,可以用windows下的做图工具来转换图片格式): convert -type palette boot_003.jpg boot_003.convert.png 做好了图片,就需要把图片打成bootanimation.zip包了。 这个包,除了图片目录,还有一个desc.txt的文件,这个文本文件是用来告诉系统,如何使用图片目录来实现动画的。 所以有一定的语法,不过很简单: 目标屏幕宽度(480) 目标屏幕高度(800) 每次帧间隔 p 重复次数 播放完成后停顿 图片文件夹名1 p 重复次数 播放完成后停顿 图片文件夹名2 以一个desc.txt为例: 480 800 15 图片宽度480,高度800,这是我们I9000屏幕参数,最后15是播放动画的每秒帧率。就是一秒钟播放多少张图片,动画的最原始实现。小时候大家都玩过吧 p 1 0 foldername // p 是一个分隔符,1 表示播放一遍,0表示播放完后停顿 0 帧,最后是图片所在的zip包里的目录名。比如你的zip包里最后是这么个结构 // folder0(里面包含很多图片) + desc.txt, 那么你可以在这里把foldername 替换成folder0 根据这个语法,我们也可以自定义各种动画形式,例如下面所示: p 2 30 folder0 将folder0里的图片,播放2遍,播放完一遍后停顿30帧,因为我们之前设置了帧率是15帧每秒,那么这里就等于停顿2秒。 p 0 0 folder1 将folder1里的图片无限循环播放,每次播放不停顿。 如果你设置的宽度和高度不充满屏幕也没关系,剩余区域,系统会填充黑色。如果你设置的宽度和高度大过屏幕,系统会自动裁剪显示居中部分的图片区域。 4. 将转换好的图片集打包在不同的目录下, 然后把图片目录和一个描述动画的desc.txt 无压缩率格式打包成bootanimation.zip, 下面是ubuntu命令,你可以用winrar等工具,但是注意要选择无压缩率,无损压缩。另外保持压缩包后的目录结构。 zip -0 -r bootanimation.zip part0 part1 desc.txt 5. 最后将这个zip文件 拷贝到你的机器里 /data/local/bootanimation.zip 需要注意的是 如果你使用winrar进行压缩打包的话,需要设置参数如下: 压缩格式选zip 压缩方式选:存储(即不压缩)

更多相关文章

  1. 常用Android开发组件之图像类组件
  2. android ListView 中getview学习总结
  3. 写一个没有Activity的 HelloWorld for android
  4. android图片涂鸦,具有设置画笔,撤销,缩放移动等功能(一)
  5. ym—— Android(安卓)5.0学习之Activity过渡动画
  6. Android(安卓)NDK JNI 的环境搭建以及简单的代码
  7. Android(安卓)App组件之Fragment说明和示例
  8. freescale Android(安卓)Camera 调试总结
  9. Android(安卓)网络图片加载

随机推荐

  1. 【eoeAndroid社区索引】android 条形码的
  2. android 之 install Location
  3. java解析json字符串的两种方法详解(Andro
  4. Android 输入限制
  5. 非一般的原因:Unable instantiate applica
  6. 实现Android简单动画旋转案例
  7. Android用户界面 UI组件--自动提示输入框
  8. OpenCV4Android开发之旅(一)----OpenCV2.
  9. android设定手机的显示模式,横竖屏,是否全
  10. [转载]系统内置的一些工具类