zipalign: Align an APK Before Signing in CI
zipalign 4 <in> <out> aligns uncompressed entries in an APK to 4-byte boundaries so Android can mmap them directly.
zipalign is a small but order-sensitive step: it must run before apksigner, because re-aligning a signed APK breaks the v2 signature. In CI it is one line, but getting that order wrong causes verification failures downstream.
What it does
zipalign rewrites an APK so that uncompressed data starts on aligned boundaries (4 bytes, or 16KB page alignment with -p for shared libraries), which lets Android access resources via mmap without copying. It does not sign; it only rearranges alignment. -c checks alignment without writing.
Common usage
zipalign -v 4 app-unsigned.apk app-aligned.apk
zipalign -p 4 app-unsigned.apk app-aligned.apk # page-align .so files
zipalign -c -v 4 app-aligned.apk # verify alignment only
zipalign -f 4 in.apk out.apk # overwrite outputOptions
| Flag | What it does |
|---|---|
| 4 | Alignment in bytes (always 4 for APKs) |
| -p | Page-align uncompressed .so shared libraries |
| -c | Check alignment; do not write output |
| -v | Verbose output |
| -f | Overwrite the output file if it exists |
In CI
Run zipalign then apksigner, in that order. If your Gradle release build already produces a signed, aligned APK, do not re-align it. zipalign lives in $ANDROID_HOME/build-tools/<version>/, so add that to PATH or call it by full path.
Common errors in CI
"zipalign: command not found" means the build-tools bin is not on PATH; use the full path under $ANDROID_HOME/build-tools. "Unable to open ... as zip archive" means the input is not a valid APK/zip. If a later apksigner verify reports the v2 signature does not verify, you likely aligned after signing; align first, then sign.