Manifest文件
每一个应用在其根目录下必须包含一个AndroidManifest.xml文件(必须是这个名字)。这个manifest描述应用程序在android系统中必要的信息,这些信息在每一个应用程序代码运行之前必须配备。除了其他情况,manifest介绍如下:
- manifest里面注册了应用程序的Java的包名。这个包名是应用程序唯一的标识。
- manifest描述了应用程序的组件——应用程序中包含的活动(Activity),服务(Service),广播接收者(broadcast receiver),和内容提供者(content provider)。在该文件中注册了实现了这些组件的类的名字并且公开他们的功能(例如,什么样的Intent消息它们可以处理)。这些声明使得Android系统知道设么样的组件可以被启动或是在什么情况下它们被启动。
- manifest确定哪些进程将要掌管应用程序组件
- manifest声明了应用程序想要使用API中受保护的部分或与其他应用程序交互而必须拥有的权限。
- manifest也声明了其他应用程序想要与本程序组件交互所需要的权限
- manifest列出Instrumentation类,这些类提供了应用程序运行时的性能分析和其他的信息。
- manifest声明了应用程序所支持的Android API的最小版本。
- manifest列出了应用程序需要的库
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文件中的所有元素和属性:
-
元素(Elements)
- 仅在<manifest>和<application>两个标签中可以包含元素,这两个标签必须出现且必须仅出现一次。其他的标签大多数都会出现很多次或者不出现——尽管为了能够使manifest文件有意义至少他们中的一些标签必须出现。
-
如果一个元素包含了它的所有,它就包含了其他元素。所有的值都通过属性来设置,而不是通过在元素中的字符数据。
-
同一级别的元素通常没有顺序。例如<activity>,<provider>,和<service>元素可以可以在完全无序出现(但是<activity-alias>元素是一个例外:它必须跟随者以它化名的<activity>后面)。
属性(Attributes)
-
理论上来说,所有的属性都是可以选择的。然而,一些必须在指定的元素中来实现。对于真正的可以选择的属性来说,在空值的情况下使用一个默认值。
-
除了根元素的一些属性外,所有的属性名字前面都以一个“android:”前缀开始——例如"android:alwaysRetainTaskState"。由于前缀是普遍性的,在文档中忽略掉它直接引用其名。
声明类名
- 很多元素对应着Java对象,包括<application>标签和它的主要成分——<activity>,<service>, <receiver>, 和<provider>。
-
如果定义子类,你会经常去定义那些组件的子类(
Activity,service,broadcastReceiver和contentprovider
),这些子类通过一个名字属性声明。这个名字包含完整的包名。例如一个Service可以声明如下:
<manifest . . . > <application . . . > <service android:name="com.example.project.SecretService" . . . > . . . </service> . . . </application> </manifest>
还存在一种缩写形式,如果字符串的首字母是个点,那么这个字符串代表的追加到应用程序包名后的字符串(在<manifest>元素的包属性中指定的)。以下形式与上面等效。
<manifest package="com.example.project" . . . > <application . . . > <service android:name=".SecretService" . . . > . . . </service> . . . </application> </manifest>
-
当启动一个组件的时候,Android就会创建一个这样命名的子类的实例。如果子类没有被指定,就会创建一个父类实例。
多重值
-
如果多于一个的值被指定,元素通常被重复书写多次,而不是在一个元素当中罗列多个值。例如,一个intent filter可以写多个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的标签和图标。这些属性的值应该被定位,因此通过资源(resource)或主题(theme)来设定。资源值用以下格式表达:
@[package:]type:name
如果资源位于应用程序的同一个包内,那么包名可以被省略,type是一个资源的类型——如“string”或“drawable”——用名字来指定特定的资源。例如:
<activity android:icon="@drawable/smallPic" . . . >
来自一个主题(theme)的值可以用相同的方式表达,但是首字母用“?”而不用“@”:
?[package:]type:name
字符串值
-
如果一个属性值是一个字符串,双反斜杠
('
\\
')必须被用于转义——例如'\\n
'表示换行, '\\uxxxx
'表示Unicode字符。
文件特征
以下段落描述Android的特性如何被manifest文件所反映。
Intent Filters
一个应用程序的核心组件(它的activities, services, 和 broadcast receivers)是通过intent来激活的。一个intent是一个数据包(一个intent对象),它描述一个期望的行为——包括这些行为的数据和组件的类型。这些组件来执行这个行为和其他相关指令。Android会查找一个适当的组件来响应这个intent,如果有必要会创建一个该组件的新的实例,然后把它传递给intnet对象。
通过intent filter,组件公布他们的功能,使得等够识别intent的类别。由于在启动一个组件之前,Android系统必须知道这个组件能够处理什么样的intent,intnet filter被定义在manifest的<intent-filter>元素中。一个组件可以拥有任意数量个filter,每一个都描述一个不同的功能。
一个intent指明一个目标组件来激活它;这个filter并不扮演角色。但是仅当可以通过一个组件的filter来激活一个组件时,intent可以不通过名字来激活这个组件。
图标和标签
很多元素为小图标和文本标签提供了图标(icon)和标签(label
)属性,这些属性可以展示给用户。一些还为更长的注释文本提供了描述属性,这些属性也可以被显示在屏幕上。例如,<permission>元素拥有三个这样的属性,所以用户会被询问到是否授予应用程序这样的权限,包括代表权限的图标,权限的名字,和它需求的表述都会呈现给用户。
在任何情况下,图标(icon)和标签(label)已经被设置到了被包含的元素中,因为默认的图标和标签已经被设置到了所有的子元素中。那么,在<appplication>元素中的图标和标签已为每一个应用程序组件做了默认的设置。同样,组件的图标和标签亦是如此。——例如,一个<Activity>,元素——已为每一个组件的<intent-filter>元素做了默认设置。如果一个<application>元素设置了一个标签,但是一个activity和它的intent filter没有设置,这个应用程序标签就被用于所有的activity和intent filter。
intent filter的图标和标签集合用来表示一个组件,无论何时,这些组件都会暴露给用户来实现filter声明的方法。例如,一个filter带有"android.intent.action.MAIN
" 和"android.intent.category.LAUNCHER
"的设定,声明了一个activity来启动应用程序——那就是作为一个被展示在应用程序中的启动器。在filter中的图标和标签集合就在启动器中被展示。
权限
权限是一种对于进入部分代码或访问设备数据的限制。这个限制用来保护临界数据和代码,否则会损害用户体验。
每一种权限都有一个唯一的标识。这个标识指明被限制的动作。例如,Android中定义一些权限:
android.permission.CALL_EMERGENCY_NUMBERS
android.permission.READ_OWNER_DATA
android.permission.SET_WALLPAPER
android.permission.DEVICE_POWER
A feature can be protected by at most one permission.
一个特性可以通过权限得到最大程度的保护
如果一个应用程序试图通过权限来访问一个特性,它必须在manifest文件中的<uses-permission>元素中声明这种权限。然后,当应用程序安装到设备时,安装器通过检查权限和签名证书来决定是否授予这样的权限,别且有时会向用户询问。如果已被授权,应用程序就可以使用受保护的特性。否则,访问将失败别且不会通知用户。
一个应用程序也可以通过权限来保护自己的组件(activities, services, broadcast receivers, 和 content providers)。它可以使用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属性在permission的其他地方被声明(例如asandroid.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>元素来给每一个库命名。(库的名字可以在包的文档中找到)。
===================================================================================================================================
英语不大好,很多地方翻译的不准,见谅!!!