본문 바로가기

IT/Android

Caching in the Android Build Process

728x90
반응형

목차

  • Gradle이란 무엇입니까?
  • 빌드 디렉토리 및 증분 빌드
  • Gradle 빌드 캐시
  • Android 스튜디오 시스템 캐시
  • Android Gradle 플러그인 빌드 캐시
  • 추가 리소스

 

그래서 Gradle은 무엇입니까?

Android Studio에는 강력한 코드 편집기와 개발자 도구가 포함되어 있지만, wheel 을 재발명하고 프로젝트의 빌드 프로세를 관리하는 대신 기존 빌드 자동화 도구인 Gradle에 위임합니다. high level 에서 Gradle의 빌드 프로세스 에는 소스 코드를 Dalvik 바이트 코드 (.dex 파일) 및 컴파일된 리소스로 컴파일한 다음 컴파일된 파일을 APK로 결합하고 마지막으로 APK에 서명하는 작업이 포함됩니다. 각 단계는 구성할 수 있으며 Android 프로젝트에서 볼 수 있는 모든 Gradle 관련 파일 (build.gradle , gradle.properties등)은 프로젝트의 빌드를 사용자 지정하고 구성하는 데 사용됩니다.

 

Gradle 은 거의 모든 유형의 소프트웨어를 빌드할 수 있을 만큼 충분히 유연하며, 플러그인 을 통해 규칙 및 미리 빌드된 기능 계층을 추가하여 특정 프로젝트 유형에 사용할 수 있습니다 . Android Studio는 앱 빌드 프로세스와 관련된 기능을 추가하는 Android Gradle 플러그인을 사용합니다. 예를 들어 프로젝트의 build.gradle 파일에 buildTypes 블록이 있을 수 있습니다. 이 블록 은 기본 Gradle API에는 없지만 Android Gradle 플러그인에서 단일 프로젝트에서 앱의 다양한 버전(디버그, 릴리스 등) 빌드를 지원하는 데 사용됩니다.

 

build.gradle 의 root-level 의 종속성 블록을 보면 사용 중인 Gradle 버전을 확인할 수 있습니다 .

dependencies {
    classpath ‘com.android.tools.build:gradle:<GRADLE_VERSION>’
}

 

Gradle과 Android 플러그인은 Android Studio와 독립적으로 실행되므로 다양한 command-line command 을 사용하여 command line 에서도 앱을 빌드하고 실행할 수 있습니다.( ./gradlew <TASK>) Gradle에서 task 는 테스트 실행(./gradlew test ) 또는 Javadoc 생성 (./gradlew javadoc )과 같이 프로젝트에서 수행할 수 있는 작업의 한 부분을 나타냅니다 . 그것들은 다른 작업에 종속될 수 있습니다. Android Studio의 오른쪽 상단에 있는 Gradle 패널을 열면 프로젝트에 사용할 수 있는 모든 작업을 볼 수 있습니다.

 

 

Android Studio에서 발생하는 코드 편집과 Gradle에 위임된 앱 빌드의 상호 작용은 빌드 프로세스 중에 빌드 디렉토리, Gradle 캐시 및 Android Studio 시스템 캐시의 세 가지 캐싱 메커니즘이 사용된다는 것을 의미합니다. 이 문서에서는 각 메커니즘, 빌드 오류가 발생할 수 있는 방법 및 오류 수정 방법에 대해 설명합니다.

 

빌드 디렉토리 및 증분 빌드

그것이 하는 일

앱을 빌드할 때마다 생성되는 빌드 디렉토리에 이미 익숙할 것입니다. 일반적으로 가장 관심을 가질 이 디렉토리의 파일은 "outputs" 폴더 내의 APK 파일(또는 라이브러리 모듈 인 경우 AAR 또는 JAR )이지만 빌드 프로세스 중에 생성된 다른 파일도 여기에 나타납니다. Dagger 또는 Room과 같은 annotation processors 에서 생성된 코드 파일 또는 사용하는 linters의 결과입니다.

 

 

Annotation Processor란?

일반적으로 애노테이션에 대한 코드베이스를 검사, 수정 또는 생성하는데 사용됩니다. 본질적으로 애노테이션 프로세서는 java 컴파일러의 플러그인의 일종입니다. 애노테이션 프로세서를 적재적소에 잘 사용한다면 개발자의 코드를 단순화 할 수 있습니다. 자세한 내용은 위의 링크를 참조하세요.

 

빌드 디렉토리는 일반적으로 프로젝트의 root level 에 표시되지만 root build.gradle파일 에서 구성을 변경하여 표시되는 위치를 변경할 수 있습니다 .

 
allprojects { 
    buildDir = “/path/to/build/${rootProject.name}/${project.name}” 
}

