AndroidManifest.xml 文件详解
概述
每一个android应用程序项目都必须包含有AndroidManifest.xml
文件(后称清单文件)并且放在项目资源集的根目录中(即main文件夹下)。清单文件描述了应用必要的信息提供给Android编译工具、Android操作系统以及应用商店(如Google Play)。
清单文件要求以下的声明:
声明与代码的命名空间相匹配的应用包名。
Android编译工具在编译项目的时候通过应用包名定位代码实体的位置。在应用进行打包的同时,编译工具使用Gradle编译文件中的application ID
与该应用包名进行替换。以此作为应用在Android操作系统以及应用商店的唯一的标识符。应用的组件
包括应用中所有的Activity
、Service
、Broadcast Receiver
、Content Provider
。每一个组件必须定义基本的属性,它可以声明设备配置的特性、“Intent filter”(用以描述组件在何种状况下启用)应用所需要访问的权限
包括访问系统及其他应用所受保护的权限。应用也可声明供其他应用访问该应用特定内容的权限(如果其他应用需要访问已经声明权限的内容,也必须在自身应用清单中声明该权限)。
文件特性
以下内容讲述的是清单文件中一些重要的字符
包名和应用ID(application ID)
清单文件的根元素要求声明应用的包名称(一般情况下与项目中的Java目录结构一致)
以下代码片段展示的是根元素和应用包名com.example.myapp
:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapp"
android:versionCode="1"
android:versionName="1.0" >
...
</manifest>
把应用打包成最终的APK,Android编译工具将 package
属性应用于以下2处:
将该名称作为应用的命名空间以生成
R.java
类文件(用来访问应用的资源)
比如上面的清单文件中,R
类文件被创建为com.example.myapp.R
用以解决清单文件中的相似类名,以缩短命名。
比如上面的清单文件中,activity
声明为<activity android:name=".MainActivity">
来代替com.example.myapp.MainActivity
要注意的是,一旦APK被编译,package
属性也可以表示app全局唯一的应用Id。待编译器完成以上任务后,编译器将build.gradle
文件中的applicationId
熟悉与package
进行替换。这个最终的值必须是全局唯一的,以此来保证应用的唯一性。
manifest中的package
和build.gradle
文件中的applicationId
会让人感到些许困惑。通常把两者的值设置成一致便可避免不必要的麻烦。
应用程序组件(App components)
应用中每个创建的组件必须在清单文件中声明一个相对应的XML元素。
<activity>
对应于Activity
类<service>
对应于Service
类<receiver>
对应于BroadcastReceiver
类<provider>
对应于ContentProvider
类
如果创建的组件类未在清单文件中声明,操作系统将无法启用该组件。
Activity
中的name
属性必须指定完整包名,如下所示:
<manifest ... >
<application ... >
<activity android:name="com.example.myapp.MainActivity" ... >
</activity>
</application>
</manifest>
如果Activity
中的name
属性值中的第一个字符为.
,则应用的包名(即<manifest>
元素的package
属性值)作为name
属性的前缀。如下所示,Activity
的name
熟悉值与"com.example.myapp.MainActivity"
相同:
<manifest package="com.example.myapp" ... >
<application ... >
<activity android:name=".MainActivity" ... >
...
</activity>
</application>
</manifest>
意图过滤器(Intent filters)
应用的Activity
、Service
、Broadcast Receiver
、由intent激活。intent是由Intent
对象定义的一个用以描述动作与行为的消息。
包括可用的数据、可表示行为的组件类别以及其他指令。
当应用分发一个intent给操作系统,操作系统可以通过应用清单文件的intent filter定位到可接收该intent应用组件。如果超过了一个应用可以处理该intent,系统会弹出选择对话框让用户选择使用哪个应用进行处理。
应用组件拥有无数个intent filter(使用进行定义),每个都可以声明组件的不同功能。
Icons和labels
大多数的manifest节点都有icon
和label
属性来显示一个小图标和文本标签,以引导用户找到对应的应用组件。
但凡在父节点中声明了icon
和label
值,该值将会变成子节点的默认值。比如在<application>
节点声明该值作为Activity的默认值。
你可以给<intent-filter>
声明自身的icon
和 label
,用以展示在上述的选择对话框的图标中(比如文件分享弹出的选择对话框)。
权限(Permissions)
Android应用如果要访问用户的敏感数据(例如联系人和短信)或者系统功能(如摄像头和网络)就必须申请相应的权限并用每个权限有独特的标签进行标识。
例如应用需要发消息就必须在清单文件中进行如下声明:
<manifest ... >
<uses-permission android:name="android.permission.SEND_SMS"/>
...
</manifest>
从Android 6.0(API 23)开始,可以允许在运行时允许或拒绝应用权限。但无论应用的版本是多少,都必须使用<uses-permission>
在清单文件中声明所有的请求权限。如果授予该权限,应用便可访问受保护的功能。如果不授予,则访问该功能将失败。应用还可以通过权限来保护自己的组件。它可以使用任意由罗列在android.Manifest.permission
中Andoird定义的权限。应用程序还可以定义自己的权限。一个新的许可声明 <permission>
标签。
设备兼容性(Device compatibility)
清单文件中可以声明应用要求软硬件的特性以及应用兼容哪一种类型的设备。Google 应用商店不允许应用安装在与系统版本、特性不匹配的设备上。
有多个清单的标签定义应用程序兼容什么类型的设备,以下几个是最常见的标签
<uses-feature>
允许声明应用所需的硬件和软件特性。例如,如果应用程序必须要在有电子罗盘上才能运行,你可以在清单文件中声明电子罗盘的特性标签:
<manifest ... >
<uses-feature android:name="android.hardware.sensor.compass"
android:required="true" />
...
</manifest>
每次发布的平台系统版本,通常会添加一些之前版本不兼容的新的API。为了表明应用程序所兼容的最低版本,你必须在<uses-sdk>
标签中声明minSdkVersion
属性值。
需要注意的是,<uses-sdk>
由build.gradle
文件中的相对应的属性重写。因此如果你使用Android Studio,就必须在build.gradle
文件中定义minSdkVersion
和targetSdkVersion
值。:
android {
defaultConfig {
applicationId 'com.example.myapp'
// Defines the minimum API level required to run the app.
minSdkVersion 15
// Specifies the API level used to test the app.
targetSdkVersion 26
...
}
}
文件规范
本节描述适用于所有的元素和属性的清单文件的一般惯例和规则。
元素(Elements)
仅仅适用于和元素。二者都只能使用一次。大多数其他的元素可以使用0次以上。
通过属性设置所有的值,而不是为一个元素内字符数据。
元素在同一个层级通常不要求固定顺序。如<activity>
, <provider>
, and <service>
元素可以防止在任意位置。这条规则有个例外
<activity-alias>
元素作为<activity>
的别名必须放在其之后。<application>
元素必须作为最后一个元素放在<manifest>
元素里面.
属性(Attributes)
从技术上来讲,所有的属性应该都是可选的。然而,许多属性必须定义值以让元素可以实现其特定的功能。对于真正使用的属性都会有一个默认值。
根元素<manifest>
的一些属性都是以android:
前缀开头,例如android:alwaysRetainTaskState
。
多重值
如果多于一个值被定义,该元素几乎总是重复,相当于多个值被列在单一元素里。比如,一个intent filter可以列出多个actions:
<intent-filter ... >
<action android:name="android.intent.action.EDIT" />
<action android:name="android.intent.action.INSERT" />
<action android:name="android.intent.action.DELETE" />
...
</intent-filter>
资源值(Resource values)
一些展示给用户的属性值,比如activity的标题和图标。这些属性值也许要在不同的语言或者设备配置(比如基于设备的像素密度提供不同的图标尺寸)中展示不一样。
属性值应该要通过资源或者主题进行设置,而不是通过硬编码的方式写死在清单文件里面。针对不同设备配置,实际值可以根据提供的可替代资源进行改变。
资源必须以如下格式进行表示:
"@[package:]type/name"
如果该资源是由应用自身(包括依赖的库,因为库资源会合并进应用程序当中)提供的,你也可以省略package
名称。如果你想要用android框架里面的资源,可用的package 名称便是android
。
type
是指资源的类型,比如string
或者是drawable
,name
是定义好的资源的名称。比如:
<activity android:icon="@drawable/smallPic" ... >
定义主题theme
值,第一个字符必须是?
而不是@
:
"?[package:]type/name"
字符串值(String value)
使用字符串属性值,必须用双斜杠\\
对特定字符进行转义,比如下一行可以用\\n
或者Unicode编码的\\uxxxx
字符进行表示。
清单文件元素参考目录
下表提供AndroidManifest.xml
所有有效元素索引及功能描述。
元素 | 功能描述 |
---|---|
<action> | 添加一个action 到intent filter |
<activity> | 声明 activity组件 |
<activity-alias> | 声明activity别名 |
<application> | 声明应用程序 |
<category> | 添加一个category 名称到intent filter |
<compatible-screens> | 定义应用所兼容的每种屏幕配置 |
<data> | 添加数据定义到intent filter |
<grant-uri-permission> | 定义应用数据的子集以供父内容提供者有权限可以访问 |
<instrumentation> | 声明Instrumentation工具类并是您可以监控应用程序的交互系统 |
<intent-filter> | 定义activity、service或者是broadcast receiver可以响应的意图(intent)类型, |
<manifest> | AndroidManifest.xml文件中的根元素 |
<meta-data> | 一条额外添加的名称-值对,可以给父组件提供任意的数据。 |
<path-permission> | 在content provider内定义所需路径和权限特定子集数据 |
<permission> | 声明一个安全权限,可以用来限制访问特定应用的组件或功能 |
<permission-group> | 声明一个相关权限的逻辑组名称 |
<permission-tree> | 声明权限树的基础名称 |
<provider> | 声明一个内容提供者(content provider)组件 |
<receiver> | 声明一个广播接收器(broadcast receiver)组件 |
<service> | 声明一个服务(service)组件 |
<supports-gl-texture> | 声明一种应用单一支持的GL纹理(texture)压缩格式 |
<supports-screens> | 声明应用所支持的屏幕尺寸大小以及在启用兼容模式下系统屏幕超出应用所支持的尺寸 |
<uses-configuration> | 声明应用程序的软硬件需求 |
<uses-feature> | 声明应用程序需要用到的软、硬件特性。 |
<uses-library> | 指定应用程序必须引用的共享库 |
<uses-permission> | 指定了让应用程序正常运行,用户必须授予的系统权限。 |
<uses-permission-sdk-23> | 指定了应用程序在Android 6.0以上所需的特定权限 |
<uses-sdk> | 通过API整数值来声明应用程序所兼容的Android平台版本 |
manifest文件代码样例
以下展示的是有两个activity的manifest文件代码样例
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="1"
android:versionName="1.0"
package="com.example.myapp">
<!-- Beware that these values are overridden by the build.gradle file -->
<uses-sdk android:minSdkVersion="15" android:targetSdkVersion="26" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher_round"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<!-- This name is resolved to com.example.myapp.MainActivity
based upon the package attribute -->
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".DisplayMessageActivity"
android:parentActivityName=".MainActivity" />
</application>
</manifest>
原文地址 https://blog.csdn.net/u013560890/article/details/81240356