안드로이드 시스템·Compose 용어 사전
빌드난독화 · ProGuard · minifyEnabled · shrinkResources

R8

코드를 줄이고 난독화하고 최적화하는 컴파일러. 릴리스 빌드의 핵심.

코드를 줄이고 · 난독화하고 · 최적화하는 컴파일러. ProGuard를 대체했다.

buildTypes {
    release {
        isMinifyEnabled = true          // 코드 축소 + 난독화 + 최적화
        isShrinkResources = true        // 안 쓰는 리소스 제거 (minify 가 켜져야 동작)
        proguardFiles(
            getDefaultProguardFile("proguard-android-optimize.txt"),
            "proguard-rules.pro"
        )
    }
}

네 가지 일을 한다

  • 축소(shrink) — 도달 불가능한 클래스·메서드·필드를 제거한다
  • 난독화(obfuscate) 이름을 a·b·c 로 바꾼다 (크기 감소 + 리버싱 난이도)
  • 최적화(optimize) — 인라이닝 · 죽은 분기 제거 · 클래스 병합
  • 탈설탕(desugar) — 최신 자바 API 를 구버전에서 쓰게 만든다

리플렉션이 무너뜨린다

R8 은 정적으로 '도달 가능한지' 를 본다 리플렉션·JSON 역직렬화·Room 은 이름으로 클래스를 찾는다

  • R8 이 "아무도 안 쓰네" 하고 지운다 → 릴리스에서만 크래시

증상: 디버그는 멀쩡한데 릴리스에서 ClassNotFoundException / 필드가 null

# 모델 클래스 보존
-keep class com.example.model.** { *; }

# kotlinx.serialization
-keepattributes *Annotation*, InnerClasses
-keep,includedescriptorclasses class com.example.**$$serializer { *; }

# 예외 스택트레이스를 읽을 수 있게
-keepattributes SourceFile,LineNumberTable
-renamesourcefileattribute SourceFile

요즘 대부분의 라이브러리는 자체 규칙을 AAR 에 담아 배포한다

  • (consumer-rules.pro) → 직접 쓸 일이 줄었다

그래도 '내 모델 클래스' 는 내가 지켜야 한다

매핑 파일이 생명줄이다

build/outputs/mapping/release/mapping.txt

난독화된 스택트레이스를 원래 이름으로 되돌리는 유일한 열쇠다

  • Play Console 에 업로드하면 자동 복원된다
  • Crashlytics 도 업로드해야 한다
  • 버전마다 다르다 — 반드시 보관한다

잃어버리면 그 버전의 크래시 로그는 영원히 읽을 수 없다

반드시 릴리스 빌드를 테스트한다

"디버그에서 잘 됐는데" 는 R8 앞에서 아무 보증이 아니다

  • CI 에서 릴리스 빌드로 계측 테스트를 돌린다
  • 내부 테스트 트랙으로 먼저 배포한다

면접 함정

  • "난독화가 보안이다" → 리버싱을 늦출 뿐이다. 비밀은 서버에 둔다.
  • -keep class **로 전부 보존한다 → 축소 효과가 사라진다. 필요한 것만 좁게 지정한다.

디버깅 — 어디까지 지웠는지 본다

build/outputs/mapping/release/
  mapping.txt     원래 이름 ↔ 난독화된 이름
  usage.txt       제거된 코드 목록  ← "왜 사라졌나" 를 여기서 확인한다
  seeds.txt       보존된(keep) 항목 목록
  configuration.txt  실제 적용된 규칙 전체 (라이브러리 규칙 포함)

스택트레이스 복원

# retrace 로 직접 되돌린다
retrace mapping.txt obfuscated_stacktrace.txt

흔한 keep 규칙

# 리플렉션으로 인스턴스화되는 클래스
-keep class * extends androidx.work.Worker { <init>(...); }

# enum 의 values()/valueOf() — 직렬화가 쓴다
-keepclassmembers enum * { *; }

# Parcelable CREATOR
-keepclassmembers class * implements android.os.Parcelable {
    public static final ** CREATOR;
}

# 네이티브 메서드
-keepclasseswithmembernames class * { native <methods>; }

최적화 수준을 조절한다

  • proguard-android.txt — 최적화 없음 (축소·난독화만)

  • proguard-android-optimize.txt — 최적화 포함 — 기본으로 이쪽을 쓴다

  • 최적화가 문제를 일으키면 개별로 끈다

    • -optimizations !method/inlining/*

함께 보면 좋은 용어

노트에서 맥락과 함께 보기 — 빌드 — Gradle·빌드 변형·R8/난독화·App Bundle