본문 바로가기

[Android] Gradle 매커니즘 및 안드로이드 빌드 동작원리 알아보기

@Marchbreeze2025. 5. 27. 02:23

Gradle은 단순한 빌드 도구를 넘어 프로젝트 구조, 의존성 관리, 멀티모듈 설계, 플러그인 확장까지 담당하는 핵심 플랫폼입니다.

이 글에서는 Gradle의 동작 원리부터 Android APK/AAB가 만들어지는 파이프라인, Wrapper와 SDK 설정, 그리고 R8을 활용한 최적화·난독화·Desugaring까지의 과정을 살펴보았습니다.

 

 


1. Gradle 빌드 매커니즘

(1) Gradle 빌드 개요

Gradle

JVM 위에서 동작하는 범용 빌드 자동화 도구입니다.

Groovy(또는 Kotlin)로 작성된 빌드 스크립트를 해석하여, 프로젝트에 필요한 각종 작업을 자동으로 수행합니다.

DSL(도메인 특화 언어)를 활용해, maven의 상속 구조보다 재사용에 용이하고 간결한 정의가 가능합니다.

 

빌드(Build)

소스 코드를 apk와 같이 실행 가능한 애플리케이션으로 변환하는 과정입니다.

어플리케이션 또는 라이브러리를 분석, 컴파일, 연결, 패키징하는 여러 도구가 포함됩니다.

 

플러그인(plugin)

태스크와 태스크 구성을 정의합니다. (태스크 : 작업 단위)

빌드에 플러그인을 적용하면 태스크가 등록되고 입력과 출력을 사용하여 태스크가 서로 연결됩니다.

ex. 빌드 파일에 AGP(Android Gradle Plugin) 적용 시 Android 라이브러리를 빌드하는 데 필요한 모든 작업들이 등록됩니다.

 

(2) Gradle 빌드 과정

의존성 관리 매커니즘

Gradle은 어떤 태스크가 실행되기 전에 실행되어야 할 다른 태스크들의 의존 관계를 그래프로 관리합니다.

각 태스크의 입출력 파일을 추적하여, 변경이 없는 경우 태스크를 “UP-TO-DATE”로 판단해 재실행을 건너뛰어 빌드 시간을 단축합니다.

 

Gradle의 빌드는 초기화-구성-실행으로 이어지는 3단계로 이루어집니다.

 

1. 초기화 단계 (Initialization)

  • settings.gradle 파일을 파싱하여, 프로젝트 구조 (루트 프로젝트, 서브프로젝트 트리)가 반영된 Setting 객체를 생성합니다.
  • Settings 객체에 등록된 각 서브프로젝트 경로마다 Project 객체가 만들어집니다.
  • 각 모듈의 build.gradle을 해석하기 위한 classpath(클래스 정의(.class), 라이브러리(.jar)의 검색 경로)를 준비한 후, 해당하는 플러그인을 등록하여 JVM에 로드합니다.

 

2. 구성 단계 (Configuration)

  • Projectbuild.gradle를 순차적으로 실행하여, 모든 태스크를 Project 객체에 등록합니다.
  • 사용자가 요청한 모든 필수 빌드 단계를 나타내는 태스크의 방향성 비순환 그래프 (DAG)를 구성합니다.

 

3. 실행 단계 (Execution)

  • DAG 그래프에 정의된 순서대로 태스크를 실행합니다.
  • buildType, flavorType 에 맞춰 사용자가 원하는 버전의 APK를 빌드합니다.

 

(3) Gradle Wrapper

Gradle은 wrapper를 통해서 다른 환경에서도 동일한 빌드를 보장합니다.

로컬에 Gradle이 없어도, Wrapper 스크립트(gradlew)가 필요한 버전을 다운로드하여 빌드를 진행합니다.

project-root/
 ├─ gradlew                ← 유닉스/macOS용 실행 스크립트
 ├─ gradlew.bat            ← Windows용 실행 스크립트
 └─ gradle/wrapper/
     ├─ gradle-wrapper.jar           ← Wrapper 로직(다운로드·실행 등)
     └─ gradle-wrapper.properties    ← distributionUrl 등 설정
  • gradle-wrapper.jar : 필요한 버전의 gradle을 실행할 수 있는지 확인하고, 없으면 zip 파일 다운로드와 압축 해제를 진행합니다.
  • gradle-wrapper.properties : gradle-wrapper.jar 파일에서 사용할 변수들을 포함합니다. distributionUrl을 통해서 Gradle 버전을 확인할 수 있습니다.

 

(4) SDK

Android SDK

