用AndroidStudio开发Android工程的时候,是用gradle管理构建的。gradle里有很多配置,很多时候我们对这些配置其实是一知半解的。比如minSdkVersion,compileSdkVersion,targetSdkVersion,就不一定能分清分别是什么意思,有什么区别。

配置

这三个配置一般是在项目主module的build.gradle里。

  1. android {
  2. compileSdkVersion 23
  3. buildToolsVersion '25.0.0'
  4. defaultConfig {
  5. applicationId "com.xxx.xxx"
  6. minSdkVersion 14
  7. targetSdkVersion 23
  8. versionCode 1
  9. versionName "1.0"
  10. }
  11. ...

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会提示报错。
image.png
这种情况有两种应对:

  • 升级minSdkVersion到 >= 引入新api的api level
  • 如果用老的api也可以满足需求,可以不升级minSdkVersion,在运行时根据当前api level选择不同的api。比如:
    1. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
    2. view.setBackground(bg);
    3. } else {
    4. view.setBackgroundDrawable(bg);
    5. }

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越高越能应用新的系统特性。