"Run 'app'", "Rebuild Project" 및 "Build APK(s)"를 포함하여 빌드 디렉토리를 생성하는 여러 Android Studio 메뉴 옵션이 있습니다. ./gradlew assembleDebug 사용하여 Gradle의 assembleDebug task 를 command line 에서 생성할 수 도 있습니다.

 

기본적으로 Gradle은 Android 프로젝트를 빌드할 때 증분 빌드 기능을 사용합니다. 즉, task 을 실행하기 전에 Gradle은 입력 파일이 이전 빌드에서 변경되었는지 여부를 확인합니다. 그렇지 않은 경우 새 output 을 생성하기 위해 task 을 다시 실행하는 대신 이전 빌드의 output 을 재사용합니다. 즉, Gradle은 생성된 빌드 디렉토리를 캐시로 사용하여 빌드 시간을 크게 단축합니다 . 가능할 때마다 incremental annotation processor 를 사용하여 이것의 모든 이점을 얻을 수 있습니다 . 예를 들어 Room을 데이터베이스 라이브러리로 사용하는 경우 app-level build.gradle 에 다음을 추가하여 수행할 수 있는 incremental annotation processor 를 활성화하는 것이 좋습니다 .

 

 
android { 
    ... 
    defaultConfig { 
        ... 
        javaCompileOptions { 
            annotationProcessorOptions { 
                arguments = [“room.incremental”:”true”] 
            } 
        } 
    } 
}

task 이름 옆에 "UP-TO-DATE"가 표시되면 Gradle이 task 를 다시 실행하는 대신 기존 빌드 output 을 재사용하고 있음을 의미합니다.

 

 

지우는 시기와 방법

불행히도 Gradle은 입력 소스 파일의 코드 변경 사항을 놓치는 경우가 있습니다. 예를 들어 Dagger 코드 또는 리소스 파일을 업데이트했지만 Gradle이 이를 인식하지 못하고 이전 빌드에서 잘못된 output 파일을 재사용하려고 하여 빌드가 실패하는 문제가 발생할 수 있습니다. 두 가지 일반적인 오류는 "바이트를 dex로 변환하는 중 오류" 및 "R.layout.main Cannot Be Found/Cannot Resolve Symbol R"입니다. 이는 Android Studio에서 리소스용 R.java 파일을 생성하는 데 문제가 있음을 의미합니다.

빌드 디렉토리에서 생성된 파일을 언급하는 빌드 실패가 표시되면 클린 빌드를 수행하는 것이 좋은 첫 번째 단계입니다. 전체 빌드 디렉토리를 삭제하는 Gradle의 "clean" task 을 실행해야 합니다. 이것이 Android Studio의 "Build" -> "Clean Project" 메뉴 옵션이 하는 일입니다. command-line 에 해당하는 항목은 ./gradlew clean입니다.

 

Gradle 빌드 캐시

그것이 하는 일

Gradle 빌드 캐시 는 2017년 Gradle 4.0에서 도입되었으며 빌드 디렉토리와 별도의 메커니즘입니다. 빌드 디렉토리는 프로젝트의 workspace 내에 있기 때문에 로컬 시스템에서 현재 프로젝트의 캐시로만 사용할 수 있습니다. 반면 빌드 캐시는 프로젝트 workspace 가 아닌 로컬 또는 원격 빌드 캐시에 task output 을 저장합니다. 기본적으로 ~/.gradle/caches에 있습니다 . 작업 중인 모든 Gradle 프로젝트 간에 공유되므로 Gradle이 다른 프로젝트의 이전 빌드에서 task output 을 재사용할 수 있습니다. 이것이 유용한 예는 동일한 외부 라이브러리에 의존하는 여러 프로젝트가 있는 경우입니다. 한 프로젝트를 빌드하는 동안 Gradle이 다운로드하면 Gradle이 다른 프로젝트도 빌드할 때 사용할 수 있습니다.

 

단일 Android 프로젝트로만 작업하는 경우에도 빌드 캐시는 빌드 시간을 개선할 수 있습니다. 예를 들어, branch 를 앞뒤로 전환할 때 task output 은 다른 branch 간에 input 이 약간 다르기 때문에 반복해서 다시 작성됩니다. 증분 빌드는 가장 최근 빌드의 output 만 캐시하므로 이 경우에는 그다지 도움이 되지 않습니다. 빌드 캐시는 이전 빌드 output 을 기억하고 이전에 여러 빌드를 로컬에서 이미 빌드한 경우 다시 빌드할 필요성을 크게 줄입니다.

 

