ProGuard

2026. 2. 15. 23:31·안드로이드/정리

ProGuard

ProGuard는 "단순히 코드를 알아보기 어렵게 만드는 난독화 도구"로만 알려져 있지만, 실제로는 자바 바이트코드를 분석하고 재구성하는 일종의 전처리 컴파일러에 가깝다.
ProGuard는 자바 바이트코드(.class)를 대상으로 동작하는 도구로

  1. 코드 난독화 (Obfuscation)
  2. 코드 축소 (Shrinking)
  3. 코드 최적화 (Optimization)

를 수행한다.

 

ProGuard의 핵심 원리는 크게 네 단계로 나눌 수 있다.


첫 번째는 분석(Analysis) 단계다. 이 단계에서 ProGuard는 모든 클래스, 메서드, 필드 간의 참조 관계를 그래프 형태로 분석한다. 어떤 코드가 실제로 사용되고 있는지, 어디서 호출되는지, 서로 어떤 의존성을 가지는지를 추적한다.
두 번째는 축소(Shrinking) 단계다. 분석 결과를 기반으로 실제로 참조되지 않는 코드, 즉 실행 경로상 절대 사용되지 않는 클래스나 메서드를 제거한다. 이를 통해 APK 용량을 줄이고 불필요한 코드 노출을 방지한다.
세 번째는 최적화(Optimization) 단계다. 여기서는 불필요한 분기를 제거하거나 단순한 메서드를 인라인 처리하거나 중복 코드를 정리하는 등의 작업이 이루어진다.
마지막 단계가 우리가 흔히 알고 있는 난독화(Obfuscation)다. 이 과정에서 클래스명, 메서드명, 변수명이 의미 없는 짧은 이름으로 변경된다. 중요한 점은 난독화는 전체 과정의 일부일 뿐이며 실제로는 코드 제거와 구조 재배치가 더 큰 비중을 차지한다는 것이다.

 

안드로이드에서 설정 방법

minifyEnabled 속성을 이용해 활성/비활성 설정을 활성화하면 release 빌드 시 ProGuard가 동작하게 된다.

  • 현재는 R8이 대체하고 있음
buildTypes {
        release {
            // 프로가드 활성화
            minifyEnabled true
            // 기본 프로가드 설정
            proguardFile getDefaultProguardFile('proguard-android.txt')
            // 프로젝트에 필요한 프로가드 설정
            proguardFile 'proguard-rules.pro'
        }

        debug{
            // 프로가드 비활성화
            minifyEnabled false
            proguardFile getDefaultProguardFile('proguard-android.txt')
            proguardFile 'proguard-rules.pro'
        }
    }

 

Keep Rule은 왜 필요한가

ProGuard가 이렇게 공격적으로 코드를 제거할 수 있는 이유는 "명시적으로 사용되지 않는 코드는 필요 없다"는 전제를 기반으로 동작하기 때문이다. 컴파일 타임에 참조가 확인되지 않는 코드들은 제거 대상이 된다.
문제는 안드로이드 환경에서는 리플렉션, JSON 직렬화 라이브러리(Gson 등), XML 기반 호출처럼 런타임에 동적으로 사용되는 코드가 많다는 점이다. 이러한 코드는 정적 분석 단계에서 사용 여부가 드러나지 않기 때문에 별도의 지시가 없으면 제거되거나 이름이 변경되어 런타임 오류가 발생할 수 있다. 이때 사용하는 것이 바로 Keep Rule이다.

대표적인 옵션은 다음 3가지다.

옵션 의미
-keep 클래스 + 멤버 모두 유지
-keepclassmembers 클래스는 난독화 가능, 멤버는 유지
-keepclasseswithmembers 특정 멤버가 있을 때만 클래스 유지

 

난독화는 어떻게 이뤄지는가?

  • 아무 Rule이 없을 때
  • public class ReturnDataBean { private String tradeResultCode; public String getTradeResultCode() { ... } }
  • proguard 적용 후: 의미는 사라지고 동작만 유지
    • 클래스 명 -> b
    • 변수명 -> a
    • 메서드명 -> a()
      public class b {
          private String a;
          public Stirng a() { ... }
      }

