安卓修改开机动画
2014-07-23 15:25
501 查看
一、概述
为了在项目中对安卓系统进行定制化,需要将其开机动画进行修改,因此,上网搜了一堆原理教程,这里就根据自己的理解进行梳理,有任何错漏,欢迎指正。
二、开机动画原理
安卓系统完整的启动过程具体如下:
1. 启动BootLoader
2. 加载系统内核
3. 启动Init和其它重要守护进程
4. 启动Zygote进程
5. 启动Runtime进程,初始化Service Manager。启动SystemService
6. 启动HomeLaucher
7. 启动其它应用程序
这里我们要关注的是第3点,启动Init和其它重要守护进程。
在系统内核加载完成之后,系统启动第一个用户进程,即Init进程。Init进程一启动就根据init.rc和init.hardware.rc(hardware为具体硬件名称)脚本文件执行需要启动的命令及服务。
在init.rc启动服务过程中,直接启动了一个SurfaceFlinger服务。SurfaceFlinger服务用于管理安卓系统应用端所有的surface,每个应用相当于客户端,surfaceFlinger相当于服务端,客户端完成图形处理之后,请求SurfaceFlinger显示到屏幕上。
启动surfaceFlinger的过程中,调用了开机动画的应用程序bootanim,使得开机动画能够进行显示;当启动结束时,surfaceFlinger会请求bootanim退出,然后开机过程结束。
这里的启动过程就是如上所述的那样,下面看看源码是如何写的。
1、init.rc启动SurfaceFlinger服务
代码位置:\android42\device\softwinner\wing-common\init.rc(该源码为cubieboard2配套源码,下同)。
这部分代码设置了surfaceflinger在init进程中启动及启动surfaceflinger。具体细节如下:
1)设置surfaceflinger在init进程中启动
在android系统中核心的Service(如surfaceFlinger)都由ServiceManager管理,核心Service启动一般是在SystemServer来启动。而这里的setprop语句用于设置属性值,将system_init.startsurfaceflinger设置为0时,表示系统将在init进程中启动surfaceflinger,不需要再SystemServer中启动。
可参考SystemServer启动SurfaceFlinger服务的代码:
代码位置:\android42\frameworks\base\cmds\system_server\library\system_init.cpp
2)Init.rc启动surfaceflinger
该部分脚本代码遵循Android Init Language规范,该规范可参考官网中http://www.kandroid.org/online-pdk/guide/bring_up.html的介绍,或者在android42\system\core\init\ReadMe.txt中。
这里定义了surfaceflinger为init进程中的一个服务及其相应的文件位置,并将其归为main类,在此类中,所有服务同时启动。在surfaceflinger服务重新启动时,重启zygote服务。
2、启动surfaceFlinger服务。
入口函数源码位于:
android42\frameworks\native\cmds\surfaceflinger\main_surfaceflinger.cpp
该部分将SurfaceFlinger服务在ServiceManager中进行注册并启动。
在surfaceFlinger服务启动之后,它会调用startBootAnim()来启动开机动画。
代码位置:
android42\frameworks\native\services\surfaceflinger\SurfaceFlinger.cpp
其中startBootAnim()通过ctl.start启动bootanim的应用程序。
在bootFinished()中通过service.bootanim.exit请求bootanim自动退出。
此外,在adb shell中,可通过命令“setprop ctl.start bootanim”启动开机动画;命令“setprop ctl.stop bootanim”停止开机动画。
3、运行bootanim应用程序。
具体bootanim应用程序的源码位于:
android42\frameworks\base\cmds\bootanimation\
包括:bootanimation_main.cpp(应用程序入口),BootAnimation.cpp(应用程序实现),BootAnimation.h(头文件)。
在bootanimation_main.cpp中,实现了与SurfaceFlinger的绑定并启动开机动画实现的应用程序。源代码如下:
在main函数中,首先获取init.rc/build.prop中debug.sf.nobootanimation的值是否为0。该值为0则执行开机动画程序,该值为1则不执行。默认情况下该文件中没有这个属性,在该函数中,当没有这个属性时,获取到的值将其设置为0。即系统是默认执行开机动画程序。
开机动画应用程序源码为BootAnimation.cpp,具体如下:
具体开机动画控制的相关函数,可参考具体代码。
从代码中可以看出:为了显示自定义的开机动画效果,需要确保:
1)init.rc/build.prop中没有debug.sf.nobootanimation属性,或者该属性值为0。
2)/data/local/或者/system/media/文件夹中有bootanimation.zip。
4、bootanimation.zip说明。
此处对bootanimation.zip进行说明,里面的内容是:
注意:此处不能有上层文件夹。
其中,desc.txt的文本内容为
第一行:数字的含义分别是屏幕宽度,屏幕长度,帧数(每秒多少帧);
第二行:第一项是标识符,p表示该行是该animation的一个part;
第二项是循环次数,1表示循环一次,0表示无限循环;
第三项是两次循环之间的间隔时间;
第四项是对应的目录名。
压缩是需要用存储的方式,否则程序无法读取内容。
1.windows使用winrar打包,选择ZIP 格式,压缩标准要选“储存”;
2. linux下,zip -0 -r ../bootanimation.zip ./*
linux命令使用-0 指定压缩等级为最低等级stored,即只归档不压缩,否则可能由于包格式问题引起动画显示为黑屏。
此外还应注意打包之后需要修改其运行权限,否则无法正常显示。
在shell中运行:chmod 777 bootanimation.zip
三、在CubieBoard2上修改步骤
参照《A10_android内容定制说明文档V2.1》上的说明,压缩相应的动画文件bootanimation.zip并进行权限修改,存放在\android42\device\softwinner\smfy-super3\media\目录下,进行系统编译,固件下载。
此外,也可以将bootanimation.zip存放在系统的/data/local/或者/system/media/文件夹中,无需编译即可实现开机动画效果。
四、参考文档
《android从init到开机动画启动关闭流程一简易图》
《Android 启动过程详解》
《android系统启动过程》
《Android系统启动过程剖析》
《Android4.2.2SurfaceFlinger启动流程详解》
《学习SurfaceFlinger》
《A10_android内容定制说明文档V2.1》
为了在项目中对安卓系统进行定制化,需要将其开机动画进行修改,因此,上网搜了一堆原理教程,这里就根据自己的理解进行梳理,有任何错漏,欢迎指正。
二、开机动画原理
安卓系统完整的启动过程具体如下:
1. 启动BootLoader
2. 加载系统内核
3. 启动Init和其它重要守护进程
4. 启动Zygote进程
5. 启动Runtime进程,初始化Service Manager。启动SystemService
6. 启动HomeLaucher
7. 启动其它应用程序
这里我们要关注的是第3点,启动Init和其它重要守护进程。
在系统内核加载完成之后,系统启动第一个用户进程,即Init进程。Init进程一启动就根据init.rc和init.hardware.rc(hardware为具体硬件名称)脚本文件执行需要启动的命令及服务。
在init.rc启动服务过程中,直接启动了一个SurfaceFlinger服务。SurfaceFlinger服务用于管理安卓系统应用端所有的surface,每个应用相当于客户端,surfaceFlinger相当于服务端,客户端完成图形处理之后,请求SurfaceFlinger显示到屏幕上。
启动surfaceFlinger的过程中,调用了开机动画的应用程序bootanim,使得开机动画能够进行显示;当启动结束时,surfaceFlinger会请求bootanim退出,然后开机过程结束。
这里的启动过程就是如上所述的那样,下面看看源码是如何写的。
1、init.rc启动SurfaceFlinger服务
代码位置:\android42\device\softwinner\wing-common\init.rc(该源码为cubieboard2配套源码,下同)。
# Set this property so surfaceflinger is not started by system_init setprop system_init.startsurfaceflinger 0 service surfaceflinger /system/bin/surfaceflinger class main user system group graphics drmrpc onrestart restart zygote
这部分代码设置了surfaceflinger在init进程中启动及启动surfaceflinger。具体细节如下:
1)设置surfaceflinger在init进程中启动
在android系统中核心的Service(如surfaceFlinger)都由ServiceManager管理,核心Service启动一般是在SystemServer来启动。而这里的setprop语句用于设置属性值,将system_init.startsurfaceflinger设置为0时,表示系统将在init进程中启动surfaceflinger,不需要再SystemServer中启动。
可参考SystemServer启动SurfaceFlinger服务的代码:
代码位置:\android42\frameworks\base\cmds\system_server\library\system_init.cpp
extern "C" status_t system_init() { … char propBuf[PROPERTY_VALUE_MAX]; //获取init.rc中的system_init.startsurfaceflinger属性。 //若该属性为1,则启动SurfceFlinger服务。 //若为0,表示该服务已在init进程中启动。 property_get("system_init.startsurfaceflinger", propBuf, "1"); if (strcmp(propBuf, "1") == 0) { // Start the SurfaceFlinger SurfaceFlinger::instantiate(); } … }
2)Init.rc启动surfaceflinger
该部分脚本代码遵循Android Init Language规范,该规范可参考官网中http://www.kandroid.org/online-pdk/guide/bring_up.html的介绍,或者在android42\system\core\init\ReadMe.txt中。
这里定义了surfaceflinger为init进程中的一个服务及其相应的文件位置,并将其归为main类,在此类中,所有服务同时启动。在surfaceflinger服务重新启动时,重启zygote服务。
2、启动surfaceFlinger服务。
入口函数源码位于:
android42\frameworks\native\cmds\surfaceflinger\main_surfaceflinger.cpp
int main(int argc, char** argv) { SurfaceFlinger::publishAndJoinThreadPool(true); // When SF is launched in its own process, limit the number of // binder threads to 4. ProcessState::self()->setThreadPoolMaxThreadCount(4); return 0; }
该部分将SurfaceFlinger服务在ServiceManager中进行注册并启动。
在surfaceFlinger服务启动之后,它会调用startBootAnim()来启动开机动画。
代码位置:
android42\frameworks\native\services\surfaceflinger\SurfaceFlinger.cpp
status_t SurfaceFlinger::readyToRun() { … // start boot animation startBootAnim(); … } void SurfaceFlinger::startBootAnim() { // start boot animation property_set("service.bootanim.exit", "0"); property_set("ctl.start", "bootanim"); } void SurfaceFlinger::bootFinished() { … // 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"); … }
其中startBootAnim()通过ctl.start启动bootanim的应用程序。
在bootFinished()中通过service.bootanim.exit请求bootanim自动退出。
此外,在adb shell中,可通过命令“setprop ctl.start bootanim”启动开机动画;命令“setprop ctl.stop bootanim”停止开机动画。
3、运行bootanim应用程序。
具体bootanim应用程序的源码位于:
android42\frameworks\base\cmds\bootanimation\
包括:bootanimation_main.cpp(应用程序入口),BootAnimation.cpp(应用程序实现),BootAnimation.h(头文件)。
在bootanimation_main.cpp中,实现了与SurfaceFlinger的绑定并启动开机动画实现的应用程序。源代码如下:
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); ALOGI_IF(noBootAnimation, "boot animation disabled"); if (!noBootAnimation) { sp<ProcessState> proc(ProcessState::self()); ProcessState::self()->startThreadPool(); // create the boot animation object sp<BootAnimation> boot = new BootAnimation(); boot->playBootMusic("/system/media/boot.wav"); IPCThreadState::self()->joinThreadPool(); } return 0; }
在main函数中,首先获取init.rc/build.prop中debug.sf.nobootanimation的值是否为0。该值为0则执行开机动画程序,该值为1则不执行。默认情况下该文件中没有这个属性,在该函数中,当没有这个属性时,获取到的值将其设置为0。即系统是默认执行开机动画程序。
开机动画应用程序源码为BootAnimation.cpp,具体如下:
//定义用户自定义开机动画文件位置 #define USER_BOOTANIMATION_FILE "/data/local/bootanimation.zip" #define SYSTEM_BOOTANIMATION_FILE "/system/media/bootanimation.zip" #define SYSTEM_ENCRYPTED_BOOTANIMATION_FILE "/system/media/bootanimation-encrypted.zip" //线程启动初始化函数 status_t BootAnimation::readyToRun() { … //判断是否存在用户自定义开机动画文件,若存在,则将mAndroidAnimation设置为false if ((encryptedAnimation && (access(SYSTEM_ENCRYPTED_BOOTANIMATION_FILE, R_OK) == 0) && (mZip.open(SYSTEM_ENCRYPTED_BOOTANIMATION_FILE) == NO_ERROR)) || ((access(USER_BOOTANIMATION_FILE, R_OK) == 0) && (mZip.open(USER_BOOTANIMATION_FILE) == NO_ERROR)) || ((access(SYSTEM_BOOTANIMATION_FILE, R_OK) == 0) && (mZip.open(SYSTEM_BOOTANIMATION_FILE) == NO_ERROR))) { mAndroidAnimation = false; } … } //线程循环函数。 //若mAndroidAnimation为true,则调用android(),这是安卓系统默认的开机动画 //会根据/frameworks/base/core/res/assets/images/android-logo-mask.png,///frameworks/base/core/res/assets /images/android-logo-shine.png的两张图 //片,通过代码控制达到动画效果。 //若mAndroidAnimation为false,则显示用户自定义的动画。 bool BootAnimation::threadLoop() { bool r; if (mAndroidAnimation) { r = android(); } else { r = movie(); } }
具体开机动画控制的相关函数,可参考具体代码。
从代码中可以看出:为了显示自定义的开机动画效果,需要确保:
1)init.rc/build.prop中没有debug.sf.nobootanimation属性,或者该属性值为0。
2)/data/local/或者/system/media/文件夹中有bootanimation.zip。
4、bootanimation.zip说明。
此处对bootanimation.zip进行说明,里面的内容是:
注意:此处不能有上层文件夹。
其中,desc.txt的文本内容为
1280 720 40 p 0 0 part0 p 0 0 part1
第一行:数字的含义分别是屏幕宽度,屏幕长度,帧数(每秒多少帧);
第二行:第一项是标识符,p表示该行是该animation的一个part;
第二项是循环次数,1表示循环一次,0表示无限循环;
第三项是两次循环之间的间隔时间;
第四项是对应的目录名。
压缩是需要用存储的方式,否则程序无法读取内容。
1.windows使用winrar打包,选择ZIP 格式,压缩标准要选“储存”;
2. linux下,zip -0 -r ../bootanimation.zip ./*
linux命令使用-0 指定压缩等级为最低等级stored,即只归档不压缩,否则可能由于包格式问题引起动画显示为黑屏。
此外还应注意打包之后需要修改其运行权限,否则无法正常显示。
在shell中运行:chmod 777 bootanimation.zip
三、在CubieBoard2上修改步骤
参照《A10_android内容定制说明文档V2.1》上的说明,压缩相应的动画文件bootanimation.zip并进行权限修改,存放在\android42\device\softwinner\smfy-super3\media\目录下,进行系统编译,固件下载。
此外,也可以将bootanimation.zip存放在系统的/data/local/或者/system/media/文件夹中,无需编译即可实现开机动画效果。
四、参考文档
《android从init到开机动画启动关闭流程一简易图》
《Android 启动过程详解》
《android系统启动过程》
《Android系统启动过程剖析》
《Android4.2.2SurfaceFlinger启动流程详解》
《学习SurfaceFlinger》
《A10_android内容定制说明文档V2.1》
相关文章推荐
- 教你修改安卓手机开机第二屏动画。(以及你为什么失败的原因)
- 安卓手机开机动画制作修改教程
- 工作笔记之安卓开机动画与logo修改
- Android 开机图片/文字/动画的修改
- 原创安卓开机动画集合贴[Feng自己…
- HTC one 数字雨矩阵 安卓开机动画
- 【安卓开机动画】小米正在排队,请…
- 安卓开机动画之批量旋转图片(将横…
- 安卓开机动画之批量旋转图片(将横…
- 安卓开机动画——天降之物
- 【安卓开机动画】最强大脑 周杰伦…
- 【安卓开机动画制作】如何将视频转…
- 【安卓开机动画】安卓4.4 kit…
- 安卓开机动画集合贴【自己做的哦~…
- 【安卓开机动画制作教程】(二)如…
- 安卓开机动画——代码编辑器Notepad+…
- 【安卓开机动画】魔兽世界-燃烧的…
- 【安卓开机动画】迈克尔·杰克逊(M…
- 400个安卓开机动画大合集(有预览…
- HTC one 数字雨矩阵 安卓开机动画