在 Android 开发中,AndroidManifest.xml 是应用的核心配置文件,定义了应用的基本信息、组件声明、权限请求等关键内容。以下是需要掌握的核心知识:
一、AndroidManifest 的作用
- 声明应用组件
- Activity、Service、BroadcastReceiver、ContentProvider 等组件的注册。
- 权限管理
- 声明应用需要的权限(如相机、网络访问)。
- 应用元数据
- 应用名称、图标、版本号、支持的 Android 版本等。
- 入口点定义
- 指定应用启动时的主 Activity。
- 特殊功能配置
- 处理深链接(Deep Link)、多窗口模式、硬件需求等。
二、文件基础结构
xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.myapp"> <!-- 应用包名(与 build.gradle 中的 applicationId 可能不同) -->
<!-- 权限声明 -->
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme"
tools:targetApi="31">
<!-- 主 Activity(入口点) -->
<activity
android:name=".MainActivity"
android:exported="true"> <!-- Android 12+ 必须显式声明 exported -->
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- 其他 Activity -->
<activity
android:name=".SecondActivity"
android:label="Second Screen"
android:exported="false" />
<!-- Service 示例 -->
<service android:name=".MyService" />
<!-- BroadcastReceiver 示例 -->
<receiver android:name=".MyBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
</manifest>
三、关键配置详解
1. 权限声明
- 普通权限(自动授予):xml
<uses-permission android:name="android.permission.INTERNET" />
- 危险权限(需运行时请求):xml在 Kotlin 中动态请求:
<uses-permission android:name="android.permission.CAMERA" />
kotlinif (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.CAMERA), REQUEST_CODE) }
2. Activity 配置
- 基本属性:xml
<activity android:name=".MainActivity" <!-- 类名(相对于包名) --> android:label="Home" <!-- 界面标题 --> android:screenOrientation="portrait" <!-- 强制竖屏 --> android:exported="true" <!-- 是否允许其他应用启动 --> android:launchMode="singleTop" /> <!-- 启动模式 -->
- Intent Filter(定义 Activity 的响应场景):xml
<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="example.com" /> </intent-filter>
3. Application 标签
- 全局配置:xml
<application android:name=".MyApplication" <!-- 自定义 Application 类 --> android:icon="@mipmap/ic_launcher" <!-- 应用图标 --> android:label="@string/app_name" <!-- 应用名称 --> android:theme="@style/AppTheme" <!-- 全局主题 --> android:usesCleartextTraffic="true"><!-- 允许 HTTP 明文流量 -->
四、高级配置示例
1. 适配新版本 Android
- 指定
targetSdkVersion
兼容性:xml<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="34" />
2. 处理配置变更
- 禁止 Activity 在旋转屏幕时重建:xml
<activity android:name=".CameraActivity" android:configChanges="orientation|screenSize|keyboardHidden" />
3. 多进程配置
- 为 Service 指定独立进程:xml
<service android:name=".BackgroundService" android:process=":remote" />
五、与 Kotlin 代码的交互
1. 获取 Meta-Data 信息
在 Manifest 中定义:
xml
<meta-data
android:name="com.example.API_KEY"
android:value="your_api_key_here" />
在 Kotlin 中读取:
kotlin
val appInfo = packageManager.getApplicationInfo(packageName, PackageManager.GET_META_DATA)
val apiKey = appInfo.metaData.getString("com.example.API_KEY")
2. 动态注册组件
- 代码中注册 BroadcastReceiver:kotlin
val filter = IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION) registerReceiver(networkReceiver, filter)
六、注意事项
Android 12+ 的 exported 属性
所有包含<intent-filter>
的组件必须显式声明android:exported="true|false"
。权限分组
请求危险权限时,需处理用户拒绝的情况(参考运行时权限最佳实践)。包名管理
package
属性用于生成 R 类,而build.gradle
中的applicationId
是应用唯一标识,二者可不同。ProGuard/R8 混淆
需在proguard-rules.pro
中保留 Manifest 中声明的组件:-keep public class * extends android.app.Activity -keep public class * extends android.app.Service
通过合理配置 AndroidManifest.xml,你可以确保应用功能正确运行并适配不同设备。
Activity、布局文件和AndroidManifest之间的关系
在 Android 开发中,Activity、布局文件和 AndroidManifest.xml 是三个紧密关联的核心概念,它们共同协作完成应用的界面展示和功能逻辑。以下是它们之间的关系解析:
一、角色分工
组件 | 作用 | 类比 |
---|---|---|
Activity | 控制用户界面逻辑的「控制器」,负责处理用户交互、数据加载和生命周期管理。 | 餐厅的「服务员」 |
布局文件 | 定义用户界面的「视图模板」,描述屏幕上显示哪些组件(按钮、文本框等)及其排列方式。 | 餐厅的「菜单和餐桌布局」 |
AndroidManifest | 应用的「全局配置中心」,声明所有组件(如 Activity)的存在和权限等元信息。 | 餐厅的「营业执照和经营许可」 |
二、具体关系解析
1. Activity 与布局文件
- 绑定关系
Activity 通过setContentView(R.layout.xxx)
加载布局文件,将 XML 定义的 UI 渲染到屏幕上:kotlinclass MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // 绑定布局文件 } }
- 动态操作
Activity 通过findViewById
或 View Binding 获取布局中的视图对象,并控制其行为:kotlin// 传统方式 val button = findViewById<Button>(R.id.btn_submit) button.setOnClickListener { /* 处理点击事件 */ } // View Binding 方式 private lateinit var binding: ActivityMainBinding binding = ActivityMainBinding.inflate(layoutInflater) binding.btnSubmit.text = "更新文本"
2. Activity 与 AndroidManifest
- 注册关系
所有 Activity 必须 在AndroidManifest.xml
中声明,否则系统无法识别和启动它:xml<application> <activity android:name=".MainActivity" <!-- 类名(相对于包名) --> android:label="主界面" <!-- 界面标题 --> android:exported="true"> <!-- 是否允许外部应用启动 --> <intent-filter> <!-- 定义启动入口 --> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application>
- 启动规则
- 通过
Intent
启动其他 Activity 时,目标 Activity 必须在 Manifest 中注册。 android:exported
属性控制是否允许其他应用调用该 Activity。
- 通过
3. 布局文件与 AndroidManifest
- 间接关联
布局文件本身不直接与 Manifest 交互,但通过 Activity 间接关联:- Manifest 声明 Activity 的存在和属性。
- Activity 负责加载布局文件并渲染 UI。
三、协作流程示例
以启动一个 Activity 为例,三者协作过程如下:
用户点击应用图标
- Manifest 中声明了
MainActivity
的<intent-filter>
,系统识别其为入口 Activity。
- Manifest 中声明了
系统创建 MainActivity 实例
- 调用
onCreate()
方法,执行setContentView(R.layout.activity_main)
加载布局文件。
- 调用
渲染界面
- 布局文件
activity_main.xml
定义的 UI 被解析并显示在屏幕上。
- 布局文件
用户交互
- Activity 通过代码操作布局中的视图(如按钮点击事件)。
跳转到其他 Activity
- 通过
Intent
启动SecondActivity
,Manifest 必须已注册该 Activity。
- 通过
四、关键依赖总结
依赖方向 | 说明 |
---|---|
Activity → 布局文件 | Activity 依赖布局文件定义界面结构。 |
Activity → Manifest | Activity 必须在 Manifest 中注册才能被系统识别。 |
布局文件 → Activity | 布局文件中的视图通过 Activity 的代码实现动态逻辑(如点击事件、数据加载)。 |
Manifest → 系统 | Manifest 向 Android 系统声明应用的组件和权限,是应用运行的「许可证」。 |
五、常见问题
1. 如果忘记在 Manifest 中注册 Activity 会怎样?
- 尝试启动该 Activity 时会抛出
ActivityNotFoundException
,应用崩溃。
2. 一个 Activity 可以绑定多个布局文件吗?
- 可以!通过代码动态切换(如横竖屏适配):kotlin
override fun onCreate(savedInstanceState: Bundle?) { if (isLandscape) { setContentView(R.layout.activity_main_land) } else { setContentView(R.layout.activity_main_port) } }
3. 布局文件能否被多个 Activity 共享?
- 可以,但通常不推荐。更好的做法是通过 Fragment 或自定义 View 实现复用。
六、最佳实践
- 模块化:为每个 Activity 创建独立的布局文件,命名清晰(如
activity_main.xml
)。 - View Binding:替代
findViewById
,避免空指针异常,提升代码可读性。 - Manifest 最小化:只声明必要的权限和组件,减少安全风险。
掌握三者关系是 Android 开发的基础,后续可深入学习 Fragment、ViewModel 和 Navigation 等高级主题。