原文链接:http://android.eoe.cn/topic/android_sdk
每一个应用程序在工程的根目录下必须要有一个AndroidManifest.xml文件(一定要用这个名称)。这个清单文件向安卓系统提供关于该应用的重要信息,这些信息在它运行任何应用代码之前是必须要有的。除了其他方面,清单文件执行以下操作:
:* 它列出了应用程序的包名。这个包名充当这个应用程序的唯一的标识符。
:* 它描述了这个应用程序的组件 :活动、服务、广播接收者和内容提供者。它列举了每一个组件的级别和这些组件所具有的能力(例如,它们能操作哪一类意图)。这些声明让安卓系统知道这些组件具体是哪个及在什么样的条件下它们能被启动。
:* 它决定了哪个进程将会使用这些应用组件。
:* 它声明了应用程序一定要有的权限,如果打算访问API受保护的部分或者与其他程序进行交互。
:* 它也声明了其他应用程序需要访问这个应用程序组件的权限。
:* 它列出了Instrumentation类,这个类提供了程序运行时候的性能分析和其他信息。这些声明要存在于清单中,仅当这个应用程序正在被开发和测试,在发布应用程序之前应该将它们移除掉。
:* 它声明了这个应用程序的最小的Android API级别。
:* 它列出了这个应用程序一定会被链接到的库。
:下图展示了清单的通用结构和它能包含的每一元素。每一元素与它们的属性一起被记录在一个单独的文件中。为了观察到每一元素的详细信息,点击图中每一元素的名字,跟随下图中的字母列表元素,或者其他任何提及到的元素名。
<?xml version"utf-8"?>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
<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 /> </provider> <uses-library /> </application>
|
:所有这些元素可能出现在清单文件的,按照字母顺序全被列出在下面。这些是唯一合法的元素,你不能添加你自己元素或属性。
:[http://docs.eoeandroid.com/guide/topics/manifest/permission-tree-element.html]
:
:
清单中普遍适用于所有的元素和属性的一些约定和规则。
:如果一个元素包含任何东西,它当然也能包含其他元素。所有的值都是通过设置属性,而不是仅将字符数据放在一个元素中。
:同一等级的元素通常都是无序的。例如、 和元素能以任意顺序混杂在一起。(元素是这一规则的一个特例:它必须跟在该别名所指的之后。)
:除了元素中的一些属性,所有的属性名字都是以android:作为前缀。例如android:alwaysRetainTaskState.因为这个前缀是通用的,当提及到属性名时,这篇文档通常省略它。
:如果你定义一个子类,跟组件类(Activity,Service,BroadcastReceiver,和ContentProvider)一样,这个子类通过一个name的属性来声明。这个名字必须包含完整的包名。例如,一个Service子类可能会被像下面声明:
:然而,为了简写,如果字符串的第一个字符是一个点号“.”,这个字符串被附加到这个应用程序的包名上(例如通过元素的package属性指定)。下面的写法跟上面一个一样的.
:当启动一个组件时,安卓会创建这个被命令的子类的实例。如果没有指定子类,它会创建一个基类的实例。
::@[package:]type:name
:如果资源在同一个应用的同一个包中,包名可以被省略。type是资源的类型----例如"string"或者"drawable"。name是用来标识特定资源名。例如:
:一个主题的值的也是以一个类似的方式来表示,但是是以?开头而不是以@。
::?[package:]type:name
以下几段描述一些安卓特性是如何反映在清单文件上。
应用程序的核心组件(活动,服务,广播接收者)通过Intents被激活。一个意图是一捆的信息(一个Intent对象),这些信息描述了一个请求动作——包括有用的数据,用来执行动作的组件的类别,和其他相关的指令。安卓找到一个合适的组件来响应这个意图,启动一个新的组件实例,如果需要的话,并传递这个意图对象。
组件公布它们的能力--各种各样的它们能响应的意图--通过意图滤波器。由于安卓系统在启动一个组件之前必须了解这个组件能操作哪种意图,意图滤波器要在清单中的中被指定。一个组件可能有许多滤波器,每一个都描述一种不同的能力。
一个意图显式的命名一个目标组件将会激活那个组件;这时滤波器不扮演任何角色。(滤波器无效)。
但是一个意图不指明目标时,只有通过一个组件的滤波器时,才能激活这个组件。
关于一个意图对象怎样通过意图滤波器的测试,查看单独的文档:Intents and Intent Filters
许多元素都有icon和label属性,这些属性是为了向用户展示一个小的图标或者一个文本标签。一些也有一个description 属性,这个属性是为了在屏幕上能显示一些长的说明文本。例如元素有这三个属性,所以当用户被问及请求的应用程序是否授权,一个表示权限的图标,权限的名称,和一个描述它的细节都会被呈现给用户。
在任何情况下,设置在一个包含元素里的图标和标签会成为该容器所有子元素的缺省设置。因此元素里的图标和标签是每一个应用程序组件的缺省图标和标签。同样地,为一个组件设置的图标和标签——例如元素——是这个组件的元素的缺省设置。如果一个元素设置一个标签,但是一个活动和它的意图滤波器没有设置,这个应用程序的标签被当作是这个活动和意图滤波器的标签。
这个意图滤波器的图标和标签集被用来表示一个组件,无论何时这个组件通过一个滤波器来为用户实现这个功能。例如,一个带有"android.intent.action.MAIM"和"android.intent.category.LAUNCHER"设置的活动将会启动一个应用----那就是,作为一个应该在启动栏中被显示的应用。滤波器中的这个图标和标签集因此也会在启动栏中被显示。
权限是一种约束。限制对部分代码或者设备的数据的访问。这种限制用于保护关键数据和代码,这些东西有可能会被滥用
进而扭曲和损害用户的体验。
每一个权限被唯一的标签所标识。通常标签声明约束的动作。例如,这里有一些安卓系统定义的权限:
:android.permission.CALL_EMERGENCY_NUMBERS
:android.permission.READ_OWNER_DATA
:android.permission.SET_WALLPAPER
:android.permission.DEVICE_POWER
一个特性可以被至多一个权限所保护。
如果一个应用程序需要访问一个受保护的特性,它必须在清单中用元素声明,以表明它需要这个权限。这样,当这个程序被安装到设备上时,安装器决定是否授予请求的权限,通过检测相关权限,这些权限被应用程序的认证书所证明。在一些情况下,会询问用户。如果权限被授予,这个应用程序将有能力去访问这些受保护的特性。否则,它将尝试去访问那些特性,将会失败用不会给用户任何通知。
应用程序也能用权限来保护它自己的组件(活动,服务,广播接收者和内容提供者)。它可以使用安卓所定义的任何权限(在android.Manifest.permission列出来了)或者通过其他应用来声明。或者自己定义。一个新的权限通过元素来声明。例如,一个活动可以用下面方式保护:
注意,在这个例子中,DEBIT_ACCT权限不仅仅被元素声明,它还需要在元素中声明。为了应用程序的其他组件可以启动这个受保护的活动,必须请求它的权限,即使这个保护是应用程序自己引入的。
同一个例子中,如果permission属性已经在别处声明了(例如android.permission.CALL_EMERGENCY_NUMBERS),那么不必再次在元素中声明它。但还要在来声明。
元素为将被定义在代码中的一组权限声明一个命令空间。
声明为一组权限(用声明的那些或者在别处声明的那些)定义一个标签。它只影响权限怎样分组,当展示给用户的时候元素并不指定哪个权限属于这一组;它仅仅给这个组一个名字。一个权限要被放入这一组中,是通过分配这一组的名字给元素的permissionGroup属性。
每一个应用程序被链接到默认的安卓库,这个库包含创建应用程序的基本包(有公共类如:活动,服务,意图,视图,按钮,应用,内容提供者等等)。
然而,一些包拥有它自己的库。如果你的应用程序使用这些包中的代码,则必须显式地声明来链接它们。这时清单一定要包含一个独立的元素来标记每一个库(这个库名能在包中的文件中找到。)