本文将介绍如何修改Android的开机动画,基于AOSP分支android-14.0.0_r28。
源码分析
Android绘制开机动画相关的代码,主要集中在frameworks/base/cmds/bootanimation/
中,打开我们可以看到如下的目录结构:
至于开机动画的实际绘制,具体在BootAnimation.cpp
中,其它的代码无需关心,重点要看从815行开始的代码:
从这里我们可以看到,这里面做了一个判断,如果没有对应的zip file,那么会执行android()
,如果没有,那么会执行movie()
。
实际上,当我们查看两个方法的时候可以看到无论我们使用哪种方法,最后实际上都是使用opengl来绘制的,只是movie会读取对应zip文件中的图片来进行绘制。
那么这里我们可以得出一个结论,我们有两种方法来修改Android的开机动画,第一种,就是我们提供给Android所需的zip文件,第二种,就是我们直接使用opengl来手绘我们的开机动画。
BootAnimation Zip 文件方式修改开机动画
首先介绍最常用的一种方法,提供开机动画Zip文件。
Where
从上面的源码分析,我们现在第一步要做的,就是要找到这个mZipFileName
是怎么赋值的。
实际上Android关于这的处理也比较简单,主要是这两个方法:
从代码逻辑上我们可以看到,如果是sys.init.userspace_reboot.in_progress
这个值为true,那么就会使用userspaceRebootFiles
,如果当前是关机的话,那么会使用shutdownFiles
,最后才会使用bootFiles
。
从名字上我们可以得知,第一种是在Android软启动的时候,才会使用的zipfile,这是关于Android软启动的介绍:
第二种则是Android关机的时候,才会使用的zipFile,第三种则是平常开机时候,使用的zipFile。
软启动时候,所寻找的zip文件位置如下:
关机的时候,所寻找的zip文件位置如下:
平常开机的时候,所寻找的zip文件位置如下:
注意,从代码逻辑上可以看出,这些文件是有优先级的,比如如果同时存在/system/media/bootanimation.zip
和/product/media/bootanimation.zip
,那么会优先使用/product/media/bootanimation.zip
。
关于上面的这个playDarkAnim
,我找了半天也没找到ro.boot.theme
这个值是在哪设置的,看了下git hisotry,这个代码19年就在了,有知道的可以留言讨论一下。
How
现在已经知道我们该把文件输出到哪里了,接下来我们就要找到,这个文件是个什么格式。
关于Bootanimation Zip文件的格式,可以查看/frameworks/base/cmds/bootanimation/FORMAT.md
这个文件,里面详细介绍了该zip文件的格式以及我们要准备的内容。
打开文件,我们可以看到下面的内容:
那么从这里面我们可以知道,zip文件中的第一层结构,就是一个desc.txt
和一堆以part0
开头的文件夹,里面要放我们的动画文件,也就是png格式的图片。
首先,我们来看一下这个desc.txt
的详细描述:
文件很长,而且有有些配置是可选的,我们先写一个最简单的:
css
320 480 24
p 1 2 android
p 0 0 part1
注意,这里我得目录名没有以part0开头,因为实际上在解析zip文件的时候,是先解析desc.txt,然后再去寻找对应的目录。
然后这是我的zip第一层目录结构,和里面的png frame:
Do It
现在,我们准备好了我们的zip文件,就要想办法编译到我们的android系统里面了。
首先,将bootanimation.zip
复制到/device/generic/goldfish/data/media
下面,接着,我们修改/device/generic/goldfish/x86_64-vendor.mk
文件,从28行开始修改成如下指令:
make
PRODUCT_COPY_FILES += \
device/generic/goldfish/data/media/test/swirl_136x144_mpeg4.mp4:data/media/0/test/CtsMediaTestCases-1.4/swirl_136x144_mpeg4.mp4 \
device/generic/goldfish/data/media/test/swirl_132x130_mpeg4.mp4:data/media/0/test/CtsMediaTestCases-1.4/swirl_132x130_mpeg4.mp4 \
device/generic/goldfish/data/media/test/swirl_130x132_mpeg4.mp4:data/media/0/test/CtsMediaTestCases-1.4/swirl_130x132_mpeg4.mp4 \
device/generic/goldfish/data/media/test/swirl_144x136_mpeg4.mp4:data/media/0/test/CtsMediaTestCases-1.4/swirl_144x136_mpeg4.mp4 \
device/generic/goldfish/data/media/test/swirl_128x128_mpeg4.mp4:data/media/0/test/CtsMediaTestCases-1.4/swirl_128x128_mpeg4.mp4\
device/generic/goldfish/data/media/bootanimation.zip:product/media/bootanimation.zip
可以看到,最后一行会在编译时,将我们的zip文件复制到product/media
下面,从上面的代码分析我们可以知道,在这里提供bootanimation.zip
也是可行的。
这样就完成了,接下来,我们重新编译项目:
bash
. build/envsetup.sh
lunch sdk_phone_x86_64
make
编译成功之后,如果在/out/target/product/emulator_x86_64/product/media
下面看到我们的bootanimation.zip
,那么就说明我们成功了:
之后运行模拟器:
bash
emulator
最终我们就会看到开机动画已经被修改了:
Opengl方式,修改开机动画
进入上面说过的android()
方法,我们可以看到android使用opengl库进行绘制:
如果需要通过OpenGL方式修改开机动画,可以不提供zip文件,直接在这里进行修改。
注意,可以在源代码里面看到,android()方法绘制开机动画时,android官方特意将其限制为12fps,这是为了不要绘制的太快,防止影响CPU处理其它重要工作:
其它
bootanimation.zip增加音效
在描述zip文件的FORMAT.md
,提到我们可以为每个动画的part提供音效文件,这些音效会在开机时播放。
压缩PNG帧
官方建议我们将每一帧png图片尽量压缩,并且提到了可以使用如下工具: