Введение

«Расскажите, что вы знаете про AndroidManifest.xml» — вопрос, который большинство кандидатов сводит к фразе «там объявлена MainActivity». И теряет баллы, потому что манифест — это точка входа в понимание того, как Android вообще запускает ваше приложение.

Манифест — недооценённая тема. Его не спрашивают «в лоб» так часто, как lifecycle или контексты, но он всплывает в десятке смежных вопросов: почему система не видит мой Activity, зачем нужен android:exported, как разрешения связаны с защитой компонентов, почему приложение нельзя установить на Android 12.

Когда я провожу собеседования, вопросы про манифест — отличный «фильтр глубины». Кандидат, который понимает, что манифест описывает приложение трём потребителям — инструментам сборки, операционной системе и Google Play, — отвечает на половину платформенных вопросов без шпаргалок. Разберём всё, что реально спрашивают: назначение, структура, компоненты, intent-filter, permissions и android:exported.

Зачем нужен манифест

Формальное определение из официальной документации: файл манифеста описывает основную информацию о приложении для инструментов сборки Android, операционной системы и Google Play. Одна фраза — три разных потребителя, и за каждым стоит конкретная функция.

Инструменты сборки читают манифест, чтобы понять, какой код упаковывать и как: версии SDK, имена компонентов, ресурсы. Операционная система — чтобы знать, какие компоненты у приложения есть и как их запускать. Google Play — чтобы показывать приложение совместимым устройствам: из манифеста Play узнаёт про требуемые разрешения и функции.

Самое важное следствие: компонент, не объявленный в манифесте, система запустить не может. Создали класс DetailActivity и забыли добавить его в манифест — при переходе на экран приложение упадёт с ошибкой, потому что система просто не знает о существовании такого компонента. Это первый пункт, который стоит проговорить на собеседовании.

Ключевая мысль

AndroidManifest.xml — это «паспорт» приложения для трёх читателей: инструментов сборки, операционной системы и Google Play. Компонент без объявления в манифесте недоступен системе — она его просто не видит.

Структура: корневой элемент и application

Корневой элемент манифеста — <manifest>. Внутри него живут <application> и все объявления компонентов. Элемент <application> описывает приложение целиком: иконку и label, тему, возможность отладки, имя класса Application, если оно кастомное.

Разберём реальный минимальный манифест:

AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

    <application
        android:label="@string/app_name"
        android:icon="@mipmap/ic_launcher"
        android:theme="@style/Theme.MyApp">

        <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>

    </application>

</manifest>

Теперь важный нюанс, который ломает многих: атрибута package в манифесте больше нет. Раньше в корне манифеста писали package="com.example.myapp", и он задавал имя пакета и namespace. В современных версиях Android Gradle Plugin идентификатор приложения задаётся через applicationId в build.gradle, а namespace — через свойство namespace того же модуля. Именно namespace подставляется в имена компонентов: если в манифесте написано .MainActivity, то с namespace com.example.myapp это превращается в com.example.myapp.MainActivity.

На собеседовании это различать важно: applicationId — уникальный идентификатор приложения в системе и на Play (менять можно, но лучше не после публикации), а namespace — пространство имён для кода и R-класса.

Частая ошибка кандидатов: путать package в манифесте, applicationId и namespace. Сейчас пакет из манифеста убран, namespace живёт в build.gradle модуля, а applicationId — отдельная сущность, которую видит система и Play.

Компоненты и intent-filter

В манифесте объявляются четыре типа компонентов — ровно четыре базовых компонента Android:

  • <activity> — для каждого подкласса Activity;
  • <service> — для каждого подкласса Service;
  • <receiver> — для каждого подкласса BroadcastReceiver;
  • <provider> — для каждого подкласса ContentProvider.

У каждого компонента есть имя класса в атрибуте android:name. Полное имя — com.example.myapp.MainActivity, сокращённое с точкой — .MainActivity: тогда к имени подставляется namespace из build.gradle.

Отдельно стоит android:icon и android:label — они показываются пользователю, и компонент можно защитить разрешением (android:permission) — об этом в следующем разделе. Но главное, что связывает компоненты с платформой, — <intent-filter>: механизм, с помощью которого система решает, какой компонент запустить по интенту. Интент описывает действие («открыть что-то», «отправить»), а система ищет компонент, чей intent-filter подходит под это действие.

В примере выше MainActivity объявлена с фильтром MAIN + LAUNCHER — именно эта комбинация делает Activity точкой входа в приложение: её показывает лаунчер. Ключевой нюанс из документации: если интент подходит нескольким приложениям, система показывает пользователю выбор. Это и есть механизм «открыть ссылку через браузер или приложение» — он работает не «магией», а через intent-filter, объявленные в манифестах всех установленных приложений.

intent-filter-example.xml
<activity
    android:name=".ShareActivity"
    android:exported="true">
    <intent-filter>
        <action android:name="android.intent.action.SEND" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:mimeType="text/plain" />
    </intent-filter>
</activity>

