【转】http://www.cnblogs.com/xiaoxuetu/
1 前言
我们都知道,Android的版本在不断的迭代,并且每个版本都加入了不同的新特性。那么随着Android的用户量越来越多,Android的开发人员就必须熟悉Android各个版本的特性并且确保自己的应用能够正常运行在不同版本中。
由于Android的版本实在太多,开发人员的精力总是有限的,不可能一下子都能兼顾得到所有的版本,这个时候,我们就必须通过一种方式能够说明当前应用能够支持的最低Android版本、最高版本,同时系统能够自动获取到这些信息并且判断当前系统版本是否支持该应用,不支持的版本就不给予安装,避免用户安装后才发现不不支持带来的负体验。
当然,谷歌这个巨头肯定也考虑到了这方面的事情,所以就提供了<uses-sdk>标签,里面包含了minSdkVersion、targetSdkVersion、maxSdkVersion三个字段,本文会跟大家一起去学习了解。
示例代码:https://github.com/xiaoxuetu/gs-android/tree/master/gs-target-setting
官方文档:https://developer.android.com/guide/topics/manifest/uses-sdk-element.html#provisional
⚠️ 注意
附上示例代码,大家可以下载下来,使用Android Studio导入学习实践
2 什么是API Level
在讲解<uses-sdk>标签之前,我们一起来了解下API Leval究竟是什么东西?
按照官方的说法是:API Level是一个整数,是安卓系统中所使用的框架版本的唯一标识。它并不是我们开发时所使用的SDK版本,也不是指Android的版本,但是它和我们所使用的Android的版本却存在一定的对应关系。如下表中的Android 2.3 和 2.3.1 所使用的API Level 是 9,而2.3.3 所使用的API Level是10。
下图是来自谷歌官方文档的Android系统版本和API Level的对应关系
3 <uses-sdk>标签说明
<uses-sdk> 标签是在AndroidMainfest.xml文件中使用的,它的用法是:
1 <uses-sdk android:minSdkVersion="integer" 2 android:targetSdkVersion="integer" 3 android:maxSdkVersion="integer" />
此时需要注意的是:
过去我们使用Eclipse进行开发的时候,uses-sdk是需要我们直接在AndroidMainfest.xml进行声明的。
而如今我们使用的是Android Studio,同时我们是在app模块的build.gradle进行声明,在编译的时候将会自动生成到AndroidMainfest.xml中。大家可以直接打开gs-target-setting/app/build/intermediates/manifests/full/debug/AndroidMainfest.xml进行查看。
如果你直接在AndroidMainfest.xml声明了,那么编译的时候将会被忽略,同时会以build.gradle的为准重新生成覆盖原来的值。
好了,我们都知道uses-sdk标签里面总共包含了minSdkVersion、maxSdkVersion、targetSdkVersion三个属性,另外,当我们使用Android Studio后,我们创建的项目同时也是Gradle项目,里面会包含有compileSdkVersion和buildToolsVersion属性,接下来我们就一起来了解下这五个属性的作用和使用方式。
3.1 minSdkVersion
1> 作用一:指定应用运行时所需要的最小API Level
该属性主要用于指定该应用运行时所需要的最小API Level。如果我们不去特别指明的话,默认值为1,意思是该应用兼容所有的Android版本。
如果我们设置了应用运行时所需要的最小API Level,并且系统的API Level低于我们设置的minSdkVersion,那么Android系统将会拒绝该应用的安装。
下面我们将会举一个例子进行说明:
设备信息:
品牌 | 红米Note3 双网通 |
Android系统版本 | Android 5.0.2 |
API Level | 21 |
将github中的示例代码clone下来后,使用Android Studio,修改build.gradle中的minSdkVersion的值为21以上,比如22.然后点击运行的时候,编译后的安装包将无法安装到设备上,并且会有类似下图的提示
2> 作用二:Lint将会对项目进行静态代码检测,当项目中使用的API高于minSdkVersion,将会进行警告,避免在低版本中调用了不存在的API导致应用产生Bug。
下面我们也举一个例子进行说明
例如我们设置了minSdkVersion为1,那么我们在项目中调用了ActionBar(ActionBar是属于API Level为11提供的新API),IDE将会利用Lint进行检测并且提示我们调用了API Level为11才能调用的API
3.2 targetSdkVersion
该属性用于指定该应用的目标API Level,也是一个整数。如果我们不进行设置,那么targetSdkVersion默认值将会和minSdkVersion的值一样。
这个属性的作用是用于通知系统该应用已经针对这个API Level的Android版本进行过测试,系统不必再使用兼容模式来让应用程序向前兼容这个目标版本。当然,应用依然能够在低于targetSdkVersion的系统上正常运行。
如果平台的API Level高于你的应用程序中的targetSdkVersion属性指定的值,系统会开启兼容行为来确保你的应用程序继续以期望的形式来运行。
根据我们设置的targetSdkVersion 的值,系统会执行很多兼容行为。具体的兼容行为在对应平台版本的Build.VERSION_CODES(传送门)中有讨论。
一般情况下应该将这个属性的值设置为最新的API level 值,这样我们才可以利用新版本系统上的新特性。
下面举个例子来进行说明:
如果我们将targetSdkVersion的值设置为11甚至更高,当你的应用运行在Android3.0或更高的系统上时,系统会为你的应用使用新的默认主题(Holo主题),并且当运行在大屏幕的设备上时会禁用屏幕兼容模式(screen compatibility mode),因为支持了 API level 11就意味着支持大屏幕。
3.3 maxSdkVersion
该属性主要用于指定可以运行我们的应用的最高API Level版本。
根据谷歌官方文档的说明,
在Android1.5, 1.6, 2.0 和2.0.1,在安装应用或系统升级时,系统会检查这个值。此时会存在两种情况:
1> 如果应用设置的maxSdkVersion 值低于系统本身使用的API Level,系统将不会允许安装该应用
2> 在系统升级后,新系统会重新校验这个值,如果新系统的API Level高于这个值,新系统会删除你的应用
在高于2.0.1的系统上,安装应用时不会再检验应用中设置的maxSdkVersion值,在系统升级后也不会重新校验这个值。此时会存在以下两种情况:
1> 在Google Play中,将会继续使用这个属性进行过滤,不会将该应用展现在API Level高于maxSdkVersion的系统的可安装应用列表中。
2> 即使我们的应用设置了maxSdkVersion为9(Android 2.3),在Android 4.2的设备上,我们依然可以安装该应用。
⚠️ 注意
根据官方文档中的说明, 已经不再推荐使用这个属性。
3.4 compileSdkVersion
这并不是<uses-sdk>标签的属性,而是在们创建的Android Gradle项目中,必需在build.gradle声明并且赋值的属性。
compileSdkVersion的作用是指定用于编译我们应用的API Level对应的Android SDK。如果我们的应用中使用了新添加的API,就必须要使用和新添加的API对应Level的Android SDK。
compileSdkVersion并不会改变应用运行时的行为。当我们修改compileSdkVersion的时候,Android Studio将会出现一些编译警告、编译错误提示,我们要注意关注并且进行相应的修正。
根据官方文档的说明,强烈推荐我们使用最新版本的SDK进行编译,为使用新的特性做好准备。
⚠️ 注意
在ecplise的项目中,compileSdkVersion对应的是projects.properties中的target属性
例如我们在projects.properties中设置target=android-19,,就是使用sdk中platforms目录下android-19目录中的android.jar这个jar包编译项目。
3.5 buildToolsVersion
这个和compileSdkVersion一样,并不是<uses-sdk>标签的属性,而是在们创建的Android Gradle项目中,必需在build.gradle声明并且赋值的属性。
buildToolsVersion的作用是指定用于应用构建的工具版本,例如我们所熟悉的aapt、dx等等。这些工具的一般位于以下目录:
${ANDROID_SDK_HOME}/build-tools/${buildToolsVersion}
其中 ${ANDROID_SDK_HOME}表示我们的SDK所在的路径,${buildToolsVersion}表示我们所配置的buildToolsVersion的值
这里需要注意的是,buildToolsVersion并没有强制的要求,我们既可以使用新版本的构建工具来构建我们的低版本应用,也可以使用旧版本的构建工具来构建我们的高版本应用。
下面举个例子进行说明:
1> compileSdkVersion为19,buildToolsVersion为21.1.2,意思是使用高版本的构建工具来构建低版本的应用
2> compileSdkVersion为21,buildToolsVersion为19.1.0,意思是使用低版本的构建工具来构建高版本的应用
⚠️ 注意
在ecplise的项目中,buildToolsVersion对应的是projects.properties中的sdk.buildtools属性。
例如我们可以在project.properties中设置sdk.buildtools=19.1.0。也可以不设置,不设置的话就是指定最新版本。
4 总结
通过上面了解每个属性的作用后,我们将会发现minSdkVersion、targetSdkVersion、compileSdkVersion三个属性的关系如下:
minSdkVersion <= targetSdkVersion <= compileSdkVersion
理想状态下,minSdkVersion、targetSdkVersion、compileSdkVersion三个属性的关系如下:
minSdkVersion(越低越好) <= targetSdkVersion == compileSdkVersion(最新的API Level)
此时的好处是
1> 用较低的 minSdkVersion 来覆盖最大的人群
2> 用最新的 SDK 设置 target 和 compile 来获得最好的外观和行为,更好的利用新特性