android:minSdkVersion
- 如果 compileSdkVersion 设置为可用的最新 API,那么 minSdkVersion 则是应用可以运行的最低要求,限制用户设备的最低版本号。minSdkVersion 是 Google Play 商店用来判断用户设备是否可以安装某个应用的标志之一。
- 在开发时 minSdkVersion 也起到一个重要角色:lint 默认会在项目中运行,它在你使用了高于 minSdkVersion 的 API 时会警告你,帮你避免调用不存在的 API 的运行时问题。如果只在较高版本的系统上才使用某些 API,通常使用“运行时检查系统版本”的方式解决。
- 请记住,你所使用的库,如 Support Library 或 Google Play services,可能有他们自己的 minSdkVersion 。你的应用设置的 minSdkVersion 必须大于等于这些库的 minSdkVersion 。例如有三个库,它们的 minSdkVersion 分别是 4, 7 和 9 ,那么你的 minSdkVersion 必需至少是 9 才能使用它们。在少数情况下,你仍然想用一个比你应用的 minSdkVersion 还高的库(处理所有的边缘情况,确保它只在较新的平台上使用),你可以使用 tools:overrideLibrary 标记,但请做彻底的测试!
- 那么实际开发中怎么确定这个属性呢?最佳情况当然越小越好,因为这个数值越大能兼容的设备就越少!但也要看当前Android市场的版本分布,比如现在有90%以上的设备都在Andorid4.0以上 ,那么设为14,当然如果有新的API项目中非用不可,那这个值直接调整增大即可。
- 还有个问题,比如Android6.0新增了权限判断,我们的项目如果想加入权限判断,难道android:minSdkVersion 要调整为23吗,要是这样的话那没多少用户能装我们的app了! 这时候就需要support-library了。
minSdkVersion属性对app啥影响呢
举个例子:比如checkSelfPermission(检查权限)这个方法是API 23加入的,OK,把compileSdkVersion =23,如果android:minSdkVersion<23,会报错但是不影响编译
项目成功编译,运行在Android6.0的手机,没问题。
运行在Android4.4的手机,打开直接崩溃,报错信息为:Method NotFound,找不到这个方法,这是Android6.0才加入的方法,运行在Android4.4的系统环境肯定找不到啦。
怎么办呢? Android官方给出两种解决办法:
第一种,如果这个API对你很重要,费用不可,那么将android:minSdkVersion调到这个API需要的版本吧
第二种,这个API可以不用,或者你有替代办法,那android:minSdkVersion越小越好,可以在sdk版本运行时检查
private void checkPermission(){
if(Build.VERSION.SDK_INT>=23){
checkSelfPermission("");
}else {
// do something
}
}
android:compileSdkVersion
- compileSdkVersion 告诉 Gradle 用哪个 Android SDK 版本编译你的应用。使用任何新添加的 API 就需要使用对应等级的 Android SDK。
- 需要强调的是修改 compileSdkVersion 不会改变运行时的行为。当你修改了 compileSdkVersion 的时候,可能会出现新的编译警告、编译错误,但新的 compileSdkVersion 不会被包含到 APK 中:它纯粹只是在编译的时候使用。(你真的应该修复这些警告,他们的出现一定是有原因的!)
- 因此我们强烈推荐你总是使用最新的 SDK 进行编译。在现有代码上使用新的编译检查可以获得很多好处,避免新弃用的 API ,并且为使用新的 API 做好准备。
注意,如果使用 Support Library ,那么使用最新发布的 Support Library 就需要使用最新的 SDK 编译。例如,要使用 23.1.1 版本的 Support Library,compileSdkVersion 就必需至少是 23 (大版本号要一致!)。通常,新版的 Support Library 随着新的系统版本而发布,它为系统新增加的 API 和新特性提供兼容性支持。
这个属性设置的越大被废弃的方法就越多,当然我们就能最早接触到新增的api。实际开发中compileSdkVersion一般设置为最成熟用户量最多的Android版本,比如现在的6.0或者5.0版本
android:targetSdkVersion
三个版本号中最有趣的就是 targetSdkVersion 了。 targetSdkVersion 是 Android 提供向前兼容的主要依据,在应用的 targetSdkVersion 没有更新之前系统不会应用最新的行为变化。这允许你在适应新的行为变化之前就可以使用新的 API (因为你已经更新了 compileSdkVersion 不是吗?)。
targetSdkVersion 是 Android 系统提供前向兼容的主要手段。这是什么意思呢?随着 Android 系统的升级,某个系统的 API 或者模块的行为可能会发生改变,但是为了保证老 APK 的行为还是和以前兼容。只要 APK 的 targetSdkVersion 不变,即使这个 APK 安装在新 Android 系统上,其行为还是保持老的系统上的行为,这样就保证了系统对老应用的前向兼容性。
targetSdkVersion 所暗示的许多行为变化都记录在 VERSION_CODES 文档中了,但是所有恐怖的细节也都列在每次发布的平台亮点中了,在这个 API Level 表中可以方便地找到相应的链接。
比如说,在Android 6.0(targetSdkVersion=23)以后,Android提供了权限管理的功能,危险权限不仅需要在Manifest.xml文件中声明,还需要在代码运行过程中动态向用户申请。
那如果我设置了targetSdkVersion=22呢?
那就无视了Android 6.0提供的权限管理的功能,无论是一般权限还是危险权限,依旧只需要在Manifest.xml文件中声明,不需要在代码运行过程中动态向用户申请。
这就给了开发者适应新的行为变化的时间,避免在开发者做代码修改及充分测试前,高级版本系统上运行之前的应用有可能出现的兼容性问题。
所以Google说,targetSdkVersion是Android提供向前兼容的主要依据。
如果说Android 6.0新增了权限管理功能,会成为开发者升级targetSdkVersion的动力的话(毕竟保护用户的隐私安全是开发者需要关注并付诸于行动的),那么Android 4.4对闹钟API的行为的调整,也许会成为某些应用的开发者拒绝升级targetSdkVersion的原因。
在Android 4.4(API 19)以后,Android调整了AlarmManager的set()和setRepeat()两个API的行为:
在Android4.4以前,这两个API设置的时间都是精确的时间,Android系统需要更多的耗电才能保证闹钟唤醒的时间够精确;
而在Android4.4以后,Android为了降低耗电,系统会将这两个API设置的时间处理成不精确的时间,也就是会在设置的时间之后的某个时刻进行唤醒。
虽然API没有发生变化,但行为已经发生了变化。
那如果应用是一个闹钟类型的应用,十分需要在精确时间唤醒呢?相信这个应用的开发者会倾向于拒绝升级targetSdkVersion到19吧。
当然,Google还是建议开发者优先将targetSdkVersion更新到最新版的SDK的。
最后,要强调的一点是:如果修改了targetSdkVersion,一定要进行充分测试!至于测试应用的哪些部分,我想自然是应用中与targetSdkVersion升级区间内发生变化的功能和API行为的部分了。
Gradle 和 SDK 版本
所以设置正确的 compileSdkVersion, minSdkVersion 和 targetSdkVersion 很重要。如你所想,Gradle 和 Android Studio 都在构建系统中集成了它们。在你的模块的 build.gradle 文件中(也可以在 Android Studio 的项目结构选项中)设置:
android {
compileSdkVersion 23
buildToolsVersion "23.0.1"
defaultConfig {
applicationId "com.example.checkyourtargetsdk"
minSdkVersion 7
targetSdkVersion 23
versionCode 1
versionName “1.0”
}
}
编译时用到的 compileSdkVersion 是和构建工具版本一起设置的 Android 设置之一。其他两个稍有不同,他们在构建变体(build variant)的那里声明。defaultConfig 是所有构建变体的基础,也是设置这些默认值的地方。你可以想象在一个更复杂的系统中,应用的某些版本可能会有不同的 minSdkVersion 。
minSdkVersion 和 targetSdkVersion 与 compileSdkVersion 的另一个不同之处是它们会被包含进最终的 APK 文件中