1.1 介绍应用的Manifest
每个Android项目都包含一个manifest文件,AndroidManifest.xml,被放在项目的根目录中。这个manifest让你定义应用的结构和元数据,以及他的组件和相关要求。
他包括每个组成你应用的组件(Activities,Services,Content Providers,和Broadcast Receivers等),使用Intent过滤器和权限设定,他可以确认组件之间是是如何交互的。
manifest也支持提供应用的属性设定以及元数据的指定,同时最高级别的节点被用作安全设置,单元测试、和定义硬件和平台支持需求,如下所述:
manifest 由一个<manifest>的根标签和一个package属性组成。他通常包括一个xmlns:android命名空间属性,用来在文件中提供系统属性。
使用VersionCode属性去定义当前应用的版本,需要是一个整型数字。这个值内部被用来比较应用的版本号。使用VersionName属性可以去指定一个公共的版本号,用来展示给用户。
一个典型的manifest 节点如下所示:
<manifest xmlns:android=http://schemas.android.com/apk/res/android
package="com.my_domain.my_app"
android:versionCode="1"
android:versionName="0.9 Beta">
[ ... manifest nodes ... ]
</manifest>
<manifest>标签包括的节点定义了应用的组件、安全设置、测试类和一些组成你应用的必要属性值。下边列举了一些可用的<manifest>节点标签,并用一个XML片段展示了每个如何被使用:
1.1.1 uses-sdk
这个节点允许你定义最小、最大以及目标SDK版本号这些在设备上必须可用,以保证你应用功能能正常执行。使用minSDKVersion,maxSDKVersion和targetSDKVersion属性,你能够约束你应该运行的平台以及SDK的版本号。
最小的SDK版本指定了最低的SDK版本以及使用的API的版本。如果你没有指定一个最小版本号,那么当你访问当前设备上没有的API,应用就会崩溃。
最大SDK版本号的定义限制你想支持的平台以及SDK版本,这个一般在google的应用市场上不可见。一个较好的实践经验就是不设置这个属性值,除非你知道你的应用肯定不会在一个更高的版本上运行。
目标SDK的版本属性让你指定了特定的平台,这个平台是你用来测试和开发的。设置这个就是告诉系统在这个指定的版本上不需要考虑兼容性测试。
<uses-sdk android:minSdkVersion="4"
android:targetSdkVersion="5">
</uses-sdk>
注意:支持的SDK版本号不是平台版本号,这个没啥关联。例如,Android的2.0平台支持SDK的版本号是5.我们可以通过如下链接去找到对应关系:http://developer.android.com/guide/appendix/api-levels.html
1.1.2 uses-configuration
使用uses-configuration节点去指定应用支持的每个组件的输入机制。你可以指定的组件输入设备包括:
· reqFiveWayNav:设定为true的时候,设备是能够进行上、下、左、右的导航,并且能点击选中的部分。这个包括trackball 和D-pads。
· reqHardKeyboard:设定为true的时候,说明应用需要硬件的键盘支持
· reqKeyboardType:让你指定键盘的类型,可以是下列之一nokey,qwerty,twelvekey 或者undefined
· reqNavigation:属性值有nonav,dpad,trackball,whell,或者定义为undefined,这样就是要求有导航的设备。
· reqTouchScreen:属性值有 notouch,stylus,finger,或者定义为undefined,这样就是要求有触摸屏输入。
你可以指定多种支持的配置,例如一个设备支持touchscreen,trackball或者要求有十二个键的硬件键盘,显示如下:
<uses-configuration android:reqTouchScreen=["finger"]
android:reqNavigation=["trackball"]
android:reqHardKeyboard=["true"]
android:reqKeyboardType=["qwerty"/>
<uses-configuration android:reqTouchScreen=["finger"]
android:reqNavigation=["trackball"]
android:reqHardKeyboard=["true"]
android:reqKeyboardType=["twelvekey"]/>
注意:当你指定了上边的配置项就意味着你的应用运行的设备必须支持上述选型,否则就安装不上。很显然这个uses- configuration节点不是必选项。
1.1.3 uses-feature
Android的一个最大的长处是能在多种硬件平台上运行。使用uses-feature节点去指定你的应用需要的硬件特性。这个能帮助你避免将应用安装在不合适的平台上。在兼容性设备上,你可以要求对硬件支持做可选性操作。当前硬件支持的可选性包括
· android.hardware.camera :针对那些需要照相机硬件的应用
· android.hardware.camera.autofocus:如果你需要一个自动对焦的相机,可以选择这个
Android被越来越多的平台使用,所以硬件的可选性较多,我们可以通过以下的链接找到uses-feature在各个硬件平台上的支持:http://developer.android.com/guide/topics/manifest/uses-feature-element.html
你也可以使用uses-feature节点去指定一个应用需要的最小版本号的OpenGL。使用glEsVersion属性,指定OpenGL ES版本值。前十六位代表最大数值,后边的16位代表最小数值。
<uses-feature android:glEsVersion=" 0x00010001" android:name="android.hardware.camera" />
1.1.4 supports-screens
这个节点标签就是让你指定你的应用能支持的屏幕大小和不能支持的屏幕大小。具体的像素取决于硬件,但是一般来讲,支持屏幕的大小可以分为如下几类:
smallScreens
较小的屏幕,比传统的HVGA还小
normalScreens
常被用来指定为典型的手机屏幕,至少为HVGA,包括WVGA和WQVGA
largeScreens
比普通屏幕要大,这种情况下,一个大屏经常被认为比一般的手机显示器大明显大很多。
anyDensity
如果你的应用能够自适应大小的话,可以设置为true
小结
SDK1.6(API 版本为4),对每个值的默认属性都是true,可以使用这个节点去指定你不支持的屏幕大小。
<supports-screens android:smallScreens=["false"]
android:normalScreens=["true"]
android:largeScreens=["true"]
android:anyDensity=["false"] />
备注:你应该利用resources文件夹尽可能的优化你的应用去适应不同的屏幕大小以及分辨率。如果你指定了supports-screen节点不支持一定的屏幕,那么你的应用将不能被安装在不支持的屏幕的设备上。
1.1.5 application
一个manifest文件只能包含一个application节点。他使用属性值去指定应用的元数据(包括标题、图标和主题)。在开发阶段,你应该设定debugable属性为true去开启调试,在正式发布的时候,将这个属性设置为false。
<application>节点扮演了一个容器的角色,他包含了Activity,Service,Content Provider,和Broadcast Receiver标签,这些标签用来指定应用的组件。你也可以定义你的应用实现类。这章之后的部分将让你料及额如何创建和使用应用类的扩展去管理应用的状态。
<application android:icon="@drawable/icon"
android:theme="@style/my_theme"
android:name="MyApplication"
android:debuggable="true">
[ ... application nodes ... ]
</application>
activity
<activity>标签是每个应用的必选项。使用android:name属性去指定Activity的类名。
你必须包含最核心的加载Activity和其他能用来显示的屏幕或者对话框。去启动一个没有被定义在manifest中的Activity将会抛出一个运行时异常。每个Activity节点支持<intent-filter>子标签,用来指定哪个Intents来启动这个Activity。
<activity android:name=".MyActivity" android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
service
和activity标签类似,我们需要为应用中的每个Service类创建一个service标签。Service标签也支持<intent-filter>子标签去允许运行时绑定。
<service android:enabled="true" android:name=".MyService"></service>
provider
Provider标签指定了你应用中的每个Content Providers.Content Provider常被用作应用间数据库访问管理和数据共享,我们会在第七章中详细论述。
<provider android:permission="com.paad.MY_PERMISSION"
android:name=".MyContentProvider"
android:enabled="true"
android:authorities="com.paad.myapp.MyContentProvider">
</provider>
receiver
通过增加一个receiver标签,你不需要加载你的应用就可以注册一个Broadcast Receiver。就如你在第五章中将看到的,Broadcast Receivers更像是一个全局的事件监听器,一旦注册了,当匹配上一个被系统或应用触发了的Intent,就会执行。通过在manifest中注册一个Broadcast Receiver你可以让进程完全自动应答。如果一个被匹配的Intent被广播,你的应用就会自动启动,并且注册了的Broadcast Receiver将会自动运行。
<receiver android:enabled="true"
android:label="My Intent Receiver"
android:name=".MyIntentReceiver">
</receiver>
1.1.6 uses-permission
作为安全模型的一部分,uses-permission标签声明了你的应用需要获取的权限。这些应用需要的权限将在用户安装前声明中提示给用户。很多本地的Android服务的调用权限是很必要的,特别是那些容易带来成本和安全意义上的权限(例如打电话和接收短信或者使用位置定位服务等)
<uses-permission android:name="android.permission.ACCESS_LOCATION"/>
1.1.7 permission
在提供访问和共享应用组件之前,第三方应用也可以定义自己组件的访问权限。在你能定义应用的访问权限之前,你需要在manifest中定义一个权限(permission)。使用permission标签去创建一个permission定义。
随后应用组件可以通过增加 android:permission属性标签要求访问权限。其他的应用如果要访问这些组件,就需要定义uses-permission标签在他们的manifest文件中。
在permission标签中,你可以指定允许访问的权限(可选值:normal,dangerous,signature,signatureOrSystem),一个标签,和一个外部资源的调用描述,以此解释访问带来的风险。
<permission android:name="com.paad.DETONATE_DEVICE"
android:protectionLevel="dangerous"
android:label="Self Destruct"
android:description="@string/detonate_description">
</permission>
1.1.8 instrumentation
Instrumentation 类为你的应用组件在运行时提供了测试框架。他们提供了钩子函数去监控你的应用和他们与系统资源的交互。为你的应用的每个测试类创建一个新节点。
<instrumentation android:label="My Test"
android:name=".MyTestClass"
android:targetPackage="com.paad.aPackage">
</instrumentation>
1.1.9 小结
针对manifest的每个节点的更加详细的描述,你可以在如下站点找到:
http://developer.android.com/guide/topics/manifest/manifest-intro.html
当你用ADT新项目向导创建项目时,会自动创建一个manifest文件。