Knowledge Base

ProGuard Rules for Android

Optimize release builds by preserving essential classes and avoiding runtime crashes.

Problem

When building a release version of an Android app with minification enabled, the app may crash at runtime due to ProGuard or R8 shrinking or obfuscating necessary code. To ensure the app runs smoothly in release builds, it’s important to explicitly retain critical classes and methods. This can be achieved by adjusting your ProGuard rules to prevent essential code from being removed or altered during the minification process.

Symptoms:

  • The app compiles successfully with no errors.
  • The app crashes immediately upon launching in a release build.
  • Logs or crash reports may indicate missing or improperly obfuscated classes/methods.

Example crash log:

To help identify issues caused by missing or obfuscated classes, here’s a typical crash log that you might encounter when the necessary ProGuard rules are not applied:

// Example crash log java.lang.NoSuchMethodError: no static method "Llive/ditto/internal/swig/ffi/dittoffiJNI;.SwigDirector_Retainable_retain(Llive/ditto/internal/swig/ffi/Retainable;)V”

How to Diagnose

  1. Build and Deploy: Build the release APK or AAB using the release variant with minification enabled.
  2. Deploy to a Device or Emulator: Install and run the app on a real device or emulator.
  3. Crash Detection: If the app crashes immediately at launch when Ditto is created and starts to sync, check the logs via adb logcat or your crash reporting tool to determine the root cause. Look for missing classes, methods, or any ClassNotFoundException or NoSuchMethodException errors.

Solution

To ensure optimal app performance when using the Ditto SDK, update your ProGuard rules to retain critical classes. Depending on the features you're using, you’ll need to add specific rules to prevent ProGuard from stripping essential code:

Ditto Native Bindings - Required for All Ditto SDK Use:

This rule ensures that all native bindings related to Ditto are preserved and available at runtime.

-keep class live.ditto.internal.swig.ffi.** { *; }

Ditto Blanket Exclusion - Required for Presence

This rule retains all Ditto classes, which is essential for features like Presence Viewer, and ensures Jackson classes are preserved for proper JSON deserialization.

-keep class live.ditto.** { *; } -keepnames class com.fasterxml.jackson.** { *; }

Explanation:

  • keep class live.ditto.internal.swig.ffi.** ensures that all classes and interfaces under the live.ditto.internal.swig.ffi package (including sub-packages) are retained.
  • { *; } specifies that all members (fields, methods, constructors, etc.) of these classes should be preserved as well.
  • This rule prevents ProGuard from shrinking, obfuscating, or modifying these classes, ensuring that your app functions correctly in a minified release build.

Additional Tips:

  • ProGuard Optimization: While adding keep rules is essential, try to keep them as specific as possible to avoid retaining unnecessary classes, which can lead to a larger APK/AAB size.
  • Testing: Always thoroughly test your app in both debug and release modes. Use logging or crash reporting to capture issues during the release phase.
  • ProGuard Mapping Files: Generate and keep mapping files during your release builds (minifyEnabled true). They are useful for decoding stack traces and identifying the causes of crashes related to ProGuard

Need additional help? Contact us! Our support team is ready to assist with any further questions.