[Android] Manifest란?

이승우·2023년 5월 26일
0

최근에 Android Manifest의 역할에 대한 질문을 받았는데, 이에 대한 명확한 답을 하지 못해서 공부하고자 정리하려고 한다.

컴포넌트는 애플리케이션을 이루고 있는 구성요소이다. 이러한 컴포넌트들을 매니페스트 파일에 적어줌으로써 안드로이드 시스템이 어떤 컴포넌트를 사용하고 있는지 알도록 해야 애플리케이션이 실행된다.

즉, 어떤 컴포넌트 요소를 어떤 클래스를 이용하여 생성하였는지 알려주어야 안드로이드에서 객체들을 만들고 실행시켜줄 수 있다.

Manifest에 대한 사전적인 의미를 확인해보자. "표시나 행동을 통해 무언가를 명확하게 보여주는 것을 의미한다."고 한다.

안드로이드 스튜디오에서 사용되는 Manifest는 특별한 설정이 없다면 무조건 생성되는 파일로 빌드를 명확하게 보여주는 파일이다.

그렇다면 빌드를 왜 설명해야할까? 그 이유는 아래와 같다.

안드로이드 스튜디오는 코드 작성과 빌드가 구분되어 있기 때문이다. 정확히 안드로이드 스튜디오는 코드 편집 기능을 하는 IDE일 뿐이고, 빌드는 gradle 파일에서 설정하고 AAR(Android ARchive) library나 JAR(Java ARchive) libraries 등을 받아서 수행하기 때문이다.

매니페스트 파일은 이렇게 분리되어 있는 코드와 빌드에 대한 연관 관계 및 코드 수행시 알아야 할 필수적인 정보들을 모아놓은 파일이다. 이 코드들을 빌드하기 위해서는 이런 설정과 정보들을 알아야 한다고 말하는 것이 Manifest 파일이며 위에서 말한 "표시나 행동을 위해 무언가를 명확하게 보여준다"와 일맥상통한다고 볼 수 있다.

📌 Manifest 구성

AndroidManifest.xml 로 프로젝트 내부에 위치하며, 별도의 지정을 하지 않으면 src/main에 위치하게 된다. 매니페스트 파일은 Android 빌드 도구, Android 운영체제 및 Google Play에 앱에 관한 필수 정보를 설명하게 된다. 그리고 아래의 4가지 내용이 반드시 선언되어야 한다.

  1. 앱의 패키지 이름
  2. 앱의 구성 요소(Activity, Service, Broadcast Receiver, Content Provider)
  3. 앱이 시스템 또는 다른 앱의 보호된 부분에 액세스하기 위해 필요한 접근 권한
  4. 앱에 필요한 하드웨어 및 소프트웨어 기능

1. 앱의 패키지 이름

앱의 패키지 이름 즉, APK(Android Application Package) 이름에 대한 선언이 필요하다. manifest 선언 중 package에 해당하는 부분이 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개의 역할을 수행한다.
1) 매니페스트에서 선언한 패키지 이름은 App Resource에 접근하는데 사용되는 R 클래스의 네임스페이스(개체를 구분할 수 있는 범위, 변수명, 함수명 등을 의미)로 적용된다.

2) 매니페스트에서 선언한 패키지 이름은 파일 내에서 선언된 다른 코드들의 상대 경로가 된다. MainActivity가 있을 때, 최종 경로는 com.example.flip.MainActivity가 된다.

R 클래스에는 R.Java가 있는데, 리소스 접근을 위한 ID들을 모아놓은 파일로 이처럼 R 클래스는 리소스에 접근할 때 사용되는 클래스이다.
경로 : com.example.flip.R

2. 앱의 구성요소

앱의 구성요소인 4대 컴포넌트들을 사용하고 싶다면 매니페스트 파일에 선언해줘야 한다. 매니페스트 파일 내부에서 아래와 같이 선언할 수 있다.

<activity> : Activity 이름 및 내용
<service> : Service 이름 및 내용
<receiver> : Broadcase Receiver 이름 및 내용
<provider> : Content Provider 이름 및 내용

위의 컴포넌트들은 인텐트에 의해서 활성화된다. 인텐트라 일종의 메시지 객체이며 어떤 행동을 수행할지에 대한 명령이나 작업에 필요한 데이터를 포함한다.

...
        <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-filter 태그로 action과 category가 지정되어 있는 걸 확인할 수 있다.

앱에서 인텐트를 시스템에 전달하면 시스템은 각 앱의 매니페스트에 선언된 intent-filter를 확인하여 해당 인텐트를 처리할 수 있는 인텐트를 포함한 컴포넌트를 찾게 된다. 만약, 여러 개의 앱이 인텐트를 다룰 수 있다면, 사용자가 해당 인텐트를 어떤 앱에게 넘길지 선택할 수 있게 된다.

추가적으로 매니페스트에 선언된 컴포넌트들과 application은 유저에게 보여줄 수 있는 icon과 label 속성을 갖고 있다. xml로 구성하면 트리 구조가 되어 부모 - 자식 관계가 생기는데, 자식 element에 icon과 label이 설정되어있지 않다면 부모에 설정된 값이 기본값으로 들어가게 된다. 그렇기 때문에 각 컴포넌트마다 설정하지 않고 앱 전체에 기본값을 설정하려면 application에 설정하면 된다.

3. 권한

앱이 시스템 또는 다른 앱의 보호된 부분에 접근하기 위해 필요한 권한이다. 이때 다른 앱이 이 앱의 콘텐츠에 접근하고자 하는 경우, 반드시 있어야 하는 모든 권한 역시 매니페스트에 선언되어야 한다.

구체적으로는 연락처, SMS, 카메라, 위치정보 등 민감한 사용자 데이터 접근 여부 권한을 의미한다. Android 6.0부터는 사용자가 런타임에서 일부 앱 권한을 승인하거나 거절할 수 있게 되었다. 사용자의 허가 여부와 상관없이 매니페스트에는 앱이 접근하고자 하는 데이터와 관련된 권한을 모두 선언해야 하며, 선언되어 있지 않다면 접근하려는 시도 자체가 실패하게 된다.

4. 기기 호환성

매니페스트 파일에서 앱에 필요한 하드웨어 또는 소프트웨어 기능을 선언할 수 있다. 또한, 앱과 호환되는 기기 유형도 선언이 가능하다. Google Play Store에서는 앱에 기기 호환성에서 선언한 내용이 충족되지 않은 기기에는 앱 설치를 허용하지 않게 된다.

ex) AR 기능을 사용하는 앱의 매니페스트에서 AR 기능을 지원하는 기기가 필요하다고 선언한다면 AR 기능이 없는 기기는 Google Play Store에서 다운로드 받을 수 없게 된다.

기기 호환성에는 Android 버전인 SDK 역시 선언할 수 있으나 Android Studio에서는 build.gradle 파일에서 minSdkVersion 속성으로 재정의할 수 있으므로 안드로이드 최소버전 설정은 build.gradle 파일에서 하는게 좋다.

Ref

profile
Android Developer

0개의 댓글