Repository navigation
build: compress DEX and native libs in APK (legacy packaging) - #364
TimeToBuildBob wants to merge 1 commit into
Conversation
Sets dex.useLegacyPackaging = true and jniLibs.useLegacyPackaging = true so that DEX and .so files are stored compressed rather than uncompressed. Per-ABI APKs are currently 61–73 MB uncompressed. IzzyOnDroid maintainer estimates legacy packaging reduces APK size by 30–40 MB, potentially bringing arm64 within the ~30 MB per-app limit. Trade-off: compressed .so prevents Android 9+ from mmapping the library directly from the APK zip, adding extraction overhead on install/update. The size benefit is significant enough for third-party repo distribution. Closes: ActivityWatch#61 (pending CI measurement) Git-Session-Id: 63be8af6-6fc3-4ea8-9852-4cf1b5219c81
🤖 AI code reviewAdds a Safe to merge — no P0/P1 findingsConfidence 5/5 ✅ No findings. The diff looks correct to me on this pass. Files changed (1) — the diff as I read it
Previous review passes
Reviewed Maintainer commands
|
|
Updated after IzzySoft's clarification on ActivityWatch/aw-android#61: this PR is now draft, not waiting only on a merge click. IzzyOnDroid relisting is ruled out under its no-LLM policy. The diff currently enables compression globally, while universal and per-ABI builds have different download/installed-storage trade-offs. The APK build matrix was skipped, so passing tests do not supply the promised size comparison. Removed the issue-closing claim from the description. Maintainer distribution-scope/F-Droid preference and measured APK/installed-footprint evidence remain prerequisites to selecting a default; no code change or merge made. |
|
@greptileai review |
[High impact] No actionable defect was found; the packaging change appears safe to merge. SummaryEnables
Reviews (1) · Last reviewed commit: "build: compress DEX and native libs in A..." · Reviewed by Greptile |
Measured compression effect on the published v0.14.3 APKsThe build matrix is skipped on PRs, so there is no before/after APK measurement from CI. I measured the compression effect directly against the published v0.14.3 artifacts instead (byte sizes match the release assets exactly; SHA-256 verified for the four per-ABI APKs, universal downloaded from the release). Method: One finding first: the
|
| APK | current | est. after | saving | % |
|---|---|---|---|---|
arm64-v8a |
70.56 MB | 25.40 MB | 45.16 MB | 64.0% |
armeabi-v7a |
61.40 MB | 23.47 MB | 37.94 MB | 61.8% |
x86 |
73.20 MB | 26.25 MB | 46.95 MB | 64.1% |
x86_64 |
73.13 MB | 25.77 MB | 47.36 MB | 64.8% |
| universal | 271.24 MB | 93.84 MB | 177.40 MB | 65.4% |
The native payloads compress ~2.9×, roughly 4 MB better than the ~30 MB / "around 40 MB" figures in #61 — the per-ABI APKs would land at ~24-26 MB.
Installed footprint is where universal and per-ABI diverge
Legacy packaging also sets extractNativeLibs=true, so libs are extracted at install rather than mmapped from the APK. Derived (not measured) on an arm64 device:
- Universal: ≈ 94 MB APK + ≈ 69 MB extracted arm64 libs ≈ 163 MB, versus ≈ 271 MB today — better on both axes (the non-matching ABI libs stay compressed inside the APK instead of sitting on disk).
- Per-ABI: ≈ 25 MB APK + ≈ 69 MB extracted libs ≈ 94 MB, versus ≈ 70.6 MB today — a ~24 MB installed regression traded for the ~45 MB download saving.
So the universal-only option this PR leaves open is the one with no installed-footprint penalty; the global option costs per-ABI installs ~24 MB and an install-time extraction step.
Not verified
- No startup measurement for the extracted-library path (no Java/emulator toolchain here); the mechanism is extraction at first launch.
- No real rebuild, so AGP's actual deflate output is unconfirmed.
I'm not selecting a default — that's the maintainer scope decision this PR is waiting on. But the data reframes it: it is no longer "universal vs global at ~30-40 MB", it is "universal is a strict win on both axes; global trades ~24 MB of per-ABI installed storage for the download saving." Given IzzyOnDroid relisting is ruled out on policy (not size), the remaining question is whether download size alone justifies that per-ABI cost.
Head: 59b89c1963fa1eabb336560c1d6a5349096187fb
Summary
Proposes
dex.useLegacyPackaging = trueandjniLibs.useLegacyPackaging = trueinmobile/build.gradle, compressing DEX and native-library ZIP entries. The current diff applies to both universal and per-ABI APKs; it is not a universal-only change.Related: #61. This is a packaging experiment, not an issue-closing fix or an IzzyOnDroid relisting path.
Distribution decision still needed
IzzySoft's follow-up confirms that ActivityWatch is not eligible for IzzyOnDroid under its no-LLM policy. A smaller APK does not change that decision.
The remaining motivation is reducing download/transfer cost, especially for the universal APK. Compressing native libraries requires extraction on install, trading smaller APKs against extraction overhead and an additional native-library copy on device. Universal and single-ABI builds have different trade-offs; do not infer installed-size savings from download savings alone.
Before adopting this globally, maintainers should decide whether compression should be universal-only or also apply to per-ABI builds, and clarify F-Droid's preference as IzzySoft suggested. This PR does not establish that preference.
Verification
Current-head tests passed, including the release-variant R8 smoke test and Android API 29 E2E check. The APK build matrix was skipped, so these checks do not provide before/after release APK size measurements or installed-footprint evidence.
Still required before choosing a default: comparable universal/per-ABI build sizes, installed-footprint and startup checks for the compressed native-library path, and a maintainer decision on distribution scope. The size reductions discussed in the issue remain estimates, not measurements of this PR.