关于Android SDK里的compileSdk、minSdk

本篇文章介绍了Android SDK更新的包里关于compileSdk、minSdk、targetSdk、buildTools、Tools、Platform-tools的概念

0 前言

在开发中经常发现有AS有更新提示,在之前没有完全弄明白这些SDK,Tools的概念前都不敢轻易去更新,总担心更完就编译出错,API不能用==情况。所以对这几个概念进行深度梳理。
1 参考文章

国外一篇很清楚的关于compileSdk、minSdk、targetSdk的文章,建议看完译文后再重新看一遍原文

原文:
picking-your-compilesdkversion-minsdkversion-targetsdkversion

译文:
如何选择 compileSdkVersion, minSdkVersion 和 targetSdkVersion

关于tools的解释:
Android关于buildToolVersion与CompileSdkVersion的区别
2 compileSdk、minSdk、targetSdk到概念

以下内容摘自译文
2.1 compileSdkVersion

compileSdkVersion 告诉 Gradle 用哪个 Android SDK 版本编译你的应用。使用任何新添加的 API 就需要使用对应 Level 的 Android SDK。

需要强调的是 修改 compileSdkVersion 不会改变运行时的行为 。当你修改了 compileSdkVersion 的时候,可能会出现新的编译警告、编译错误,但新的 compileSdkVersion 不会被包含到 APK 中:它纯粹只是在编译的时候使用。(你真的应该修复这些警告,他们的出现一定是有原因的)

因此我们强烈推荐 总是使用最新的 SDK 进行编译 。在现有代码上使用新的编译检查可以获得很多好处,避免新弃用的 API ,并且为使用新的 API 做好准备。

注意,如果使用 Support Library ,那么使用最新发布的 Support Library 就需要使用最新的 SDK 编译。例如,要使用 23.1.1 版本的 Support Library ,compileSdkVersion 就必需至少是 23 (大版本号要一致!)。通常,新版的 Support Library 随着新的系统版本而发布,它为系统新增加的 API 和新特性提供兼容性支持。
2.2 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 标记,但请做彻底的测试!

当你决定使用什么 minSdkVersion 时候,你应该参考当前的 Android 分布统计,它显示了最近 7 天所有访问 Google Play 的设备信息。他们就是你把应用发布到 Google Play 时的潜在用户。最终这是一个商业决策问题,取决于为了支持额外 3% 的设备,确保最佳体验而付出的开发和测试成本是否值得。

当然,如果某个新的 API 是你整个应用的关键,那么确定 minSdkVersion 的值就比较容易了。不过要记得 14 亿设备中的 0.7% 也是个不小的数字。
2.3 targetSdkVersion

三个版本号中最有趣的就是 targetSdkVersion 了。 targetSdkVersion 是 Android 提供向前兼容的主要依据,在应用的 targetSdkVersion 没有更新之前系统不会应用最新的行为变化。这允许你在适应新的行为变化之前就可以使用新的 API (因为你已经更新了 compileSdkVersion 不是吗?)。

targetSdkVersion 所暗示的许多行为变化都记录在 VERSION_CODES 文档中了,但是所有恐怖的细节也都列在每次发布的平台亮点中了,在这个 API Level 表中可以方便地找到相应的链接。

例如,Android 6.0 变化文档中谈了 target 为 API 23 时会如何把你的应用转换到运行时权限模型上,Android 4.4 行为变化阐述了 target 为 API 19 及以上时使用 set() 和 setRepeating() 设置 alarm 会有怎样的行为变化。
由于某些行为的变化对用户是非常明显的(弃用的 menu 按钮,运行时权限等),所以将 target 更新为最新的 SDK 是所有应用都应该优先处理的事情。但这不意味着你一定要使用所有新引入的功能,也不意味着你可以不做任何测试就盲目地更新 targetSdkVersion ,请一定在更新 targetSdkVersion 之前做测试!你的用户会感谢你的。
3 buildTools、Tools、Platform-tools

buildTools、Tools、Platform-tools这3个东西其实都是开发工具,即它的版本更新并不会影响运行的APP,只是工具上的升级。

