Android Studio 프로젝트에서 코드를 혼동하기 위해 build.gradle 파일에 다음 설정을 추가합니다. 이때 혼동 규칙은 일반적으로 proguard-rules.pro 파일에 정의되며, 필요 시 사용자 정의 파일로 대체할 수 있습니다.
buildTypes {
release {
signingConfig signingConfigs.release
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
이후 proguard-rules.pro 파일에 아래 규칙을 포함시켜 기본적인 보호 조건을 설정합니다:
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
-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.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService
-keepclasseswithmembernames class * {
native <methods>;
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
Android Studio는 libs/ 폴더 내의 모든 JAR 파일을 자동으로 번들링 처리하므로, 수동으로 추가하지 않아야 합니다. 중복 등록 시 java.io.IOException: The same input jar is specified twice 오류가 발생합니다.
외부 라이브러리가 이미 혼동되어 있거나 리플렉션을 사용하는 경우, 해당 라이브러리 패키지에 대한 혼동을 제외해야 합니다. 예시로 다음과 같이 설정할 수 있습니다:
-keep class org.greenrobot.greendao.** { *; }
-dontwarn org.greenrobot.greendao.**
-keep class com.jakewharton.** { *; }
-dontwarn com.jakewharton.**
-keep class io.reactivex.** { *; }
-dontwarn io.reactivex.**
-keep class org.jsoup.** { *; }
-dontwarn org.jsoup.**
-keep class com.squareup.retrofit2.** { *; }
-dontwarn com.squareup.retrofit2.**
-keep class com.scottyab.** { *; }
-dontwarn com.scottyab.**
-keep class com.pddstudio.preferences.encrypted.** { *; }
-dontwarn com.pddstudio.preferences.encrypted.**
경고 메시지 can't find referenced class가 발생할 경우, 해당 클래스가 실제로 사용되지 않는다고 확신되면 -dontwarn 옵션을 사용해 경고를 무시할 수 있습니다. 그러나 이는 위험할 수 있으며, 실행 시 ClassNotFoundException가 발생할 수 있으므로 신중하게 사용해야 합니다.
더 안전한 접근 방식은 혼동 대상 외에 특정 라이브러리 패키지를 유지하면서 경고를 억제하는 것입니다:
-keep class com.welhzh.android.gms.** { *; }
-dontwarn com.welhzh.android.gms.**
또는 더 세밀하게 공개된 구성 요소만 유지하는 방식도 가능합니다:
-keep public class com.welhzh.android.gms.* { public *; }
-dontwarn com.welhzh.android.gms.**
Google Play Services 관련 오류가 발생하는 경우, 다음 규칙을 추가하여 문제를 해결할 수 있습니다:
-keep class * extends java.util.ListResourceBundle {
protected Object[][] getContents();
}
-keep public class com.google.android.gms.common.internal.safeparcel.SafeParcelable {
public static final *** NULL;
}
-keepnames @com.google.android.gms.common.annotation.KeepName class *
-keepclassmembernames class * {
@com.google.android.gms.common.annotation.KeepName *;
}
-keepnames class * implements android.os.Parcelable {
public static final ** CREATOR;
}
필요 시 특정 패키지만 혼동을 적용하거나, 반대로 일부 패키지는 혼동을 피할 수도 있습니다:
-keep class !com.foo.**,!com.bar.** { *; }
-dontwarn !com.foo.**,!com.bar.**