매니페스트 (Manifest) 를 영어사전에 검색하면 '명백한' 의미를 가진 형용사라고 나온다. 더 정확하게, 영어 사전의 의미에서는 동사로 사용될 땐 표시나 행동을 통해 무언가를 명확하게 보여주는 것을 의미한다.
사실 전문용어(terminology)로 분류되어 관계자 외엔 잘 안쓰인다고 한다.
안드로이드 스튜디오에서 사용되는 Manifest 는 특별한 설정이 없다면 무조건 생성되는 파일로, 의미 그대로 안드로이드 스튜디오에서 빌드
를 명확하게 보여주는 파일이다.
빌드를 왜 설명할까? VS code나 어떤 IDE를 사용하더라도 C언어나 Java script 코드를 작성한 후에 "어떻게 컴파일을 하세요, 어떻게 빌드를 하세요."와 같은 내용을 작성한 기억은 없는데 안드로이드 스튜디오는 빌드에 관한 설명이 필요한걸까?
그 이유는 안드로이드 스튜디오는 코드 작성과 빌드가 구분되어 있기 때문이다. 더 정확하게는 안드로이드 스튜디오는 코드 편집만 기능하는 IDE 일 뿐이고, 빌드는 gradle 파일에서 설정을 하고 AAR(Android ARchive) libraries 나 JAR(Java ARchive) libraries 등을 받아서 수행하기 때문이다. 더 자세한 설명은 여기로.
매니페스트 파일은 이렇게 분리되어 있는 코드와 빌드에 대한 연관 관계 및 코드 수행 시 알아야할 필수 정보들을 모아놓은 파일이다. 이 코드들을 빌드하기 위해선 이런 설정과 정보들을 알아야 한다고
라고 말하는 것이 Manifest 파일이니, 표시나 행동을 통해 무언가를 명확하게 보여주다.
라는 의미를 한 껏 살린 참으로 긱스들스러운 표현이다.
한 줄 요약하면 Manifest = 안드로이드 스튜디오 빌드 설정 파일
매니페스트는 AndroidManifest.xml
명칭으로 프로젝트 내부에 있어야 한다. 별도의 지정을 하지 않으면 src/main 으로 간다고 하지만, manifest 디렉토리에 있기도 한다. 매니페스트 파일은 Android 빌드 도구, Android 운영체제 및 Google Play 에 앱에 관한 필수 정보를 설명하게 된다.
매니페스트 파일은 다음 4개의 내용이 반드시 선언되어야 하는데,
앱의 패키지 이름, APK(Android aPplication Package) 이름에 대한 선언이 필요하다.
다음은 매니페스트 파일의 일부로, <manifest> 내부에 package = "com.example.flip"으로 된 부분이 APK의 선언에 해당한다.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.flip"> // APK 이름 선언
...
<activity
android:name=".MainActivity"
android:exported="true">
...
매니페스트 내에서 선언된 APK는 2개의 역할을 수행한다.
첫째로, 매니페스트에서 선언한 패키지 이름은 App Resource 에 접속하는데 사용되는 R 클래스의 네임 스페이스 (= 개체를 구분할 수 있는 범위, 변수명, 함수명 등을 의미) 로 적용된다.
TMI 1. R 클래스에는 R.Java 가 있는데, 리소스 접근을 위한 ID 들을 모아놓은 파일로 이처럼 R클래스는 리소스에 접속할 때 사용되는 클래스이다.
TMI 2. 위의 manifest 코드대로라면 com.example.flip.R 로 생성된다.
둘째로, 매니페스트에서 선언한 패키지 이름은 파일 내에서 선언된 다른 코드들의 상대경로가 된다. 위의 코드에서 MainActivity 의 최종 경로는 com.example.flip.MainActivity"가 된다.
앱의 구성 요소 (액티비티, 서비스, Broadcast Receiver, 콘텐츠 제공자를 포함) 들을 사용하고 싶다면 매니페스트 파일에서 선언해주어야 한다. 매니페스트 파일 내부에서 각각 다음과 같이 사용할 수 있다.
<activity> : Activity 이름 및 내용
<service> : Service 이름 및 내용
<receiver> : Broadcast Receiver 이름 및 내용
<provider> : Provider 이름 및 내용
위의 컴포넌트들은 인텐트에 의해서 활성화된다. 인텐트란 메세지 객체로, 어떤 행동을 수행할지에 대한 명령이나 작업에 필요한 데이터를 포함한다. 다음은 프로젝트 명을 flip으로 생성한 후 설정을 건드리지 않은 매니페스트의 코드이다.
...
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
...
<activity> 태그 내부에 <intent> 태그로 액션과 카테고리를 지정해주는 모습을 알 수 있다.
앱이 인텐트를 시스템에 발행하면 시스템은 각 앱의 매니페스트에 선언된 intent-filter 에 기초하여 처리할 수 있는 인텐트를 컴포넌트를 찾게 된다. 만약 여러 개의 앱이 인텐트를 다룰 수 있다면, 사용자가 해당 인텐트를 어떤 앱에게 넘길지 선택할 수 있게 된다.
그리고 매니페스트에 선언된 컴포넌트들과 <application> 은 유저에게 보여줄 수 있는 icon 과 label 속성을 갖고 있다. 그리고 xml 로 구성하다보면 트리 구조기 때문에 부모-자식 관계가 생기되는데, 이때 자식 element에 icon 과 label 이 설정되어있지 않다면 부모에 설정된 값이 기본 값으로 설정되게 된다. 그렇기 때문에 각 컴포넌트마다 설정하지 않고 앱 전체에 기본 값을 설정하려면 <application> 에 설정하면 된다.
앱이 시스템 또는 다른 앱의 보호된 부분에 액세스하기 위해 필요한 권한. 이때 다른 앱이 이 앱의 콘텐츠에 액세스하고자 하는 경우 반드시 있어야 하는 모든 권한 역시 매니페스트에서 선언되어야 한다.
구체적으로는 연락처, SMS, 카메라, 위치정보 등 민감한 사용자 데이터에 액세스 여부 권한을 의미한다. Android 6.0부터는 사용자가 런타임에서 일부 앱 권한을 승인하거나 거절할 수 있게 된다. 사용자의 허가 여부와 상관 없이, 매니페스트에는 앱이 액세스하고자 하는 데이터에 권한을 모두 선언하여야 하며, 선언되어 있지 않다면 액세스 하려는 시도 자체가 실패하게 된다.
매니페스트 파일에서 앱에 필요한 하드웨어 또는 소프트웨어 기능을 선언할 수 있다. 또한 앱과 호환되는 기기 유형도 선언이 가능하다. Google Play Store 에서는 앱에 기기 호환성에서 선언한 내용이 충족되지 않는 기기에는 앱 설치를 허용하지 않게 된다. 예시로 AR 기능을 사용하는 앱을 개발하였고, 매니페스트에서 AR 기능을 지원하는 기기가 필요하다고 선언한다면 AR기능이 없는 기기는 Google Play Store 에서 다운로드 받을 수 없게 된다.
기기 호환성에는 Android 버전인 SDK 역시 선언할 수 있으나 안드로이드 스튜디오로 코드를 작성하고 있다면 build.gradle 파일의 minSdkVersion
속성으로 재정의되므로 안드로이드 최소 버전 설정에 대해서는 매니페스트 파일이 아닌 build.gradle 에 선언하는 것이 좋다.
출처