HOME > android > feature

Android App Bundle로 Apk 크기를 더 작게 만들기

JSFollow09 Jun 2019

Android App bundle(안드로이드 앱 번들)은 앱의 설치파일인 Apk의 사이즈를 줄이기 위한 목적으로, P 버전에서 소개되었습니다. Android App bundle은 모든 리소스를 갖고 있는 확장자가 aab인 파일을 말합니다. Apk 사이즈를 줄이는 방법은 PlayStore가 디바이스에 필요한 파일만 App bundle에서 꺼내 디바이스로 전달하여 설치하는 것입니다. 그러면 불필요한 리소스가 설치되지 않아도 됩니다. 디바이스의 특성에 따라 리소스를 분리하여 전달 및 설치하는 것을 Dynamic delivery라고 합니다.

Apk는 앱의 코드와 라이브러리, 리소스 등의 파일들을 함께 갖고 있습니다. 예를 들어, 앱은 CPU 아키텍처(이하 ABI)별로 네이티브 라이브러리(확장자가 so)를 갖고 있습니다. 특히 apk는 모든 Density의 이미지를 갖고 있고 모든 국가의 String을 갖고 있습니다. 사실 설치하는 단말에 필요한 것은 특정 ABI의 네이티브 라이브러리이고, 특정 국가의 String뿐인데 말이죠. 구글은 이런 부분 때문에 Apk가 점점 커지고, 이런 부분을 해결하면 Apk 사이즈가 줄어들 것이라는 것에 초점을 맞추었습니다. 그렇게 해서 만들어진 것이 Android App Bundle입니다.

App bunlde은 코드(dex), 라이브러리, 리소스 등 모든 데이터가 포함되어있습니다. 개발자가 App bundle 파일을 PlayStore에 업로드하면, PlayStore는 미리 aab파일에서 아키텍처, Density, ABI, Locale 별로 파일들을 분리하여 apk파일을 만듭니다. 그리고 설치 요청이 들어오면 사용자의 환경에 맞게 필요한 파일만 전달하여 설치합니다.

앱 번들 파일의 구조는 아래와 같습니다. android app bundle format

Split apk와 Dynamic delivery

App bundle로 인해 사용자에게 전달되는 apk 파일은 1개 이상이 될 수 있습니다. 코드는 Base apk에 존재하기 때문에 이 apk는 항상 설치되어야 합니다. 그리고 Density, Locale, ABI 별로 리소스를 분리할 수 있으며 별개의 Configuration apk들이 생성됩니다. 즉, 사용자가 앱을 설치할 때 Base apk와 디바이스에 필요한 Configuration apk 파일들이 함께 전달되어 설치됩니다.

  • Base apk : 코드(dex)가 포함된 Apk
  • Density Configuration apk : 특정 Density에 대한 리소스가 포함된 apk
  • Locale Configuration apk : 특정 Locale에 대한 리소스가 포함된 apk
  • CPU ABI Configuration apk : 특정 ABI에 대한 리소스가 포함된 apk

사실, 여러개의 apk로 1개의 앱(Package name이 동일한)을 설치하는 것은 Split apk라는 기술입니다. Split apk는 L버전부터 제공되기 시작했습니다. Split apk는 단순히 어떤 package의 리소스 및 코드를 여러 apk 파일들에 분산시키는 기술입니다.

예를 들어, package name이 com.example이라는 앱이 있다면, 그 앱의 코드와 리스소를 다음 3개의 apk로 나눌 수 있습니다. 3개로 나뉘어 있기 때문에 모든 리소스를 사용하려면 3개의 앱이 모두 설치되어야 합니다.

  • split1.apk
  • split2.apk
  • split3.apk

Dynamic delivery는 Split apk를 이용하여 Locale, ABI, Density에 따라 Base와 Configuration apk등을 나누어 설치하는 것 뿐입니다.

Dynamic feature

Dynamic feature는 위의 Apk에 추가로 split apk들을 만드는 것을 말합니다. 예를 들어, 이벤트를 위해 한번만 사용되는 코드의 리소스가 매우 커서 앱에 포함시키기 곤란한 경우가 있습니다. Apk가 매우 크면 사용자는 다운받다가 취소할 수 있기 때문에 일회성 코드를 포함시키는 것은 좋은 생각이 아닐 수 있습니다. App bundle을 이용하여, 이런 일회성 코드들은 Base apk에서 제외하고 Dynamic feature 만들어버릴 수 있습니다. 일회성 코드가 동작되어야 할 때 분리된 Apk를 다운받아 설치한 후 동작시킬 수 있습니다. 이 부분은 해보지 않아서 앱이 언제 동적으로 설치할 수 있는지는 등은 잘 모르겠습니다. (구글 코드랩에 Dynamic feature module을 설정하는 튜토리얼이 있습니다.)

아래 그림은 Base, Configuration, Dynamic feature apk들의 관계입니다. Apk splits tree

리소스 분리 설정

Base apk에서 Density, Locale, ABI 관련 리소스들은 Configuration apk로 분리할 수 있습니다. 분리가 필요한 것들은 다음과 같이 build.gradle에서 설정을 할 수 있습니다.

bundle {
   language {
       enableSplit = true
   }
   density {
       enableSplit = true
   }
   abi {
       enableSplit = true
   }
}

App bundle 테스트

앱 번들 파일이 잘 만들어졌는지 테스트 해볼 수 있습니다. bundletool이라는 툴을 이용하면 PlayStore가 어떻게 apk들을 만드는지 볼 수 있습니다. 다음 파일들은 App bundle로 만들어낸 apk파일들 입니다. 실제로 PlayStore가 App bundle 파일로 여러 apk을 미리 만들어 둔다는 것을 알 수 있습니다. 자세한 테스트 방법은 구글 코드랩 튜토리얼을 확인해주세요.

extracting: apks/base-xhdpi.apk     
extracting: apks/base-hdpi.apk      
extracting: apks/base-mdpi.apk      
extracting: apks/base-sq.apk        
extracting: apks/base-fr.apk        
extracting: apks/base-ar.apk        
extracting: apks/base-master.apk    
extracting: apks/base-sr.apk        
extracting: apks/base-hr.apk        
extracting: apks/base-mr.apk        
extracting: apks/base-tr.apk        
....Dynamic feature
extracting: apks/base-zh.apk        
extracting: apks/base-en.apk        
extracting: apks/base-jp.apk        
extracting: apks/base-armeabi_v7a.apk  
extracting: apks/base-arm64_v8a.apk  
extracting: apks/base-x86_64.apk    
extracting: apks/base-x86.apk

정리

Android App bundle에 대해서 알아보았습니다. Dynamic delivery라는 기술로 분리할 수 있는 리소스들을 여러 apk로 분리하고 디바이스에 전달하며, Split apk라는 기술을 사용하여 필요한 apk들만 디바이스에 설치하도록 하였습니다. App bundle만 만들고 PlayStore에 올리면 구글이 알아서 해주기 때문에 내부적인 동작 원리는 몰라도 됩니다. App bundle을 설정하는 방법과 App bundle 파일을 생성하는 방법은 구글 코드랩 튜토리얼ProAndroidDev의 글을 참고해주세요.

참고