안드로이드 릴리즈 모드에서만 나타나는 예외


보통 이런경우에는 prougard 를 꼭 의심해라.

1. 상황

정말 편한 새주소 앱을 개발하며 생긴 일이다.

디버그 모드로 개발을 완료하고 정상 동작을 확인하고 난 후 마스터 브랜치로 커밋, Google play Store 에 이미 업로드가 완료되고 저녁밥을 먹으며 심심풀이차 다운로드 및 앱을 실행하니 전혀 난데없는 Exception이 발생하는것. image

세상에.. 이게모람… 밥을 허겁지겁 먹고 바로 안드로이드 스튜디오를 띄웠으나 정상 동작하는것.. 세상에..

이런 경우에는 우선 릴리즈모드로 실행을 해보아야한다. 릴리즈모드의 경우 proguard의 개입으로 실제 바이너리가 디버그 모드와는 다른 바이너리가 생성되기 떄문.

바로 릴리즈 모드로 실행해보니 해당 에러가 재현이 되었고, image

조사결과 다음과 같은 결론을 얻을수 있었다.

2. 원인

간단하게는 gson 처리에 제네릭 타입 를 사용하고, 이는 컴파일타임에 타입이 어긋나지 않는지 검사할뿐 런타임에는 타입의 정보가 제대로 남아있지 않으며(정확하겐 지워지며[^1]), 이때 deserialization 과정에서 문제가 생긴다.

자세한 설명은 다음의 세 링크를 참조하길 바란다. (#1, #2, #3)

3. 해법

여러 해법이 있겠지만 가장 쉬운건 proguard 에 gson 관련 모델들을 제외처리하는것이다.

##---------------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
-keep class sun.misc.Unsafe { *; }
#-keep class com.google.gson.stream.** { *; }

# Application classes that will be serialized/deserialized over Gson
## 개별 모델에 따른 패키지명.객체명 지정 필수
-keep class com.jc01rho.NaverOpenApi.LocalSearch.** { *; }
-keep class com.jc01rho.juso.** { *; }
-keep class com.jc01rho.NaverOpenApi.PlaceSearch.** { *; }


##---------------End: proguard configuration for Gson  ----------

혹은 위의 링크 #2를 참고하자.







© 2018. by jc01rho

Powered by aiden