일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- jvm 작동 원리
- 안드로이드 레트로핏 사용법
- 안드로이드 유닛 테스트
- rxjava disposable
- 안드로이드 유닛 테스트 예시
- 2022 플러터 설치
- Rxjava Observable
- 큐 자바 코드
- 멤버변수
- 클래스
- rxjava cold observable
- 안드로이드 유닛테스트란
- 안드로이드 라이선스
- ANR이란
- jvm이란
- android ar 개발
- rxjava hot observable
- 스택 큐 차이
- 안드로이드 레트로핏 crud
- 안드로이드 os 구조
- 스택 자바 코드
- android retrofit login
- 자바 다형성
- 안드로이드 라이선스 종류
- 플러터 설치 2022
- 2022 플러터 안드로이드 스튜디오
- ar vr 차이
- 서비스 쓰레드 차이
- 서비스 vs 쓰레드
- 객체
- Today
- Total
나만을 위한 블로그
난독화란? R8 컴파일러란? 본문
안드로이드 앱을 열심히 만들고 aab 파일을 만들어 플레이 콘솔에 올리면 경고 메시지가 나타난다. R8 또는 proguard를 사용해 난독화된 코드를 사용하라는 경고인데 무시해도 앱은 스토어에 올라간다.
그러나 이게 대체 뭐길래 안드로이드는 이걸 사용해서 앱을 난독화하라는 경고를 보여주는 것인가? 애초에 난독화를 하면 뭐가 좋을까? 경고문구를 보기 싫어서 난독화를 해 왔지만 이번에 난독화와 R8, proguard가 무엇인지 확인하고 넘어가려고 한다.
아래는 난독화에 대한 안드로이드 디벨로퍼 문서다.
https://developer.android.com/studio/build/shrink-code?hl=ko
앱을 최대한 작게 만들려면 출시 빌드에 축소를 사용 설정해서 미사용 코드와 리소스를 삭제해야 한다. 축소를 사용하면 앱 클래스와 멤버의 이름을 줄이는 난독화 및 앱 크기를 추가로 줄이는 더 공격적인 전략을 적용하는 최적화 기능을 활용할 수도 있다. 안드로이드 스튜디오 플러그인 3.4.0 이상을 사용해 프로젝트를 빌드하는 경우 플러그인은 더 이상 ProGuard를 사용해 컴파일 시간 코드 최적화 작업을 하지 않는다. 대신 플러그인은 R8 컴파일러를 이용해 컴파일 시간 작업을 처리한다.
- 코드 축소(또는 Tree Shaking) : 앱 및 라이브러리 종속 항목에서 미사용 클래스, 필드, 메서드, 속성을 감지해 안전하게 삭제한다(64K 참조 제한을 해결하기 위한 유용한 도구). 예를 들어 라이브러리 종속 항목에서 몇 개의 API만 쓴다면 축소는 앱이 사용하지 않는 라이브러리 코드를 식별하고 앱에서 그 코드만 삭제할 수 있다
- 리소스 축소 : 앱 라이브러리 종속 항목의 미사용 리소스를 포함해 패키징된 앱에서 사용하지 않는 리소스를 삭제한다. 리소스 축소는 코드 축소와 함께 사용해 미사용 코드를 삭제하고 마찬가지로 더 이상 참조되지 않는 리소스도 안전하게 삭제할 수 있다
- 난독화 : 클래스, 멤버 이름을 줄여 DEX 파일 크기를 줄인다
- 최적화 : 코드를 검사하고 재작성해 앱 DEX 파일의 크기를 더 줄인다. 예를 들어 if/else 구문의 else 분기가 사용되지 않음을 R8에서 감지한 경우 R8이 else 분기 코드를 삭제한다
앱의 출시 버전을 빌드할 때 기본적으로 R8은 컴파일 시간 작업을 자동 진행한다. 하지만 ProGuard 규칙 파일을 사용해 특정 작업을 중지하거나 R8의 동작을 맞춤설정할 수 있다. 실제로 R8은 기존의 모든 ProGuard 규칙 파일과 호환되므로 R8을 사용하도록 안드로이드 gradle 플러그인을 업데이트하면 기존 규칙을 변경할 필요가 없다...(중략)...R8은 프로젝트의 자바 바이트 코드를 안드로이드 플랫폼에서 실행되는 DEX 형식으로 변환하는 기본 컴파일러다
이 페이지에서 난독화와 R8이 무엇인지 알려주고 있다. 참고로 안드로이드 스튜디오 3.4.0 버전은 2019년 4월 출시된 구버전이다.
난독화는 클래스, 변수명을 줄이는 걸 말하고 R8은 자바 바이트 코드를 DEX 형식으로 바꿔주는 기본 컴파일러라고 한다. 그런데 자바 바이트 코드와 DEX 형식이라는 키워드가 뭔지 모르겠다.
자바 바이트 코드란?
자바 바이트 코드가 뭔지 이해하려면 먼저 JVM이라는 걸 알아야 한다. JVM은 "Java Virtual Machine"의 약어로, 이것의 설명은 예전에 쓴 포스팅이 있으니 이것으로 대체한다.
https://onlyfor-me-blog.tistory.com/385
결론은 자바 바이트 코드는 JVM의 명령어 집합이다. 그리고 JVM은 자바 바이트 코드로 짜여진 프로그램을 실행하는 기반이 되는 가상 머신이다. 또한 자바 바이트 코드는 플랫폼 독립적이고 JVM에 의존해 실행된다. 이 말은 플랫폼에 맞춰 소스코드를 빌드하지 않고도 한 번 빌드하는 걸로 여러 플랫폼에서 실행할 수 있음을 의미한다.
그런데 안드로이드와 자바 언어는 무슨 상관이 있는가?
원래 안드로이드가 앱 개발 언어로 선택했던 언어는 자바였다. 그래서 안드로이드 관련 레거시 자료를 찾아보면 이클립스에서 자바로 안드로이드 앱을 개발하는 화면을 찾아볼 수 있는데 이것 때문이다.
그래서 안드로이드는 자바의 특징을 그대로 답습하고 있다. 여기서 달빅 가상 머신(DVM)과 현재 사용되는 ART 런타임에 대한 이야기가 나오는데 이 포스팅 주제와는 거리가 있기 때문에 생략한다.
DEX 형식이란?
DEX는 "Dalvik Executable Format"의 약자로 예전에 쓰였던 런타임인 DVM에서 사용된 형식이다. 이 형식의 파일 안에는 애플리케이션의 모든 클래스가 한 파일로 압축돼 있다. 즉 안드로이드 런타임에서 실행하는 코드가 들어있으며 기계어로 작성된 파일이다.
DEX 파일이 생성되는 순서는 먼저 자바 소스코드를 자바 컴파일러가 ".class" 파일로 컴파일한 다음, 이 파일을 dexer(dx)라는 툴이 중복 정보들을 제거하는 등 처리를 한 후, 달빅 바이트 코드가 포함된 DEX 파일 형식으로 만들어낸다.
이 DEX 파일은 여러 리소스들과 같이 합쳐져서 apk라는 확장자를 가진 파일이 되고 안드로이드 개발자들은 이 apk 확장자 파일을 만들어내서 스토어에 올렸었다. 현재는 aab 형식으로 올리지만 나도 예전엔 apk 파일을 만들고 이 파일을 스토어에 올려 앱을 등록했었다.
지금은 ART를 쓰는데 뜬금없이 웬 달빅이냐고 할 수 있는데, ART는 DEX 바이트 코드를 실행할 수 있는 런타임이기에 일부 경우를 제외하면 문제될 것은 없다. 자세한 것은 아래 링크 참고.
https://source.android.com/docs/core/dalvik
다시 R8로 돌아와서 이 R8 컴파일러에 대해 다른 블로그에는 어떻게 써 있는지 확인한다.
https://blog.mindorks.com/r8-vs-proguard-in-android
R8은 자바 바이트 코드를 최적화된 DEX 코드로 변환하는 도구다. 전체 응용 프로그램을 반복한 다음 쓰지 않는 클래스, 메서드 등을 제거해 최적화한다. 컴파일 시간에 실행된다. 빌드 크기를 줄이고 앱을 더 안전하게 만드는 데 도움이 된다. R8은 Proguard 규칙을 써서 기본 동작을 수정한다...(중략)...이 과정에서 클래스명, 다른 변수명을 난독화한다. 예를 들어 클래스명이 MainActivity면 a 또는 크기가 더 작은 다른 것으로 난독화한다
https://android-developers.googleblog.com/2018/11/r8-new-code-shrinker-from-google-is.html
R8은 축소, 디슈가링, 덱싱을 모두 한 단계로 수행한다. 현재 코드 축소 솔루션인 Proguard와 비교할 때 R8은 출력 크기를 개선하면서 코드를 더 빠르게 축소한다.
사용법은 구글링하면 많이 나오니 생략하고, 앱 수준 gradle에서 필요한 처리를 하면 Proguard에 내가 어떻게 적었냐에 따라 어떤 클래스는 난독화하고 어떤 클래스는 난독화하지 않는다는 게 중요하다.
주의할 것은 예전 FCM을 붙인 프로젝트를 스토어에 올렸을 때 디버그 모드에선 잘 오던 푸시가 릴리즈 모드에선 받아볼 수 없었다. 이유는 MyFirebaseMessaging 서비스 파일과 스플래시 액티비티에서 FCM 토큰을 받는 부분도 암호화했었는데 그 영향으로 발급받은 FCM 토큰까지 난독화되서 푸시 알림을 받아볼 수 없던 것이었다. 이런 일도 발생할 수 있으니 Proguard를 작성할 땐 주의하자. SNS 로그인도 영향을 줄 수 있다.
'모르는 용어 정리' 카테고리의 다른 글
순수 함수란? (0) | 2023.02.01 |
---|---|
동시성이란? 가시성이란? 원자성이란? (0) | 2022.10.23 |
해시 충돌이란 (0) | 2022.07.05 |
직렬화(Serialization), 역직렬화(Deserialization)란? (0) | 2022.06.06 |
타입스크립트란? (0) | 2022.04.14 |