[Android] Gradle Task 종류 및 사용법

mhyun, Park·2023년 5월 14일
2

Android 개발에서 매우 중요한 부분 중 하나는 Build, Debug 및 Release 프로세스이다.
Gradle 은 이러한 중요 Task들을 쉽게 관리할 수 있는 위한 유용한 Tool이며, 많은 개발자들은 gradle을 이용하여 Project를 구축하는 데 사용하고 있다.

Android에선 gradle을 기본 Tool로써 사용하고 있기에 gradle 자체적으로 제공하고 있는 기능들을 손 쉽게 사용할 수 있지만, 쉬운 접근성으로 인해 우리가 Android 개발을 하면서 무지성으로 Gradle을 이용하고 있는 부분이 생기게 되고 나 또한 다소 국한된 gradle task만을 사용하고 있고 각각의 task에 대한 역할을 정확하게 이해하지 못한 채 이용하고 있었다.

그래서 이번 posting을 기회로 Android 개발에서의 gradle 사용법과 Gradle이 기본적으로 제공하고 있는 task를 모아서 각각의 task의 역할은 무엇인지 알아보려한다.

1. Gradlew (gradle wrapper)

gradlew란 gradle 빌드 시스템을 사용할 때, application에서 필요한 gradle 버전을 자동으로 다운로드하고 설치하는 도구이며, 이를 통해 application의 gradle 버전과 다른 컴퓨터나 CI 환경에서도 일관성 있게 사용할 수 있다.

즉, gradlew를 사용함에따라 매번 환경을 맞추어 주는 번거로움을 줄일 수 있기에 일관성 있는 빌드를 보장할 수 있으므로 gradle wrapper를 사용하도록 권장하고 있고 있다. 따라서, 앞으로 소개할 gradle 명령어는 gradlew를 기반으로 진행될 예정이다.

2. Gradlew Task

2-1) build

./gradlew build

gradle build는 application 소스 코드를 실체화 하기 위한 task로써
아래와 같은 일련의 과정을 자동으로 수행하고 최종 산출물인 APK 파일을 생성한다.

  • library dependency 체크
  • resource file 패키징
  • source code compile
  • test code 수행

만약, build 과정이 성공적으로 끝나게 되면 application이 조립되었고 모든 테스트가 성공적으로 통과되었음을 의미하고 project build directory에 build 수행 결과를 포함하는 directory를 생성한다.

  • classes dir
    Java 소스 파일에 대해 Java 컴파일러를 실행한 결과로 컴파일된 .class 파일이 포함된다.
  • libs dir
    생성된 jar 파일, 실행 또는 publish 준비가 된 모든 컴파일된 클래스가 포함된 아카이브가 포함된다.
  • reports dir
    Test 결과를 요약한 HTML 보고서가 포함되어 있으며, 빌드가 실패할 경우 build/reports/tests/test/index.html에서 fail 정보를 확인할 수 있다.

또한, 기본적으로 gradle은 증분 빌드(incremental build)를 지향하고 있다.
증분 빌드는 재빌드를 할 때 이전 빌드와 비교하여 다시 빌드할 필요성이 있는지 없는지 판단하여 필요한 부분만 다시 빌드하는 것을 말하며,
이 때 필요한 부분만 다시 빌드할 수 있도록 local에 caching 해두는 것을 build cache라고 한다.
build cache는 기본적으로는 꺼져있으며 키기 위해서는 실행시 --build-cache 옵션을 사용하면 되고 만약 기본적으로 사용하고 싶다면 gradle.properties 파일에 org.gradle.caching=true 옵션을 추가하면 된다.

2-2) clean

./gradlew clean

gradle clean는 앞서 gradle build을 통해 생성된 모든 build artifact를 포함하여 gradle cache 및 gradle directory 등 모든 output 산출물을 삭제하는 task로써 project를 처음 build 했었던 상태로 되돌리는 역할을 한다.

즉, gradle clean을 통해 build 환경을 초기화함으로써 새로운 build를 시작할 때, 이전 build에서 쌓인 cache와 build directory의 영향을 받지 않기 때문에 빌드 시간을 단축할 수 있으며, 이전 build에서 발생한 문제 혹은 오류 등이 남아있지 않게 되기 때문에 build 안정성을 향상시킬 수 있다.

Q) cache를 지우는데.. 왜 빌드 시간이 단축되고 안정성이 올라갈 수 있을까?
> cache된 data가 많을 경우, cache data를 불러오는 시간이 disk data를 불러오는 시간보다 오히려 길어질 수 있기에 전체적인 build 시간이 늘어날 수 있다. 또한, cache data의 space가 크면 disk space가 부족해짐에따라 build가 실패할 수 있다.

