Android开发-API指南-Manifest介绍

时间:2023-03-09 20:15:05
Android开发-API指南-Manifest介绍

App Manifest

英文原文:http://developer.android.com/guide/topics/manifest/manifest-intro.html
采集(更新)日期:2014-6-27
搬迁自原博客:http://blog.sina.com.cn/s/blog_48d491300102uwhe.html

每个应用程序都必须在根目录包含一个 AndroidManifest.xml 文件(只能是这个文件名)。

Manifest 文件向 Android 系统报告了应用程序的一些基本信息,以及运行该应用程序的代码所必需的系统条件。

其中,Manifest 文件的以下用途尤为重要:

  • 它定义了应用程序的 Java 包名称。包名称是应用程序的唯一标识。
  • 它声明了构成应用程序的各个组件 — Activity、服务、广播接收器和 Content Provider。
    它命名了每个组件的类名,并声明了组件的功能(例如,可以响应哪个
    Intent
    消息)。
    通过这些声明, Android 系统可以知晓存在哪些组件、在什么场合可以启动这些组件。
  • 它决定了应用程序的各个组件可以放入哪个进程中运行。
  • 它声明了应用程序所必需的权限,用于访问受保护的 API 或与其他应用程序交互。
  • 它还声明了其他应用程序和本程序中的组件交互所必需的权限。
  • 它给出了
    Instrumentation
    类,用于定义应用程序运行时的配置等信息。
    只有在开发和测试应用程序时,这些定义才会出现在 Manifest 中。在正式发布之前,这些信息都会被删除。
  • 它声明了应用程序所需的 Android API 最低版本。
  • 它给出了应用程序必须链接的库

Manifest 文件的结构


下面给出了 Manifest 文件的基本结构,以及文件内可包含的所有元素。
每个元素,包括内部的所有属性,都会在单独的文档中进行说明。
要查看每个元素的详细信息,可以点击示例中的元素名,或者点击下文中按字母排序的元素列表,或者其他任何提及元素名称的地方。

 <?xml version="1.0" encoding="utf-8"?>

 <manifest>

     <uses-permission />
<permission />
<permission-tree />
<permission-group />
<instrumentation />
<uses-sdk />
<uses-configuration />
<uses-feature />
<supports-screens />
<compatible-screens />
<supports-gl-texture /> <application> <activity>
<intent-filter>
<action />
<category />
<data />
</intent-filter>
<meta-data />
</activity> <activity-alias>
<intent-filter> . . . </intent-filter>
<meta-data />
</activity-alias> <service>
<intent-filter> . . . </intent-filter>
<meta-data/>
</service> <receiver>
<intent-filter> . . . </intent-filter>
<meta-data />
</receiver> <provider>
<grant-uri-permission />
<meta-data />
<path-permission />
</provider> <uses-library /> </application> </manifest>

Manifest 文件中所有可能出现的元素都按字母顺序列在下面。 合法的元素就只有这些,不允许添加自定义的元素或属性。

<action>
<activity>
<activity-alias>
<application>
<category>
<data>
<grant-uri-permission>
<instrumentation>
<intent-filter>
<manifest>
<meta-data>
<permission>
<permission-group>
<permission-tree>
<provider>
<receiver>
<service>
<supports-screens>
<uses-configuration>
<uses-feature>
<uses-library>
<uses-permission>
<uses-sdk>

约定


以下约定和规则适用于 Manifest 文件中的所有元素和属性:

元素
只有 <manifest><application> 元素是必需的,缺一不可,且只能出现一次。 其余大部分元素都可以多次出现,或者根本就不出现 — 虽然为了完成某些功能,某些元素还是必须给出的。

一个元素只允许包含其他元素,不能包含其他东西。 所有元素值都是通过属性来设置的,而不是通过在元素内包含字符来实现。

同一级别的元素是没有顺序的。例如, <activity><provider><service> 元素可以按照任何顺序放置。(但 <activity-alias> 元素除外,它必须跟在需要定义别名的 <activity> 后面。)

