跪拜 Guibai
← All articles
Frontend · Android · Flutter

R8 Configuration Analyzer Turns Keep Rules into Hard Numbers

By 恋猫de小郭 ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

Keep rules have been a blind spot: a single overly broad consumer rule from a library can silently block optimization across thousands of methods. This tool makes the cost visible and measurable, so teams can stop guessing and start trimming.

Summary

R8 Configuration Analyzer, now built into AGP 9.3, assigns a Shrinking Score, Optimization Score, and Obfuscation Score to a release build, quantifying the exact percentage of classes, fields, and methods still eligible for R8's transformations. A drop from 82% to 61% optimization after a dependency bump immediately flags the culprit. The tool maps every keep rule to its blast radius — the precise count of live classes, fields, and methods it locks out of optimization — and traces the rule back to its source file and Maven coordinate, including consumer rules buried inside third-party AARs. It also detects subsumed rules, where a broad wildcard already covers a narrower, redundant keep statement. Google ships an `r8-analyzer` Skill in the official `android/skills` repo that packages the entire workflow — running the analyzer, converting protobuf output to JSON, and generating a ranked report — into a scripted SOP a coding agent can execute. For projects stuck on older AGP versions, the Skill falls back to a heuristic path that flags package-wide wildcards and other high-impact patterns by syntax alone.

Takeaways
R8 Configuration Analyzer produces three scores — Shrinking, Optimization, Obfuscation — that represent the percentage of live code still eligible for each transformation.
An Optimization Score of 66% means 34% of classes, fields, and methods are blocked from inlining, merging, and other structural optimizations by keep rules.
The analyzer maps every keep rule to its blast radius: the exact count of live classes, fields, and methods it constrains, along with the specific constraint type (DONT_OPTIMIZE, DONT_SHRINK, DONT_OBFUSCATE).
Consumer rules from third-party AARs are included in the analysis, and the tool traces each rule back to its source file and Maven coordinate.
Subsumed rules — where a broad wildcard already covers a narrower keep statement — are explicitly detected and flagged.
AGP 9.3 adds a standalone Gradle task `analyzeReleaseR8Config` that runs the analyzer without building a full APK or App Bundle.
Google's `r8-analyzer` Skill automates the full pipeline: version detection, protobuf-to-JSON conversion, quantitative analysis, and report generation.
For projects without a compatible R8 version, the Skill falls back to a heuristic path that checks for high-risk patterns like package-wide wildcards and `!` inversion.
Conclusions

The analyzer closes a long-standing feedback gap: developers could write keep rules but had no way to measure their actual cost in lost optimization. Now that cost is a number that trends up or down with every config change.

Shifting the analysis from syntax to compiler-level program graphs means the tool sees the merged reality of all rules — including those injected silently by libraries — rather than just what's written in the app's own proguard file.

Packaging the analyzer as an agent-executable Skill signals Google's bet that keep-rule hygiene will become a routine, automated CI check rather than a manual audit.

The tool explicitly cannot prove a rule is safe to remove; it only quantifies the blast radius. The final call still requires runtime semantics knowledge — reflection, JNI, serialization — that static analysis cannot supply.

Concepts & terms
Blast Radius
In R8 Configuration Analyzer, the precise count of live classes, fields, and methods that a single keep rule prevents from being shrunk, optimized, or obfuscated. Each rule's blast radius is recorded in a table alongside its constraint types and source location.
Consumer Rules
ProGuard/R8 keep rules bundled inside an Android library (AAR) that are automatically merged into the host app's full configuration. Library authors often write these conservatively, and they can silently block optimization across large portions of an app.
Subsumed Rules
A keep rule whose effect is already fully covered by a broader rule elsewhere in the configuration. For example, `-keep class com.example.package.User` is subsumed by `-keep class com.example.package.** { *; }`. The analyzer detects and flags these redundancies.
Source: juejin.cn ↗ Google Translate ↗ Backup ↗