앱 빌드속도 빠르게 하기

이번 포스팅에서는 안드로이드 스튜디오에서 앱의 빌드속도를 빠르게 할 수 있는 여러가지 설정들에 대해 알아보도록 하겠습니다.

구글에서는 빌드속도를 최적화하는 여러가지 방법들에 대해 정리하여 소개했고 유튜브에서도 공개하고 있습니다. 오늘은 이 내용을 정리해 보겠습니다.

# 최신버전의 Gradle 사용

우선은 최신버전의 Gradle을 사용하는게 중요합니다. 모듈에 대한 build.gradle 파일에서 사용하는 코틀린의 버전이나, 그래들 플러그인의 버전을 정할 수 있게 되어 있습니다. 버전내역을 보시면 플러그인이 업데이트 될 수록 빌드를 빠르게 하는 기술이 적용되기 때문에, 버전을 항상 최신버전으로 유지하는게 중요합니다.

Gradle 버전은 안드로이드 스튜디오에서 앱을 생성할 때 최신버전으로 생성이 되기 때문에 새로 생성하는 프로젝트에 대해서는 신경 쓸 필요가 없지만, 과거에 작성한 프로젝트의 경우에는 이 빌드플러그인을 가능한 최신 버전으로 업데이트해서 사용하시는걸 추천합니다.

# 개발시 서로 다른 빌드세팅 사용

다음은 개발할 때 서로 다른 빌드세팅을 사용하는 겁니다.

빌드 그래들 파일에 보시면 buildTypes 블럭이 있는데, 디버그를 위한 debug 블럭과 릴리즈를 위한 release 블럭을 나누어서 사용할 수 있습니다.

릴리즈 블럭 안에는 실제 릴리즈를 할 때 수행할 내용이 들어가게 됩니다. 여기에 디버그 블럭을 추가합니다.

예를들어 릴리즈시에는 코드의 암호화를 설정해야 하는데 디버그에서는 적용할 필요가 없으므로 설정을 구분해서 빌드를 할 수 있습니다.

# multidex 사용하지 않음

자바 코드는 실행환경에 의존하지 않는 바이트코드로 컴파일 되어 자바 가상머신(JVM)이 실행되는 환경이라면 어디서나 동일하게 실행할 수 있습니다. 구글에서는 라이센스 문제를 피하기 위해 JVM 대신 Dalvik VM을 만들었고 이 DVM에서 돌리기 위해 자바 바이트코드를 DEX(Dalvik Executable)로 변환하여 사용하도록 했습니다.

그런데 DVM을 사용하다보니 여러가지 문제가 있어서 새로 개발한 것이 ART VM입니다. 차이점을 간단하게 정리해 보면 다음과 같습니다.

# Dalvik VM

  • 32비트만 지원.
  • JIT(Just In Time) 컴파일러 사용.
  • 실행할 때 마다 필요한 컴파일을 수행하므로 설치파일이 작고 CPU, 메모리 사용이 높아 배터리 소모량이 큼.

# Android RunTime(ART) VM

  • 32, 64 비트 지원.
  • AOT(Ahead On Time) 컴파일러 사용.
  • 설치시 모든 컴파일 작업을 수행해 놓으므로 설치파일이 크고 설치가 느리지만 실행중 자원소모량은 JIT보다 적어 배터리 효율이 높다.
  • GC 효율이 향상됨.
  • 킷캣 KitKat 버전부터 지원이 시작되었으며 롤리팝 Lolipop 버전 이후는 AOT 컴파일러가 기본으로 적용됨
  • 누가 Nougat 버전 부터 JIT와 AOT를 모두 탑재하여 최초 설치시에는 JIT으로 컴파일 해 설치시간과 용량을 줄이고, 차후 기기를 사용하지 않을 때나 충전 중일 경우 컴파일을 조금씩 하여, 자주 사용되는 앱을 AOT 방식으로 전환하는 방식으로 바뀜.

단일 DEX(Dalvik Executable) 에서 사용가능한 함수의 최대개수는 65536개입니다. 이 개수를 넘으면 처리를 위해 multidex를 도입해야 하는데 API Level 21 롤리팝 미만에서는 멀티덱스 처리가 느린 Dalvik 런타임이 사용됩니다. 그러나 API 21 이상에서는 ART 런타임을 사용하기 때문에 빌드속도가 빨라집니다. 그것을 위해서는 minSDKVersion을 21로 설정하면 됩니다.

