ABI 관련 APK 빌드Building ABI-Specific APKs

이 문서에서는 Xamarin.Android를 사용하여 단일 ABI를 대상으로 하는 APK를 빌드하는 방법을 설명합니다.This document will discuss how to build an APK that will target a single ABI using Xamarin.Android.

개요Overview

애플리케이션에 여러 APK를 포함하는 것이 유리한 경우가 있습니다. 각 APK는 동일한 키 스토리지를 사용하여 서명되고 동일한 패키지 이름을 공유하지만 특정 디바이스나 Android 구성을 위해 컴파일됩니다.In some situations it may be advantageous for an application to have multiple APKs - each APK is signed with the same keystore and shares the same package name but it is compiled for a specific device or Android configuration. 이는 권장되는 방법이 아닙니다. 여러 디바이스와 구성을 지원할 수 있는 APK 하나를 포함하는 것이 훨씬 더 간단합니다.This is not the recommended approach - it is much simpler to have one APK that can support multiple devices and configurations. 다음과 같이 여러 APK를 만드는 것이 유용한 경우도 있습니다.There are some situations where creating multiple APKs can be useful, such as:

  • APK 크기 축소 - Google Play는 APK 파일에 100MB 크기 제한을 적용합니다.Reduce the size of the APK - Google Play imposes a 100MB size limit on APK files. 디바이스별 APK를 만들면 애플리케이션의 자산 및 리소스를 일부만 제공하면 되므로 APK의 크기를 줄일 수 있습니다.Creating device specific APK's can reduce the size of the APK as you only need to supply a subset of assets and resources for the application.

  • 여러 CPU 아키텍처 지원 - 애플리케이션에 특정 CPU에 대한 공유 라이브러리가 있을 경우 해당 CPU에 대한 공유 라이브러리만 배포할 수 있습니다.Support different CPU architectures - If your application has shared libraries for specific CPU's, you can distribute only the shared libraries for that CPU.

여러 APK가 있으면 배포가 복잡해질 수 있음 - Google Play에서 해결한 문제입니다.Multiple APKs can complicate distribution - a problem that is addressed by Google Play. Google Play는 AndroidManifest.XML에 포함된 애플리케이션의 버전 코드 및 기타 메타데이터에 따라 디바이스에 올바른 APK가 제공되도록 합니다.Google Play will ensure that the correct APK is delivered to a device based on the application's version code and other metadata contained with AndroidManifest.XML. Google Play에서 애플리케이션에 여러 APK를 지원하는 방식에 대한 자세한 내용과 제한 사항은 여러 APK 지원에 대한 Google 설명서를 참조하세요.For specific details and restrictions on how Google Play supports multiple APKs for an application, consult Google's documentation on multiple APK support.

이 가이드에서는 Xamarin.Android 애플리케이션을 위해 각 APK가 특정 ABI를 대상으로 하는 여러 APK 빌드를 스크립팅하는 방법을 설명합니다.This guide will address how to script the building multiple APKs for a Xamarin.Android application, each APK targeting a specific ABI. 다음 토픽을 살펴봅니다.It will cover the following topics:

  1. APK의 고유한 버전 코드를 만듭니다.Create a unique version code for the APK.
  2. 이 APK에 사용할 임시 버전의 AndroidManifest.XML을 만듭니다.Create a temporary version of AndroidManifest.XML that will be used for this APK.
  3. 이전 단계의 AndroidManifest.XML을 사용하여 애플리케이션을 빌드합니다.Build the application using the AndroidManifest.XML from the previous step.
  4. APK에 서명하고 zipalign하여 릴리스를 준비합니다.Prepare the APK for release by signing and zip-aligning it.

이 가이드의 뒷부분에 Rake를 사용하여 이러한 단계를 스크립팅하는 방법을 보여주는 연습이 있습니다.At the end of this guide is a walkthrough that will demonstrate how to script these steps using Rake.