안드로이드 앱 개발에 필요한 도구를 포함하는 개발 키트이며, 다음 도구들을 포함합니다.

  1. 플랫폼 도구 : adb(Android Debug Bridge), fastboot 등 디바이스 통신 및 디버깅을 위한 도구
  2. 빌드 도구 : aapt, dx, zipalign 등 APK를 빌드하고 최적화하는 데 필요한 도구
  3. 에뮬레이터 : 다양한 API 레벨과 기기 환경을 에뮬레이션할 수 있는 시스템 이미지와 가상 디바이스
  4. 표준 라이브러리와 풍부한 API 문서

 

Android SDK는 3가지 버전의 지정이 필요합니다.

minSdk

앱이 지원할 Android의 최소 버전이며, 이 버전보다 낮은 기기에서는 앱이 설치되거나 실행되지 않습니다.

 

compileSdk

Gradle이 소스 코드를 컴파일할 때 사용할 수 있는 Android 및 Java API를 결정합니다.

 

targetSdk

애플리케이션의 런타임 동작을 설정하며, 테스트 및 안정성을 확인할 수 있습니다.

complieSdk의 버전과 같거나 낮아야 합니다.

 

targetSdk 버전이 complieSdk 버전보다 낮게 설정되는 경우, 다음 문제가 발생할 수 있습니다.

  1. 최신 Android OS의 변경 사항이나 보안 정책 등이 레거시 모드(호환 모드)로 적용되어, 앱이 구버전 동작 방식으로 실행됩니다.
  2. 시스템은 targetSdk 기반으로 호환성을 보장하려고 노력하므로, 일부 새로운 기능이나 변경된 동작이 반영되지 않을 수 있습니다.

 

 


2. Android 빌드

(1) APK 빌드 파이프라인

Android Gradle Plugin이 내부적으로 수행하는 순서는 다음과 같습니다.