2-3) assembleDebug, installDebug

./gradlew assembleDebug
./gradlew installDebug

gradle assembleDebug는 Android app을 Debug mode로 build하고 Debug APK를 포함한 archive를 생성하는 task로써 Debug 가능한 코드와 Debug 정보를 포함시킨다.

그리고 ./gradlew installDebug를 통해, 이러한 Debug APK를 생성하는 동시에 기기 혹은 emulator에 설치할 수 있다.

2-3) assembleRelease, installRelease

./gradlew assembleRelease
./gradlew installRelease

gradle assembleRelease는 Android app을 Release mode로 build하고 Release APK를 포함한 archive를 생성하는 task로써 Debug 정보를 포함하지 않기에 APK 파일 크기가 줄어들고 pro-guard를 통한 코드 난독화 및 최적화를 진행함으로써 App의 보안이 강화된 APK를 생성한다.

그리고 ./gradlew installRelease를 통해, 이러한 Release APK를 생성하는 동시에 기기 혹은 emulator에 설치할 수 있다.

2-4) lint

./gradlew lint

gradle lint는 project에서 code 품질을 검사하는 task로써 Android Studio에서 제공하는 Lint 도구를 사용하여 코드에 대한 정적 분석을 수행한다. Lint 정적 분석의 종류로는 크게 아래와 같으며

  • 사용하지 않는 리소스
  • 성능 문제가 될 수 있는 부분
  • 보안 문제
  • code style에 벗어난 부분
  • midSdk, targetSdk, compileSdk level에 따라 오류가 발생할 수 있는 부분

문제 발생 시엔 build/reports/lint-results-debug.html에 결과가 생성되어 문제점을 시각적으로 파악할 수 있다.

이러한 lint 검사 항목은 android studio 내에서도 쉽게 선택할 수 있고

project 성격에 따라, 엄격한 coding convention을 적용하기 위해
사용자가 직접 custom lint를 정의하여 complile time에 검사를 수행시킬 수 있다.

ps) lint는 Android 전용 코드 품질 Tool로써, Android project가 아닌 경우엔 ./gradlew check를 사용한다.

2-5) test

./gradlew test

gradle test는 project에 구현 된 모든 단위 테스트(Unit Test)를 실행하기 위한 task이며, 세부 option을 넣어줌으로써 지정된 test만 수행 시킬 수 있다.

  • 특정 하위프로젝트 전체 TestCase 수행
    ./gradlew <module>:testDebugUnitTest

  • 특정 패키지에 대한 TestCase 수행
    ./gradlew <module>:testDebugUnitTest --tests "<package>.*"
    --> ./gradlew model:testDebugUnitTest --tests "com.android.app.sample.setting.*"

  • 특정 TestCase만 수행
    ./gradlew <module>:testDebugUnitTest --tests "<package>.<test_name>"
    --> ./gradlew model:testDebugUnitTest --tests "com.android.app.sample.setting.SettingModelTest"

2-6) dependencies

./gradlew dependencies
./gradlew <module>:dependencies

gradle dependencies는 project에서 사용 중인 Library에 대한 dependency tree를 알 수 있는 task이다.

gradle에서의 의존성끼리의 충돌은 서로 동일한 library를 사용하고 있지만 서로 다른 버전을 사용할 때 발생하는데, 이 경우 gradle에선 사용자가 어떤 버전을 사용할지 모르기 때문에 error msg를 띄우고 사용자는 gradle dependencies 를 통해서 문제가 되는 library를 찾아 해결할 수 있다.

마무리

이렇게 Gradle은 build와 관련된 다양한 작업을 수행할 수 있는 Task들을 제공하여 효율적인 build 작업을 수행할 수 있는 것을 알아보았다.

이번 blog posting에선, Gradle이 제공하는 기본적인 Task만을 소개했지만,
Gradle은 사용자가 직접 custom task를 만들 수 있는 환경을 제공하기때문에 Project 성격에 따라 Test Coverage report, Javadoc report, Custom coding convention Tool 등 다양한 사용자 정의 Task를 만들어 build sequence에 포함시켜보도록 하자.

1. Gradle build command
2. 안드로이드에서 Custom Lint 활용하기
3. Gradle에서 dependency conflict 해결하기

profile
Android Framework Developer

2개의 댓글

comment-user-thumbnail
2024년 2월 1일

좋은 글 감사합니다!
혹시 그런데 ./gradlew build 명령어를 사용하면 앱은 debug, release variants 에서 앱이 빌드되는지 전부 확인해보는 것이 맞을까요?

1개의 답글