APK의 버전 코드 만들기Creating the Version Code for the APK

Google에서는 7자리 버전 코드를 사용하는 버전 코드에 특정 알고리즘을 권장합니다(여러 APK 지원 문서에서 버전 코드 구성표 사용 섹션 참조).Google recommends a particular algorithm for the version code that uses a seven digit version code (please see the section Using a version code scheme in the Multiple APK support document). 이 버전 코드 구성표를 8자리로 확장하면 일부 ABI 정보를 버전 코드에 포함하여 Google Play에서 디바이스에 올바른 APK를 배포하도록 할 수 있습니다.By expanding this version code scheme to eight digits, it is possible to include some ABI information into the version code that will ensure that Google Play will distribute the correct APK to a device. 다음 목록에서는 이 8자리 버전 코드 형식을 설명합니다(왼쪽에서 오른쪽으로 인덱싱됨).The following list explains this eight digit version code format (indexed from left to right):

  • 인덱스 0(아래 다이어그램에서 빨간색) – ABI의 정수:Index 0 (red in diagram below) – An integer for the ABI:

    • 1 – armeabi1 – armeabi
    • 2 – armeabi-v7a2 – armeabi-v7a
    • 6 – x866 – x86
  • 인덱스 1-2(아래 다이어그램에서 주황색) – 애플리케이션에서 지원하는 최소 API 수준입니다.Index 1-2 (orange in diagram below) – The minimum API level supported by the application.

  • 인덱스 3-4(아래 다이어그램에서 파란색) – 지원되는 화면 크기:Index 3-4 (blue in diagram below) – The screen sizes supported:

    • 1 – 소형1 – small
    • 2 – 표준2 – normal
    • 3 – 대형3 – large
    • 4 – 초대형4 – xlarge
  • 인덱스 5-7(아래 다이어그램에서 녹색) – 버전 코드의 고유 번호입니다.Index 5-7 (green in diagram below) – A unique number for the version code. 이 항목은 개발자가 설정합니다.This is set by the developer. 애플리케이션의 각 공용 릴리스마다 증가해야 합니다.It should increase for each public release of the application.

다음 다이어그램에서는 위 목록에 설명된 각 코드의 위치를 보여줍니다.The following diagram illustrates the position of each code described in the above list:

다이어그램의 8자리 버전 코드 형식의 다이어그램(색상으로 구분)Diagram of eight-digit version code format, coded by color

Google Play에서는 versionCode 및 APK 구성에 따라 디바이스에 올바른 APK가 제공되도록 합니다.Google Play will ensure that the correct APK is delivered to the device based on the versionCode and APK configuration. 가장 높은 버전 코드를 가진 APK가 디바이스에 제공됩니다.The APK with the highest version code will be delivered to the device. 예를 들어 애플리케이션에 다음 버전 코드를 갖는 세 APK가 있을 수 있습니다.As an example, an application could have three APKs with the following version codes:

  • 11413456 - ABI가 armeabi이고, API 수준 14, 소형~대형 화면을 대상으로 하며, 버전 번호는 456입니다.11413456 - The ABI is armeabi ; targetting API level 14; small to large screens; with a version number of 456.
  • 21423456 - ABI가 armeabi-v7a이고, API 수준 14, 표준 및 대형 화면을 대상으로 하며, 버전 번호는 456입니다.21423456 - The ABI is armeabi-v7a ; targetting API level 14; normal & large screens; with a version number of 456.
  • 61423456 - ABI가 x86이고, API 수준 14, 표준 및 대형 화면을 대상으로 하며, 버전 번호는 456입니다.61423456 - The ABI is x86 ; targetting API level 14; normal & large screens; with a version number of 456.