在 build.gradle 中的 buildToolsVersion 版本号一般是API-LEVEL.0.0,其中API-LEVEL要大于等于compileSdkVersion。

在前面的compileSdkVersion解释中建议选用最新的SDK Version,so,buildToolsVersion也建议选择最新的版本号。build.gradle中这2个的修改可以让你体验最新的API和工具。

至于Tools、Platform-tools这2个东西,直接更新最新吧。Only 工具。
总结

经过上面的深入了解后,总结以下:

当AS提示Gradle或者Android SDK更新后,大胆更新吧,先全部下载下来
更新完后,直接将compileSdkVersion、buildToolsVersion修改为最新的版本号,放心的更改,该完后如果有废弃API编译器还会给你提示。
minSdkVersion 和 targetSdkVersion 要慎重修改。除非核心代码中会提高minSdkVersion的版本号,其他的建议运行时判断版本号。targetSdkVersion的修改要注意代码是否适应更新后的版本号,要测试完全,最典型的例子就是23版本的运行时权限问题的处理。如果targetSdkVersion提升到了23,如果代码没有进行运行时权限判断会直接崩溃。

来源:https://juejin.im/post/59c4bfa9f265da06456d7905

---------------------------

Picking your compileSdkVersion, minSdkVersion, and targetSdkVersion

Depending on the time of the year, it might only be a few months after you release an app that a new version of Android is announced. What does that mean for your app though — is everything going to break?

You’ll be happy to know that forward compatibility is a strong focus of Android — existing apps built against prior SDKs should not break when the user updates to a new version of Android. This is where compileSdkVersion, minSdkVersion, and targetSdkVersion come in: they control what APIs are available, what the required API level is, and what compatiblity modes are applied, respectively.

根据一年中的不同时间,可能只有几个月后,你发布了一个新版本的Android。但这对你的应用程序意味着什么——一切都会崩溃吗?

你会高兴地知道,前向兼容性是Android的一个强大的重点-现有的应用程序建立在以前的SDK不应该打破当用户更新到一个新版本的Android。这就是compileSdkVersion、minSdkVersion和targetSdkVersion的作用:它们分别控制可用的API、所需的API级别以及应用的兼容模式。

compileSdkVersion

compileSdkVersion is your way to tell Gradle what version of the Android SDK to compile your app with. Using the new Android SDK is a requirement to use any of the new APIs added in that level.

It should be emphasized that changing your compileSdkVersion does not change runtime behavior. While new compiler warnings/errors may be present when changing your compileSdkVersion, your compileSdkVersion is not included in your APK: it is purely used at compile time. (You should really fix those warnings though — they were added for a reason!)

compile SDK version是告诉Gradle使用哪个版本的Android SDK编译应用程序的方法。使用新的Android SDK需要使用该级别中添加的任何新api。

应该强调的是,更改compileSdkVersion不会更改运行时行为。虽然在更改compileSdkVersion时可能会出现新的编译器警告/错误,但APK中不包括compileSdkVersion:它仅在编译时使用。(你真的应该修复那些警告-它们是有原因添加的!)

Therefore it is strongly recommended that you always compile with the latest SDK. You’ll get all the benefits of new compilation checks on existing code, avoid newly deprecated APIs, and be ready to use new APIs.

Note that if you use the Support Library, compiling with the latest SDK is a requirement for using the latest Support Library releases. For example, to use the 23.1.1 Support Library, you must have a compileSdkVersion of at least 23 (those first numbers need to match!). In general, a new version of the Support Library is released alongside a new platform version, providing compatibility shims to newly added APIs as well as new features.

因此,强烈建议您始终使用最新的SDK进行编译。您将获得对现有代码的新编译检查的所有好处,避免新未被推荐的API,并准备使用新API。

请注意,如果使用支持库,则使用最新的SDK编译是使用最新支持库版本的要求。例如,要使用23.1.1支持库,CompilesDK版本必须至少为23(第一个数字必须匹配!)。通常,新版本的支持库与新平台版本一起发布,为新添加的API和新功能提供兼容性垫片。

