Android 16开机动画定制全攻略:desc.txt修改、打包与避坑指南
2026/9/18 2:53:13 网站建设 项目流程

搞安卓定制的朋友应该都碰过开机动画,这东西看起来就是个 zip 包,但里面那个desc.txt一旦写错,轻则黑屏半天起不来,重则开机动画直接不显示、卡在 logo 不动。尤其是现在 Android 16 的 boot 流程和分区校验越来越严,很多老一套的改法已经不好使了。我这段时间正好在做 RK3568 平台和几台高通机型的开机动画定制,踩了不少坑,也把 desc.txt 的规则彻底摸了一遍,这篇就把修改逻辑、参数计算、打包签名这些环节完整捋清楚。

先说清一个概念:Android 的开机动画本质上不是视频,而是按帧播放的 PNG 图片序列。系统开机时通过bootanimation这个 native 进程去解析/system/media/bootanimation.zip(部分机型也可能是/oem/media//product/media/),desc.txt就是整个动画的“导演脚本”,它决定图片按什么顺序、什么尺寸、什么帧率播放,以及播放多少次。所以改开机动画,核心工作就是改这个 txt 和里面的图片目录。

1. 先搞清楚开机动画的运行机制,再动手改文件

1.1 bootanimation 进程的启动链路

不少同学上来直接改 desc.txt,结果发现改了没效果,或者开机动画直接没了。这通常是因为没搞懂 Android 系统是在哪个阶段、由谁去读这个文件的。在 Android 16 上,开机动画的加载链路大概是这样的:

  • Kernel 启动完成后,init 进程解析init.rc,其中有一个关键服务叫bootanim,它执行的二进制就是/system/bin/bootanimation
  • bootanimation启动后,会先去读取系统属性persist.sys.boot.animation或者默认路径下的bootanimation.zip
  • 解压 zip 后,第一件事就是解析desc.txt,按描述文件里的字段去加载对应的帧目录。
  • 同时 SurfaceFlinger 已经起来了,bootanimation 通过它把每一帧图像提交到屏幕上,形成动画效果。
  • 开机动画播放结束(或收到boot_completed属性变化)后,进程退出,系统切换到桌面。

Android 16 相比老版本,变化比较大的地方是分区只读校验更强/system分区默认是 EROFS 或 ext4 只读挂载,如果你没有 root 或者没解锁 bootloader,直接去改 system 里的 zip 是写不进去的。所以现在的常规做法是做“覆盖式定制”:通过vendor分区、oem分区或者product分区里的同名文件去覆盖默认路径,或者直接用临时挂载 overlay 的方式替换。

1.2 为什么要改 desc.txt 而不是只换图片

很多人以为换开机动画 = 换图片,实际上如果你只替换了part0里的 PNG,但 desc.txt 里写的解析逻辑还是老样子的,可能出现两种情况:图片尺寸不匹配导致黑边、拉伸;帧数太多但 desc.txt 里定义的总帧数只有 20 帧,后面的图根本不会播。

desc.txt 里定义的核心信息包括:

  • 动画的宽和高(单位像素)
  • 帧率(fps)
  • 播放模式(静态、循环、按次播放)
  • 每个 part 的目录名、循环次数、暂停时间

所以它是整个动画的“心脏”,图片只是素材。改动画逻辑,必须同步改 desc.txt。

1.3 搞清楚文件结构再下手

一个标准的 bootanimation.zip 内部结构如下:

bootanimation.zip ├── desc.txt ├── part0/ │ ├── 00000.png │ ├── 00001.png │ ├── ... │ └── 00039.png └── part1/ ├── 00000.png ├── ... └── 00019.png

desc.txt 示例内容(最常见写法):

720 1280 30 p 1 0 part0 p 0 10 part1

逐行解释:

  • 第一行是全局参数:宽度 高度 帧率,这里是 720x1280,30 帧/秒。
  • 第二行:p 1 0 part0,表示播放part0目录 1 次,播放结束后停顿 0 帧(立即进入下一个 part)。
  • 第三行:p 0 10 part1,表示part1目录循环播放(0 表示无限循环),每次循环结束后暂停 10 帧的时间。

如果你想把动画做成“播一次就停”,把最后一行改成p 1 0 part1即可。

2. desc.txt 逐字段拆解,参数含义和常见写法一次讲透

2.1 第一行全局参数:宽、高、帧率

第一行的720 1280 30是最容易出问题的地方。很多人会把这里理解成“图片的最大尺寸”,其实它是一个全局缩放基准。bootanimation 进程在播放时,会以这里的宽高作为基准去适配屏幕。如果你的屏幕是 1080x2400,但 desc.txt 写的是 720x1280,动画会被拉伸到全屏,图片本身如果也是 720x1280 就会被模糊放大。

这里建议的做法是:按屏幕实际分辨率写。你可以在 adb shell 里执行:

wm size

拿到类似Physical size: 1440x3120的输出,然后 desc.txt 第一行就写1440 3120 30。图片素材也按这个尺寸做,才能保证锐利。

帧率的选择同样有讲究。常见的是 30,也有用 60 的。帧率越高动画越流畅,但 zip 包体积会暴增,而且低端设备在开机阶段 CPU 频率还没拉高,高帧率动画容易掉帧甚至卡死。我的经验是:非特殊需求一律 30,如果想要顺滑一些,可以 24~30 之间取一个,60 除非是演示机,否则不建议。

2.2 第二行开始的 p 指令:播放策略

p 指令的格式是:

p <循环次数> <暂停帧数> <目录名>
  • 循环次数:0代表无限循环,正整数代表播放完该次数后进入下一个 part,如果这是最后一个 part,则动画结束。
  • 暂停帧数:每次循环结束后额外停顿多少帧(不是秒,是帧),常用于在两个 part 之间做短暂停留,制造“停顿感”。
  • 目录名:对应 zip 内的图片目录。

举个例子,一个常见的三段式动画:

1080 2400 30 p 1 0 part0 p 0 10 part1

意思是:part0 播放 1 次(一般是 logo 出现、放大消失的过程),然后 part1 无限循环(一般是“系统正在启动”之类的循环 loading 效果),每次循环结束停 10 帧(约 0.33 秒)。

2.3 多 part 的衔接逻辑和注意事项

多 part 场景下,图片数量要按“总帧数 = 帧率 × 时长”来准备。比如你希望第一个动画播放 2 秒,帧率 30,那 part0 里就应该放 60 张 PNG。系统按文件名顺序读取,常见命名规则是00000.png00001.png……注意必须是 5 位数字。

还要注意:所有 part 目录里的图片命名要连续、从 0 开始。如果中间缺了某个编号,bootanimation 会提前结束当前 part,甚至导致整个动画闪退。

2.4 常见 desc.txt 错误写法避坑

有一种老教程会把 desc.txt 写成:

720 1280 30 p 1 0 part0 p 1 0 part1

这在老版本没问题,但在部分高版本设备上,第二个 part 播完就没了,动画结束得很突兀,桌面出现前会有一黑屏。更稳妥的做法是用一个“结束帧”在 part0 里完成收尾,或者让最后一个 part 循环播放直到系统启动完成。在 Android 16 上,如果动画提前结束,但系统还没启动好,屏幕上会一直停在 bootanimation 最后停留的那一帧,然后才跳到桌面,看起来就像卡死了一样,其实是在等 SystemUI 启动。

3. 完整实操:解包、修改、打包、替换,一步不落

3.1 工具准备和基础环境要求

修改 bootanimation.zip 不需要编译整个系统,只要有解压/压缩工具、图片处理工具就行。我自己常用的组合是:

  • 7-Zip 或 Linux 下的zip命令(打包压缩)
  • GIMP 或 Photoshop(批量处理 PNG)
  • adb(推送到设备测试)
  • 任意文本编辑器(改 desc.txt,推荐 VS Code,注意编码必须 UTF-8 无 BOM)

如果是在 Windows 上操作,建议装一个Notepad3之类能显示编码的工具,避免 Windows 记事本把 txt 存成带 BOM 的 UTF-8,这会导致第一行解析失败。这个问题我见过很多次,症状是开机动画完全没有,黑屏一段时间直接进桌面。

3.2 解包并查看原始 desc.txt

这一节以一台 android 16 的测试机为例。先用 adb 把原始 zip 拉出来:

adb root adb remount adb pull /system/media/bootanimation.zip

如果你已经 root,也可以直接从/product/media/或者/oem/media/下找。有些国产 ROM 会把开机动画放在/system/media/,把关机动画放在/system/media/shutanimation.zip,注意区分。

拉到本地后,解压看 desc.txt:

mkdir bootanim_extract cd bootanim_extract unzip ../bootanimation.zip cat desc.txt

看到一个典型的原始内容:

1080 2400 30 p 1 0 part0 p 0 0 part1

不用急着改,先把 part0 和 part1 的图片数量统计一下:

ls part0 | wc -l ls part1 | wc -l

比如 part0 有 90 张、part1 有 120 张,那么原始设计就是“播放 3 秒动画 + 无限循环 4 秒动画”。

3.3 修改 desc.txt 的具体步骤

假设我的需求是:把第一段动画改成 2 秒(60 帧),第二段循环动画改成 5 秒后停住,不要无限循环。

那么新的 desc.txt 这样写:

1080 2400 30 p 1 0 part0 p 1 150 part1

解释:part0 播放 1 次、停 0 帧;part1 播放 1 次、结束后暂停 150 帧(即 5 秒)。但要注意,这里暂停是在最后一次循环之后,不是每次循环后都暂停。也就是说 part1 播完一次后动画就停了,但后面还“挂在”最后一帧 5 秒,然后退出。

如果想让 part1 循环 3 次,每次之间停 5 帧,最后停 0 帧,就写:

p 3 5 part1

注意这个5是每次循环结束后都暂停 5 帧,包括最后一次。如果最后不想停,就不能用这种写法,要拆成两个 part 或在图片素材里多复制几帧来做停顿。

3.4 打包时必须注意的压缩方式

很多人在这一步翻车。bootanimation.zip 不是随便 zip 一下就能用,不能使用压缩率极高的方式,也不能在 zip 里带有顶层目录。标准要求是:

  • 压缩方式建议用“存储(Stored)”或“仅存储”,至少不要用 LZMA 这类高压缩算法。实测部分老版本 bootanimation 进程解析不了高压缩 zip,会直接跳过动画。
  • zip 内路径不能包含顶层文件夹,desc.txt必须在压缩包根目录。
  • 文件名编码建议保持 ASCII,不要有中文。

Linux 下推荐这样打包:

cd bootanim_extract zip -0 -r ../bootanimation.zip desc.txt part0 part1

-0表示不压缩,纯存储。-r表示递归。注意这里的desc.txtpart0part1都是相对路径,不要带./前缀。

Windows 下用 7-Zip 时,压缩方式选“存储”,压缩级别选“仅存储”,并且确保打开 zip 后第一层就是这些文件和目录。

3.5 替换到系统并验证

打包完成后,先把新 zip 推到/data/local/tmp下做验证:

adb push bootanimation.zip /data/local/tmp/ adb shell cd /data/local/tmp cp bootanimation.zip /system/media/bootanimation.zip chmod 644 /system/media/bootanimation.zip

如果你有 root 并且已经 remount 了系统分区,这个操作是可以成功的。完成后重启看效果:

adb reboot

如果动画没生效,先不要急着重启,执行一次:

setprop ctl.stop bootanim setprop ctl.start bootanim

可以热切换,不用重启系统就能预览。

3.6 免 root 替换方案的说明

如果你的设备没有 root,但 bootloader 已解锁,可以走 boot 镜像内嵌或者动态分区 overlay 的方式,这超出了单篇教程的范畴,简单说就是你可以在vendor分区里放一个 bootanimation.zip,同时通过 overlay 机制让它覆盖/system/media下的同名文件。具体操作在 Android 16 上依赖于overlayfs,需要你修改fstab并启用对应的 mount 配置。这块不建议新手直接搞,容易把系统弄成无法开机。

4. 常见问题与排查技巧实录,遇到黑屏先别慌

4.1 开机动画不显示、黑屏后直接进桌面

这通常不是图片问题,而是 desc.txt 解析失败。先确认:

  • 编码是否是 UTF-8 无 BOM?
  • 第一行有没有多余空格?比如1080 2400 30后面多了个空格,某些严格解析会崩。
  • 换行符是不是 LF?Windows 记事本默认 CRLF,在 Android 上解析时可能异常。

修好这几项,重新打包测试,大概率解决。我遇到过最离谱的一次是 desc.txt 文件名被改成了desc.txt.txt,系统找不到文件,直接跳过动画。

4.2 有动画但画面拉伸、变形或出现黑边

这是宽高参数和图片尺寸不一致导致的。建议在修改前统一确认“屏幕物理分辨率”“图片实际分辨率”“desc.txt 第一行宽高”三者的关系。如果有黑边,多半是图片尺寸小于屏幕分辨率,系统按原比例居中显示;如果拉伸,多半是图片分辨率与屏幕比例不一致。比如屏幕是 20:9,但图片是 16:9,就会明显变形。

一个稳妥做法是:图片按屏幕比例裁切,desc.txt 写屏幕物理分辨率。不要为了省素材体积把图片宽度缩小,因为放大后模糊比黑边更难看。

4.3 动画只播放 part0,不进入 part1

一般是 part1 路径写错了,或者目录里没有任何 PNG。bootanimation 在解析不到帧时,会直接跳过该 part。检查 zip 里part1/*.png是否存在,以及命名是否为00000.png开头。

4.4 动画播放速度过快或过慢

这是帧率问题。desc.txt 第一行的 fps 和实际图片数量不匹配。比如你希望播 3 秒,素材 90 张,那 fps 应写 30。如果你 fps 写 60,播放时间会缩到 1.5 秒,看起来就像“快进”。另外要注意,部分设备有“快启动”策略,开机动画会在系统 boot 完成前强制退出,这种情况下不是你的参数问题,是系统急着进桌面,不要浪费时间去调帧率。

4.5 边角有残留的静态 logo

这种情况在系统默认开机动画里常见。Android 内核启动后会先显示一个静态 logo(logo.bmp),然后 bootanimation 接管。如果你看到的是一张图固定不动几秒,然后才开始动,那不是你的动画卡住,而是 logo 阶段。要改这部分需要去改内核里的 logo 图片,和 bootanimation.zip 无关。这块很多人误解,先说明白免得白忙。

4.6 快速排查速查表

症状可能原因排查方向
无动画黑屏desc.txt 解析失败编码、换行符、第一行格式
动画结束时黑屏几秒最后一个 part 播放次数有限,早于系统启动完成把最后 part 改无限循环
拉伸变形宽高参数与屏幕不匹配用 wm size 查实际分辨率
静态画面不切换zip 压缩方式不对重新打包用存储模式
只播一个部分part 路径或素材缺失检查目录和 PNG 命名
动画播完但停不下来最后 part 设为无限循环改固定次数加暂停帧数

4.7 关于 Android 16 的新变化和避坑经验

到了 Android 16,有几个点值得单独说:

  • 动态分区和只读系统分区进一步普及,手动 remount 失败的概率变高。如果adb remount报错,建议用adb disable-verity(需要解锁 bootloader)再重试。
  • 部分设备对 zip 的校验更严格,要求desc.txt以换行符结尾,否则解析到最后一行可能崩溃。建议修改后统一在文件最后按一个回车。
  • 使用p 0 0 part1这种无限循环写法时,如果 part1 的图片数量太少,循环切换会非常生硬。我一般会确保循环 part 至少 10~20 帧,并能构成一个完整的视觉闭环,否则看起来就像卡顿。
  • 如果你的设备有“关机动画”,它就是另一个 zip,修改方式完全一样,只是路径不同。碰到关机动画不生效,优先检查路径,而不是怀疑 desc.txt 写错。

5. 高效制作和测试流程,以及自动化批处理的思路

5.1 批量生成和调整图片素材

做动画最麻烦的是图片素材。手头有视频素材时,可以用 ffmpeg 批量转帧:

ffmpeg -i input.mp4 -vf "scale=1080:2400" -start_number 0 part0/%05d.png

注意把分辨率按设备实际值调整。处理完记得确认生成的第一张是00000.png,并清理掉所有非 PNG 文件。

如果是自己用 Photoshop 或 GIMP 设计的一整套图,导出的命名规则也要统一。我习惯用“5位数字 + 下划线 + 描述”的方式命名,比如00000_logo.png,bootanimation 会忽略下划线后的部分,但保留 .png 后缀即可。不过为了保险起见,建议文件名只保留数字,避免某些解析器不识别。

5.2 desc.txt 变体用法:关机动画和充电动画

关机动画的 desc.txt 格式和开机动画完全一样,只是存放路径不同。充电动画则不在 bootanimation 进程管理范围内,通常是 framework 直接读帧,路径一般在/system/media//product/media/下,文件名可能是charging_animation.zip之类。改之前先用命令行找一下:

adb shell find /system /product /oem -name "*animation*" -o -name "*charging*"

搜出来的路径才是你真正要改的目标。

5.3 用脚本做自动打包和推送

手动操作多了会烦,而且容易漏步骤。我习惯写一个简单的打包推送脚本:

#!/bin/bash cd bootanim_extract zip -0 -r ../bootanimation.zip desc.txt part0 part1 adb push ../bootanimation.zip /data/local/tmp/ adb shell "cp /data/local/tmp/bootanimation.zip /system/media/bootanimation.zip && chmod 644 /system/media/bootanimation.zip" adb shell "setprop ctl.stop bootanim; setprop ctl.start bootanim"

脚本跑完直接热切换预览,不用反复重启。这里提个醒:setprop ctl.start bootanim如果在系统已经 boot 完成后执行,部分机型能正常显示动画,但有的机型因为 SurfaceFlinger 状态不对,热切换会黑屏几秒,这是正常现象,不用慌。

5.4 记录每次修改,方便回滚

这是个很容易被忽略但极其重要的习惯。bootanimation.zip 不像普通应用能随便卸载重装,改错了想恢复,如果没有备份原始文件会非常被动。我在本地目录维护了一个历史版本文件夹,每次改之前先把原包cp进去,命名带时间戳:

cp bootanimation.zip backups/bootanimation_$(date +%Y%m%d_%H%M%S).zip

这样即使改得面目全非,也能一键恢复。

6. desc.txt 高级用法和进阶定制思路

6.1 多分辨率适配

如果你的固件要跑在一批屏幕分辨率不同的设备上,不建议为每台设备做一套 zip。虽然 desc.txt 支持“自动缩放”的语义,但实际效果并不可靠。更稳的方案是:图片用最大分辨率做一份,desc.txt 写最大分辨率,让 bootanimation 的缩放能力去适配小屏。放大模糊,缩小相对可接受,所以统一用最大尺寸更省事。另一种做法是通过系统属性动态选择 zip,这需要改 bootanimation 的源代码或 init.rc,适合有完整源码环境的团队,量产机型用户一般不碰。

6.2 在动画中加入类似“读条”的效果

开机动画也可以实现进度条效果,原理是播放最后一帧时根据系统启动进度做进度映射。但这个功能 bootanimation 原生不支持,需要改 native 代码,不是改 desc.txt 能搞定的。简单替代方案是做一个“循环转圈”动画,这也是绝大多数国产 ROM 的做法,视觉上已经有了“正在加载”的心理暗示。

6.3 动态使用不同动画的思路

Android 16 上有一些定制系统支持根据当前主题切换开机动画,实现方式通常是复制多份 zip 到不同目录,然后在 framework 层通过 overlay 或属性动态选择。对于普通用户来说,能做到的就是在 root 后用 magisk 模块挂载不同动画包。

6.4 关于开机动画包体积和性能

zip 体积越做越大,开机时解压时间变长会影响启动速度。建议单张 PNG 控制体积,使用优化过的调色板,或把图片压缩到 256 色以内(如果动画对颜色不敏感)。实测下来,同样 30 帧动画,调色板优化后 zip 体积能缩小一半左右,解压耗时也明显下降。如果一定要大尺寸、高帧率,那就用存储模式打包,尽量减少 CPU 解压负担。

7. 最后分享一个实际项目中的踩坑记录和心得

我在给某款基于 Android 16 的 RK3568 设备做开机动画时,第一次替换完,重启后开机动画正常,但随后系统一直启动不起来,卡在 bootanimation 结束后黑屏。排查了很久才发现不是动画的问题,而是动画播完后,系统在等待sys.boot_completed属性,但因为我同时改了build.prop里某些跟启动相关的参数,导致 SystemUI 一直没起来。把这个还原后才恢复正常。

另一个印象很深的坑是:同事在 Windows 下用自带记事本改了 desc.txt,存成了UTF-8 with BOM,结果动画全程黑屏,重新用 VS Code 改存为 UTF-8 无 BOM 后一切正常。这个坑非常隐蔽,因为 desc.txt 在 Windows 下看起来完全没问题,但 Android 端不认 BOM 头。所以如果你是在 Windows 上改 desc.txt,建议改完后用 hex 工具确认文件开头是70(字符 p),而不是EF BB BF

还有一次是在打包时用了 Windows 默认的 zip 工具,打出来的包在 Android 上解析时提示 zip 格式非法。后来换成 7-Zip 的存储模式才解决。如果你发现开机动画在部分设备上失效,先检查 zip 是不是“仅存储”方式打的。

改开机动画这件事,技术上不难,但细节多,尤其是 desc.txt 这种“一行定生死”的文件,错了不会有任何报错提示,表现出来就是动画没了或黑屏。按上面这套流程走,先确认宽高、帧率、part 播放逻辑,再统一图片素材分辨率,打包用存储模式,替换前备份原始文件,每一步都验证,基本就不会出幺蛾子。希望这篇能帮你在 Android 16 上把开机动画定制这条路走顺。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询