이 예제로 계속 진행하려면 armeabi-v7a와 관련된 버그가 해결되었다고 간주하세요.To continue on with this example, imagine that a bug was fixed which was specific to armeabi-v7a. 앱 버전이 457로 증가하고, android:versionCode를 21423457로 설정하여 새 APK가 빌드됩니다.The app version increases to 457, and an new APK is built with the android:versionCode set to 21423457. armeabix86 버전의 versionCodes는 동일하게 유지됩니다.The versionCodes for the armeabi and x86 versions would remain the same.

x86 버전이 최신 API(API 수준 19)를 대상으로 하는 업데이트나 버그 수정을 받아서 앱의 버전이 500이 된다고 가정해 보겠습니다.Now imagine that the x86 version receives some updates or bug fixes that target a newer API (API level 19), making this version 500 of the app. versionCode는 61923500으로 변경되고, armeabi/armeabi-v7a는 그대로 유지됩니다.The new versionCode would change to 61923500 while the armeabi/armeabi-v7a remain unchanged. 이때 버전 코드는 다음과 같습니다.At this point in time, the version codes would be:

  • 11413456 - ABI가 armeabi이고, API 수준 14, 소형~대형 화면을 대상으로 하며, 버전 이름은 456입니다.11413456 - The ABI is armeabi ; targetting API level 14; small to large screens; with a version name of 456.
  • 21423457 - ABI가 armeabi-v7a이고, API 수준 14, 소형~대형 화면을 대상으로 하며, 버전 이름은 457입니다.21423457 - The ABI is armeabi-v7a ; targetting API level 14; normal & large screens; with a version name of 457.
  • 61923500 - ABI가 x86이고, API 수준 19, 소형~대형 화면을 대상으로 하며, 버전 이름은 500입니다.61923500 - The ABI is x86 ; targetting API level 19; normal & large screens; with a version name of 500.

이러한 버전 코드를 수동으로 유지 관리하는 것은 개발자에게 큰 부담이 될 수 있습니다.Maintaining these version codes manually can be a significant burden on the developer. 정확한 android:versionCode를 계산한 후 APK를 빌드하는 프로세스는 자동화되어야 합니다.The process of calculating the correct android:versionCode and then building the APK's should be automated. 이를 수행하는 방법에 대한 예는 이 문서의 뒷부분에 나오는 연습에서 설명합니다.An example of how to do so will be covered in the walkthrough at the end of this document.

임시 AndroidManifest.XML 만들기Create A Temporary AndroidManifest.XML

꼭 필요하지는 않지만 각 ABI에 대한 임시 AndroidManifest.XML을 만들면 한 APK에서 다른 APK로 정보가 유출되면서 발생하는 문제를 방지할 수 있습니다.Although not strictly necessary, creating an temporary AndroidManifest.XML for each ABI can help prevent issues that might arise with information leaking from one APK to the other. 예를 들어 android:versionCode 특성은 각 APK에 대해 고유해야 합니다.For example, it is crucial that the android:versionCode attribute is unique for each APK.

이를 수행하는 방법은 관련 스크립팅 시스템에 따라 다르지만 일반적으로 개발 중에 사용한 Android 매니페스트의 사본을 만들고, 수정한 후, 빌드 프로세스 중에 그 수정된 매니페스트를 사용하는 것입니다.How this is done depends on the scripting system involved, but typically involves taking a copy of the Android manifest used during development, modifying it, and then using that modify manifest during the build process.

APK 컴파일Compiling the APK

ABI별 APK를 빌드할 때는 다음 샘플 명령줄에 나와 있는 것처럼 xbuild 또는 msbuild를 사용하는 것이 가장 좋습니다.Building the APK per ABI is best accomplished by using either xbuild or msbuild as shown in the following sample command line:

/Library/Frameworks/Mono.framework/Commands/xbuild /t:Package /p:AndroidSupportedAbis=<TARGET_ABI> /p:IntermediateOutputPath=obj.<TARGET_ABI>/ /p:AndroidManifest=<PATH_TO_ANDROIDMANIFEST.XML> /p:OutputPath=bin.<TARGET_ABI> /p:Configuration=Release <CSPROJ FILE>

