Android 应用在打包后,系统识别应用身份、入口页面、权限范围以及组件构成的关键文件就是 AndroidManifest.xml。它位于 app/src/main 目录下,采用 XML 格式描述应用包名、版本、组件、权限、硬件特性等元数据。构建阶段 Gradle 会把主工程的 manifest 与依赖库里的 manifest 进行合并,最终生成 APK 中的二进制清单。若文件中的声明与实际代码不一致,轻则组件无法调用,重则应用安装失败或直接崩溃。

一、manifest 根节点与全局属性
AndroidManifest.xml 的根节点是 <manifest>,所有组件声明都必须放在这个节点之内。根节点通常带有 xmlns:android 命名空间,用于引入 Android 系统定义的属性集合。历史上 <manifest> 节点必须显式声明 package 属性,用来标记应用唯一包名,例如 package="com.example.demo"。但在新版 Android Gradle Plugin 中,包名已经迁移到 build.gradle 的 namespace 字段中,manifest 里的 package 属性不再是必填项,不过保留它仍然可以兼容旧版构建工具。
除了 package,manifest 节点上还有几个值得注意的属性。android:versionCode 和 android:versionName 用于区分应用版本,前者是整数,用于系统判断升级逻辑;后者是展示给用户的版本字符串。现在官方推荐在 build.gradle 中统一管理 versionCode 和 versionName,并通过 defaultConfig 注入,这样可以避免 manifest 与 Gradle 配置不一致。根节点中还可以声明 android:sharedUserId,但这个属性已经在新版本中被逐步弃用,因为它会带来签名权限共享方面的安全隐患。
一个基础但完整的根节点结构如下:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.demo">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme">
<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>
需要特别注意的是,manifest 文件是 XML 格式,所有标签都必须正确闭合,属性值必须使用引号。很多人排查启动失败问题时,最后发现是 <activity> 缺少闭合标签或命名空间写错,因此在修改该文件时建议保持标签对称和缩进清晰。
二、application 节点与四大组件注册
<application> 节点表示整个应用,所有组件都必须在其内部注册。它的常用属性包括 android:icon、android:label、android:theme、android:allowBackup 以及 android:usesCleartextTraffic。icon 和 label 决定桌面显示图标与应用名称,theme 设置全局主题,allowBackup 控制是否允许系统备份应用数据。如果应用需要访问 HTTP 明文接口,在 Android 9 及以上版本中需要将 usesCleartextTraffic 设为 true,或者使用 networkSecurityConfig 指向网络安全配置文件。
四大组件中,Activity 对应界面,Service 负责后台任务,BroadcastReceiver 接收广播,ContentProvider 管理数据共享。它们分别通过 <activity>、<service>、<receiver>、<provider> 子节点声明。例如注册一个 Activity 的最小写法是在 <application> 内声明 <activity android:name=".MainActivity" />。Android 12 及以上的系统对组件可见性做了更严格限制,凡是带有 intent-filter 的组件,必须显式声明 android:exported 属性,告诉系统该组件是否允许被外部应用调用。
android:exported 属性看似简单,却是常见的构建失败原因之一。如果 Activity、Service 或 Receiver 声明了 <intent-filter>,但没有写 android:exported,在 targetSdkVersion 为 31 及以上时,应用安装后可能无法启动,构建阶段也可能直接报错。正确的做法是根据业务需求设置 true 或 false。例如入口 Activity 需要被桌面启动器调用,应设置为 true;而仅内部使用的 Service 应设置为 false,降低安全风险。
三、intent-filter 与隐式启动
<intent-filter> 的作用是告诉系统该组件可以响应哪些隐式 Intent。它由 action、category 和 data 三类子节点组成。action 表示要执行的动作,例如 android.intent.action.VIEW 表示查看数据,android.intent.action.SEND 表示分享内容。category 用于补充动作的执行环境,其中 android.intent.category.LAUNCHER 配合 MAIN 可以让 Activity 显示在桌面启动器中,成为应用入口。
一个组件可以包含多个 intent-filter,每个 filter 描述一种能力。系统在匹配隐式 Intent 时,会要求 Intent 中的 action 必须与 filter 中的某个 action 一致,category 必须全部被 filter 包含,data 部分则需要满足 scheme、host、path 等规则。如果某个 Activity 想被浏览器唤起,可以配置如下:
<activity
android:name=".WebViewActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" android:host="www.ippipp.com" />
</intent-filter>
</activity>
需要留意的是,隐式启动时可被外部调用的组件同样要声明 android:exported,且必须带上 DEFAULT category。如果外部 Intent 没有显式指定组件名,系统只会匹配包含 DEFAULT 的 filter。很多隐性匹配失败的问题,都是因为遗漏了 DEFAULT category,导致 filter 只在显式指定类名时才能命中。
四、权限与 feature 声明
Android 的权限体系分为普通权限、危险权限和特殊权限。应用需要访问相机、定位、通讯录等敏感数据时,必须在 manifest 中使用 <uses-permission> 声明权限。例如 <uses-permission android:name="android.permission.CAMERA" /> 表示申请相机权限。对于危险权限,仅声明还不够,运行时还必须通过 ActivityCompat.requestPermissions 动态申请。如果 manifest 中缺少对应权限声明,即便代码中执行了权限请求,系统也会直接拒绝,甚至在某些设备上抛出 SecurityException。
<uses-feature> 节点用于声明应用依赖的硬件或软件特性,例如摄像头、蓝牙、NFC 等。它的作用是帮助应用商店过滤不兼容设备,例如 <uses-feature android:name="android.hardware.camera" android:required="true" /> 表示应用必须运行在带摄像头的设备上。如果应用对某项硬件只是可选依赖,可以把 required 设为 false,这样应用在没有该硬件的设备上也能安装,但需要在代码中做好特性检测。
应用还可以通过 <permission> 声明自定义权限,用来保护自己的组件或广播。声明之后,其他应用必须申请该权限才能访问对应组件。自定义权限的 android:protectionLevel 可以设置 normal、dangerous、signature 等级别。一般建议使用 signature 级别,这样只有使用相同签名证书的应用才能获得权限,安全系数更高。
五、manifest 合并与常见配置错误
实际项目中,依赖库常常自带的 manifest 会通过 manifest merger 与主工程合并。合并过程中可能出现属性冲突,例如主工程和某个 SDK 都声明了同一个 <activity>,但属性不一致。此时可以在主工程的 manifest 中借助 tools:replace 或 tools:node 来指定合并策略。tools 命名空间需要声明 xmlns:tools。常用写法包括 tools:replace="android:theme" 表示用主工程的 theme 覆盖依赖库中的值,tools:node="remove" 则可以直接移除某个组件节点。
如果合并失败,Gradle 会在构建日志中输出 manifest merger 的报告,并给出冲突详情。开发者在遇到这类问题时,不要直接修改依赖库源码,而应该优先通过 tools 命名空间解决。例如某个推送 SDK 声明了一个主题,与应用全局主题冲突,可以在应用节点加入 tools:replace="android:theme"。需要注意的是,tools 命名空间仅用于构建期处理,不会影响 APK 运行时的行为。
常见的 manifest 配置错误还包括:包名与 build.gradle 中的 applicationId 不一致、Activity 未在 manifest 中注册导致 ClassNotFoundException、缺少权限导致调用系统功能崩溃、application 节点中 label 引用了不存在的资源导致安装后无图标等。排查这些问题时,可以先检查 APK 中的 manifest 内容,再对照代码逐个确认。只要理解根节点、application 属性、组件声明、intent-filter 和权限这几个核心模块,大多数 manifest 配置问题都能快速定位并解决。
AndroidManifest.xmlmanifest配置安卓应用清单修改时间:2026-08-29 00:27:31