gonnux.com



LIT-r8-code-shrink-obfuscate-overview

2026-02-20

topic/android

요약

R8은 Android의 기본 코드 축소·난독화·최적화 도구다. ProGuard의 후속작으로 AGP 3.4부터 내장되었다. build.gradle에서 minifyEnabled true를 설정하면 릴리스 빌드 시 자동으로 동작한다.

R8이 하는 4가지 일

1. 코드 축소 (Shrinking)

앱의 진입점(Activity, Service 등)에서 시작해 실제로 호출되는 코드만 추적한다. 도달 불가능한 클래스, 메서드, 필드는 최종 빌드에서 제거된다. 라이브러리에서 쓰지 않는 기능도 잘려나간다.

2. 난독화 (Obfuscation)

남은 코드의 클래스명, 메서드명, 필드명을 a, b, c 같은 짧은 이름으로 바꾼다. 두 가지 효과가 있다:

  • DEX 파일 크기 감소 (긴 이름 → 짧은 이름)
  • 리버스 엔지니어링 난이도 증가

3. 최적화 (Optimization)

바이트코드 수준에서 인라이닝, 상수 폴딩, 불필요한 분기 제거 등을 수행한다.

4. 리소스 축소 (Resource Shrinking)

shrinkResources true를 함께 설정하면, 코드에서 참조되지 않는 이미지, 레이아웃, 문자열 등 리소스 파일도 제거한다.

Mapping 파일

R8이 난독화를 수행하면 app/build/outputs/mapping/release/mapping.txt가 생성된다. 이 파일은 난독화 전후 이름의 매핑 정보를 담고 있다.

원래 이름                    → 난독화된 이름
com.gonnux.secureqr.Crypto  → a.b.c
encrypt()                    → a()

앱이 crash되면 스택 트레이스에 a.b.c.a() 같은 이름만 나온다. mapping 파일이 있어야 원래 코드로 복원할 수 있다. Play Console에 업로드하면 crash 보고서가 자동 해석된다. 파일을 분실하면 해당 버전의 crash는 영구적으로 해석 불가능하다.

ProGuard Rules

R8은 코드 도달 가능성을 정적 분석으로 판단하므로, 리플렉션이나 JNI처럼 동적으로 접근하는 코드는 "안 쓰는 코드"로 오판해 제거할 수 있다. proguard-rules.pro 파일에 -keep 규칙을 작성해서 보존할 코드를 명시한다.

# Gson이 리플렉션으로 접근하는 모델 클래스 보존
-keep class com.gonnux.secureqr.model.** { *; }

나의 생각

R8은 "공짜 최적화"처럼 보이지만 대가가 있다. 디버깅이 어려워지고, keep 규칙을 잘못 설정하면 런타임에 ClassNotFoundException이 발생한다. 특히 라이브러리 업데이트 시 기존 keep 규칙이 부족해질 수 있어서, R8을 켜면 릴리스 빌드를 반드시 실기기에서 테스트해야 한다.

Links

  • 원본: REF-android-dev-r8-shrink-obfuscate
  • 관련 Permanent Note: r8-trades-debuggability-for-size-and-security