属性
从形式上说,所有的属性都是可选的。 但是,还是有一些属性是必须设置的,因为元素要完成某些功能。请参考相应的文档。 对于那些确实可选的属性,文档中给出了默认值或默认状态。

除了根元素 <manifest> 的某些属性外,所有属性的名称均以 android: 开头 — 例如, android:alwaysRetainTaskState。 因为这个前缀是通用的,文档在引用属性名称时通常会省略掉它。

声明类名
很多元素都对应着某个 Java 对象,包括 Application 本身( <application> 元素)及其主要组件 — Activity ( <activity>)、 服务( <service>)、 广播接收器( <receiver>) 和 Content Provider( <provider>)。

如果定义了一个子类,则子类通过name属性进行声明。对于组件类( ActivityServiceBroadcastReceiverContentProvider) 而言,基本上一定会定义子类。该名称必须包含完整的包名。 例如, Service 的子类可以声明如下:

<manifest . . . >
<application . . . >
<service android:name="com.example.project.SecretService" . . . >
. . .
</service>
. . .
</application>
</manifest>

不过,作为简称,如果名称的第一个字符是句点,则会将应用程序的包名(由 <manifest> 元素的 package 属性指定)作为前缀加上。以下声明的效果与上述定义相同:

<manifest package="com.example.project" . . . >
<application . . . >
<service android:name=".SecretService" . . . >
. . .
</service>
. . .
</application>
</manifest>

在启动组件的时候, Android 会创建一个已命名子类的实例。 如果子类名称未指定,就会创建一个基类的实例。

多个值
如果某个元素可以定义多个值,那么应该把该元素重复声明多次,而不是在一个元素中罗列多个值。 例如,一个 Intent 过滤器可以罗列多个 Action:
<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>
资源值
某些属性值包含了显示给用户查看的内容 — 比如 Activity 的文本标签和图标。 这些属性值应该是要被本地化的,所以要由资源或主题来定义。 资源值用以下格式表示:

@[package:]type:name

如果资源位于应用程序所在包内,则这里的 package 名可以省略。 type 是指资源的类型,比如“string”或“drawable”。 name 是标识某个资源的的名称。 例如:

<activity android:icon="@drawable/smallPic" . . . >

由主题定义的值用类似的方式表示,只是开头的“@”替换为“?”:

?[package:]type:name

字符串值
在字符串类型的属性值中,必须用双反斜杠(“\\”)作为转义字符。 例如,用“\\n”表示换行,用“\\uxxxx”表示 Unicode 字符集。

Android 特性


以下章节说明了 Manifest 文件中反映 Android 特性的部分。

Intent 过滤器

应用程序的核心组件(Activity、服务和广播接收器)都是由 Intent 来激活的。 一个 Intent 就是一组信息的集合(一个 Intent 对象),其中指定了某个 Action — 包含了要处理的数据、执行该 Action 的组件类型、以及其他相关指令。 Android 会查找合适的组件来响应 Intent ,必要时会新建组件的实例,并把 Intent 对象传给组件。

所有组件都会通过Intent 过滤器公布自己的处理能力 — 即它们可以响应的 Intent 类型。 因为在启动组件之前, Android 系统必须知晓组件可以处理哪种 Intent,所以必须在 Manifest 文件中用 <intent-filter> 元素声明 Intent 过滤器。 一个组件可以拥有任意数量的 Intent 过滤器,每个过滤器都声明了一种处理能力。

明确指明目标组件名称的 Intent 将会激活指定的组件,这时过滤器将不起作用。 但是假如 Intent 未指定目标,那它就只能通过组件的某个过滤器来激活组件。

关于 Intent 对象如何通过过滤器的检测,请参阅另一篇文档 Intent 和 Intent 过滤器

图标和文本标签

有些元素带有iconlabel 属性,可以向用户显示一个小图标和一个文本标签。 某些元素还带有description属性,用于在屏幕上显示更多说明性的信息。 例如, <permission> 元素就同时拥有这三种属性,这样在询问用户是否授予这些权限时,就可以显示代表该权限的图标、权限名称及其招致的后果信息。