다음 목록에서는 각 명령줄 매개 변수를 설명합니다.The following list explains each command line parameter:

  • /t:Package – 디버그 키 저장소를 사용하여 서명된 Android APK를 만듭니다./t:Package – Creates an Android APK that is signed using the debug keystore

  • /p:AndroidSupportedAbis=<TARGET_ABI> – 대상으로 할 ABI입니다./p:AndroidSupportedAbis=<TARGET_ABI> – This the ABI to target. armeabi, armeabi-v7a 또는 x86 중 하나여야 합니다.Must one of armeabi, armeabi-v7a, or x86

  • /p:IntermediateOutputPath=obj.<TARGET_ABI>/ – 이는 빌드의 일부로 생성된 중간 파일을 저장하는 디렉터리입니다./p:IntermediateOutputPath=obj.<TARGET_ABI>/ – This is the directory that will hold the intermediate files that are created as a part of the build. Xamarin.Android는 필요할 경우 ABI의 이름을 딴 디렉터리를 만듭니다(예: obj.armeabi-v7a).If necessary, Xamarin.Android will create a directory named after the ABI, such as obj.armeabi-v7a. 한 빌드에서 다른 빌드로 파일이 "유출"되는 결과를 가져오는 문제를 방지할 수 있으므로 각 ABI당 하나의 폴더를 사용하는 것이 좋습니다.It is recommended to use one folder for each ABI as this will prevent issues that make result with files "leaking" from one build to another. 이 값은 디렉터리 구분 기호(OS X의 경우 /)를 사용하여 종결됩니다.Notice that this value is terminated with a directory separator (a / in the case of OS X).

  • /p:AndroidManifest – 이 속성은 빌드 중에 사용되는 AndroidManifest.XML 파일에 대한 경로를 지정합니다./p:AndroidManifest – This property specifies the path to the AndroidManifest.XML file that will be used during the build.

  • /p:OutputPath=bin.<TARGET_ABI> – 이는 최종 APK가 저장될 디렉터리입니다./p:OutputPath=bin.<TARGET_ABI> – This is the directory that will house the final APK. Xamarin.Android는 ABI의 이름을 딴 디렉터리를 만듭니다(예: bin.armeabi-v7a).Xamarin.Android will create a directory named after the ABI, for example bin.armeabi-v7a.

  • /p:Configuration=Release – APK의 릴리스 빌드를 수행합니다./p:Configuration=Release – Perform a Release build of the APK. 디버그 빌드는 Google Play에 업로드하지 못할 수 있습니다.Debug builds may not be uploaded to Google Play.

  • <CS_PROJ FILE> – 이는 Xamarin.Android 프로젝트의 .csproj 파일에 대한 경로입니다.<CS_PROJ FILE> – This is the path to the .csproj file for the Xamarin.Android project.

APK 서명 및 ZipalignSign and Zipalign The APK

APK에 서명해야 Google Play를 통해 배포할 수 있습니다.It is necessary to sign the APK before it can be distributed via Google Play. 이는 Java 개발자 키트에 포함된 jarsigner 애플리케이션을 사용하여 수행할 수 있습니다.This can be performed by using the jarsigner application that is a part of the Java Developer's Kit. 다음 명령은 명령줄에서 jarsigner를 사용하는 방법을 보여줍니다.The following command line demonstrats how to use jarsigner at the command line:

jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore <PATH/TO/KEYSTORE> -storepass <PASSWORD> -signedjar <PATH/FOR/SIGNED_JAR> <PATH/FOR/JAR/TO/SIGN> <NAME_OF_KEY_IN_KEYSTORE>

모든 Xamarin.Android 애플리케이션은 zipalign되어야 디바이스에서 실행될 수 있습니다.All Xamarin.Android applications must be zip-aligned before they can be run on a device. 사용할 명령줄의 형식은 다음과 같습니다.This is the format of the command line to use:

