diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 8f6e4d24..8c8cc2c7 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -45,7 +45,8 @@ android { manifestPlaceholders["KAKAO_APP_KEY"] = kakaoKey manifestPlaceholders["APP_LINK_HOST"] = appLinkHost - isMinifyEnabled = false + isMinifyEnabled = true + isShrinkResources = true proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 1e97e068..b0a14542 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -20,34 +20,73 @@ # hide the original source file name. #-renamesourcefileattribute SourceFile -# Retrofit +# ───────────────────────────────────────────── +# 공통: 리플렉션/제네릭 기반 라이브러리들이 필요로 하는 속성 +# (Kakao SDK 내부 Retrofit+Gson, kotlinx.serialization 모두 공통으로 사용) +# ───────────────────────────────────────────── -keepattributes Signature, InnerClasses, EnclosingMethod -keepattributes RuntimeVisibleAnnotations, RuntimeVisibleParameterAnnotations -keepattributes AnnotationDefault --keepclassmembers,allowshrinking,allowobfuscation interface * { - @retrofit2.http.* ; -} +# ───────────────────────────────────────────── +# Kakao SDK +# 카카오 SDK는 내부적으로 Retrofit + Gson을 번들링해서 씀. +# 모델 클래스가 리플렉션으로 필드에 접근하므로 난독화/축소에서 제외. +# ───────────────────────────────────────────── +-keep class com.kakao.sdk.** { *; } +-keep class * extends com.google.gson.TypeAdapter +-keep class * implements com.google.gson.TypeAdapterFactory +-keep class * implements com.google.gson.JsonSerializer +-keep class * implements com.google.gson.JsonDeserializer --dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement +-dontwarn org.slf4j.** +-dontwarn org.bouncycastle.jsse.** +-dontwarn org.conscrypt.** +-dontwarn org.openjsse.** -dontwarn javax.annotation.** --dontwarn kotlin.Unit --dontwarn retrofit2.KotlinExtensions --dontwarn retrofit2.KotlinExtensions$* - -# suspend 함수 반환 타입 유지 --if interface * { @retrofit2.http.* ; } --keep,allowobfuscation interface <1> - --if interface * { @retrofit2.http.* ; } --keep,allowobfuscation interface * extends <1> - -# Retrofit이 사용하는 제네릭 타입 --keep,allowobfuscation,allowshrinking class retrofit2.Response --keep,allowobfuscation,allowshrinking class kotlin.coroutines.Continuation --keep,allowobfuscation,allowshrinking interface retrofit2.Call --keep,allowobfuscation,allowshrinking class retrofit2.Response --keep,allowobfuscation,allowshrinking class kotlin.coroutines.Continuation - --if interface * { @retrofit2.http.* ; } --keep,allowobfuscation interface <1> \ No newline at end of file + +# ───────────────────────────────────────────── +# OkHttp / Okio (Ktor의 OkHttp 엔진이 사용) +# 데스크톱 전용 TLS 프로바이더 감지 코드가 참조하지만 안드로이드엔 없는 클래스들. +# ───────────────────────────────────────────── +-dontwarn okhttp3.internal.platform.** +-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement + +# ───────────────────────────────────────────── +# Ktor +# 클라이언트 엔진(OkHttp)을 리플렉션 기반 ServiceLoader로 찾기 때문에 keep 필요. +# ───────────────────────────────────────────── +-keep class io.ktor.** { *; } +-keep interface io.ktor.** { *; } +-dontwarn io.ktor.** + +# ───────────────────────────────────────────── +# kotlinx.serialization +# 공식 권장 규칙(https://github.com/Kotlin/kotlinx.serialization#android) — +# @Serializable 클래스의 Companion/serializer()가 리플렉션처럼 조회되는 경로를 보존. +# ───────────────────────────────────────────── +-if @kotlinx.serialization.Serializable class ** +-keepclassmembers class <1> { + static <1>$Companion Companion; +} + +-if @kotlinx.serialization.Serializable class ** { + static **$* *; +} +-keepclassmembers class <2>$* { + kotlinx.serialization.KSerializer serializer(...); +} + +-if @kotlinx.serialization.Serializable class ** { + public static ** INSTANCE; +} +-keepclassmembers class <1> { + public static <1> INSTANCE; + kotlinx.serialization.KSerializer serializer(...); +} + +-keepclasseswithmembers class **$$serializer { + *** serializer(...); +} + +-dontnote kotlinx.serialization.AnnotationsKt