API level 21이면 안드 OS로 따지면 5.0인데 보통은 4.4 킷캣까지 대응하시는 경우도 있지만 저 개인적으로는 큰 문제가 없다면 5.0 대응을 추천드립니다.

# 복수의 APK 생성기능 비활성화

안드로이드 앱은 화면 해상도에 따라 서로 다른 앱이 각각 만들어지게 됩니다. 그래서 APK 파일이 크다면 abi/화면 해상도별로 APK 파일을 나누어 앱 용량을 줄일수가 있습니다.

어차피 테스트를 하는 과정에서는 기능을 확인하는게 중요하기 때문에 다른 해상도에 대해 빌드를 생략해서 속도를 빠르게 할 수 있습니다. gradle에서 다음과 같이 코드를 쓰면 됩니다.

1
2
splits.abi.enable = false
splits.density.enable = false

# 패키징 리소스 최소화

앞에서는 특정 해상도에 대해서만 빌드하도록 설정을 했는데, 앱에 보시면 언어별로도 각각 앱이 만들어지게 되어 있습니다. 그래서 테스트 해야하는 언어 이외에는 빌드를 안하도록 설정을 할 수 있는데요, 예를들어 영어, 일본어, 독일어, 한국어에 대응하도록 만들었다면 기능확인을 위해 한국어 앱만 빌드를 하게 할 수 있습니다.

1
2
3
4
5
6
7
8
defaultConfig{
    applicationVariants.all { variant ->
        if (variant.buildType.name == "debug") {
            variant.mergedFlavor.resourceConfiguration.clear()
            variant.mergedFlavor.resourceConfiguration.add("ko")
        }
    }
}

빌드가 디버그면 설정을 다 없애버리고 한국어만 추가한다는 내용인데요, 참고로 현재 빌드가 디버그인지 릴리즈인지는 화면 왼쪽에 Build Variants 탭을 열어서 확인할 수 있습니다.

패키징 리소스는 resConfig라는 기능을 이용해 간단하게 구현할 수도 있는데 그럴려면 productFlavor 블럭을 추가로 만들어서 다음과 같이 사용하면 됩니다. resConfigbuildTypes 안에서는 사용할 수 없기 때문입니다. productFlavor의 구체적인 사용방법에 대해서는 Create a build variant for development를 참고하세요.

1
2
3
4
5
productFlavors{
    dev {
        resConfigs "ko", "xxxhdpi"
    }
}

# PNG 크런칭 비활성화

안드로이드에서 PNG 파일이 포함되면 PNG 파일을 압축하는 기능이 실행되는데요, 이 기능은 debug 빌드에서는 기본적으로 사용이 중지되기 때문에 신경 쓸 필요가 없습니다. 다만 release 빌드에서도 기능사용을 중지시키고 싶다면 코드를 다음과 같이 쓰면 됩니다.

1
2
3
4
5
buildTypes{
    release {
        crunchPngs false
    }
}

# 필요없는 변경하지 않기

앱이 처음 실행되는 시작점의 역할을 하는 manifest 파일이 있습니다. 그런데 manifest를 변경하면 빌드가 처음부터 다시 이루어지게 됩니다.

그런데 버전넘버와 버전코드를 변경하면 마니페스트 파일도 변경되어 앱이 처음부터 다시 빌드가 되기 때문에 테스트 시에는 이 값을 숫자로 고정하여 사용하는 것도 빌드를 빠르게 할 수 있는 방법이 될 수 있습니다.

# 오류리포팅 기능 사용안함

안드로이드 앱에서는 Crashlytics 보고서를 자동으로 작성하도록 되어있습니다. 이 기능을 다음과 같이 비활성화 시켜 줍니다.

1
2
3
debug{
    ext.enableCrashlytics false
}

# 라이브러리 버전

라이브러리를 사용할 때 버전을 x.x+ 형식으로 지정할 경우 x.x대의 최신버전을 사용하라는 뜻입니다. 그런데 이 경우 24시간마다 최신버전을 웹에서 확인하게 되기 때문에 빌드시간이 증가하게 됩니다. 따라서 라이브러리의 버전을 정확히 정해주면 빌드시간을 줄일 수 있습니다.

1
2
3
4
dependencies {
-    compile 'com.android.support:appcompat-v7:26.+'
+    compile 'com.android.support:appcompat-v7:26.0.0-alpha1'
}

이렇게 해서 안드로이드 스튜디오에서 빌드속도를 빠르게하는 여러가지 방법에 대해 알아보았습니다.

Built with Hugo
Theme Stack designed by Jimmy