zipalign -f -v 4 <SIGNED_APK_TO_ZIPALIGN> <PATH/TO/ZIP_ALIGNED.APK>

Rake를 사용한 APK 만들기 자동화Automating APK Creation With Rake

샘플 프로젝트 OneABIPerAPK는 ABI별 버전 번호를 계산하고 다음과 같은 각 ABI별로 별도의 APK 3개를 빌드하는 방법을 보여 주는 간단한 Android 프로젝트입니다.The sample project OneABIPerAPK is a simple Android project that will demonstrate how to calculate an ABI specific version number and build three separate APK's for each of the following ABI's:

  • armeabiarmeabi
  • armeabi-v7aarmeabi-v7a
  • x86x86

샘플 프로젝트의 rakefile은 이전 섹션에 설명된 각 단계를 수행합니다.The rakefile in the sample project performs each of the steps that were described in the previous sections:

  1. APK에 대한 android:versionCode를 만듭니다.Create an android:versionCode for the APK.

  2. 해당 APK의 사용자 지정 AndroidManifest.XMLandroid:versionCode를 작성합니다.Write the android:versionCode to a custom AndroidManifest.XML for that APK.

  3. 이전 단계에서 생성된 AndroidManifest.XML을 사용하여 ABI를 개별 대상으로 하는 Xamarin.Android 프로젝트의 릴리스 빌드를 컴파일합니다.Compile a release build of the Xamarin.Android project that will singularly target the ABI and using the AndroidManifest.XML that was created in the previous step.

  4. 프로덕션 키 저장소를 사용하여 APK에 서명합니다.Sign the APK with a production keystore.

  5. APK zipalign을 수행합니다.Zipalign the APK.

애플리케이션의 모든 APK를 빌드하려면 명령줄에서 build Rake 작업을 실행합니다.To build all of the APKs for the application, run the build Rake task from the command line:

$ rake build
==> Building an APK for ABI armeabi with ./Properties/AndroidManifest.xml.armeabi, android:versionCode = 10814120.
==> Building an APK for ABI x86 with ./Properties/AndroidManifest.xml.x86, android:versionCode = 60814120.
==> Building an APK for ABI armeabi-v7a with ./Properties/AndroidManifest.xml.armeabi-v7a, android:versionCode = 20814120.

Rake 작업이 완료되면 xamarin.helloworld.apk 파일이 있는 bin 폴더 3개가 있을 것입니다.Once the rake task has completed, there will be three bin folders with the file xamarin.helloworld.apk. 다음 스크린샷은 이러한 각각의 폴더와 그 내용을 보여줍니다.The next screenshot shows each of these folders with their contents:

xamarin.helloworld.apk를 포함하는 플랫폼별 폴더의 위치Locations of platform-specific folders containing xamarin.helloworld.apk

참고

이 가이드에 설명된 빌드 프로세스는 여러 다른 빌드 시스템 중 하나에서 구현될 수 있습니다.The build process outlined in this guide may be implemented in one of many different build systems. 미리 작성된 예제는 없지만 Powershell / psake 또는 Fake를 사용하면 가능합니다.Although we don't have a pre-written example, it should also be possible with Powershell / psake or Fake.

요약Summary

이 가이드에서는 특정 ABI를 대상으로 하는 Android APK를 만드는 방법과 관련된 몇 가지 제안 사항을 제공했습니다.This guide provided some suggestions with how to create Android APK's that target a specify ABI. 또한 APK가 대상으로 하는 CPU 아키텍처를 식별하는 android:versionCodes를 만들기 위한 하나의 구성표도 설명했습니다.It also discussed one possible scheme for creating android:versionCodes that will identify the CPU architecture that the APK is intended for. 연습에서는 Rake를 사용하여 빌드를 스크립팅한 샘플 프로젝트를 제공했습니다.The walkthrough included a sample project that has it's build scripted using Rake.