「本文已参与好文召集令活动,点击查看:后端、大前端双赛道投稿,2万元奖池等你挑战!」
在安卓开发项目的build.gradle
配置文件中,一共可以定义四种不同的SdkVersion,这里就对于它们的使用场景和异同来做一个简单的比较和总结。
minSdkVersion
Defines the minimum API level required to run the app
这个比较容易理解,minSdkVersion
就是安卓项目所支持的最低SDK版本,也就是可使用的Android API的最低版本。举个例子,如果minSdkVersion = 24,也就是Android 7,那么在Android 6或以下的设备上运行这个APP就会报错并出现:the minimum accepted SDK version of your app is Android 7
提示。
minSdkVersion
的另外一个作用就是通过Link检查可以获得关于当前使用的更高版本的Android API的提示。比如当minSdkVersion = 24时,如果在代码中调用一个Android 11才引入的新的函数,编译器会警告并且要求在代码前添加一个SDK版本检查的逻辑,示例代码:
private fun setUpActionBar() {
// 保证在安卓版本11及以上才能调用setDisplayHomeAsUpEnabled()方法
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
actionBar.setDisplayHomeAsUpEnabled(true)
}
}
除此之外值得注意的是,如果项目的多个依赖库(dependency library)所规定的minSdkVersion
不相同,APP的minSdkVersion
要以依赖库中minSdkVersion
最高的那个为准。这个也很好理解,如果你的项目有三个依赖库,分别定义的最低SDK版本是20, 22, 24,那么项目本身的minSdkVersion
必须是24或以上,就是一个向下兼容的问题。
maxSdkVersion
和minSdkVersion
类似,maxSdkVersion
就是安卓项目所支持的最高SDK版本,但是安卓平台本身是完美向下兼容的,所以这个参数一般不做任何设置。当然一旦设置了之后,在高于maxSdkVersion
版本号的设备上运行时,项目会报错或无法安装。
complieSdkVersion
compileSdkVersion specifies the Android API level Gradle should use to compile your app. This means your app can use the API features included in this API level and lower.
从这里开始就稍微复杂一点。compileSdkVersion
从字面来看就是告诉编译器你的安卓项目会在哪个Android版本上去进行编译。最重要的一点就是:compileSdkVersion
只定义编译时(compile time)的版本号,它对于运行时(runtime)的行为没有任何影响。那么它影响什么呢?其实它主要影响的是使用某个版本开始引入的API的情况。同样举例说明,如果一个API在Android X版本被引入,那么你只能在compileSdkVersion
等于或高于X时使用这个API。根据Google官方文档的介绍,Google强烈建议把compileSdkVersion
设置在最新的版本,原因包括:
- 可以对已有代码进行更新的编译检查(you will get all benefits of new compilation checks on existing code);
- 可以避免使用将会被弃用的API(avoid using newly deprecated API);
- 可以使用新版本引入的API(ready to use any new API)。
另外要说明的一点就是:如果安卓项目中使用了Android Support library,那么complieSdkVersion
必须要大于等于support library的主版本号(版本号第一个数字)。例如你的项目使用的Android Support库的版本是23.1.1,那么complieSdkVersion
至少是23及以上才能通过编译。如果项目使用了AndroidX库,那么complieSdkVersion
至少需要是28及以上才能通过编译。
targetSdkVersion
最后一个,也是最有意思的一个,就是targetSdkVersion
。上面说到compileSdkVersion
不影响运行时(runtime)的行为,而targetSdkVersion
正相反,它影响的就是运行时(runtime)的行为。从字面来看它指的就是你的安卓项目是以哪个Android版本作为目标来进行开发的。
举例说明,在Android 6(SDK版本号23)中引入了运行时应用权限管理(runtime permission check)机制,如果你的项目设置targetSdkVersion
是22或以下,那么系统就会知道你的APP是面向22或更低的版本来编写的。此时如果项目运行在Android 6的设备上,系统依旧会开启运行时应用权限管理的特性,但是是由系统完全进行接管和进行处理的。通过这种方式,可以保证低版本的项目运行在高版本的设备上时,可以使用新的版本特性,并且不需要关注行为变更。
所以既然不影响使用新特性以及向后兼容,那么targetSdkVersion
是不是可以一直保持在一个很低的版本不更新呢?事实上Google推荐开发者随时保持targetSdkVersion
版本号的更新,因为版本号过低的话可能会导致应用市场拒绝上架。此外,在更新targetSdkVersion
之后一定要进行一系列完整的测试,以保证行为变更不会造成任何影响。
SdkVersion比较
这里对除了maxSdkVersion(用得实在太少)以外的三种版本号进行一个比较和总结:
默认值 | 是否保存在最终生成APK内 | 声明位置 | |
---|---|---|---|
minSdkVersion | 1 | 是 | android -> defaultConfig |
compileSdkVersion | None(必须在build.gradle中声明) | 否 | android |
targetSdkVersion | minSdkVersion | 是 | android -> defaultConfig |
所以理想情况下,项目的版本号之间应该存在以下的关系:
minSdkVersion(越小越好) <= targetSdkVersion == compileSdkVersion(保持最新SDK版本)
更小的minSdkVersion
版本号可以让你的项目支持更多不同版本的设备,而更高的compileSdkVersion
版本号可以随时获得新的API和新的特性,也会更容易对项目进行维护。
总结
刚接触安卓开发时,我对于build.gradle
配置文件中出现的这四种SDK版本号总是觉得含糊不清,一头雾水,所以就去查阅了Google的官方文档和其他博客文章,想较为全面完整的对它们的异同进行一个比较,加深自己的理解,这也就是这篇文章的全部目的了,希望能对你有所帮助。
参考文章
Google Android Developer Doc - SDK Versions
Google Manifest <uses-sdk> tag
Picking your compileSdkVersion, minSdkVersion, targetSdkVersion