Android源码学习之开机动画

1. Android 开机动画的基本机制

Android 的开机动画由 bootanimation 进程控制,它会读取 /system/media/bootanimation.zip/product/media/bootanimation.zip,然后按照配置播放开机动画。

动画格式

Android 的开机动画是一个 ZIP 压缩包,里面包含多个帧图片,以及一个 desc.txt 配置文件。

存放路径

  • /system/media/bootanimation.zip
  • /product/media/bootanimation.zip
  • /oem/media/bootanimation.zip(某些设备)

系统会按照以上顺序查找,找到后即播放。

2. 制作开机动画

创建开机动画资源

开机动画是一组连续播放的帧动画,一般包含多个子文件夹,每个文件夹代表动画的一个阶段。

目录结构

makefile 复制代码
bootanimation.zip
│── desc.txt
│── part0/
│   ├── 001.png
│   ├── 002.png
│   ├── ...
│── part1/
│   ├── 001.png
│   ├── 002.png
│   ├── ...
  • desc.txt:定义动画播放规则
  • part0/part1/:存放帧图片,每个文件夹对应动画的不同阶段

desc.txt 配置

desc.txt 是动画的描述文件,定义了动画的播放规则。其格式如下:

第一行:定义动画的全局参数
makefile 复制代码
WIDTH HEIGHT FPS
  • WIDTH:动画的宽度(像素)。
  • HEIGHT:动画的高度(像素)。
  • FPS:帧率(每秒播放的帧数,例如 60)。
后续行:定义每个动画段的播放规则
makefile 复制代码
TYPE COUNT PAUSE PATH [#RGBHEX CLOCK]
  • TYPE:动画段的类型:
    • p:可被暂停的动画段。
    • c:必须播放完成的动画段(一般不会用这个,会影响开机速度)。
  • COUNT:动画段的播放次数:
    • 0:无限循环,直到开机完成。
    • 1 或其他正整数:播放指定次数。
  • PAUSE:动画段结束后停留的帧数。
  • PATH:动画段对应的资源目录(如 part0)。
  • #RGBHEX(可选):背景颜色,格式为 #RRGGBB
  • CLOCK(可选):显示当前时间的 Y 坐标(用于智能手表等设备)。
示例 desc.txt 文件
makefile 复制代码
1080 360 60
c 1 0 part0 #ffee00
c 0 0 part1 #ffee00
c 1 0 part2 #ffee00
c 1 1 part3 #ffee00
c 1 0 part4 #ffee00
  • 动画分辨率为 1080x360,帧率为 60 FPS。
  • part0 播放 1 次,不暂停。
  • part1 无限循环,直到开机完成。
  • part2 播放 1 次,不暂停。
  • part3 播放 1 次,结束后停留 1 帧。
  • part4 播放 1 次,不暂停。

3. 打包为 ZIP 文件

desc.txt 和所有动画资源目录(如 part0, part1 等)打包为 bootanimation.zip

makefile 复制代码
zip -r -X -Z store bootanimation part*/* desc.txt

当前目录下执行上面命令即可。

  • -r:递归打包。
  • -X:不包含额外的文件属性。
  • -Z store:使用存储模式(不压缩,加快加载速度)。

4. 部署到 Android 设备

手动替换

bootanimation.zip 直接推送到设备(注意要用 userdebug 版本):

makefile 复制代码
adb root
adb remount
adb push bootanimation.zip /system/media/bootanimation.zip
adb reboot

5. Framework 源码分析

bootanimation 的源码在 frameworks/base/cmds/bootanimation/,核心逻辑在 BootAnimation.cpp

makefile 复制代码
[BootAnimation.cpp] threadLoop() -> movie() -> playAnimation()
  • movie 中读取 zip 文件封装成 animation,然后初始化了一些变量和画布,并调用 playAnimation 方法。
  • playAnimation() 中递归读取 partfor 循环加载图片。

6. 定制厂商开机动画

在源码根目录创建 vendor 目录,用于存放厂商特定的东西。

== 如果是接手别人的项目,开机动画可能在源码中某个目录下创建的,一般也是自定义的文件夹 == 接着创建 bootanimation 文件夹,用于专门存放开机动画 将上面制作好的动画压缩包放到该文件夹下 在 vendor 目录下,创建 vendor_product.mk文件,增加命令,拷贝动画 zip 到编译产物的 system/media ⽬录下:

bash 复制代码
PRODUCT_COPY_FILES += \
vendor/bootanimation/bootanimation.zip:system/media/bootanimation.zip

此时在编译工程中该编译文件,不会执行,因为没有任何地方引用,如果需要让 vendor_product.mk执行,就需要把它引入到另一个肯定会编译到的.mk 文件中 ,这时候就要用到:

bash 复制代码
$(call inherit-product, <file-path>) 

$(call inherit-product, <file-path>) 是 编译系统中的 Makefile 语法,它用于 在当前编译环境中引入另一个 .mk 文件,并执行其中的变量和命令。

这个肯定会编译到的文件,一般是配置设备属性的.mk 文件(不同版本系统 文件名可能不一样),将 $(call inherit-product, vendor/vendor_product.mk)放入到该文件内就行了。 比如在上篇文章中 lunch 的是 sdk_phone_x86_64-eng 就可以找到build/target/product/sdk_phone_x86_64.mk文件,在该文件中可以看到系统设置中显示的一些系统配置属性,然后将 vendor_product.mk 加进去即可,后面在编译的时候vendor_product.mk就能被找到并编译了。

如果编译过程中出现类似以下内容报错:

bash 复制代码
build/make/core/artifact_path_requirements.mk:26: warning:
build/make/target/product/sdk_phone_x86_64.mk produces files inside
build/make/target/product/generic_system.mks artifact path requirement.
Offending entries:
system/media/bootanimation.zip
In file included from build/make/core/main.mk:1342:
build/make/core/artifact_path_requirements.mk:26: error: Build failed.

是因为 违反了 make 规则,需要将以下内容增加到 vendor_product.mk

bash 复制代码
PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST += \
/system/media/bootanimation.zip

然后执行以下命令,编译镜像文件,注意先按上篇文章说的,在 out/target/product/emulator_x86_64/ 目录下搜索 .img 文件,全部删除!

bash 复制代码
source build/envsetup.sh

//选择上次编译过的机型
lunch sdk_phone_x86_64-eng

//启动模拟器
emulator -writable-system

就可以查看效果了:)

相关推荐
然后就去远行吧24 分钟前
小程序 wxml 语法 —— 37 setData() - 修改对象类型数据
android·前端·小程序
熙曦Sakura38 分钟前
【MySQL】数据类型
android·mysql·adb
故事与他6451 小时前
CTFHub-上传文件
android·ide·windows·web安全·网络安全·android studio·xss
大胃粥1 小时前
Android app 冷启动(7) 执行动画
android
yi诺千金1 小时前
Android U 分屏——SystemUI侧处理
android
顾林海1 小时前
Flutter Dart 流程控制语句详解
android·前端·flutter
Cui晨2 小时前
Android 滑块开关 自定义Switch
android
&有梦想的咸鱼&2 小时前
Android Retrofit 框架注解定义与解析模块深度剖析(一)
android·retrofit
烬奇小云2 小时前
安卓7.0到11.0的更新变化(简单理解)
android·安卓逆向
whatever who cares2 小时前
android:实现圆角效果
android