R8 changes more than names
R8 is Android’s default code optimizer. Google documents tree shaking, method inlining, class merging, resource shrinking and name minification. An interface or helper class from the source may disappear because its code was folded into a caller. A lambda can become a synthetic class. A constant branch can vanish.
This is why searching for the original architecture fails. The release APK contains the optimized program, and that program is the evidence. Request paths, Android entry points, serialized field names and observable calls remain useful even when abstractions are gone.
Reconstruct the optimized path
We begin with the action visible to the user and follow the optimized call graph into the network layer. HTTP libraries, content types, hostnames, error parsers and storage calls provide anchors. When R8 has inlined a signer or serializer, data flow exposes the operation inside its new parent method.
- Identify code kept for reflection, JNI and Android components.
- Track values rather than relying on class names.
- Separate library code from application-specific request logic.
- Confirm inferred types against runtime inputs and responses.
Turn the optimized build into a client
The deliverable restores clear names and boundaries across the full application flow. It covers session setup, request construction, parsing and failures. Recreating the original source tree is unnecessary when a smaller, tested client expresses the same server API specification.
Reviewed 30 August 2026 · SReverse research desk