안드로이드 디버그때는 정상 동작 / 플레이스토어에 업로드시 작동 안됨 (R8 Proguard, gson 문제)
결론부터 말하자면,
프로젝트에 Gson과 Proguard R8을 같이 쓸 경우
코드 난독화 및 축소시 (minifyEnabled = true) 오류가 난다!
해결법은 이걸 proguard-rules.pro 에 적으면 된다.
##---------------Begin: proguard configuration for Gson ----------
# Gson uses generic type information stored in a class file when working with fields. Proguard # removes such information by default, so configure it to keep all of it. -keepattributes Signature # For using GSON @Expose annotation -keepattributes *Annotation* # Gson specific classes -dontwarn sun.misc.** #-keep class com.google.gson.stream.** { *; } # Application classes that will be serialized/deserialized over Gson -keep class com.google.gson.examples.android.model.** { <fields>; } # Prevent proguard from stripping interface information from TypeAdapter, TypeAdapterFactory, # JsonSerializer, JsonDeserializer instances (so they can be used in @JsonAdapter) -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 # Prevent R8 from leaving Data object members always null -keepclassmembers,allowobfuscation class * { @com.google.gson.annotations.SerializedName <fields>; } ##---------------End: proguard configuration for Gson ----------
위 설정에서 가장 중요한 부분은 요거다.
-keep class com.google.gson.examples.android.model.** { <fields>; }
# ex) -keep class com.example.Person { <fields>; }
Person을 직접 만든 클래스로 바꿔 주는 것!
그럼 난독화 할 때 프로퍼티 name -> a 로 무지성 변경되는 것을 막아준다.
minifyEnabled 설정
앱 서명 후 APK 빌드까지 문제없이 진행됐지만
release 모드로 빌드된 apk가 실제 실행환경에서 똑바로 동작하지 않고 강제 종료되었습니다.
앱 시작 시 튕기는 현상이며, debug 모드가 아니라서 crash 로그를 얻을 방법이 없었습니다.
검색으로 찾아낸 원인은 바로 minifyEnabled
<- 이녀석입니다
build.gradle(Module-gonefashion-android)
buildTypes {
release {
debuggable false
jniDebuggable false
renderscriptDebuggable false
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
if (project.hasProperty("RELEASE_STORE_FILE")) {
signingConfig signingConfigs.release
}
일단 minifyEnable과 shrinkResources을 false로 하면 정상적으로 실행되며
crash는 발생하지 않습니다.
Proguard 설정 추가
좀 더 검색을 해서 minify기능을 사용할 수 있는 방법을 찾았습니다.
proguard 룰을 추가해 주면 됩니다. 아래의 규칙을 추가합니다.
-keep class com.google.android.gms.** { *; }
-keep class com.google.firebase.** { *; }
-keep class com.google.games.** { *; }
기본적으로 안드로이드 스튜디오에서 프로젝트를 생성하면
Gradle Scripts -> proguard-rules.pro 라는 파일이 생성됩니다.
그리고 앱 레벨의 build.gradle에
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
이런 코드 또한 작성되어 있습니다.
코드를 보면 minifyEnabled false 죠?
말 그대로 활성화가 되어있지 않다는 뜻입니다.
false -> true로 변경해주게되면 앱을 릴리즈할 때 프로가드가 적용되고
코드가 난독화됩니다.
그리고 만약 Debug 할 때도 프로가드를 적용하고 싶다면
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
이렇게 debug도 추가해주면 됩니다.
그런데 프로가드 적용 후 에러가 발생하는 경우가 있습니다.
1. 라이브러리를 사용하는 경우
https://github.com/PhilJay/MPAndroidChart
위 같은 라이브러리를 사용하는 경우에 프로가드가 적용되어 있으면
에러가 발생하는데요. 이유는 다양하겠지만 보통 라이브러리의 코드가 난독화되면
클래스를 찾지 못해서 발생하는 듯 합니다.
보통 라이브러리는 Documentation을 같이 제공하죠.
문서를 찾아보면 Proguard 코드난독화에서 제외시키는 방법에 대해 나옵니다.
위 차트라이브러리의 경우 proguard-rules.pro 파일에
-keep class com.github.mikephil.charting.** { *; }
코드를 추가하라고 나옵니다. 시키는 대로 하면 에러 해결됩니다.
2. 'META-INF/proguard/androidx-annotations.pro'
저는 위 에러가 발생했는데요.
위 에러를 해결하려면 앱 레벨의 build.gradle -> android{} 블록 아래에
packagingOptions {
exclude 'META-INF/proguard/androidx-annotations.pro'
}
를 추가해주면 됩니다.
참고 주소:
https://develop-branch.tistory.com/23
gson 모듈의 공식 proguard config 가이드 문서
https://github.com/google/gson/blob/master/examples/android-proguard-example/proguard.cfg