无论何时,元素中设置的图标和文本标签都是其内部子元素的默认 iconlabel 值。 因此, <application> 元素的图标和文本标签就是应用程序的所有组件的默认图标和文本标签。 同理,组件的图标和文本标签 — 比如 <activity> 元素 — 也就是组件内所有 <intent-filter> 元素的默认图标和标签。 如果 <application> 元素设置了文本标签,但是 Activity 及其 Intent 过滤器都没有设置,那么应用程序的文本标签就被视为 Activity 和 Intent 过滤器的文本标签。

每当过滤器声明的功能被触发、需要向用户显示组件时,过滤器的图标和文本标签就用来代表该组件。 例如,某个带有“android.intent.action.MAIN”和“android.intent.category.LAUNCHER” 的过滤器声明了该 Activity 是应用程序的初始 Activity — 也就是说,该 Activity 应该在应用程序启动器中显示。 因此,该过滤器的图标和文本标签将会显示在启动器中。

权限

permission 用于对某部分代码或本机某些数据进行访问限制。 进行限制是为了保护某些关键数据和代码,这些数据如果被滥用,可能会干扰甚至破坏用户的体验。

所有权限都由唯一的文本标签标识。这个标签通常指明了受限的 Action。 例如,下面列出了 Android 预定义的一些权限:

android.permission.CALL_EMERGENCY_NUMBERS
android.permission.READ_OWNER_DATA

android.permission.SET_WALLPAPER

android.permission.DEVICE_POWER

一个特性最多只能受到一个权限的保护。

如果应用程序需要使用受到权限保护的特性,就必须声明它需要对应的权限,这通过 Manifest 文件中的
<uses-permission>
元素完成。
然后,当安装该应用时,安装程序会确定是否授权,这通过检查应用程序签名来完成,有时还会请用户来决定。
如果授权通过,则应用程序就能够使用这些受保护的特性。
如果授权未通过,则使用这些特性时就会失败,但不会向用户发送任何通知。

应用程序还可以用权限来保护自己的组件(Activity、服务、广播接收器、Content Provider)。
可以使用任何 Android 预定义的权限(在
android.Manifest.permission
)或其他应用程序声明的权限。
或者还可以定义自己的权限。新的权限通过
<permission>
元素进行声明。
比如,可以按照以下方式对 Activity 进行保护:

<manifest . . . >
<permission android:name="com.example.project.DEBIT_ACCT" . . . />
<uses-permission android:name="com.example.project.DEBIT_ACCT" />
. . .
<application . . .>
<activity android:name="com.example.project.FreneticActivity"
android:permission="com.example.project.DEBIT_ACCT"
. . . >
. . .
</activity>
</application>
</manifest>

请注意,上述例子中,DEBIT_ACCT 权限不仅用到 <permission> 元素进行了声明,在使用的时候还要用 <uses-permission> 元素进行申请。 即使保护措施是由本应用程序施加的,使用权限时也必须提出申请,这样应用程序的其他组件才可以启动这个受保护的 Activity 。

在示例中,如果 permission 属性设置为其他地方声明过的权限(比如 android.permission.CALL_EMERGENCY_NUMBERS ), 那就不必再用 <permission> 元素进行声明了。不过,为了申请使用,还是要用到 <uses-permission> 元素进行声明。

<permission-tree> 元素为一组权限声明了一个将由代码定义的命名空间。 <permission-group> 为一组权限定义了一个文本标签(包括 Manifest 中 <permission> 元素声明的和其他地方声明的权限)。 这只是在向用户显示时才会有用,决定了权限的分组显示。 <permission-group> 元素并不指定组中包含哪些权限,它只是给出权限组的名称。 要把权限放入某个组中,只要给 <permission> 元素的 permissionGroup 属性赋值为权限组名称即可。

每个应用程序都会链接默认的 Android 库,其中包含了建立应用程序的基础包 (类似 Activity、Service、Intent、View、 Button、Application、ContentProvider 等的常用类)

然而,某些包是位于默认库之外的。 如果应用程序用到了这些包中的代码,就必须显式地请求链接这些库。 Manifest 必须包含一个 <uses-library> 元素,以便给出库的名称。(库名称可以在包的文档中找到。)