用AndroidStudio开发Android工程的时候,是用gradle管理构建的。gradle里有很多配置,很多时候我们对这些配置其实是一知半解的。比如minSdkVersion,compileSdkVersion,targetSdkVersion,就不一定能分清分别是什么意思,有什么区别。
配置
这三个配置一般是在项目主module的build.gradle里。
android {
compileSdkVersion 23
buildToolsVersion '25.0.0'
defaultConfig {
applicationId "com.xxx.xxx"
minSdkVersion 14
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
...
minSdkVersion
minSdkVersion表示的是这个app最低可以运行在什么api level对应的系统上。如果当前手机android系统的api level低于指定的minSdkVersion,那尝试安装的时候系统会阻止安装。如果没有设置默认是1。
minSdkVersion is the lower bound for your app
因为android sdk不断更新的版本可能会加入新的api,我们开发的时候可能会用到新加入的api。比如用到了api level 16引入的一个方法,如果忘了设置minSdkVersion导致用了默认值1,或者设置了比16低的值,那在运行到这个地方的时候,app就会因为系统找不到这个方法crash。
上面提到的这种情况,其实在AS里写代码的时候静态代码检查工具lint会提示报错。
这种情况有两种应对:
- 升级minSdkVersion到 >= 引入新api的api level
- 如果用老的api也可以满足需求,可以不升级minSdkVersion,在运行时根据当前api level选择不同的api。比如:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
view.setBackground(bg);
} else {
view.setBackgroundDrawable(bg);
}
compileSdkVersion
compileSdkVersion告诉gradle要用什么版本的sdk编译我们的app。
如果新的android sdk里加了一些新的api,我们想要使用的话,就要把compileSdk升级。google建议我们尽量使用最新的api level作为compileSdkVersion。
如果使用了Support library,compileSdkVersion要和Support library版本中的大版本号一致。
选择不同的compileSdkVersion只影响编译,不会影响运行时的行为。运行时的行为其实是实际运行的设备的系统版本和targetSdkVersion决定的。
targetSdkVersion
因为我们的app发布出去之后,可能会被装在各种版本的系统上,targetSdkVersion表示的是我们期望app在不同版本上表现得跟在targetSdkVersion对应的版本上一样。如果没有设置默认等于minSdkVersion。
targetSdkVersion 是 Android 提供向前兼容的主要依据
怎么理解呢?因为随着系统的升级,同样的api,在老系统和新系统上的表现可能会不一样,又或者默认的主题不一样。而指定了targetSdkVersion的话,如果app在更新的系统上运行,系统会在运行时检查app指定的targetSdkVersion,保证在新系统和上跟老系统表现一样,也可以避免出现一些问题。
一个常见的例子是,android在6.0后引入了动态权限,有些被定义为Dangerous Permission的权限,需要在app运行时用到的时候申请。而6.0以前,app声明需要的所有权限都会在app安装时候直接授权。如果我们还没有针对动态权限申请做适配,可以暂时保持targetSdkVersion在23(android 6.0对应的api level)之下,这样,app在6.0及以上的系统安装的时候,还是会授予全部权限。要是targetSdkVersion升到了23代码里没有适配,app运行到需要权限的地方会抛出exception,可能会导致crash。
总结
上面分别说了这个配置的作用,有两个要注意的点
- minSdkVersion不设置默认1
- android:targetSdkVersion不设置默认等于minSdkVersion
一般来说,这三个值的大小关系应该如下:
minSdkVersion (越低越好) <= targetSdkVersion == compileSdkVersion (跟随最新系统)
minSdkVersion越低就能覆盖越多用户,targetSdkVersion和compileSdkVersion越高越能应用新的系统特性。