출처 : 본 블로그 (https://marchbreeze.tistory.com)

1. 리소스 및 AIDL 처리

  • 레이아웃(XML), 이미지(drawable), 문자열(values), 매니페스트(Manifest) 등의 리소스를 처리합니다.
  • AAPT(Android Asset Packging Tool)에 의해, 해당 리소스 파일을 참조할 수 있는 고유 ID(R.java)가 부여됩니다.
  • IPC(프로세스 간 통신)에서 사용할 인터페이스가 정의된 AIDL 파일을 자바 인터페이스로 변환합니다.

 

2. 자바 소스 컴파일

  • 앞 단계에서 생성한 R.java 파일, Java Interface 파일과 함께 일반 소스 코드를 컴파일합니다.
  • 자바 코드는 javac, 코틀린 코드는 kotlinc 컴파일러를 이용하여 자바 바이트코드(.class)로 변환합니다.
  • 다른 라이브러리들의 소스의 경우, JAR이나 AAR파일 안에서 이미 .class로 이미 변환이 되어 있는 상태입니다.

 

3. DEX 변환

  • ART 가상머신에서 동작하기 위해 R8(또는 D8)에서 바이트코드(.class)를 DEX(Dalvik Executable) 포맷으로 변환합니다.
  • 하나의 DEX 파일 내 참조 가능한 메소드의 개수는 최대 64K(65,536개)이며, 이보다 큰 앱을 빌드하는 경우 Multidex를 활용해서 여러개의 Dex 파일로 쪼개주는 작업이 필요합니다.
  • 그러나 Multidex의 경우 여러 Dex 파일의 병합 과정에서 빌드 시간이 증가하며, 로드 과정에서 런타임 성능에 영향을 줄 수 있어 자체적으로 외부 라이브러리를 줄이고 코드를 최적화하거나, ProGuard/R8을 활용한 코드 축소를 활용하는 방식이 권장됩니다.

 

4. APK 빌드 및 서명

  • Gradle의 빌드 스크립트가 DEX 파일 + 컴파일된 리소스 파일 + c/c++과 관련있는 .so 파일을 하나의 APK 파일로 묶습니다.
  • 안드로이드 빌드 툴체인 내의 apksigner을 활용해, 디버그용/릴리즈용의 Signed APK를 생성합니다.
  • 이후 zipalign 툴로 정렬(APK 내부 압축 데이터를 4바이트 경계로 정렬)하여 Signed and Aligned APK가 완성됩니다.

 

(2) Android App Bundle(AAB)

AAB

앱의 모든 리소스와 코드를 포함하는 압축된 파일 형식입니다.

AAB 파일을 업로드하면, Google Play가 분석하여 다양한 기기별로 최적화된 APK들을 생성하며, 사용자의 기기 환경에 맞춰 필요한 코드와 리소스만을 포함한 APK들이 동적으로 생성되어 전달됩니다.

 

APK 대비 장점

1. APK 크기 감소 : 불필요한 리소스 배포 과정에서 자동으로 제거됩니다.

2. 동적 기능 모듈 : 앱의 특정 기능을 모듈화하여, 사용자가 필요한 경우에만 해당 모듈을 다운로드하도록 지원합니다.

3. 보안성 향상 : 사용자 기기에 전달되는 APK는 Google Play가 서명한 상태로 배포됩니다.

 

(3) Proguard/R8

R8

DEX 변환 과정에서 최적화 및 보안 강화를 위한 여러 작업 추가적으로 수행합니다.

AGP 3.4부터 도입되어, 기존의 ProGuard(코드 축소 및 난독화) + D8(DEX 생성) 기능을 R8을 통해 모두 처리가 가능합니다.

기존 ProGuard에 비해 Gradle/AGP와 밀접하게 통합되어 메모리 사용량을 줄이고, 빌드 속도가 빠르며, 정교한 최적화가 진행됩니다.

 

1. 코드 축소 (Code Shrinking)

  • 소스 코드나 포함된 라이브러리에서 실제 실행 시 사용되지 않는 클래스, 메소드, 필드 등을 제거하여 크기를 줄이는 과정입니다.
  • 최종 APK 크기를 줄일 수 있어, 64K 참조 제한을 해결하여 여러개의 DEX 파일 생성을 방지할 수 있습니다.
  • 각 Entry Point에 해당하는 클래스(Application, Activity, ...)로부터 시작해 클래스, 필드, 메서드 호출 여부에 대해서 참조 그래프를 생성한 후, 참조되지 않으면 Dead Code로 표시합니다.
  • Proguard rule 문법(Keep Rule)을 활용하면 코드 유지 및 제거 여부를 세밀하게 설정 가능하며, Retrofit, Gson과 같은 외부 라이브러리가 리플렉션으로 호출하는 코드가 제거되지 않도록 방지하는 작업이 필요합니다.
  • 사용 시, usage.txt에 앱에서 미사용으로 제거된 코드의 목록 정보가 생성됩니다.

 

2. 리소스 축소 (Resource Shrinking)

  • 사용되지 않는 이미지, 레이아웃, 문자열 등 리소스 파일들을 APK에서 제거하는 과정입니다.
  • Code Shrinking이 완료된 후, 리소스가 실제로 참조되는지에 대한 여부를 판단한 후 제거합니다.
  • build.gradle 파일에 shrinkResources = true 설정 시 활성화할 수 있습니다.

 

3. 최적화 (Optimization)

  • 코드/리소스 축소 이후 남은 코드 중 불필요한 바이트코드를 더욱 정교하게 최적화하는 과정입니다.
  • 인라이닝 : 너무 짧거나 단순한 메소드는 호출부에 직접 삽입하여 메서드 호출 오버헤드를 줄입니다.
  • 상수 폴딩 : 컴파일 시점에 값을 알 수 있는 연산은 미리 계산해두어 런타임 오버헤드를 줄입니다.
  • 불필요한 Null 체크 제거 : 컴파일 시점에 Null이 아님을 알 수 있는 경우 불필요한 체크 로직을 제거합니다.
  • 루프 최적화 : 반복문 안에서 변화하지 않는 값을 밖으로 빼내는 등 간단한 최적화 작업을 수행합니다.

 

4. 난독화 (Obfuscation)

  • 클래스, 메소드, 변수 이름을 임의의 짧은 이름으로 변경하여 리버스 엔지니어링을 어렵게 만드는 과정입니다.
  • 코드 보안을 강화하고, 경우에 따라 APK 크기 감소에도 기여할 수 있습니다.
  • Proguard rule 문법을 활용하면 제외 여부를 세밀하게 설정 가능합니다.
  • build.gradle 파일에 minifyEnabled = true 설정 시 활성화할 수 있습니다.
  • 사용 시, mapping.txt에 난독화 과정에서 원래의 이름과 변경된 이름 간의 매핑 정보가 생성됩니다.
  • 사용 시, seeds.txt에 난독화되지 않고 유지된 클래스와 멤버의 목록 정보가 생성됩니다.

 


참고 자료:

Gradle 빌드 개요  |  Android Studio  |  Android Developers

안드로이드 개발자라면 알아야 하는 Gradle 원리

[Android] Gradle 과 Android App 의 빌드 시스템

빌드 구성  |  Android Studio  |  Android Developers

앱 축소, 난독화 및 최적화  |  Android Studio  |  Android Developers

안드로이드, 어디까지 아세요 [1] - Build process

Android의 Build Process

Marchbreeze
Marchbreeze

안드로이드 개발자, 김상호입니다.

https://github.com/Marchbreeze

목차