[Background]
안드로이드 입문한지 얼마 안됐고 처음으로 큰 안드로이드 프로젝트를 진행하다 보니깐 릴리스 모드와 디버그 모드의 차이점을 크게 모르고 릴리스 모드에만 proguard을 켜놓고 설정을 안건든체 출시를 했었다. 심사에 통과하고 마켓에 올라온 앱을 다운 받아서 테스트를 해보니깐 네트워크 통신이 아예 안되고 앱이 제대로 작동을 안하는 경험을 해봤습니다.
처음에는 원인조차 몰랐지만 많이 조사를 해본 결과 proguard문제라는 것을 파악했지만 어떻게 수정해야 하는지 막막했었습니다.
대부분의 자료들은 모듈 한개일때의 경우만 설명을 했지 멀티 모듈일때는 모든 모듈에 proguard을 설정해야 하는 것인지 아니면 일부만 하면 되는 것인지가 잘 안나옵니다.
그래서 이번에 멀티모듈 환경일때 proguard을 설정하는 방법을 알아 보겠습니다.
[기본 지식]
proguard에 대해서 먼저 간략하게 설명을 하겠습니다. 이 기능은 크게 두가지 목적을 달성하기 위해서 활용됩니다.
1. 용량 줄이기
2. 보안
컴파일러가 접근이 불가능한 코드를 없애고 클래스, 함수, 변수등의 이름을 축소및 난독화를 진행해서 전체적인 코드량도 줄이고 외부 사람이 앱을 강제로 열어서 코드를 보려고 해도 난독화가 진행되어 있기 때문에 읽기 힘들다는 장점을 줍니다.
설정하는 방법은 매우 간단합니다. 단지 gradle.kts 파일에서 MinifyEnable을 true로 설정해 주면 됩니다.
buildTypes {
release {
isMinifyEnabled = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
)
buildType에서 release로 감싸면 release 모드일때 debug으로 감싸면 debug모드에서까지 proguard을 설정하는 것이 가능합니다.
즉 테스트를 진행할떄도 난독화, 축소가 가능한데 문제는 컴파일 타임이 엄청 늘어나고 난독화 때문에 디버그할때 문제가 발생할 수 있습니다.
그리고 사용하는 라이브러리에서 알 수 없는 버그가 일어날 수 있는데 그건 멀티 모듈에서 적용하는 방법 다음에 설명하겠습니다.
[멀티 모듈에서 적용]
지금까지는 모듈이 한개일때 적용하는 방식이였고 그럼 설정을 모든 모듈에 다 따로 해야되는지 의문이 들 수도 있습니다.
다행이도 안드로이드에서 이것을 대비해서 만들어 놓은게 기능이 있습니다.
모든 다른 모듈을 알고 있는 app 모듈에서 진행한 설정은 다른 모듈에도 다 같이 적용이 됩니다. 즉 application 전체에 영향이 갑니다.
그럼 다른 모듈에서는 아무것도 안해도 되냐라고 하면 그건 또 아닙니다. 예를 들어서 common-ui와 data 모듈에 같은 기능이 있을때 data만 난독화가 안되게 하고 싶으면 data 모듈에만 그 설정을 적용하면 됩니다.
따로 설정하는 방법은 이와 같습니다.
buildTypes {
release {
consumerProguardFile("proguard-rules.pro")
}
}
consumerProguardFile을 통해서 proguard-rules.pro에 있는 설정은 이 모듈만 적용된다고 명시가 가능합니다.
[Proguard-rule 설정하기]
지금까지 설정하고 앱을 실행하는 오류가 뜨실 수 있습니다. 예를 들어서 이런 것 같은
이는 컴파일러한테 어떤 것은 난독화를 진행하면 안된다고 명시를 안해줘서 그렇습니다. 외부 라이브러리가 난독화된 우리 코드를 읽으면 어떤것을 실행해야 하는지 모르기 때문에 오류가 납니다.
해결하는 방법은 저희가 gradle 파일에서 설정할때 넣어줬던 proguard-rule.pro에 난독화를 진행하면 안되는 것을 명시해 주면됩니다.
지금 오류는 retrofit때문이니 구글에 retrofit proguard하고 치면 라이브러리 코드가 있는 깃허브 페이지가 나오는 거기에 있는 모든 코드를 상황에 맞게 알맞은 모듈의 proguard-rule에 적용해주면 됩니다.
사용하는 라이브러리에 맞게 설정을 해주면 되지만 지금까지 해본 결과 자주 쓰는 라이브러리에 오류가 나는 건 retrofit하고 gson 정도 밖에 없었던 것 같습니다.
[주의점]
라이브러리 깃헙에 있는 설정만 적용하면 에러가 나는 경우가 있습니다. 예를 들어서 Gson, 분명 설정했는데 계속 Abstract 클래스를 넘겨준다고 징징될때가 있습니다.
이는 Gson한테 파싱하라고 클래스를 넘겨줬는데 그 클래스가 난독화가 되어 있어서 오류가 나고 있습니다.
이럴때는 직접 설정을 해줘야 합니다.
-keep class com.lighthouse.data.dto.* { *; }
저같은 경우에는 Gson한테 넘겨주는 모든 클래스가 여기 폴더에 있기 때문에 이 폴더를 난독화하지 말라고 하면 실행이 다시 잘되기 시작합니다.
이와 같이 직접 설정해 줘야하는 경우도 있습니다.
(추가)
설정해도 안되는 경우가 있는데 이는 경로 문제일 가능성이 높습니다.
이렇게 폴더안에 폴더가 있는 경우에 문제가 발생하는데 이는 아래처럼 고치면 해결됩니다.
-keep class com.lighthouse.data.dto.** { *; }
* 한개는 dto 폴더 안에 있는 모든 클래스와 맴버를 포함 하지만 안에 있는 폴더까지는 포함이 안됩니다.
** 두개는 안에 있는 폴더까지 포함시킵니다
[마무리]
한번 proguard을 설정해봤는데, 몇시간동안 직접 시행차고를 겪은 것에 비하면 솔직히 많이 쉬운 것 같습니다.
이 프로젝트에서 사용한 전체 코드는 여기 확인 가능합니다
https://github.com/flash159483/multi-module-navigation
'android' 카테고리의 다른 글
(android/kotlin) Encrypted Shared Preference 적용 + AEADBadTagException 문제 해결 (0) | 2023.11.17 |
---|---|
(android/kotlin) RecyclerView + Admob 적용하기 (0) | 2023.10.13 |
(android/kotlin) 멀티 모듈에서 Google OAuth만으로 로그인 구현해보기 (0) | 2023.09.16 |