Теперь про android:exported — тема, которая в последние годы стала обязательной. Атрибут говорит системе, могут ли другие приложения запускать этот компонент. С Android 12 (API level 31) действует жёсткое требование: если у activity, service или broadcast receiver есть intent-filter, атрибут android:exported обязан быть объявлен явно — иначе приложение просто не установится на устройство с Android 12 и выше. Для компонента с LAUNCHER категорией нужно android:exported="true", в большинстве остальных случаев — false.

Типичная ошибка: не указывать android:exported у компонентов с intent-filter. Сборка падает с ошибкой «Apps targeting Android 12 and higher are required to specify an explicit value for android:exported when the corresponding component has an intent filter defined». LAUNCHER — true, внутренние экраны — false.

  • Четыре компонента: activity, service, receiver, provider — каждый объявляется своим элементом.
  • Необъявленный компонент система запустить не может.
  • .MainActivity — сокращение, которое разворачивается через namespace из build.gradle.
  • Intent-filter связывает интенты с компонентами; несколько кандидатов — пользователь выбирает.
  • android:exported — обязательно для компонентов с intent-filter, иначе приложение не установится на Android 12+.

Permissions: права доступа

Разрешения — третья большая тема манифеста. Android-приложения обязаны запрашивать доступ к чувствительным данным пользователя и защищённым функциям системы: камера, контакты, интернет, SMS. Запрос объявляется в манифесте через <uses-permission>.

Ключевые факты, которые проверяют на собеседованиях:

  • Все запросы разрешений объявляются в манифесте. С Android 6.0 (API level 23) часть разрешений пользователь подтверждает в рантайме, но объявление в манифесте нужно всегда — без него система не даст запросить доступ.
  • Разрешения делятся на установочные и рантайм-разрешения. Опасные разрешения (камера, местоположение, контакты) запрашиваются во время работы приложения, обычные выдаются при установке.
  • Приложение может защищать собственные компоненты. Атрибут android:permission на компоненте означает: запустить его сможет только приложение, у которого есть это разрешение. Так делают, например, для сервисов, которые вызываются из других приложений.
permissions.xml
<manifest ...>
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.CAMERA" />

    <application ...>
        <service
            android:name=".ExportService"
            android:permission="android.permission.EXPORT_DOCUMENT"
            android:exported="true" />
    </application>
</manifest>

Полный список системных разрешений — это android.Manifest.permission. Если ваше приложение объявляет собственные разрешения (через <permission>), их же можно навешивать на свои компоненты — так строится защита при взаимодействии между приложениями.

  • Все разрешения объявляются в манифесте через <uses-permission>.
  • С API 23 опасные разрешения подтверждаются пользователем в рантайме, но объявление обязательно всегда.
  • Свои компоненты можно защитить через android:permission.
  • INTERNET — обычное разрешение, выдачи в рантайме не требует.

Что спрашивают на собеседовании

Соберём вопросы, в которых манифест всплывает, чтобы вы не удивлялись:

  1. «Почему приложение падает при переходе на экран, если Activity не в манифесте?»
  2. «Зачем нужен android:exported и что будет, если его не указать?»
  3. «Чем отличаются package, applicationId и namespace
  4. «Как система решает, какое приложение откроет ссылку?» — через intent-filter.
  5. «Какие разрешения надо объявлять, а какие — запрашивать в рантайме?»

Если вы можете ответить на эти пять — манифест для собеседования закрыт. Обратите внимание: все ответы строятся вокруг одного понятия — манифест как описание приложения для системы. Понимание этого фундамента делает остальные вопросы платформы проще.

Мой опыт собеседований говорит, что тема манифеста — типичный «провал» на стыке junior и middle: кандидат знает про android:exported из ошибок сборки, но не может объяснить intent-filter и защиту компонентов разрешениями. Если такие дыры накапливаются — это сигнал, что нужна системная подготовка, а не новый список вопросов. Напишите в Telegram: я провожу диагностику уровня за 30–40 минут, разберу ваши пробелы и составлю план до middle — без обязательств.

Готовитесь к собеседованию на middle?

Манифест, интенты, permissions — платформенные темы, которые отличают middle от junior. На мок-собеседованиях тренируем их до уверенных ответов.

Итоги

AndroidManifest.xml — это описание приложения для инструментов сборки, операционной системы и Google Play. В нём объявляются все четыре типа компонентов, intent-filter для их запуска и разрешения. Компонент без объявления система не видит, компонент с intent-filter с Android 12 обязан явно указывать android:exported, а все разрешения объявляются в манифесте, даже если подтверждаются в рантайме.

Три тезиса, которые стоит унести с собой:

  • Манифест — паспорт приложения. Три читателя: сборка, ОС, Google Play. Не объявили компонент — система его не запустит.
  • Intent-filter связывает интенты и компоненты. Система подбирает компонент по фильтру, а при нескольких кандидатах — спрашивает пользователя. android:exported обязателен с Android 12.
  • Permissions объявляются в манифесте всегда. Рантайм-подтверждение с API 23 не отменяет объявление через <uses-permission>, а свои компоненты можно защищать разрешениями.

Если вы не смогли сходу ответить на пять вопросов из раздела выше — это нормально и закрывается за пару вечеров практики. Но если таких пробелов в платформенных темах накопилось много, лучше не идти на собеседование вслепую. Напишите в Telegram — разберём вашу ситуацию и составим план подготовки к уверенному middle.