# 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.
Related snips
package com.example.myapp
import android.app.Application
import dagger.hilt.android.HiltAndroidApp
@HiltAndroidApp
Dependency injection with Hilt
package com.example.myapp.ui
import androidx.lifecycle.*
import kotlinx.coroutines.launch
class UserViewModel(
LiveData transformations and mediators
# BAD: N+1 query problem
@users = User.all
@users.each do |user|
puts user.posts.count # Fires query for each user!
end
ActiveRecord query optimization and N+1 prevention
-- EXPLAIN ANALYZE (actual execution statistics)
EXPLAIN ANALYZE
SELECT u.username, COUNT(o.id) AS order_count
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
WHERE u.created_at >= '2024-01-01'
Advanced query optimization techniques
package com.example.myapp.utils
import android.os.Build
import android.os.StrictMode
import android.os.Trace
import timber.log.Timber
Performance optimization and profiling
const withBundleAnalyzer = require('@next/bundle-analyzer')({
enabled: process.env.ANALYZE === 'true',
openAnalyzer: true,
});
/** @type {import('next').NextConfig} */
Next.js bundle analyzer for targeted performance work
Share this code
Here's the card — post it anywhere.