# Keep line numbers for crash reports
-keepattributes SourceFile,LineNumberTable
-renamesourcefileattribute SourceFile
# Keep data classes
-keep class com.example.myapp.models.** { *; }
-keep class com.example.myapp.data.remote.** { *; }
# Keep Parcelable implementations
-keepclassmembers class * implements android.os.Parcelable {
public static final ** CREATOR;
}
# Keep Serializable classes
-keepclassmembers class * implements java.io.Serializable {
private static final java.io.ObjectStreamField[] serialPersistentFields;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}
# Retrofit
-keepattributes Signature, InnerClasses, EnclosingMethod
-keepattributes RuntimeVisibleAnnotations, RuntimeVisibleParameterAnnotations
-keepclassmembers,allowshrinking,allowobfuscation interface * {
@retrofit2.http.* <methods>;
}
# Moshi
-keepclasseswithmembers class * {
@com.squareup.moshi.* <methods>;
}
-keep @com.squareup.moshi.JsonQualifier interface *
-keepclassmembers class kotlin.Metadata {
public <methods>;
}
# Kotlin Coroutines
-keepnames class kotlinx.coroutines.internal.MainDispatcherFactory {}
-keepnames class kotlinx.coroutines.CoroutineExceptionHandler {}
-keepclassmembernames class kotlinx.** {
volatile <fields>;
}
# Glide
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep class * extends com.bumptech.glide.module.AppGlideModule {
<init>(...);
}
-keep public enum com.bumptech.glide.load.ImageHeaderParser$** {
**[] $VALUES;
public *;
}
# Room
-keep class * extends androidx.room.RoomDatabase
-keep @androidx.room.Entity class *
-dontwarn androidx.room.paging.**
# Keep custom views
-keep public class * extends android.view.View {
public <init>(android.content.Context);
public <init>(android.content.Context, android.util.AttributeSet);
public <init>(android.content.Context, android.util.AttributeSet, int);
}
# Keep enum values
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
# Remove logging in release
-assumenosideeffects class android.util.Log {
public static *** d(...);
public static *** v(...);
public static *** i(...);
}
# Keep native methods
-keepclasseswithmembernames class * {
native <methods>;
}
# Firebase
-keepattributes *Annotation*
-keepattributes Signature
-keep class com.google.firebase.** { *; }
android {
buildTypes {
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
// Keep debug symbols for crash reports
debuggable false
// Generate mapping file
proguardFiles 'proguard-rules.pro'
}
debug {
minifyEnabled false
debuggable true
}
}
}
ProGuard and R8 shrink, obfuscate, and optimize Android apps for release builds. R8 is the default tool, combining shrinking and desugaring. I configure rules in proguard-rules.pro—keeping classes used by reflection, serialization, or native code. -keep preserves classes and members, -keepnames keeps names but allows shrinking. Obfuscation renames classes/methods making reverse engineering harder. Optimization removes unused code and inlines methods. Source file and line numbers mapping enables crash report deobfuscation with mapping.txt. Data classes, Parcelable, and library-specific rules require careful configuration. Testing release builds catches configuration issues. Proper ProGuard setup reduces APK size significantly while protecting intellectual property.