I've build a release Android application with proguard, but after decompiling of APK I see that classes, which must be obfuscated, have normal sources. There's a part of my gradle build :
buildTypes {
debug {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
And here's my proguard-rules.pro file:
-dontpreverify
-repackageclasses ''
-allowaccessmodification
-keepattributes *Annotation*
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-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);
public void set*(...);
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers class * implements android.os.Parcelable {
static android.os.Parcelable$Creator CREATOR;
}
-keepclassmembers class **.R$* {
public static <fields>;
}
-keep public class * extends android.support.v4.app.Fragment
-keep public class * extends android.app.Fragment
-keepnames class * implements java.io.Serializable
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
private static final java.io.ObjectStreamField[] serialPersistentFields;
!static !transient <fields>;
!private <fields>;
!private <methods>;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}
-assumenosideeffects class android.util.Log {
public static *** e(...);
public static *** w(...);
public static *** wtf(...);
public static *** d(...);
public static *** v(...);
}
-keepclasseswithmembernames class * {
native <methods>;
}
-keepclassmembers class * {
public void *ButtonClicked(android.view.View);
}
-dontwarn okio**
-dontwarn java.lang.invoke**
-dontwarn org.apache.commons.io**
-dontwarn org.codehaus**
-keep public class java.nio**
-dontwarn android.support.v4.**
-keep class android.support.v4.** { *; }
-dontwarn android.support.v7.**
-keep class android.support.v7.** { *; }
-keep class net.sqlcipher.** { *; }
-keep class net.sqlcipher.database.** { *; }
-keep class retrofit2.** { *; }
-keepattributes Signature
-keepattributes Exceptions
-keepclasseswithmembers class * {
@retrofit2.http.* <methods>;
}
-keep class com.squareup.okhttp.** { *; }
-keep interface com.squareup.okhttp.** { *; }
-keep class com.google.gson.** { *; }
-keep class com.google.inject.* { *; }
-keep class org.apache.http.** { *; }
-keep class org.apache.james.mime4j.** { *; }
-keep class javax.inject.** { *; }
-keepclassmembernames interface * {
@retrofit.http.* <methods>;
}
-keep class sun.misc.Unsafe { *; }
-keep public class !com.vidal.cardio.datas.MySQLCipherOpenHelper { *; }
-keep public class !com.vidal.cardio.datas.SCLcipherOpenHelper { *; }
Well, I've expected that MySQLCipherOpenHelper
and SCLcipherOpenHelper
will be obfuscated, but actually they don't. Maybe there's a mistake in proguard-rules.pro?
Keep rules will be analyzed and processed independently from each other, so if you write rules like this
-keep public class !com.vidal.cardio.datas.MySQLCipherOpenHelper { *; }
-keep public class !com.vidal.cardio.datas.SCLcipherOpenHelper { *; }
ProGuard will do the following:
as you can see, with the first rule you also implicitly keep the second class, while with the second rule you keep the first one as well.
In order to not keep both of them, you have to merge the rules like that:
-keep public class !com.vidal.cardio.datas.MySQLCipherOpenHelper,
!com.vidal.cardio.datas.SCLcipherOpenHelper { *; }