접근 제어자에 따른 난독화 차이

  • { *; } : 해당 패키지의 모든 클래스와 멤버가 제거되지 않고 이름도 변경되지 않는다.
  • { public *; }: public 멤버만 유지되고 private 필드 등은 난독화 대상이 된다.
  • 아무런 규칙을 지정하지 않으면 클래스명, 메서드명, 변수명까지 모두 짧은 문자로 바뀌게 된다. 이 과정은 실행 로직에는 영향을 주지 않지만 코드의 의미를 파악하기 어렵게 만든다.

 

매개변수 이름은 왜 사라질까?

또한 매개변수 이름은 기본적으로 바이트코드에 포함되지 않기 때문에 난독화 후에는 var1같은 형태로 변경된다. 이를 유지하려면 -keepparameternames 옵션을 추가해야 한다.
이처럼 ProGuard는 바이트코드 수준에서 동작하기 때문에 소스 코드에서 보이던 구조가 그대로 유지되는 것은 아니다.

    public void setTradeResultCode(String var1)

 

이를 유지하려면 -keepparameternames 를 명시해야 한다.

 

Shrinking과 Obfuscation 차이

Shrinking과 Obfuscation의 차이도 명확히 이해할 필요가 있다.

  • Shrinking은 사용되지 않는 코드를 아예 제거하는 것. APK 용량 감소, 실행 시 존재X
  • Obfuscation은 코드는 유지하되 이름만 변경하는 것. 이름만 변경되어 실행결과는 동일

-dontshrink 옵션은 코드 제거를 막는 것이고 -dontoptimize는 최적화를 비활성화하는 것이다.
각각의 옵션은 ProGuard의 파이프라인 중 특정 단계를 조정하는 역할을 한다

ProGuard를 제대로 이해하려면 "이 코드는 컴파일 타임에 참조가 확인되는가, 아니면 런타임에 동적으로 사용되는가?"를 항상 염두에 두어야 한다. 컴파일 시점에 명확히 참조되는 코드는 대체로 안전하지만, 리플렉션이나 외부 설정 파일을 통해 접근되는 코드는 반드시 명시적으로 유지해야 한다. 원리를 이해하지 못한 채 규칙을 복사해 사용하는 경우 예상치 못한 런타임 오류를 겪기 쉽다.

ProGuard는 단순히 코드를 숨기는 도구가 아니라 애플리케이션의 구조를 재정렬하고 불필요한 요소를 제거하며 실행 효율을 개선하는 빌드 단계의 핵심 구성 요소다. 그 동작 원리를 이해하면 APK 크기를 효율적으로 줄일 수 있을 뿐 아니라 난독화로 인한 오류도 체계적으로 대응할 수 있다. ProGuard가 "어떻게 판단하고 무엇을 제거하는지"를 이해하는 것이 중요하다.

  • 런타임 참조 → 반드시 Keep Rule 필요
  • 컴파일 타임 참조 → 대부분 자동 처리

 


참고 링크

  • Proguard 사이트
저작자표시 비영리 변경금지 (새창열림)

'안드로이드 > 정리' 카테고리의 다른 글

[Compose 코드랩] 단원 1: 첫 번째 Andriod 앱  (0) 2022.12.03
[안드로이드] ScrollView  (0) 2021.09.22
[안드로이드] FrameLayout  (0) 2021.09.22
[안드로이드] RelativeLayout  (0) 2021.09.21
[안드로이드] LinearLayout  (0) 2021.09.19
'안드로이드/정리' 카테고리의 다른 글
  • [Compose 코드랩] 단원 1: 첫 번째 Andriod 앱
  • [안드로이드] ScrollView
  • [안드로이드] FrameLayout
  • [안드로이드] RelativeLayout
수웅
수웅
  • 수웅
    야금야금 공부
    수웅
  • 전체
    오늘
    어제
    • 분류 전체보기 (90) N
      • 코딩 (3)
      • 알고리즘 (48)
      • CS (15) N
      • 취준 (1)
      • 안드로이드 (17)
        • 코틀린 (6)
        • 정리 (10)
        • 프로젝트 (0)
      • Error (1)
      • Git (2)
      • 기타 (2)
  • 블로그 메뉴

    • 홈
    • 글쓰기
  • 링크

  • 공지사항

  • 인기 글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
수웅
ProGuard
상단으로

티스토리툴바