코드를 줄이고 · 난독화하고 · 최적화하는 컴파일러. 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/*