Android中<uses-sdk>属性和target属性分析
1. 概要
<uses-sdk> 用来描述该应用程序可以运行的最小和最大API级别,以及应用程序开发者设计期望运行的平台版本。通过在manifest清单文件中添加该属性,我们可以更好的控制应用在不同android 系统版本上的安装和兼容性体验问题。
(图 1)
如上图所示,<uses-sdk>通过minSdkVersion,targetSdkVersion,maxSdkVersion三个属性对应用安装兼容性方面进行控制。下面我们依次对这三个属性进行详细介绍。
2. minSdkVersion
该属性的作用主要体现在两个阶段,一个是在应用安装时,一个是在项目构建时。
2.1. 安装时作用
当安装应用的手机系统API level 小于 minSdkVersion的值时,将不能安装该应用。
minSdkVersion 用于指明应用程序运行所需的最小API level。如果不指明该属性,其默认值为1。如上图1中minSdkVersion =“8”,说明该应用在只能安装在大于等于android系统API level 为8(android2.2)的系统上。如果将该应用安装在API level 小于8的android系统上,系统会提示手机API level的版本太低,安装失败。
所以这里有一点需要引起我们注意,我们在开发时必须留意我们用到API 接口的版本。在定义minSdkVersion属性时,尽量要让minSdkVersion的值大于等于我们用到的API 接口的开始被支持的最低版本。这样可以让不支持该接口的android系统不能安装我们的应用,防止应用在一些手机上因兼容性问题而崩溃。
2.2.构建项目时作用
在程序中如果我们用到了高于minSdkVersion的值的API接口,Eclipse会自动报错提醒开发者。这里我们以getActionBar()这个接口为例,这个接口是在android 3.0(API leve 11)中出现的。我们通过设置minSdkVersion的值来查看程序中开发工具(Eclipse)对程序的检测。
- 如下图minSdkVersion = 8时,我们调用API level 为13的接口时Eclipse会自动报错提示开发者:
这里我们可以通过Eclipse 的修复提示选择Add@SuppressLIne “NewApi” 来对付编译错误,但是并不建议这样解决问题。这样虽然躲过了编译报错,能成功编译出apk文件,但是如果在低于android 3.0(API leve 13)系统的手机上安装该应用后运行可能就会出现程序崩溃现象(高于android 3.0(API leve 13)系统的手机上安装运行正常)。对于一个app来说与其在手机上出现崩溃,不如不让用户安装这个应用(个人观点),当然这里需要综合考虑新api的调用频率和场景进行综合判段。
这里采用Eclipse 的@SuppressLint(“NewApi”)方法防止报错提示。
在android 2.3(API level 9)系统上安装后运行时,应用出现崩溃现象。
- 这时我们可以考虑能用修改minSdkVersion的值来解决该问题,我们将minSdkVersion的值设置为11。
一切正常没有报错。这时在android系统版本小于android 3.0(API level 11) 时安装该应用时将不能安装;在android系统3.0以上正常安装运行。
2.3. 总结
从上面两点中我们已经看到了minSdkVersion的重要性。minSdkVersion不仅在程序安装时起作用,也会在项目构建时起作用。我们应该充分利用它的这两个作用,谨慎的设置其值,保证应用不会因为接口兼容问题在一些手机上运行时崩溃影响用户体验。
3. maxSdkVersion
标明可以运行你的应用的最高API Level版本。现在Google官方文档中已经建议不推荐使用这个属性了。
在android 1.5,1.6,2.0和2. 0. 1系统上安装应用或系统升级时,系统会检查这个值。在这两种情况下,如果应用设置的maxSdkVersion 值低于系统本身使用的API Level,系统将不会允许安装该应用;在系统升级后,新系统会重新校验这个值,如果新系统的API Level高于这个值,新系统会删除你的应用。在android 2. 0. 1(API level 6)系统后该属性作用已经失效,也建议不在使用该属性。
例如:
在android 2.3(API level 9)上安装该应用时,从下图可以看出maxSdkVersion 已经没有效果了,当系统API level大于maxSdkVersion也照样能安装该应用。
新版本系统基本上是完全兼容以前的老版本的,没有必要设置这个属性去阻止你的应用在新版本上安装;另外,如果你指定了这个属性,用户手机系统升级可能会删掉你的应用。所以这个属性完全没有必要设置的了,这可能也是Google推荐不再使用的原因吧。
4. targetSdkVersion
这个属性会告诉系统该应用已经在API level 为targetSdkVersion值的系统上进行了充分测试,如果系统的API level 和当前应用的targetSdkVersion一样,系统将不会启用兼容模式运行该应用,如果不设置其默认值将等于minSdkVersion的值。
如果平台的API Level高于你的应用程序中的targetSdkVersion属性指定的值,系统会开启兼容行为来确保你的应用程序继续你期望的形式来运行。例如,设置这个targetSdkVersion值为11或更高,当你的应用运行在Android3.0或更高的系统上时,系统会自动为你的应用使用新的默认主题(Holo主题),并且当运行在大屏幕的设备上时会禁用屏幕兼容模式(screen compatibility mode),因为支持了 API level11就暗示了支持大屏幕。一般情况下,应该将这个属性的值设置为最新的API level 值,这样的话就可以充分利用新版本系统上的新特性。Eclipse在生成项目时,默认将该值设置为最高。
Android版本更新时添加新特性详见:
http://developer.android.com/reference/android/os/Build.VERSION_CODES.html
如果平台的API Level低于你的应用程序中的targetSdkVersion属性指定的值时, 系统会开启兼容行为来确保你的应用程序能正常运行,这时一些在targetSdkVersion上的特性就没有了。但是,这个设置仅仅是一个声明、一个通知,在低版本系统中运行不会有太实质的作用。比如:使用了targetSdkVersion这个SDK版本中的一个特性,但是这个特性在低版本中是不支持的,那么在低版本的API设备上运行程序时,可能会报错:java.lang.VerifyError。也就是说,此属性不会帮你解决兼容性的测试问题。你至少需要在minSdkVersion这个版本上将程序完整的跑一遍来确定兼容性是没有问题的。
从上面的论述可知,targetSdkVersion这个属性是在程序运行时期起作用的,系统根据这个属性决定要不要以兼容模式运行这个程序。
5. target
Android工程中还有个target属性,这个属性位于Android工程根目录下project.properties中,从名字来看很容易将其功能和targetSdkVersion混淆。
其实他们的功能大相径庭:
- targetSdkVersion这个上面已经做过分析,在程序运行时起作用,系统根据这个属性决定要不要以兼容模式运行这个程序。
- project.properties中的target是指在编译的时候使用哪个版本的API进行编译。它和工程下导入的api包的API Level保持一致的。如果你更改target的值,上面的api包会跟着变化,你更改api包时target的值也会变化。