팀과 함께 프로젝트를 진행하는 경우 Gradle Enterprise 를 사용하여 원격 빌드 캐시를 공유할 수도 있습니다 . 즉, 빌드가 팀 동료의 빌드 output 이 귀하보다 최신인 경우 대신 사용할 수 있습니다. 원격 캐시는 지속적인 통합 빌드 속도도 높일 수 있습니다.

 

Gradle 빌드 캐시는 org.gradle.caching=true/false를 gradle.properties에 추가하여 활성화 또는 비활성화할 수 있습니다.

 

지우는 시기와 방법

빌드 캐시 사용의 단점은 프로젝트 내부의 빌드 디렉토리 외부에 있는 캐시된 파일을 사용할 수 있기 때문에 프로젝트를 정리한다고 해서 더 이상 처음부터 빌드된다는 보장이 없다는 것입니다. 빌드 디렉토리가 삭제된 경우에도 부실 캐시 파일로 인해 빌드 오류가 발생할 수 있습니다.

 

빌드 캐시를 무시하려면 --no-build-cache플래그 를 사용할 수 있습니다 .clean build 가 빌드 오류를 수정하기에 충분하지 않은 경우 ./gradlew clean assembleDebug --no-build-cachecommand line 에서 실행하여 로컬 빌드 폴더를 삭제하고 Gradle 캐시를 건너뜁니다.

 

불행히도 빌드에서 빌드 캐시를 우회하기 위한 Android Studio 메뉴 옵션은 없습니다.

rm -rf $HOME/.gradle/caches/ 를 실행하여 캐시를 삭제할 수도 있습니다 .

 

Android 스튜디오 시스템 캐시

그것이 하는 일

Android Studio 시스템 캐시 는 File menu의 "Invalidate Caches / Restart"를 클릭하면 무효화되는 것입니다.

 

Android Studio는 이를 사용하여 프로젝트 구조에 대한 정보를 저장하며 Gradle 및 빌드 프로세스와 관련이 없습니다. 다른 Jetbrains IDE는 유사한 캐시를 사용합니다. 일반적으로 Android Studio 캐시는 IDE 성능을 개선하지만 시간이 지남에 따라 점점 더 많은 파일이 캐시되고 캐시가 과부하될 수 있습니다. 또한 더 이상 작업하지 않는 단기 프로젝트에 대한 정보와 같이 다시는 필요하지 않은 항목을 저장할 수도 있습니다. 캐시 파일은 Android Studio가 다시 시작될 때까지 실제로 삭제되지 않습니다

 

지우는 시기와 방법

Android Studio 캐시는 프로젝트 구조 정보를 저장하기 때문에 파일을 이동하거나 새 XML 파일을 생성하면 혼동될 수 있습니다. 결과적으로 코드 편집기에서 오류가 발생할 수 있습니다. 일반적인 것은 "Unresolved reference" 및 "Cannot resolve symbol"입니다.

 

 

때때로 오류가 해결되고 캐시를 지우는 것보다 훨씬 빠르기 때문에 먼저 프로젝트를 다시 빌드하는 것이 좋습니다. 그러나 rebuild 가 도움이 되지 않으면 "Invalidate Caches / Restart"이 방법입니다. ViewBindings 를 사용할 때 이러한 오류가 많이 발생합니다 . Android Studio는 동적으로 생성된 바인딩 파일의 변경 사항을 놓치는 경우가 있습니다.

 

마찬가지로 파일을 이동한 후 빌드 실패가 발생하는 경우 근본 원인은 Gradle 캐시가 아닌 Android Studio 캐시의 오래된 정보일 수 있습니다.

 

이전에 본 또 다른 예는 "R.layout.main Cannot Be Found / Cannot resolve symbol R"입니다.

 

AGP 빌드 캐시는 어떻습니까?

이 기사에 대한 조사를 하는 동안 Android Gradle 플러그인(AGP) 빌드 캐시에 대한 많은 언급을 보았습니다. 그들 중 많은 사람들이 이 멋진 404 페이지 에 연결되어 있습니다. 주변을 파고들었고 AGP 2.3에 도입되었다는 것을 알았지만 AGP 빌드 캐시가 Gradle 빌드 캐시로 대체되었기 때문에 2020년 8월 AGP 4.1 에서 제거되었습니다. Gradle cleanBuildCachetask 와 android.enableBuildCacheGradle 속성에 대한 언급을 볼 수 있지만 둘 다 더 이상 사용되지 않는 것으로 간주됩니다. 사실, android.enableBuildCache=true/false더 이상 효과가 없으며 대신 --no-build-cache플래그와 org.gradle.caching=true/false속성을 사용해야 합니다.

 

추가 리소스

 

- 결과적으로 증분 빌드로 인해 빌드 시간이 주는 것을 경험할 수 없었다.

- 증분 빌드를 사용하지 않아도 최신 output 을 사용했다. (왜일까..)

728x90
반응형