minSdkVersion

If compileSdkVersion sets the newest APIs available to you, minSdkVersion is the lower bound for your app. The minSdkVersion is one of the signals the Google Play Store uses to determine which of a user’s devices an app can be installed on.

It also plays an important role during development: by default lint runs against your project, warning you when you use any APIs above your minSdkVersion, helping you avoid the runtime issue of attempting to call an API that doesn’t exist. Checking the system version at runtime is a common technique when using APIs only on newer platform versions.

如果compileSdkVersion为您设置了可用的最新api,那么minSdkVersion是应用程序的下限minSdkVersion是Google Play商店用来确定应用程序可以安装在哪个用户设备上的信号之一。

它在开发过程中也起着重要的作用:默认情况下,LIT对您的项目运行,当您在MIDSDKVIEW上使用任何API时警告您,帮助您避免试图调用不存在的API的运行时问题。当只在较新的平台版本上使用api时,在运行时检查系统版本是一种常见的技术。

Keep in mind that libraries you use, such as any of the Support Libraries or Google Play services, may have their own minSdkVersion — your app’s minSdkVersion must be at least as high as your dependencies’ minSdkVersion — if you have libraries that require 4, 7, and 9, your minSdkVersion must be at least 9. In rare cases where you want to continue to use a library with a higher minSdkVersion than your app (and deal with all edge cases/ensure the library is only used on newer platform versions), you can use the tools:overrideLibrary marker, but make sure to test thoroughly!

When deciding on a minSdkVersion, you should consider the stats on the Dashboards, which give you a global look on all devices that visited the Google Play Store in the prior 7 days — that’s your potential audience when putting an app on Google Play. It is ultimately a business decision on whether supporting an additional 3% of devices is worth the development and testing time required to ensure the best experience.

Of course, if a new API is key to your entire app, then that makes the minSdkVersion discussion quite a bit easier. Just remember that even 0.7% of 1.4 billion devices is a lot of devices.

请记住,您使用的库(如任何支持库或Google Play服务)可能有自己的minSdkVersion-应用程序的minSdkVersion必须至少与依赖项的minSdkVersion一样高-如果您有需要4、7和9的库,则minSdkVersion必须至少为9。在极少数情况下,如果您希望继续使用比应用程序的minsdk版本更高的库(并处理所有边缘情况/确保库仅用于较新的平台版本),则可以使用工具:overrideLibrary marker,但请确保进行彻底测试!

在决定minsdk版本时,您应该考虑仪表板上的统计数据,这些数据可以让您全面了解在过去7天访问过Google Play商店的所有设备—这是您在Google Play上安装应用程序时的潜在受众。这最终是一个业务决策,决定是否支持额外3%的设备,值得开发和测试所需的时间,以确保最佳体验。

当然,如果一个新的API是整个应用程序的关键,那么minSdkVersion的讨论就简单多了。只要记住,14亿台设备中有0.7%都是大量设备。

targetSdkVersion

The most interesting of the three, however, is targetSdkVersion. targetSdkVersion is the main way Android provides forward compatibility by not applying behavior changes unless the targetSdkVersion is updated. This allows you to use new APIs (as you did update your compileSdkVersion right?) prior to working through the behavior changes.

Much of the behavior changes that targetSdkVersion implies are documented directly in the VERSION_CODES, but all of the gory details are also listed on the each releases’ platform highlights, nicely linked in the API Levels table.

不过,这三个版本中最有趣的是targetSdkVersion。targetSdkVersion是Android提供前向兼容性的主要方式,它不应用行为更改,除非更新了targetSdkVersion。这允许您使用新的api(就像您正确地更新了compileSdkVersion一样?)在完成行为改变之前。

targetSdkVersion所暗示的许多行为更改都直接记录在版本代码中,但每个版本的平台突出显示中也列出了所有可怕的细节,并在API Levels表中进行了很好的链接。

For example, the Android 6.0 changes talk through how targeting API 23 transitions your app to the runtime permissions model and the Android 4.4 behavior changes detail how targeting API 19 or higher changes how alarms set with set() and setRepeating() work.

