본문으로 바로가기

[App bundle] 개념과 필요성 #1

category 개발이야기/Android 2021. 1. 15. 16:02
반응형

photo from unsplash

2018년 구글 IO에서 App bundle의 개념을 발표했습니다.

앱을 배포하는 새로운 방식 대한 내용이지만 배포뿐만 아니라 개발 방식에도 차이가 발생함에 따라 배포 담당자, 앱 관리자, 기획자만의 관심사항이 아닌 개발자에게도 전략적인 개발도구로 필요성이 높아졌습니다.

이미 2년 반이 지난 지금 이 필요성을 언급하는 이유는 제가 개발하고 있는 앱에서도 App bundle에서 제공하는 기능의 일부를 사용해야 하는 상황이 벌어졌기 때문입니다. 이는 처음 시작하는 앱 역시 시간이 지남에 따라 다양한 배포 방식과 덩치가 커져가는 앱을 효율화시키기 위한 해결 요소로 app bundle의 필요성이 점점 더 대두될 수밖에 없다는 점을 시사합니다.

이미 적용된 앱들도 많지만 한발늦게 적용함에 따라 앱 경쟁력은 이미 뒤처졌지만 개발하는 방법이나 적용에 대한 다른 풍부한 경험과 안정된 버전을 사용할 수 있다는 건 그나마 다행스러운 일입니다. (2018 발표 당시에는 몇몇 기능 들은 beta 버전이었습니다.)

이번 포스팅에서는 앱 번들의 개념과 필요성에 대해서 정리 합니다.

App bundle 이란?

App bundle은 말 그대로 app의 묶음입니다.

이전에는 앱은 "하나의 apk 파일로 압축되어 배포된다"의 개념이 었다면 app bundle은 "여러 개의 분할된 apk가 필요에 따라 구성되어 하나의 앱으로 동작한다"의 개념입니다.

https://www.youtube.com/watch?v=0raqVydJmNE&feature=youtu.be

따라서 앱이 동작함에 있어 필요한 전체 구성요소들을 하나로 묶어서 배포하며, 실제 apk가 Google play를 통해 설치될 때, 전체 구성요소 중 해당 단말에 최적화된 구성으로만 정리하여 앱이 설치됩니다.

따라서 불필요한 전체의 리소스가 제거됨에 따라 app의 용량이 감소합니다.

App bundle의 필요성

APK 용량의 감소

구글 발표에 의하면근 10년 동안 Android의 Google play의 store에 올라온 수억 개의 앱을 분석했을 때 앱이 6MB 증가함에 따라 전환율은 1%씩 감소한다고 합니다. 앱의 다운로드 시간과 앱의 용량에 따라 사용자들이 거부감을 느끼게 되는 겁니다.

또한 Apk의 크기가 커짐에 따라 이를 단말에서 유지하기도 힘들어집니다. 모든 사람들이 최신 단말을 사용하고, 용량이 큰 고가 단말만을 이용하지는 않습니다. 예를 들어 실버폰이나 키즈폰이라는 가격에 모든 중심을 맞춘 저용량 및 저사향 카테고리가 존재하기도 하며, 제3국에서는 아직도 저렴한 저사양이 폰이 역시 큰 시장을 차지합니다.

용량이 큰 apk는 용량이 부족한 단말에서 삭제 1순위가 되기 마련입니다.

APK 배포 관리의 장점

APK의 용량이 방대해 짐에 따라 앱별로 나름 자구책을 마련합니다.

그 자구책중의 하나로 so 라이브러리를 탑재하는 앱의 경우 각 CPU architecture별로 apk를 따로 생성하여 배포하는 방식입니다.

저희 팀에서 사용하고 있는 형태로, v7용 apk, v8용 apk, x86용 apk 등등.. 하나의 apk를 배포할 때 각 CPU에 맞는 so만을 탑재하여 apk 용량을 감소시킵니다. 물론 모든 architecture를 포함하는 universal apk도 만들어 배포합니다.

이렇게 직접 개발자가 여러 번 빌드를 진행함에 따라 배포의 공수, 관리의 공수가 너무나 많이 들어갑니다. 하지만 이런 작업들을 이제 play store에서 진행함에 따라 app bundle 하나만 마켓에 배포하면 설치는 google play에서 단말에 맞춰 진행합니다.

App bundle의 구조

APK의 구조를 먼저 보면 아래와 같이 표현할 수 있습니다.

https://www.youtube.com/watch?v=0raqVydJmNE&feature=youtu.be

APK는 위와 같이 Native library를 포함하고, 화면에 그리기 위한 해상도별 drwable을 가지고 있으며, dex file이나, string, assets 등을 가지고 있습니다.

색상으로 표현되어 있듯이 APK내에서 모든 단말을 대응하기 위한 불필요한 리소스들이 존재하는 걸 알 수 있습니다. 따라서 이를 App bundle로 만들면 Google play에서 아래와 같이 각 구성요소에 따라 분할된 APK로 만듭니다.

https://www.youtube.com/watch?v=0raqVydJmNE&feature=youtu.be

위처럼 분할된 apk들은 일반 apk처럼 dex 파일, resource, android manifest를 포함합니다. 여러 개로 분할된 apk는 단말의 사양에 맞춰 필요한 apk만 설치되며 이렇게 분할된 apk를 Android framework에서는 하나의 앱으로 인식합니다.

단 OS가 5.0 (Lollipop) 이후인 경우에만 분할 apk를 지원하므로 만약 이전 버전(4.4 kitkat)의 OS라면 universal apk가 설치됩니다.

Split APKs

App bundle에서 생성하는 분할된 apk는 세 종류로 구분됩니다. [2]

1. Base APK

앱의 기본 기능이 포함되어 사용자가 앱을 다운로드하면 가장 먼저 다운로드되어 설치됩니다. 기본적으로 단일 apk앱에서 AndroidManifest에 선언하는 service, content provider, permission, min sdk 요구사항, system dependency 등의 내용이 포함됩니다.

2.  Configuration APKs

화면에 따른(density)에 따른 resource, CPU archtecture에 따른 네이티브 라이브러리, 언어(string values)에 대한 부분이 각각 여러 개의 구성 apk로 분할되어 생성됩니다.

3. Feature Module APKs

Base APKConfiguration APKs로 각각 단말에 맞춤 apk들로만 구성하여 다운로드되고 설치됩니다. 만약 개발자가 특정 기능을 분리하여 선택적으로 탑재하고 싶은 경우 이를 모듈 형태로 만들어 이 모듈을 분리된 apk로 만들 수 있습니다.

예를 들어 여러 사람이 서버에 올린 사진을 받아와서 보는 앱이 있습니다. 이 앱은 기본적으로 서버에서 사진을 가져와서 사용자에게 보여주는 기능을 제공하고 추가적으로 자기의 사진을 편집하여 올리는 기능도 제공한다고 가정합니다.  사진을 편집하는 기능은 메인 기능이 아니라 소수의 사람들이 쓴다고 판단되면 이 기능을 모듈로 분리하여 사용자의 요청에 따라 다운로드하여 사용하도록 구성할 수 있습니다.

즉 설치 시점에는 존재하지 않으나 필요에 따라 선택적으로 기능을 다운로드하여 추가하기 위하여 분리된 APK를 말합니다.

https://developer.android.com/guide/app-bundle

app bundle을 통해서 구성되는 apk를 보면 위와 같이 base apk, configuration apks, feature apks로 구분되어 각각의 수십 개의 apk로 분할됨을 알 수 있습니다.

이렇게 분할된 apks들은 아래 그림처럼 단말의 조건에 맞춰 compact 하게 단말에 설치됩니다.

https://developers-kr.googleblog.com/2018/05/google-io-2018-whats-new-in-android.html

 

App Bundle의 주의사항

APK의 크기 제한[2]

실제로 apk를 다운로드할 때 압축되어 다운로드되는 apk의 최대 크기는 150MB로 제한됩니다. 즉 다운로드 시에 (기본 APK + 구성 APK)의 크기가 150MB가 넘는다면 설치에 실패합니다. 나중에 추가로 다운로드되도록 분리한 기능 모듈 역시 단일 크기가 150MB가 넘어가면 안 됩니다.

게임에서 많이 적용하는 추가 리소스 다운로드(Asset download) 역시 Dynamic module로 분리하여 따로 다운로드하도록 구성할 수 있습니다. Asset pack의 경우에만 512MB~2G까지 구성이 가능하며, App bundle은 최대 50개의 asset pack을 가질 수 있습니다. [4] Asset 다운로드 부분은 이 글의 범주에서 벗어나므로 추가적으로 다루지는 않습니다.

Side load 된 apk의 동작[2]

Google play store가 아닌 다른 경로로 추출되어 설치된 apk를 설치 시 문제를 일으킬 수 있습니다. App bundle 사용으로 인하여 단말에 최적화된 apk가 단말에 탑재되었는데, 구성이 다른 단말(화면 density가 다르다거나, CPU architecture가 다른 경우)에 설치된다면 정상 동작하지 않을수 있습니다.

또한 Android 10 이상에서는 이런 경로로 설치되어 필수 apk가 누락된 경우 이를 Google play store가 다운로드 시점에 확인하여 실패 처리합니다.

리소스 테이블의 동적 수정[2]

리소스 테이블을 동적으로 수정하는 도구를 사용하는 경우 App Bundle에서 생성된 APK가 정상동작하지 않을 수 있으므로 App Bundle을 빌드할 때 그런 도구들은 중지하는 게 좋습니다.

Feature Module의 Manifest 파일 구성[2]

기능 모듈도 각각의 Manifest 파일과 resource를 갖습니다. 다만 기능 모듈의 Manifest 내용은 base apk를 만들 때 base manifest로 모두 병합됩니다. 따라서 모듈의 Manifest 파일에서 모듈에 존재하는 resource를 참조하도록 구성해 놓으면 문제가 생깁니다.

모듈의 manifest 파일에서 참조하는 resource는 반드시 base module resource에 포함시켜야 합니다.

Feature Module의 빌드 구성[2]

Feature Module에도 build 구성 파일이(build.gradle) 독립적으로 존재합니다. 따라서 base apk와 충돌되는 항목이 존재할 경우 runtime에 문제가 발생할 수 있습니다. 예를 들어 base build에는 buildTypes.release.debuggable = true이나 기능 모듈에는 false로 설정한 경우를 말합니다. 이에 대한 추가적인 설명은 기능 모듈 생성 포스팅 부분에서 추가적으로 언급하겠습니다.

 

Configuration 분할 구성 사용 중지

어떠한 이유로 인하여 App bundle에서 제공하는 split apk 생성 및 적용을 부분적으로 막아야 하는 경우가 생길 수 있습니다. (위에서 언급한 동적인 resource 변경이 필수라던가, 제조사에 선 탑재되어 architecture가 분리되지 않아야 한다던가..) 이때 base module의 build.gradle파일을 아래와 같이 추가하여 configuration apk의 분할 지원을 중지할 수 있습니다. [5]

android {
    // When building Android App Bundles, the splits block is ignored.
    splits {...}

    // Instead, use the bundle block to control which types of configuration APKs
    // you want your app bundle to support.
    bundle {
        language {
            // Specifies that the app bundle should not support
            // configuration APKs for language resources. These
            // resources are instead packaged with each base and
            // feature APK.
            enableSplit = false
        }
        density {
            // This property is set to true by default.
            enableSplit = true
        }
        abi {
            // This property is set to true by default.
            enableSplit = true
        }
    }
}

 

References

[1] www.youtube.com/watch?v=0raqVydJmNE&feature=youtu.be

[2] developer.android.com/guide/app-bundle

[3] developer.android.com/studio/command-line/bundletool?hl=ko

[4] developer.android.com/guide/app-bundle/asset-delivery#size-limits

[5] developer.android.com/guide/app-bundle/configure-base

반응형