# Automating Android R8 Optimization with AI Agents

Testing how AI agents handle R8 shrinking, obfuscation, and reflection-based crashes in Android.

- **Source:** [ProAndroidDev - Medium](https://brifing.si/source/d9553fa9-7b72-4b9b-bc73-c6bf9a40dd5f)
- **Published:** 2026-11-09
- **Topic:** [technology](https://brifing.si/c/technology)
- **Original article:** <https://proandroiddev.com/ai-by-lazy-r8-shrinking-and-obfuscation-handled-by-your-agent-e7cb3e124520?source=rss----c72404660798---4>
- **On Brifing:** https://brifing.si/s/c3a0ddee-0c50-4de7-a9f0-31bf2eb2fcb2

## The R8 Optimization Challenge

Many Android projects leave R8 optimization disabled due to past, undocumented build failures. This flag, often set to false in build.gradle.kts, persists as a legacy precaution. Enabling R8 is a critical task for reducing DEX size and improving performance, yet teams frequently postpone it, fearing unpredictable runtime crashes during release.

## R8 Core Functionalities

R8 performs three primary tasks: shrinking, optimization, and obfuscation. It removes unreachable code starting from manifest entry points, inlines methods to optimize execution, and renames classes to shorten names. Since AGP 8.0, R8 operates in full mode by default, which is more aggressive and requires precise keep rules for reflection.

## Reflection and Runtime Crashes

Reflection hides code references from R8, leading to potential runtime crashes. In the test app, Gson parsed JSON into data classes without explicit constructor calls. R8 incorrectly identified these as unused, stripped the constructors, and caused instantiation errors. This demonstrates why automated optimization requires careful configuration to maintain app stability.

## Testing AI Agent Capabilities

The experiment used Claude Opus 5.5 to enable R8 on a Pixel 7 device. Three distinct runs were conducted: a blind prompt, a prompt with visible skills, and one with specific context about Gson. The goal was to reach a production-ready state where the release build functions correctly on hardware.

## Agent Performance and Success

All three AI runs successfully identified the Gson reflection issue and generated appropriate keep rules. They avoided keeping entire packages, opting for granular rules instead. Two agents correctly identified that the build was signed with a debug key, highlighting a potential issue for Play Store deployment, though they focused on R8.

## Inference Versus Verified Evidence

While the agents correctly inferred the need for keep rules, they often failed to verify their work through actual testing. One agent claimed a task detail screen opened without crashes, but could not provide evidence. These unchecked assertions mirror the human tendency to document assumptions as facts in internal wikis.

## The Danger of Unverified Claims

Agents frequently included incorrect technical justifications in their documentation, such as claims about constructor stripping that were disproven by testing. These plausible but false statements can pollute a repository's documentation. It is essential to treat any agent-generated summary without concrete evidence as a TODO item rather than a verified fact.

## Driving Hardware for Validation

Automated testing on physical devices proved difficult due to missing accessibility metadata. Agents struggled with UI interactions, sometimes resorting to raw coordinate taps. One agent accidentally triggered Google Voice Search after a failed back press. This highlights the necessity of robust UI testing frameworks when delegating build tasks to AI.

## Optimizing Keep Rule Strategy

The most effective solution involved using @SerializedName annotations and default constructor values instead of manual keep rules. This approach ensures that rules remain valid even if classes are moved between packages. By leveraging Kotlin's default parameters, developers can satisfy R8 requirements without relying on fragile, hard-coded configuration files in the repository.

## Limitations of Code Inference

The experiment succeeded because the reflection was contained within the app's own code. In real-world scenarios, reflection often hides within third-party dependencies that are difficult to analyze. In such cases, agents cannot rely on inference alone; they must run the release build and observe actual failures to identify necessary rules.

## Long-term Architectural Solutions

The ultimate solution for R8-related reflection issues is moving away from reflection-based libraries like Gson. Libraries that generate code at compile-time, such as Moshi or kotlinx.serialization, avoid these R8 surprises entirely. Migrating to these tools is a superior long-term strategy compared to maintaining complex, manual keep rules for legacy reflection-based code.

## The Golden Rule for R8

The most important takeaway is to make the build fail first. Reproduce the crash in a release build before applying any fixes. A rule created without observing a failure is merely a guess. Always separate verified evidence from agent inferences to ensure that your production build remains stable and reliable.

## Sources covering this story

- https://proandroiddev.com/ai-by-lazy-r8-shrinking-and-obfuscation-handled-by-your-agent-e7cb3e124520?source=rss----c72404660798---4 — 

---

_Summary written by Brifing from the original reporting. Copyright in the original article belongs to its publisher; read the full piece at the link above._
