Skip to content

build: R8-shrink the published APK (~72 MB) — the reflection-safe way - #332

Merged
SMK1705 merged 1 commit into
mainfrom
perf/r8-shrink-release
Jul 29, 2026
Merged

build: R8-shrink the published APK (~72 MB) — the reflection-safe way#332
SMK1705 merged 1 commit into
mainfrom
perf/r8-shrink-release

Conversation

@SMK1705

@SMK1705 SMK1705 commented Jul 29, 2026

Copy link
Copy Markdown
Owner

…ease-gated

Enables R8 minify + resource shrinking on the published (debug-signed) build, gated
behind -Pshrink so ordinary local/CI builds stay fast and un-minified. Clean-built, the
primary APK drops 94 -> ~72 MB; with the arm64 slim it's now 199 -> ~72 MB (64% smaller).

Details / hard-won specifics:
- proguard-rules.pro: -dontobfuscate (renaming is what silently breaks reflection; skipping
  it keeps the risk low while still stripping dead code + resources). Keep the ML/crypto JNI
  libs whole (native code resolves them by name), keep app models, keep annotation/signature
  attributes. Hilt/Room/Retrofit/Compose consumer rules are auto-applied from their AARs.
- AskConversationStore: StoredConversation/StoredTurn now carry @JsonClass(generateAdapter=true).
  They were the ONLY Moshi models still using the reflective KotlinJsonAdapterFactory, which
  needs kotlin-reflect at runtime — and R8 strips it, so persistence crashed the Ask/Settings
  screens under R8 (device-caught). Codegen adapters have no runtime-reflection dependency.
- build.gradle.kts: debug build type sets isMinifyEnabled/isShrinkResources only when -Pshrink.
- release-apk.yml: build the slim+shrunk PRIMARY first on the fresh CI tree (a -Pshrink build
  after a non-shrink one leaves ~20 MB of stale native-lib padding that eats the dex saving),
  then the universal fallback. Publishes the shrunk build at the stable taskmind-debug.apk URL.

Device-verified end to end on the Galaxy S25 at 71.5 MB — the reflection gauntlet all passes:
launch (SQLCipher/Room/Hilt/Compose), cloud extraction (Moshi codegen), Ask + engine,
Ask thread persist AND restore across a force-stop (the StoredConversation round-trip that
crashed before the @JsonClass fix), Settings, and the MediaPipe neural embedder.

Note: R8 is release-only, so its build failures surface in the release workflow (runs on merge)
and its RUNTIME reflection breakage only on-device — CI builds the un-minified universal. Any
NEW Moshi-serialized model must use @JsonClass(generateAdapter=true), not reflection.
@SMK1705
SMK1705 merged commit abb6c28 into main Jul 29, 2026
1 check passed
@SMK1705
SMK1705 deleted the perf/r8-shrink-release branch July 29, 2026 12:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant