다양한 API 레벨을 위한 다중 APK 만들기

앱을 Google Play에 게시하면 Android App Bundle을 빌드하고 업로드해야 합니다. 그렇게 하면 Google Play가 자동으로 각 사용자의 기기 설정에 맞는 최적화된 APK를 생성하여 제공하므로 사용자는 앱을 실행하는 데 필요한 코드와 리소스만 다운로드할 수 있습니다. Google Play에 게시하지 않는다면 다중 APK를 게시하는 것이 유용하지만 각 APK를 직접 빌드, 서명, 관리해야 합니다.

Google Play에서 다중 APK를 활용하려고 Android 애플리케이션을 개발한다면 처음부터 우수 사례를 적용하여 개발 과정에서 발생하는 불필요한 문제를 방지하는 것이 중요합니다. 이 학습 과정에서는 각각 약간 다른 범위의 API 레벨을 다루는 앱의 다중 APK를 만드는 방법을 보여줍니다. 다중 APK 코드베이스를 아주 쉽게 유지하는 데 필요한 도구도 제공합니다.

다중 APK가 필요한지 확인

여러 세대의 Android 플랫폼에서 작동하는 애플리케이션을 만들려는 개발자는 애플리케이션이 이전 버전과의 호환성을 유지하면서 새로운 기기의 새 기능을 활용하기를 바랍니다. 처음에는 다중 APK 지원이 최상의 솔루션인 듯 보이지만 그렇지 않은 경우가 많습니다. 다중 APK 개발자 가이드의 단일 APK 대신 사용 섹션에는 지원 라이브러리 사용을 포함하여 단일 APK로 새 기능을 활용하면서 이전 버전과의 호환성을 달성하는 방법에 관한 유용한 정보가 포함되어 있습니다. 이 자료의 리플렉션처럼 계산을 많이 사용하는 기법에 의존하지 않고도 단일 APK에서 특정 API 레벨에서만 실행되는 코드를 작성하는 방법도 알 수 있습니다.

관리 가능한 경우 애플리케이션을 단일 APK에 제한하면 다음과 같은 여러 이점이 있습니다.

  • 더욱 쉽게 게시하고 테스트할 수 있습니다.
  • 코드베이스를 하나만 유지 관리하면 됩니다.
  • 애플리케이션을 기기 설정 변경에 맞게 조정할 수 있습니다.
  • 여러 기기에서 앱 복원을 쉽게 할 수 있습니다.
  • 시장 선호도, APK 간 '업그레이드'에 따른 동작 또는 어떤 기기 클래스에 어떤 APK가 사용되는지 걱정할 필요가 없습니다.

이 학습 과정의 나머지 부분에서는 개발자가 주제를 조사했고 링크된 리소스의 자료를 철저히 학습했으며 다중 APK가 애플리케이션에 적합한 경로라고 파악했다고 가정합니다.

요구사항 차트

먼저 간단한 차트를 만들어 APK가 얼마나 많이 필요한지, 각 APK가 어떤 API 범위를 다루는지 빠르게 알아보세요. Android 개발자 웹사이트의 플랫폼 버전 페이지에서 지정된 버전의 Android 플랫폼을 실행하는 활성 기기의 상대적 수에 관한 데이터를 간편하게 참조할 수 있습니다. 또한 각 APK가 타겟팅할 특정 API 레벨 세트를 계속 추적하는 것은 처음에는 쉬워 보이지만 대개의 경우처럼 특히 중복이 발생하면 급속도로 어려워집니다. 다행히 쉽고 빠르게 요구사항을 차트로 작성하고 나중에 간편하게 참조할 수 있습니다.

다중 APK 차트를 만들려면 Android 플랫폼의 다양한 API 레벨을 표시하는 셀로 구성된 행으로 시작합니다. 마지막에 이후 버전의 Android를 표시할 추가 셀을 넣으세요.

3 4 5 6 7 8 9 10 11 12 13 +

이제 차트에 색상을 지정해 각 색상이 APK를 표시하도록 합니다. 다음 예는 각 APK를 특정 범위의 API 레벨에 적용하는 방법을 보여줍니다.

3 4 5 6 7 8 9 10 11 12 13 +

이 차트를 만들었다면 팀에 배포하세요. 프로젝트에 관한 팀 내 소통이 즉시 더 간단해집니다. "API 레벨 3에서 6의 APK는 어때요? Android 1.x 버전 APK요. 그거 어떤 것 같아요?"라고 묻는 대신 "파란색 APK는 어떤 것 같아요?"라고 간단히 말할 수 있기 때문입니다.

라이브러리 프로젝트에 모든 공통 코드 및 리소스 배치

기존 Android 애플리케이션을 수정하든 처음부터 새로 시작하든 코드베이스에 가장 먼저 해야 하는 일이 이 작업이며 가장 중요합니다. 라이브러리 프로젝트에 들어가는 모든 것은 한 번만 업데이트하면 되므로(언어 현지화된 문자열과 색상 테마, 공유 코드에서 수정된 버그를 생각해 보세요) 개발 시간이 단축되고 어이없는 실수가 발생할 가능성이 줄어듭니다.

참고: 라이브러리 프로젝트를 만들고 포함하는 방법의 구현 세부정보는 이 학습 과정의 범위를 벗어나지만 Android 라이브러리 만들기를 참조하여 자세히 알아볼 수 있습니다.

다중 APK 지원을 사용하려고 기존 애플리케이션을 변환한다면 모든 현지화된 문자열 파일과 값 목록, 테마 색상, 메뉴 아이콘, APK 간에 변경되지 않는 레이아웃의 코드베이스를 검색하여 모두 라이브러리 프로젝트에 배치합니다. 많이 변경되지 않는 코드도 라이브러리 프로젝트에 들어가야 합니다. 이러한 클래스를 확장하여 APK에서 APK로 한두 개의 메서드를 추가할 수도 있습니다.

반면 처음부터 애플리케이션을 만든다면 먼저 라이브러리 프로젝트에 가능한 많은 코드를 작성하고 필요한 경우에만 개별 APK로 내려보냅니다. 이 방법은 코드를 하나하나 추가하고 몇 달이 지나면 이 blob이 아무것도 망치지 않고 라이브러리 섹션으로 올라갈 수 있는지 파악하는 것보다 장기적으로 관리하기 훨씬 쉽습니다.

새로운 APK 프로젝트 만들기

출시할 각 APK에는 별도의 Android 프로젝트가 있어야 합니다. 쉽게 구성하려면 라이브러리 프로젝트와 모든 관련된 APK 프로젝트를 동일한 상위 폴더에 배치합니다. 또한 각 APK에는 동일한 패키지 이름이 있어야 하지만 반드시 패키지 이름을 라이브러리와 공유할 필요는 없습니다. 앞에서 설명한 구성표에 따라 APK가 3개 있다면 루트 디렉터리는 다음과 같습니다.

    alexlucas:~/code/multi-apks-root$ ls
    foo-blue
    foo-green
    foo-lib
    foo-red
    

프로젝트가 만들어지면 라이브러리 프로젝트를 각 APK 프로젝트의 참조로 추가하세요. 가능하다면 라이브러리 프로젝트에서 시작 활동을 정의하고 APK 프로젝트에서 그 활동을 확장하세요. 라이브러리 프로젝트에서 시작 활동을 정의하면 모든 애플리케이션 초기화를 한곳에 배치할 수 있으므로 개별 APK에서 애널리틱스 초기화, 라이선스 확인 실행, APK 간에 많이 변경되지 않는 기타 초기화 절차와 같은 '범용' 작업을 다시 구현할 필요가 없습니다.

manifest 조정

사용자가 Google Play에서 다중 APK를 사용하는 애플리케이션을 다운로드하면 다음과 같이 간단한 두 규칙에 따라 사용할 올바른 APK가 선택됩니다.

  • manifest는 특정 APK가 적합하다고 표시해야 합니다.
  • 적합한 APK 중에 가장 높은 버전 번호가 우선됩니다.

앞서 설명한 다중 APK 세트를 예로 들어 아직 APK의 최대 API 레벨을 설정하지 않았다고 가정해보겠습니다. 개별적으로 보면 각 APK의 가능한 범위는 다음과 같습니다.

3 4 5 6 7 8 9 10 11 12 13 +
3 4 5 6 7 8 9 10 11 12 13 +
3 4 5 6 7 8 9 10 11 12 13 +

더 높은 minSdkVersion이 있는 APK에는 더 높은 버전 코드도 있어야 하기 때문에 versionCode 값 측면에서 빨간색 ≥ 녹색 ≥ 파란색입니다. 따라서 다음과 같이 차트를 효과적으로 축소할 수 있습니다.

3 4 5 6 7 8 9 10 11 12 13 +

이제 빨간색 APK에는 다른 두 개에는 없는 요구사항이 있다고 가정해보겠습니다. Android 개발자 가이드의 Google Play 필터 페이지에는 가능한 전체 원인 목록이 있습니다. 예를 들어 빨간색에는 전면 카메라가 필요하다고 가정해보겠습니다. 사실 빨간색 APK의 전체 요점은 전면 카메라와 API 11에 추가된 새로운 멋진 기능을 결합하는 것입니다. 그러나 API 11을 지원하는 모든 기기에 전면 카메라가 있는 것은 아닙니다. 정말 놀라운 일이죠.

다행히 사용자가 그런 기기에서 Google Play를 탐색하면 Google Play는 manifest를 살펴보고 빨간색에서 요구사항으로 전면 카메라를 나열한 것을 확인한 후 조용히 무시합니다. 빨간색과 기기가 디지털 세상에서 천생연분이 아니라고 확인했기 때문입니다. 그런 다음 녹색이 API 11이 있는 기기의 향후 버전과 호환(maxSdkVersion이 정의되지 않았기 때문에)될 뿐 아니라 전면 카메라가 있든 없든 상관하지 않는다는 것을 확인합니다. 사용자는 계속 Google Play에서 앱을 다운로드할 수 있습니다. 전면 카메라 문제에도 불구하고 이러한 특정 API 레벨을 지원한 APK가 여전히 있었기 때문입니다.

별도의 '트랙'에 모든 APK를 보관하려면 올바른 버전 코드 체계를 갖추는 것이 중요합니다. 개발자 가이드의 버전 코드 영역에서 권장사항을 확인할 수 있습니다. 예로 든 APK 세트에서는 가능한 세 가지 측정기준 중 하나만 다루기 때문에 각 APK를 1000으로 구분하고 첫 두 자릿수를 이러한 특정 APK의 minSdkVersion으로 설정한 다음 거기서부터 증분하는 것으로 충분합니다. 다음과 같습니다.

파란색: 03001, 03002, 03003, 03004...
녹색: 07001, 07002, 07003, 07004...
빨간색:11001, 11002, 11003, 11004...

모두 종합하면 Android Manifest는 다음과 같이 표시될 것입니다.

파란색:

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        android:versionCode="03001" android:versionName="1.0" package="com.example.foo">
        <uses-sdk android:minSdkVersion="3" />
        ...
    

녹색:

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        android:versionCode="07001" android:versionName="1.0" package="com.example.foo">
        <uses-sdk android:minSdkVersion="7" />
        ...
    

빨간색:

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        android:versionCode="11001" android:versionName="1.0" package="com.example.foo">
        <uses-sdk android:minSdkVersion="11" />
        ...
    

출시 전 체크리스트 검토

Google Play에 업로드하기 전에 다음 항목을 다시 확인하세요. 이러한 항목은 다중 APK와만 관련되어 있으며 Google Play에 업로드되는 모든 애플리케이션의 전체 체크리스트를 나타내는 것은 아닙니다.

  • 모든 APK의 패키지 이름은 동일해야 합니다.
  • 모든 APK는 동일한 인증서로 서명되어야 합니다.
  • APK가 플랫폼 버전에서 중복되는 경우 minSdkVersion이 더 높은 APK의 버전 코드가 더 높아야 합니다.
  • 충돌하는 정보가 있는지 manifest 필터를 다시 확인합니다. 특대형 화면의 Cupcake만 지원하는 APK는 누구에게도 표시되지 않습니다.
  • 각 APK의 manifest는 지원되는 화면이나 openGL 텍스처, 플랫폼 버전 중 하나 이상에서 고유해야 합니다.
  • 하나 이상의 기기에서 각 APK를 테스트해 봅니다. 번거로운 테스트만 제외하면 업계에서 가장 맞춤설정하기 편리한 기기 에뮬레이터 중 하나를 개발용 컴퓨터에서 사용하고 있는 것입니다. 맘껏 활용하세요.

또한, 출시하기 전에 컴파일된 APK를 검사하여 Google Play에서 애플리케이션을 숨길 수 있는 예상치 못한 문제가 없는지 확인하는 것이 좋습니다. 'aapt' 도구를 사용하면 간편하게 확인할 수 있습니다. Aapt(Android Asset Packaging Tool)는 Android 애플리케이션을 만들고 패키징하는 빌드 프로세스의 일부이며 Android 애플리케이션을 검사하는 데도 매우 유용한 도구입니다.

    >aapt dump badging
    package: name='com.example.hello' versionCode='1' versionName='1.0'
    sdkVersion:'11'
    uses-permission:'android.permission.SEND_SMS'
    application-label:'Hello'
    application-icon-120:'res/drawable-ldpi/icon.png'
    application-icon-160:'res/drawable-mdpi/icon.png'
    application-icon-240:'res/drawable-hdpi/icon.png'
    application: label='Hello' icon='res/drawable-mdpi/icon.png'
    launchable-activity: name='com.example.hello.HelloActivity'  label='Hello' icon=''
    uses-feature:'android.hardware.telephony'
    uses-feature:'android.hardware.touchscreen'
    main
    supports-screens: 'small' 'normal' 'large' 'xlarge'
    supports-any-density: 'true'
    locales: '--_--'
    densities: '120' '160' '240'
    

aapt 출력을 검사할 때 supports-screens 및 compatible-screens에 충돌하는 값이 없는지, manifest에서 설정한 권한으로 추가된 의도하지 않은 'uses-feature' 값은 없는지 확인하세요. 위 예에서 APK는 매우 많은 기기에 표시되지 않습니다.

이유가 뭘까요? 필수 권한 SEND_SMS를 추가하면서 android.hardware.telephony의 기능 요구사항이 암시적으로 추가되었기 때문입니다. API 11은 Honeycomb(특히 태블릿에 최적화된 Android 버전)이고 Honeycomb 기기에는 텔레포니 하드웨어가 없으므로 Google Play는 API 레벨이 더 높고 텔레포니 하드웨어를 보유한 기기가 나올 때까지 모든 경우에 이 APK를 필터링합니다.

다행히 manifest에 다음을 추가하여 이 문제를 쉽게 해결할 수 있습니다.

    <uses-feature android:name="android.hardware.telephony" android:required="false" />
    

android.hardware.touchscreen 요구사항도 암시적으로 추가됩니다. APK를 터치스크린이 아닌 TV에 표시하려면 manifest에 다음을 추가해야 합니다.

    <uses-feature android:name="android.hardware.touchscreen" android:required="false" />
    

출시 전 체크리스트를 완료했다면 Google Play에 APK를 업로드하세요. Google Play를 탐색할 때 애플리케이션이 표시되는 데 약간의 시간이 걸릴 수 있지만 표시되면 마지막으로 한 번 확인합니다. 보유한 테스트 기기에 애플리케이션을 다운로드하여 APK가 의도한 기기를 타겟팅하고 있는지 확인합니다. 축하합니다. 모든 단계를 마쳤습니다.