With some of the behavior changes being very visible to users (the deprecation of the menu button, runtime permissions, etc), updating to target the latest SDK should be a high priority for every app. That doesn’t mean you have to use every new feature introduced nor should you blindly update your targetSdkVersion without testing — please, please test before updating your targetSdkVersion! Your users will thank you.

例如,Android 6.0的更改通过目标API 23如何将应用程序转换到运行时权限模型以及Android 4.4的行为更改详细说明目标API 19或更高版本如何更改使用set()和setRepeating()设置的警报的工作方式。

由于某些行为更改对用户非常可见(菜单按钮的不推荐、运行时权限等),更新到最新的SDK应该是每个应用程序的高优先级。这并不意味着您必须使用所有引入的新功能,也不应在未经测试的情况下盲目更新targetSdkVersion-请在更新targetSdkVersion之前进行测试!你的用户会感谢你的。

Gradle and SDK versions

So setting the correct compileSdkVersion, minSdkVersion, and targetSdkVersion is important. As you might imagine in a world with Gradle and Android Studio, these values are integrated into the tools system through inclusion in your module’s build.gradle file (also available through the Project Structure option in Android Studio):

因此,设置正确的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”
  }
}

The compileSdkVersion, being a compile time thing (who would have guessed!), is one of the android settings alongside with your build tools version. The other two are slightly differently in that they are declared at the build variant level — the defaultConfig is the base for all build variants and where’d you put default values for these, but you could imagine a more complicated system where specific versions of your app have a different minSdkVersion for example.

minSdkVersion and targetSdkVersion also differ from compileSdkVersion in that they are included in your final APK — if you were to look at the generated AndroidManifest.xml, you’d see a tag such as:

compileSdkVersion,是一个编译时的东西(谁会猜到!),是与生成工具版本一起使用的android设置之一。另外两个稍微有点不同,因为它们是在构建变量级别声明的——defaultConfig是所有构建变量的基础,您在哪里设置了这些变量的默认值,但是您可以想象一个更复杂的系统,例如,您的应用程序的特定版本具有不同的minSdkVersion。

minSdkVersion和targetSdkVersion也不同于compileSdkVersion,它们包含在最终的APK中—如果您查看生成的AndroidManifest.xml,您将看到一个标记,如:

<uses-sdk android:targetSdkVersion=”23" android:minSdkVersion=”7" />

You’ll find if you manually put this in your manifest, it’ll be ignored when you build with Gradle (although other build systems might certainly rely on it being there).

如果手动将其放入清单中,则在使用Gradle构建时会忽略它(尽管其他构建系统可能肯定依赖于它)。

If you made it through the bolded notes, you’ll notice a relationship between the three values:

如果您是通过粗体注释完成的,您会注意到三个值之间的关系:

minSdkVersion <= targetSdkVersion <= compileSdkVersion

This intuitively makes sense — if compileSdkVersion is your ‘maximum’ and minSdkVersion is your ‘minimum’ then your maximum must be at least as high as your minimum and the target must be somewhere in between.

Ideally, the relationship would look more like this in the steady state:

这直觉上是有意义的——如果编译器是你的“最大值”,而MimSDKVIEW是你的“最小值”,那么你的最大值必须至少和你的最小值一样高,目标必须介于两者之间。

理想情况下,这种关系在稳定状态下更像这样:

minSdkVersion (lowest possible) <= 
    targetSdkVersion == compileSdkVersion (latest SDK)

You’ll hit the biggest audience with a low minSdkVersion and look and act the best by targeting and compiling with the latest SDK — a great way to #BuildBetterApps.

Join the discussion on the Google+ post and follow the Android Development Patterns Collection for more!

你将以一个低minsdk版本来吸引最大的读者,并且通过使用最新的SDK进行目标定位和编译来表现出最佳的外观和行为,这是一个很好的构建betterapps的方法。

加入Google+帖子的讨论,跟随Android开发模式集合获取更多信息!

来源: https://medium.com/androiddevelopers/picking-your-compilesdkversion-minsdkversion-targetsdkversion-a098a0341ebd