Android's bootanimation binary (frameworks/base/cmds/bootanimation) has a deceptively simple format, but OEM customizations and subtle rules in BootAnimation.cpp cause real-world failures when tools cut corners.
-
ZIP_STORED(Method0) is mandatory forbootanimation.zip:BootAnimation.cppmaps the archive into memory (FileMap) and reads frame entries directly. Any entry compressed withDEFLATE(method8) is skipped or causes the animation to abort back to the stock Android shine logo.- Note: When packaging a Magisk module, the outer
module.zipcan be standard DEFLATE or Stored, because Magisk extractsmodule.zipinto/data/adb/modules/<id>/during installation. However, the innersystem/media/bootanimation.zipplaced inside the module must remain uncompressed (compression_method == 0for every entry).
-
Entry Ordering & Paths:
desc.txtshould be at the root ofbootanimation.zip(no top-level wrapper folder likemy_anim/desc.txt).- Part frames are loaded in the order they appear / sort within their part directory. Using zero-padded sequential names (
00000.png,00001.png, ...) and writing entries in deterministic sorted order avoids playback glitches. - Archive paths must always use forward slashes (
/) even when built on Windows.
- PNG (Recommended Default):
- Official AOSP
FORMAT.mdspecifies PNG frames. - 8-bit RGB or RGBA PNGs work reliably across stock AOSP, LineageOS, Pixel, and custom ROMs.
- 16-bit per channel PNGs or unusual interlaced PNGs can fail or render improperly on some older Skia/OpenGL ES decoders; warn when encountered.
- Official AOSP
- JPEG:
- Supported by AOSP's decoder in practice and used by many older animations (
main.pyin 2.x only output.jpg), but introduces lossy compression artifacts on flat logos/text and does not support transparency. - BootAnimix 3.5.1 keeps source frames in their original format by default and uses PNG as the default when generating new frames.
- Supported by AOSP's decoder in practice and used by many older animations (
p(play unless interrupted): LoopsCOUNTtimes (0= infinite untilservice.bootanim.exitis set), then pausesPAUSEframes. If boot completes mid-part, playback stops immediately (or moves to remainingcparts).c(play to completion): Plays all frames and repeats even after the system signals boot completion. Caution: settingc 0 ...(infinite loop on acpart) can soft-hang the boot screen on some builds because the animation refuses to exit! The validator flagscparts withCOUNT == 0as a high-severity warning.f(fade out when interrupted): Syntax isf COUNT PAUSE PATH FADE [#RGBHEX [CLOCK1 [CLOCK2]]]. NoticeFADEis an extra integer field right afterPATHthat does not exist onporclines.
While AOSP checks /system/media/bootanimation.zip first and /oem/media/bootanimation.zip second, real devices vary:
- AOSP / LineageOS / most custom ROMs:
/system/media/bootanimation.zip - Google Pixel / modern Treble devices: Often
/system/product/media/bootanimation.zip(mounted at/product/media/bootanimation.zip) - Some OEMs (OnePlus / Xiaomi / Nothing): May use
/system/product/media/bootanimation.zipor/system/system_ext/media/bootanimation.zip. Samsung OneUI uses proprietary.qmgfiles and does not playbootanimation.zipwithout a custom bootanimation binary.
Because of this, the Magisk module exporter defaults to system/media/bootanimation.zip (or system/product/media/bootanimation.zip when selected) and allows overriding the target path inside the module.