애플리케이션을 코딩하고 테스트한 후에는 배포를 위해 패키지를 준비해야 합니다. 이 패키지를 준비하는 첫 번째 작업은 릴리스용 애플리케이션을 빌드하는 것이며, 주로 일부 애플리케이션 특성을 설정해야 합니다.
다음 단계를 사용하여 릴리스용 앱을 빌드합니다.
애플리케이션 아이콘 지정 – 각 Xamarin.Android 애플리케이션에 애플리케이션 아이콘이 지정되어 있어야 합니다. 기술적으로 필요하지는 않지만 Google Play와 같은 일부 시장은 이를 요구합니다.
애플리케이션 버전 - 이 단계에서는 버전 관리 정보를 초기화하거나 업데이트합니다. 이는 향후 애플리케이션 업데이트 및 사용자가 설치한 애플리케이션의 버전을 인식하도록 하는 데 중요합니다.
APK 축소 – 관리 코드의 Xamarin.Android 링커와 Java 바이트 코드의 ProGuard를 사용하여 최종 APK의 크기를 크게 줄일 수 있습니다.
애플리케이션 보호 – 사용자 또는 공격자가 디버깅을 사용하지 않도록 설정하거나, 관리 코드를 난독 처리하고, 디버그 방지 및 변조 방지를 추가하고, 네이티브 컴파일을 사용하여 애플리케이션을 디버깅, 변조 또는 리버스 엔지니어링하지 못하도록 방지합니다.
패키징 속성 설정 – 패키징 속성은 APK(Android 애플리케이션 패키지) 생성을 제어합니다. 이 단계에서는 APK를 최적화하고, 자산을 보호하며, 필요에 따라 패키징을 모듈화합니다. 또한 디바이스에 최적화된 Android 앱 번들을 사용자에게 제공할 수 있습니다.
컴파일 – 이 단계에서는 코드와 자산을 컴파일하여 릴리스 모드에서 빌드되는지 확인합니다.
게시용 보관 – 이 단계에서는 앱을 빌드하고 서명 및 게시를 위해 보관에 배치합니다.
이러한 각 단계는 아래에 자세히 설명되어 있습니다.
애플리케이션 아이콘 지정
각 Xamarin.Android 애플리케이션에서 애플리케이션 아이콘을 지정하는 것이 좋습니다. 일부 애플리케이션 마켓플레이스에서는 Android 애플리케이션을 하나 없이 게시할 수 없습니다.
Icon 특성의 Application 속성은 Xamarin.Android 프로젝트의 애플리케이션 아이콘을 지정하는 데 사용됩니다.
Visual Studio 2017 이상에서는 다음 스크린샷과 같이 프로젝트 속성의 Android 매니페스트 섹션을 통해 애플리케이션 아이콘을 지정합니다.
이 예제에서는 Resources/drawable/icon.png 있는 아이콘 파일을 참조합니다@drawable/icon(.png 확장명은 리소스 이름에 포함되지 않음). 이 특성은 이 샘플 코드 조각과 같이 Properties\AssemblyInfo.cs 파일에서도 선언할 수 있습니다.
[assembly: Application(Icon = "@drawable/icon")]
일반적으로 using Android.App 특성은 AssemblyInfo.cs의 맨 위에 선언됩니다. 그러나 아직 없는 경우, Application 특성의 네임스페이스는 Android.App이므로 이 using 문을 추가해야 할 수 있습니다.
애플리케이션 버전 지정
버전 관리는 Android 애플리케이션 유지 관리 및 배포에 중요합니다. 어떤 종류의 버전 관리가 없으면 애플리케이션을 업데이트해야 하는지 또는 어떻게 업데이트해야 하는지 결정하기가 어렵습니다. 버전 관리를 지원하기 위해 Android는 두 가지 유형의 정보를 인식합니다.
버전 번호 – 애플리케이션의 버전을 나타내는 정수 값(Android 및 애플리케이션에서 내부적으로 사용)입니다. 대부분의 애플리케이션은 이 값을 1로 설정한 다음 각 빌드에 따라 증가합니다. 이 값에는 버전 이름 특성과 관계나 선호도가 없습니다(아래 참조). 애플리케이션 및 게시 서비스는 사용자에게 이 값을 표시해서는 안 됩니다. 이 값은 AndroidManifest.xml 파일에 다음과 같이
android:versionCode저장됩니다.버전 이름 – 특정 디바이스에 설치된 애플리케이션 버전에 대한 정보를 사용자에게 전달하는 데만 사용되는 문자열입니다. 버전 이름은 사용자 또는 Google Play에 표시될 예정입니다. 이 문자열은 Android에서 내부적으로 사용되지 않습니다. 버전 이름은 사용자가 디바이스에 설치된 빌드를 식별하는 데 도움이 되는 문자열 값일 수 있습니다. 이 값은 AndroidManifest.xml 파일에 다음과 같이
android:versionName저장됩니다.
Visual Studio에서 이러한 값은 다음 스크린샷과 같이 프로젝트 속성의 Android 매니페스트 섹션에서 설정할 수 있습니다.
APK 크기 줄이기
Xamarin.Android APK는 불필요한 관리 코드를 제거하는 Xamarin.Android 링커와 사용하지 않는 Java 바이트 코드를 제거하는 Android SDK의 ProGuard 도구를 조합하여 더 작게 만들 수 있습니다. 빌드 프로세스는 먼저 Xamarin.Android 링커를 사용하여 관리 코드(C#) 수준에서 앱을 최적화한 다음 나중에 ProGuard(사용하도록 설정된 경우)를 사용하여 Java 바이트 코드 수준에서 APK를 최적화합니다.
링커 구성 설정
릴리스 모드는 공유 런타임을 비활성화하고 애플리케이션이 런타임에 필요한 Xamarin.Android 조각만 배송되도록 링크를 활성화합니다. Xamarin.Android의 링커는 정적 분석을 사용하여 Xamarin.Android 애플리케이션에서 사용하거나 참조하는 어셈블리, 형식 및 형식 멤버를 결정합니다. 그런 다음 링커는 사용되지 않거나 참조되지 않은 모든 사용하지 않는 어셈블리, 형식 및 멤버를 삭제합니다. 이로 인해 패키지 크기가 크게 감소할 수 있습니다. 예를 들어 APK의 최종 크기가 83% 감소하는 HelloWorld 샘플을 고려합니다.
구성: 없음 – Xamarin.Android 4.2.5 크기 = 17.4MB.
구성: SDK 어셈블리만 – Xamarin.Android 4.2.5 크기 = 3.0MB.
프로젝트 속성의 Android 옵션 섹션을 통해 링커 옵션을 설정합니다.
연결 풀다운 메뉴는 링커를 제어하기 위한 다음 옵션을 제공합니다.
없음 – 링커가 꺼집니다. 연결이 수행되지 않습니다.
SDK 어셈블리만 – Xamarin.Android에 필요한 어셈블리만 연결합니다. 다른 어셈블리는 연결되지 않습니다.
Sdk 및 사용자 어셈블리 – Xamarin.Android에 필요한 어셈블리뿐만 아니라 애플리케이션에 필요한 모든 어셈블리를 연결합니다.
연결하면 의도하지 않은 부작용이 발생할 수 있으므로 물리적 디바이스의 릴리스 모드에서 애플리케이션을 다시 테스트해야 합니다.
ProGuard
ProGuard 는 Java 코드를 연결하고 난독 분석하는 Android SDK 도구입니다. ProGuard는 일반적으로 APK에 포함된 큰 라이브러리(예: Google Play 서비스)의 공간을 줄여 더 작은 애플리케이션을 만드는 데 사용됩니다. ProGuard는 사용되지 않는 Java 바이트 코드를 제거하여 결과 앱을 더 작게 만듭니다. 예를 들어 작은 Xamarin.Android 앱에서 ProGuard를 사용하면 일반적으로 크기가 약 24% 감소합니다. 여러 라이브러리 종속성이 있는 더 큰 앱에서 ProGuard를 사용하면 일반적으로 크기가 훨씬 더 크게 감소합니다.
ProGuard는 Xamarin.Android 링커의 대안이 아닙니다. Xamarin.Android 링커는 관리 코드를 연결하고 ProGuard는 Java 바이트코드를 연결합니다. 빌드 프로세스는 먼저 Xamarin.Android 링커를 사용하여 앱에서 관리(C#) 코드를 최적화한 다음 나중에 ProGuard(사용하도록 설정된 경우)를 사용하여 Java 바이트 코드 수준에서 APK를 최적화합니다.
ProGuard 사용이 선택되면 Xamarin.Android는 결과 APK에서 ProGuard 도구를 실행합니다. ProGuard 구성 파일은 빌드 시 ProGuard에서 생성되고 사용됩니다. Xamarin.Android는 사용자 지정 ProguardConfiguration 빌드 작업도 지원합니다. 사용자 지정 ProGuard 구성 파일을 프로젝트에 추가하고 마우스 오른쪽 단추로 클릭한 다음 이 예제와 같이 빌드 작업으로 선택할 수 있습니다.
ProGuard는 기본적으로 사용하지 않도록 설정됩니다. ProGuard 사용 옵션은 프로젝트가 릴리스 모드로 설정된 경우에만 사용할 수 있습니다. ProGuard 사용이 확인되지 않는 한 모든 ProGuard 빌드 작업은 무시됩니다. Xamarin.Android ProGuard 구성은 APK를 난독 처리하지 않으며 사용자 지정 구성 파일에서도 난독화를 사용하도록 설정할 수 없습니다. 난독화를 사용하려면 Dotfuscator를 사용한 애플리케이션 보호를 참조하세요.
ProGuard 도구 사용에 대한 자세한 내용은 ProGuard를 참조하세요.
애플리케이션 보호
디버깅 사용 안 함
Android 애플리케이션을 개발하는 동안 JDWP( Java Debug Wire Protocol )를 사용하여 디버깅을 수행합니다. 이 기술은 디버깅을 위해 adb 와 같은 도구가 JVM과 통신할 수 있도록 하는 기술입니다. JDWP는 기본적으로 Xamarin.Android 애플리케이션의 디버그 빌드에 대해 설정됩니다. JDWP는 개발 중에 중요하지만 릴리스된 애플리케이션에 대한 보안 문제가 발생할 수 있습니다.
중요합니다
이 디버그 상태를 사용하지 않도록 설정하지 않은 경우 Java 프로세스에 대한 모든 액세스 권한을 얻고 애플리케이션 컨텍스트에서 임의 코드를 실행할 수 있으므로 릴리스된 애플리케이션에서 항상 디버그 상태를 사용하지 않도록 설정합니다(JDWP를 통해).
Android 매니페스트에는 애플리케이션을 android:debuggable 디버그할 수 있는지 여부를 제어하는 특성이 포함되어 있습니다.
android:debuggable 특성을 false로 설정하는 것이 좋은 관행으로 여겨집니다. 이 작업을 수행하는 가장 간단한 방법은 AssemblyInfo.cs 조건부 컴파일 문을 추가하는 것입니다.
#if DEBUG
[assembly: Application(Debuggable=true)]
#else
[assembly: Application(Debuggable=false)]
#endif
디버그 빌드는 자동으로 일부 권한을 설정하여 디버그를 더 쉽게 만듭니다(예: 인터넷 및 ReadExternalStorage). 그러나 릴리스 빌드는 명시적으로 구성하는 권한만 사용합니다. 릴리스 빌드로 전환하면 앱이 디버그 빌드에서 사용할 수 있는 사용 권한을 잃게 되는 경우 사용 권한에 설명된 대로 필수 사용 권한 목록에서 이 권한을 명시적으로 사용하도록 설정했는지 확인 합니다.
Dotfuscator를 사용하여 애플리케이션 보호
디버깅을 사용하지 않도록 설정하더라도 공격자가 애플리케이션을 다시 패키지하고 구성 옵션 또는 권한을 추가하거나 제거할 수 있습니다. 이를 통해 애플리케이션을 리버스 엔지니어링, 디버그 또는 변조할 수 있습니다. Dotfuscator CE(Community Edition) 를 사용하여 관리 코드를 난독 처리하고 빌드 시 Xamarin.Android 앱에 런타임 보안 상태 검색 코드를 삽입하여 앱이 루팅된 디바이스에서 실행 중인지 감지하고 응답할 수 있습니다.
Dotfuscator CE는 Visual Studio 2017에 포함되어 있습니다. Dotfuscator를 사용하려면 Tools > PreEmptive Protection - Dotfuscator를 클릭합니다.
Dotfuscator CE를 구성하려면 Xamarin과 함께 Dotfuscator Community Edition 사용을 참조하세요. 구성되면 Dotfuscator CE는 생성된 각 빌드를 자동으로 보호합니다.
어셈블리를 네이티브 코드로 번들하기
이 옵션을 사용하도록 설정하면 어셈블리가 네이티브 공유 라이브러리에 번들로 제공됩니다. 이렇게 하면 어셈블리를 압축하여 더 .apk 작은 파일을 허용할 수 있습니다. 어셈블리 압축은 최소 형태의 난독화도 제공합니다. 그러한 난독화에 의존해서는 안 됩니다.
이 옵션을 사용하려면 엔터프라이즈 라이선스가 필요하며 빠른 배포 사용 이 비활성화된 경우에만 사용할 수 있습니다. 어셈블리를 네이티브 코드로 번들하는 것은 기본적으로 비활성화되어 있습니다.
네이티브 코드로 번들 옵션이 어셈블리가 네이티브 코드로 컴파일된다는 의미는 아닙니다. AOT 컴파일을 사용하여 어셈블리를 네이티브 코드로 컴파일할 수 없습니다.
AOT 컴파일
AOT 컴파일 옵션(패키징 속성 페이지)을 사용하면 AOT(Ahead-of-Time) 어셈블리를 컴파일할 수 있습니다. 이 옵션을 사용하도록 설정하면 런타임 전에 어셈블리를 미리 컴파일하여 JIT(Just In Time) 시작 오버헤드가 최소화됩니다. 결과 네이티브 코드는 컴파일되지 않은 어셈블리와 함께 APK에 포함됩니다. 이로 인해 애플리케이션 시작 시간이 짧아지지만 약간 더 큰 APK 크기가 발생합니다.
AOT 컴파일 옵션에는 Enterprise 라이선스 이상이 필요합니다. AOT 컴파일 은 프로젝트가 릴리스 모드로 구성되고 기본적으로 사용하지 않도록 설정된 경우에만 사용할 수 있습니다. AOT 컴파일에 대한 자세한 내용은 AOT를 참조하세요.
LLVM 최적화 컴파일러
LLVM 최적화 컴파일러는 더 작고 빠르게 컴파일된 코드를 만들고 AOT 컴파일 어셈블리를 네이티브 코드로 변환하지만 빌드 시간이 느려집니다. LLVM 컴파일러는 기본적으로 사용하지 않도록 설정됩니다. LLVM 컴파일러를 사용하려면 먼저 패키징 속성 페이지에서 AOT 컴파일 옵션을 사용하도록 설정해야 합니다.
비고
LLVM 최적화 컴파일러 옵션에는 엔터프라이즈 라이선스가 필요합니다.
패키징 속성 설정
다음 스크린샷과 같이 프로젝트 속성의 Android 옵션 섹션에서 패키징 속성을 설정할 수 있습니다.
공유 런타임 사용 및 빠른 배포 사용과 같은 대부분의 속성은 디버그 모드용입니다. 그러나 애플리케이션이 릴리스 모드로 구성된 경우 앱이 크기 및 실행 속도에 맞게 최적화되는 방법, 변조로부터 보호되는 방법 및 다양한 아키텍처 및 크기 제한을 지원하도록 패키지할 수 있는 방법을 결정하는 다른 설정이 있습니다.
지원되는 아키텍처 지정
릴리스를 위해 Xamarin.Android 앱을 준비할 때 지원되는 CPU 아키텍처를 지정해야 합니다. 단일 APK에는 여러 아키텍처를 지원하는 컴퓨터 코드가 포함될 수 있습니다. 여러 CPU 아키텍처를 지원하는 방법에 대한 자세한 내용은 CPU 아키텍처를 참조하세요.
선택한 ABI당 하나의 패키지(.APK) 생성
이 옵션을 사용하도록 설정하면 지원되는 모든 ABI에 대한 단일 대형 APK가 아닌 지원되는 각 ABI(CPU 아키텍처에 설명된 대로 고급 탭에서 선택됨)에 대해 하나의 APK가 만들어집니다. 이 옵션은 프로젝트가 릴리스 모드로 구성되고 기본적으로 사용하지 않도록 설정된 경우에만 사용할 수 있습니다.
다중 덱스 (Multi-Dex)
Multi-Dex 사용 옵션을 사용하도록 설정하면 Android SDK 도구를 사용하여 .dex 파일 형식의 65K 메서드 제한을 무시합니다. 65K 메서드 제한은 앱이 참조 하는 Java 메서드 수(앱이 의존하는 라이브러리의 메서드 포함)를 기반으로 하며 소스 코드에 작성된 메서드 수를 기반으로 하지 않습니다. 애플리케이션에서 몇 가지 메서드만 정의하지만 많은(또는 큰 라이브러리)를 사용하는 경우 65K 제한을 초과할 수 있습니다.
앱이 참조되는 모든 라이브러리의 모든 메서드를 사용하지 않을 수 있습니다. 따라서 ProGuard(위 참조)와 같은 도구가 코드에서 사용되지 않는 메서드를 제거할 수 있습니다. 가장 좋은 방법은 반드시 필요한 경우에만 Multi-Dex 를 사용하도록 설정하는 것입니다. 즉, 앱은 ProGuard를 사용한 후에도 여전히 65K 이상의 Java 메서드를 참조합니다.
다중 덱스에 대한 자세한 내용은 64K 이상의 메서드를 사용하여 앱 구성을 참조하세요.
Android 앱 번들
앱 번들은 디바이스에 직접 배포할 수 없으므로 APK와 다릅니다. 대신 컴파일된 모든 코드 및 리소스와 함께 업로드하기 위한 형식입니다. 서명된 앱 번들을 업로드한 후 Google Play는 애플리케이션의 APK를 빌드하고 서명하고 동적 배달을 사용하여 사용자에게 제공하는 데 필요한 모든 것을 갖습니다.
Android 앱 번들을 지원하려면 Android 프로젝트 옵션 내에서 Android 패키지 형식 속성의 값을 옵트인 bundle 해야 합니다. 이렇게 하기 전에 앱 번들이 릴리스 패키지 전용이므로 프로젝트를 Release 구성으로 변경해야 합니다.
이제 아카이브 플로우를 따라 앱 번들을 생성할 수 있습니다. 그러면 애플리케이션에 대한 앱 번들을 생성합니다.
Android 앱 번들에 대한 자세한 내용은 Android 앱 번들을 참조하세요.
컴파일하다
위의 모든 단계가 완료되면 앱이 컴파일할 준비가 됩니다. 빌드 > 솔루션 다시 빌드를 선택하여 릴리스 모드에서 성공적으로 빌드되는지 확인합니다. 이 단계에서는 아직 APK를 생성하지 않습니다.
앱 패키지에 서명하면 패키징 및 로그인에 대해 자세히 설명합니다.
출판용 아카이브
게시 프로세스를 시작하려면 솔루션 탐색기 에서 프로젝트를 마우스 오른쪽 단추로 클릭하고 보관... 상황에 맞는 메뉴 항목을 선택합니다.
보관... 는 보관 관리자 를 시작하고 이 스크린샷에 표시된 대로 앱 번들을 보관하는 프로세스를 시작합니다.
보관을 만드는 또 다른 방법은 솔루션 탐색기 에서 솔루션을 마우스 오른쪽 단추로 클릭하고 모두 보관을 선택하는 것입니다. 그러면 솔루션을 빌드하고 보관을 생성할 수 있는 모든 Xamarin 프로젝트를 보관합니다.
보관 및 보관 모두 모두 자동으로 보관 관리자를 시작합니다. 보관 관리자를 직접 시작하려면 도구 > 보관 관리자... 메뉴 항목을 클릭합니다.
언제든지 솔루션 노드를 마우스 오른쪽 버튼으로 클릭하고 보관 파일 보기를 선택하여 보관 파일을 확인할 수 있습니다.
보관 관리자
보관 관리자는솔루션 목록 창, 보관 목록 및 세부 정보 패널로 구성됩니다.
솔루션 목록에는 하나 이상의 보관된 프로젝트가 있는 모든 솔루션이 표시됩니다. 솔루션 목록에는 다음 섹션이 포함되어 있습니다.
- 현재 솔루션 – 현재 솔루션을 표시합니다. 현재 솔루션에 기존 보관 파일이 없는 경우 이 영역은 비어 있을 수 있습니다.
- 모든 아카이브 – 아카이브가 있는 모든 솔루션을 표시합니다.
- 위쪽의 검색 텍스트 상자 – 텍스트 상자에 입력한 검색 문자열에 따라 모든 보관 파일 목록에 나열된 솔루션을 필터링합니다.
보관 목록에는 선택한 솔루션에 대한 모든 보관 파일 목록이 표시됩니다. 보관 목록에는 다음 섹션이 포함되어 있습니다.
- 선택한 솔루션 이름 – 솔루션 목록에서 선택한 솔루션의 이름을 표시합니다. 보관 목록에 표시된 모든 정보는 이 선택한 솔루션을 참조합니다.
- 플랫폼 필터 – 이 필드를 사용하면 플랫폼 유형(예: iOS 또는 Android)을 기준으로 보관 파일을 필터링할 수 있습니다.
- 보관 항목 – 선택한 솔루션에 대한 보관 목록입니다. 이 목록의 각 항목에는 프로젝트 이름, 생성 날짜 및 플랫폼이 포함됩니다. 항목을 보관하거나 게시할 때 진행률과 같은 추가 정보를 표시할 수도 있습니다.
세부 정보 패널에는 각 보관 파일에 대한 추가 정보가 표시됩니다. 또한 사용자가 배포 워크플로를 시작하거나 배포가 만들어진 폴더를 열 수 있습니다. 빌드 주석 섹션을 사용하면 보관 파일에 빌드 주석을 포함할 수 있습니다.
분포
애플리케이션의 보관된 버전을 게시할 준비가 되면 보관 관리자 에서 보관 파일을 선택하고 배포... 단추를 클릭합니다.
배포 채널 대화 상자에는 앱에 대한 정보, 배포 워크플로 진행률 표시 및 선택한 배포 채널이 표시됩니다. 첫 번째 실행에서는 두 가지 선택 항목이 표시됩니다.
다음 배포 채널 중 하나를 선택할 수 있습니다.
임시 – Android 디바이스에 테스트용으로 로드할 수 있는 서명된 APK를 디스크에 저장합니다. 앱 패키지에 계속 서명하여 Android 서명 ID를 만들고, Android 애플리케이션에 대한 새 서명 인증서를 만들고, 임시 버전의 앱을 디스크에 게시하는 방법을 알아봅니다. 테스트를 위한 APK를 만드는 좋은 방법입니다.
Google Play – 서명된 APK를 Google Play에 게시합니다. Publishing to Google Play 계속해서 Google Play 스토어에서 APK에 서명하고 게시하는 방법을 알아보세요.