Manifest 文件
—————————————————————————————————————————————————————————————————————————————
在Android系统启动一个应用程序的部件之前,系统必须通过阅读该应用程序的AndroidManifes.xml文件来确定该部件是存在的。应用程序必须在该文件中声明其所有的部件。该文件位于应用程序工程目录的根目录下。
除了声明应用程序的部件之外,该文件中还有其它的信息:
- 标明了应用程序所需的用户许可,比如访问或者是读取用户的通讯录。
- 声明了应用程序所需的最小API的级别。
- 声明了应用程序所需的硬件和软件特性,比如摄像头,蓝牙,服务,或者是多点触控屏幕。
- 应用程序所需的了出Android框架提供的API之外的其它API库。比如 Google Maps library(谷歌地图库)
- 其它一些信息
声明部件
manifest文件的首要任务就是告诉系统应用程序有哪些部件。例如,manifest文件中可以声明如下的活动:
- <?xml version="1.0" encoding="utf-8"?>
- <manifest ... >
- <application android:icon="@drawable/app_icon.png" ... >
- <activity android:name="com.example.project.ExampleActivity"
- android:label="@string/example_label" ... >
- </activity>
- ...
- </application>
- </manifest>
在<activity>元素中,属性android:name阐明了Activity派生类的全名;属性android:label阐明了该活动的可见的标签字符串。
所有的应用程序部件都必须以如下的方式进行声明:
- <activity> 元素用来声明活动
- <service> 元素用来声明服务
- <receiver> 元素用来声明广播接收器
- <provider> 元素用来声明内容提供者
在代码中的活动,服务以及内容提供者如果没有在manifest文件中进行声明,则它们对于系统来说就是不可见的,因此也是不会运行的。然而,广播接收器是既可以在manifest文件中进行声明,又可以在代码中动态创建的(作为BraodcastReceive对象),并通过registerReceiver()向系统注册的。
更多关于应用程序中manifest文件结构的信息,请参阅文档:AndroidManifest.xml 文件。
声明部件的能力
正如我们在前面讨论的那样,在“激活部件”小节中,我们说到可以使用Intent来启动活动,服务和广播接收器。我们可以通过在Intent中明确指定目标部件的名称(使用部件类的名称)来达到启动部件的目的。然而,intents的真正能力在于intent action。使用intent action,我们只要描述期望王城的动作(action),而让系统来查找设备上可以完成该动作的部件并启动之。如果在设备上存在多个可以完成指定intent中动作(action)的部件,那就由用户来选择使用哪个部件。
系统判断部件是否能响应intent的方式就是把接收到的intent和设备上的其它程序的manifest文件中提供的intent filters(意图过滤器)进行比较。
当我们在应用程序的manifest文件中声明部件的时候,我们可以选择性的声明部件能力,以便部件可以对其它应用程序的intents做出响应。为应用程序声明意图过滤器是通过在部件声明中增加<intent-filter>子元素来完成的。
例如,就电子邮件程序来说,在其manifest文件中,有声明用于编辑邮件的活动,可以通过其子项来声明一个intent filter,以便响应“发送(send)”意图,也就是发送电子邮件。这样,我们的程序就可以创建一个带有动作为“send”的intent,而系统则会将电子邮件程序和send活动相匹配上,从而在我们调用startActivity()并传入该intent的时候启动电子邮件程序。
更多关于创建intent filter的信息,请参阅Intents and Intent Filters 文档。
声明应用程序的要求
搭载Android系统的设备数量众多,并不是全部的Android设备都能提供相同的特性和拥有相同的能力。为了避免应用程序被安装在缺少该应用程序所需特性的设备上,明确地定义应用程序所支持的设备类型的档案文件就显得十分重要。这点就是通过在manifest文件中声明设备和软件要求来完成的。这种声明在大多数情况下只是提供了一种信息,而系统并不会去阅读这些信心,但是一些诸如Google Play的外部的服务确实会读取这些信息,以便在用户查找设备上的应用程序的时候提供过滤功能。
例如,如果我们的应用程序要求设备拥有摄像头,并且使用的是Android 2.1版本的API,那么我们就应该在manifest文件中对此要求进行声明。这样,Google Play 就不会在不满足这些要求的设备上安装我们的应用程序。
然而,我们可以声明应用程序会使用摄像头,但是这不是必须的。此时,应用程序必须在运行时进行检查,判断设备是否有摄像头,以便决定是否需要显示使用摄像头的那些程序特性。
以下是一些重要的设备特征,我们应该在设计和开发应用程序把这些设备特征都考虑进去:
屏幕大小和密度
为了能够根据屏幕大小来对设备进行分类,Android为每个设备都定义了两种特征:屏幕大小(也就是屏幕的物理尺寸)和屏幕密度(屏幕上像素的密度,或者是dpi,即每英寸上的点数)。为了简化针对不同类型屏幕的配置,Android系统将不同类型的屏幕泛化为不同的组,以方便适配。
屏幕的大小划分为:小,一般,大,特大。
屏幕目的划分为:低密度,中等密度,高密度和特高密度。
缺省情况下,应用程序是和所有大小和密度的屏幕保持兼容的,这是因为Android系统对软件的UI布局和图像资源都进行了适当的调整。然而,在manifest文件中可以使用 <supports-screens> 元素来为某个指定大小的屏幕创建特殊的布局和为某个指定密度的屏幕提供特定的图像,也就是针对性地使用另外的布局。
更多信息,请参阅 Supporting Multiple Screens 文档。
输入配置
众多的Android设备提供了多种的输入方式。如物理键盘,轨迹球或者是五向导航板。如果我们的应用程序需要某种特定的输入硬件,那么我们应该在manifest文件中使用 <uses-configuration> 元素来对其进行声明。然而,应用程序需要特定的输入配置的情况是很少见的。
设备特性
对于某个指定的Android设备,可能有多个硬件或者软件特性在该设备上是没有的,比如摄像头,光感应器,蓝牙或者是某个指定版本的OpenGL,或者是指定叫你精度触控屏。我们不应该认为某个特性在所有的Android设备上都是存在的,因此我们应该在manifest文件中使用<user-feature>元素来声明应用程序所需的特性。
平台版本
不同的Android设备通常都是运行的不同版本的Android平台,比如,Android 1.6 或者是Android 2.3。每一个后续的版本中都含有之前版本中不曾含有的API。为了标明那个版本的API可能,每个平台版本中都标明了API级别。如果我们使用了任何在版本1.0之后增加的API,那么我们就应该使用<users-sdk>元素对引入声明引入了这些API的最小的API级别。
很重要的一点是:这些要求的声明都是为了我们自己的应用程序。这是因为当我们在Google Play上发布我们的应用程序时,应用商店使用这些声明来就每个设备对应用程序进行过滤。这样,我们的应用程序就只能在那些满足其要求的设备上才是可用的。
更多关于Google Play是如何基于这些要求来过滤应用程序的信息,请参阅Filters on Google Play 文档。