Android Studio에서 코드 혼동 설정 방법

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.**

태그: Android Studio proguard code obfuscation build.gradle Android SDK

7월 15일 00:43에 게시됨