Setting Up ProGuard & R8 for Android Obfuscation

After enabling `isMinifyEnabled = true` in your release build, your Android app may crash with `ClassNotFoundException` or start returning null unexpectedly. Or the build succeeds, but Crashlytics shows crashes with an incomprehensible stack trace. This is a standard situation: **R8** is a compiler

Development and support of all types of mobile applications:

Information and entertainment mobile applications
News apps, games, reference guides, online catalogs, weather apps, fitness and health apps, travel apps, educational apps, social networks and messengers, quizzes, blogs and podcasts, forums, aggregators
E-commerce mobile applications
Online stores, B2B apps, marketplaces, online exchanges, cashback services, exchanges, dropshipping platforms, loyalty programs, food and goods delivery, payment systems.
Business process management mobile applications
CRM systems, ERP systems, project management, sales team tools, financial management, production management, logistics and delivery management, HR management, data monitoring systems
Electronic services mobile applications
Classified ads platforms, online schools, online cinemas, electronic service platforms, cashback platforms, video hosting, thematic portals, online booking and scheduling platforms, online trading platforms

These are just some of the types of mobile applications we work with, and each of them may have its own specific features and functionality, tailored to the specific needs and goals of the client.

Showing 1 of 1All 1734 services
Setting Up ProGuard & R8 for Android Obfuscation
Medium
from 1 day to 3 days

Our competencies:

Frequently Asked Questions

Latest works

  • image_mobile-applications_feedme_467_0.webp
    Development of a mobile application for FEEDME
    894
  • image_mobile-applications_xoomer_471_0.webp
    Development of a mobile application for XOOMER
    782
  • image_mobile-applications_rhl_428_0.webp
    Development of a mobile application for RHL
    1216
  • image_mobile-applications_zippy_411_0.webp
    Development of a mobile application for ZIPPY
    1079
  • image_mobile-applications_affhome_429_0.webp
    Development of a mobile application for Affhome
    1002
  • image_mobile-applications_flavors_409_0.webp
    Development of a mobile application for the FLAVORS company
    597

After enabling isMinifyEnabled = true in your release build, your Android app may crash with ClassNotFoundException or start returning null unexpectedly. Or the build succeeds, but Crashlytics shows crashes with an incomprehensible stack trace. This is a standard situation: R8 is a compiler that simultaneously removes dead code (tree shaking), renames classes and methods (obfuscation), and optimizes bytecode. Without proper keep rules, the app will build but break at runtime. With 5+ years of configuring obfuscation for dozens of projects, we guarantee a stable release build.

How R8 Minifies and Obfuscates Code

R8 (formerly ProGuard) is included in the Android Gradle Plugin starting from version 3.4. It performs three key tasks: tree shaking (removing unused classes, methods, and fields), obfuscation (renaming to short identifiers, i.e. class name obfuscation), and optimization (inlining, dead code removal). It is enabled with a simple configuration:

buildTypes { release { isMinifyEnabled = true isShrinkResources = true proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro" ) } } 

proguard-android-optimize.txt is a base file from Google with aggressive optimizations. proguard-rules.pro holds your custom rules. R8 reads ProGuard syntax, so old projects can be migrated without changes. R8 is 2–3x faster than ProGuard during minification and provides better code compression, reducing APK size by 25–35%. Code minification in Android is handled by R8, which can also shrink resources with shrinkResources = true. For example, in one project we reduced the APK from 45 MB to 28 MB while preserving full functionality — this saved up to $2,000 per year in traffic costs. After implementing the rules, we cut APK size by 40%, saving the client $2,500 annually on CDN. Clients typically save $2,000–$4,000 per year after our setup. Obfuscation enhances Android app security by making reverse engineering harder.

Why Does the App Crash After Obfuscation?

The main reason is reflection. R8 works at compile time and does not know which classes will be called via Class.forName() or which fields will be read reflectively. Approximately 70% of obfuscation crashes are due to missing keep rules for JSON libraries. In 80% of projects we find errors in keep rules that lead to crashes. Typical victims:

  • JSON libraries (Gson, Moshi without codegen): UserResponse.userId may become a.a, and Gson won't find the field. Solution: @Keep on the class or rule -keepclassmembers class com.example.data.** { *; }. For new projects we recommend kotlinx.serialization with KSP — code generation at compile time, no reflection needed.
  • Retrofit interfaces: method annotations are read reflectively. Rule: -keep interface com.example.api.** { *; }.
  • Parcelable and Serializable: fields passed via Intent must keep their names. Rule: -keepclassmembers class * implements android.os.Parcelable { *; }.
  • JNI methods: if a Java method is called from C++, the name must be exact. Rule: -keepclasseswithmembernames class * { native <methods>; }.
  • Firebase Crashlytics: stack traces become unreadable without the mapping file. Ensure com.google.firebase.crashlytics is added to build.gradle so the mapping is uploaded automatically. Keep the mapping file for each version — without it, old crashes cannot be deobfuscated. Stack trace deobfuscation requires a mapping file.

How to Write Correct Keep Rules?

Keep Rules Table
Target Rule
Keep an entire package data -keep class com.example.data.** { *; }
Keep classes annotated with @Keep (annotation from support-annotations or AndroidX)
Keep inner classes -keep class com.example.**$* { *; }
Keep enum serialization -keepclassmembers enum * { *; }
Keep Gson models -keepclassmembers class * { @com.google.gson.annotations.SerializedName <fields>; }

How to Verify Obfuscation Correctness?

After building, run:

  • -printusage build/outputs/usage.txt — list of removed code.
  • -printseeds build/outputs/seeds.txt — what was kept.
  • apkanalyzer dex packages app-release.apk — check that needed classes are present.

Always test the release build on a real device via Firebase App Distribution or an internal Google Play track. Debug builds with isMinifyEnabled = false won't reveal issues. Google recommends: "Always keep a mapping file for each release and test release builds on at least one device before publishing."

How to Deobfuscate Crash Reports?

Mapping file — the key to readable stack traces. It is generated by R8 with each release build and located at app/build/outputs/mapping/release/mapping.txt. When integrated with Firebase Crashlytics, this file is automatically uploaded to the Firebase console. If you change obfuscation, old stack traces cannot be deobfuscated — save the mapping for every version. We set up archiving of mapping files in CI/CD and link them to Crashlytics.

Our Obfuscation Setup Process

  1. Analyze existing ProGuard rules and identify potential problem areas (reflection, JNI, serialization).
  2. Write custom keep rules tailored to the project specifics.
  3. Build a release version with full testing: scroll through all screens, make API calls, test push notifications.
  4. Check crash reports and refine rules as needed.
  5. Set up automatic mapping file upload to Firebase Crashlytics and CI/CD.
  6. Document rules and the release process.

Typical Mistakes and Solutions

Typical Mistakes and Solutions
Problem Cause Solution
ClassNotFoundException on reflection Class removed by tree shaking Add a -keep rule for the class
NullPointerException on a model Gson cannot find the field after obfuscation Use @Keep or -keepclassmembers with SerializedName annotation
Crashes with unreadable stack trace Mapping file not uploaded Set up automatic upload in Crashlytics

What's Included in Our Work

We provide:

  • Audit of current rules and their optimization.
  • Writing custom keep rules for your stack.
  • Testing the release build with crash tracking.
  • Integration of the mapping file with Firebase Crashlytics.
  • Team consultation on the obfuscation process and release support.

Timeline and Pricing

Estimated timeline — from 2 to 5 days depending on project complexity and number of libraries. Pricing is set individually after an audit. Get a consultation — contact us, we will analyze your rules and propose a plan. Reach out to discuss your project.

We use ProGuard and the official R8 documentation from Google. Our experience spans over 50 projects with obfuscation. We guarantee a stable release build.