如何选择 compileSdkVersion, minSdkVersion 和 targetSdkVersion

Android系统在持续更新中,当Android系统发布了新版本后,之前的应用在新版本的系统上运行会不会出问题呢?

当然不会,向前兼容是软件行业需要持续关注的事情,Android自然也很重视。Android就是通过compileSdkVersion、minSdkVersion、targetSdkVersion保证着应用和不同版本Andorid系统的和谐相处的,三者的作用分别是控制可以使用哪些API、要求的最低版本API级别是多少,以及应用的兼容模式。

 

compileSdkVersion

compileSdkVersion指定了Grandle要采用哪个版本的Android SDK编译自己的应用,应用中使用的API级别不得高于编译用的SDK的版本。如果新增了高级别的API调用,那么编译用的SDK版本也要随之升高。

Google官方建议总是使用最新版的SDK编译自己的应用,这可以避免新弃用的API,也可以为后续更新的API调用做准备。

既然要保持编译用的SDK版本最新,就涉及到compileSdkVersion的修改问题。

需要注意的是:

(1)修改compileSdkVersion并不会改变运行时的行为

(2)不过可能会导致出现新的编译警告、编译错误。

作何理解?

(1)compileSdkVersion指定的是编译用的SDK版本,只在编译阶段起作用,不会被包含到APK中,所以说不会改变运行时行为。那运行时依赖哪个SDK版本呢?targetSdkVersion。

(2)既然都已经修改了编译时用的SDK了,那API的调用方法当然有可能发现变化,甚至有些API被弃用了,所以会出现编译警告、编译错误。错误是一定要解决的,警告也应该尽量修复,对技术精进有好处的。

除此之外,要说的另一点是Support Library,使用的Support Library的版本不得高于compileSdkVersion的版本。这个等同于上文提到的API版本不得高于compileSdkVersion的版本,因为Support Library本质就是额外增加的API库。

关于Support Library,可以看一下我的另一篇博文,相信会有更多的收获:Android Support Library v4、v7、v13

 

minSdkVersion

如果说compileSdkVersion可以设置为最新的API版本,那么minSdkVersion就是应用可以运行的最低要求了,换言之,在低于minSdkVersion的Android系统上无法安装此应用。

在选择使用哪个版本的minSdkVersion时,要考虑产品定位和应用的用户群体特点,这是一个商业决策问题。

Google官方文章中说“取决于为了支持额外 3% 的设备,确保最佳体验而付出的开发和测试成本是否值得”,我想要补充的是:取决于为了涵盖有可能存在也有可能不存在的3%的低版本Android系统的用户,却要牺牲某些低版本系统中无法使用的功能和特性,以及为了兼容低版本而增加的开发和测试成本是否值得。(ps:3%只是举例,比例高低取决于minSdkVersion以下版本系统的用户比例。)

如上所说,这是一个商业决策问题,不是开发者自己所应该决定的,建议与产品和运营的同事沟通后确定。

关于Support Library,也有一点需要补充的:Support Library也会有自己的minSdkVersion,应用设置的minSdkVersion不能低于Support Library的minSdkVersion。

 

targetSdkVersion

targetSdkVersion理解起来要稍微比compileSdkVersion和minSdkVersion困难一些,我对它的理解比较直接:比如说我设置了targetSdkVersion=22,那么23及23以后的所有新特性、新功能和API的新行为我统统无视,我只认22及22之前提供的功能和API行为。

比如说,在Android 6.0(targetSdkVersion=23)以后,Android提供了权限管理的功能,危险权限不仅需要在Manifest.xml文件中声明,还需要在代码运行过程中动态向用户申请。

那如果我设置了targetSdkVersion=22呢?

那就无视了Android 6.0提供的权限管理的功能,无论是一般权限还是危险权限,依旧只需要在Manifest.xml文件中声明,不需要在代码运行过程中动态向用户申请。

(关于Android 6.0权限管理相关的技术,可以看一下我的另一篇博文:Android 6.0的权限管理)

这就给了开发者适应新的行为变化的时间,避免在开发者做代码修改及充分测试前,高级版本系统上运行之前的应用有可能出现的兼容性问题。

所以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行为的部分了。

 

综合来看

相信各位不难发现三者之间的关系是:

minSdkVersion <= targetSdkVersion <=compileSdkVersion

按照Google的建议,理想上,在稳定状态下三者之间的关系是:

minSdkVersion <= targetSdkVersion ==compileSdkVersion

也就是说:用较低的minSdkVersion来覆盖最大的人群,用最新的SDK设置target和conpile来获得最好的外观和行为。

但是,我想说的是:一定不要在已经上线的应用中随随便便升级targetSdkVersion,尤其不要盲目将targetSdkVersion升级到最高版,不然为了适应新功能和API的新行为,你可能会需要修改很多已经成型的代码块以及进行许多的测试,甚至踩不少很少有人踩过的坑。

 

感谢:

Picking your compileSdkVersion, minSdkVersion, and targetSdkVersion

如何选择 compileSdkVersion, minSdkVersion 和 targetSdkVersion

Android targetSdkVersion 原理

你可能感兴趣的:(Android)