如何选择 compileSdkVersion, minSdkVersion 和 targetSdkVersion

本文介绍了Android开发中的关键概念:compileSdkVersion、minSdkVersion和targetSdkVersion。详细解释了每个版本的意义及其对应用的影响,帮助开发者更好地进行版本管理和兼容性控制。

英文原文:Picking your compileSdkVersion, minSdkVersion, and targetSdkVersion

作者:Ian Lake,Google Android 推广工程师;翻译:韩国恺。

blob.png

当你发布一个应用之后,(取决于具体的发布时间)可能没过几个月 Android 系统就发布了一个新版本。这对你的应用意味着什么,所有东西都不能用了?

别担心,向前兼容是 Android 非常关注的事情。用户在升级到新版 Android 的时候,用以前版本的 SDK 构建的现有应用应该不会出问题。这就是 compileSdkVersionminSdkVersion 和 targetSdkVersion 的作用:他们分别控制可以使用哪些 API ,要求的 API 级别是什么,以及应用的兼容模式。

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 和新特性提供兼容性支持。

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% 也是个不小的数字。

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 之前做测试!你的用户会感谢你的。

Gradle 和 SDK 版本

所以设置正确的 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”
  }
}

编译时用到的 compileSdkVersion 是和构建工具版本一起设置的 Android 设置之一。其他两个稍有不同,他们在构建变体(build variant)的那里声明。defaultConfig 是所有构建变体的基础,也是设置这些默认值的地方。你可以想象在一个更复杂的系统中,应用的某些版本可能会有不同的 minSdkVersion 。

minSdkVersion 和 targetSdkVersion 与 compileSdkVersion 的另一个不同之处是它们会被包含进最终的 APK 文件中,如果你查看生成的 AndroidManifest.xml 文件,你会看到类似下面这样的标签:

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

如果你在 manifest 文件中手工设置,你会发现 Gradle 在构建时会忽略它们(尽管其它构建系统可能会明确依赖它们)。

综合来看

如果你按照上面示例那样配置,你会发现这三个值的关系是:

minSdkVersion <= targetSdkVersion <= compileSdkVersion

这种直觉是合理的,如果 compileSdkVersion 是你的最大值,minSdkVersion 是最小值,那么最大值必需至少和最小值一样大且 target 必需在二者之间。

理想上,在稳定状态下三者的关系应该更像这样:

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

用较低的 minSdkVersion 来覆盖最大的人群,用最新的 SDK 设置 target 和 compile 来获得最好的外观和行为。#BuildBetterApps

关于本文的内容您可以参与我们 Google+ 帖子上的讨论,关注我们的 Android Development Patterns 信息流获得更多信息。

译者注: Android Development Patterns 系列视频见 YouTube 或 优酷 。

 

androiddeveloperpatterns

文章来源:http://chinagdg.org/ 

扩展阅读

<think> 我们注意到用户的问题中提到了“compatibleSdkVersion”,但在标准的Android开发中,通常并没有这个术语。用户可能是将“minSdkVersion”误写为“compatibleSdkVersion”。因此,我们将按照标准的三个版本来解释:compileSdkVersionminSdkVersion(即用户所说的compatibleSdkVersion)targetSdkVersion。 下面我们将详细解释这三个概念: 1. **compileSdkVersion**(编译SDK版本): - 含义:指定Gradle编译应用时使用的Android SDK版本。它决定了你在编译时可以使用的API级别。 - 作用:它仅影响编译过程,不会改变应用在设备上的运行行为。使用较高的编译版本可以让你使用新版本的API,但你必须确保你的代码不会调用高于minSdkVersion的API(除非做运行时检查)。 - 建议:通常建议使用最新的Android SDK版本作为编译版本,以便使用最新的编译检查优化。 2. **minSdkVersion**(最低兼容SDK版本,即用户提到的compatibleSdkVersion): - 含义:指定应用可以运行的最低Android版本(API级别)。例如,minSdkVersion设置为19(对应Android 4.4)意味着应用不能在低于Android 4.4的设备上安装。 - 作用:它决定了应用可以兼容的最老设备。当你使用高于minSdkVersion的API时,需要做运行时检查(使用Build.VERSION.SDK_INT)或使用支持库(AndroidX)。 - 选择:需要根据目标用户群体使用的设备分布以及应用功能需求来权衡。设置过低可能无法使用新API,设置过高会丢失一部分用户。 3. **targetSdkVersion**(目标SDK版本): - 含义:指定应用设计时所针对的Android版本。它告诉系统,你的应用已经针对该版本进行了测试,系统不需要启用向前兼容的行为。 - 作用:每个新版本的Android都会引入一些行为变更(比如权限模式、后台限制等)。当应用运行在高于targetSdkVersion的系统上时,系统会启用这些行为变更;而运行在低于targetSdkVersion的系统上时,系统会保持旧版本的行为以保证兼容性。 - 建议:通常设置为最新的稳定版本(但不要超过compileSdkVersion),这样可以利用最新的系统优化。 关系不等式:$$ \text{minSdkVersion} \leq \text{targetSdkVersion} \leq \text{compileSdkVersion} $$ 下面是一个典型的build.gradle配置示例: ```groovy android { compileSdkVersion 34 // 使用Android 14 (UpsideDownCake)的SDK编译 defaultConfig { minSdkVersion 21 // 支持Android 5.0 (Lollipop)及以上 targetSdkVersion 34 // 针对Android 14进行适配 } } ``` 注意:在实际项目中,我们通常使用变量来定义这些版本号,以便统一管理。 引用说明:以上内容参考了Android官方文档[^1]。 --- §§相关问题§§ 1. 如何决定应用的最低兼容SDK版本(minSdkVersion)以达到市场覆盖设备能力的平衡? 2. 将targetSdkVersion升级到最新版本时,通常需要关注哪些重大行为变更? 3. 为什么建议将compileSdkVersion设置为最新版本? 4. 如果应用需要使用的某个API在minSdkVersion之上,应该如何处理? </think> 在 Android 开发中,`compileSdkVersion`、`minSdkVersion`(您提到的 `compatibleSdkVersion` 可能是笔误) `targetSdkVersion` 是构建配置文件中的核心参数,它们共同控制应用的编译、兼容性运行时行为: ### 1. `compileSdkVersion`(编译 SDK 版本) - **含义**:指定用于编译应用代码的 Android SDK 版本 - **作用**: - 决定编译时可用的 API 工具链(如 Java 11 特性) - 仅影响编译过程,不影响应用在设备上的运行行为 - 使用新版本可访问最新 API(如 Android 14 的预测返回手势) - **最佳实践**:始终使用最新稳定版(如 `34`),避免过时 API 警告[^1] ### 2. `minSdkVersion`(最低兼容 SDK 版本) - **含义**:应用支持的最低 Android 系统版本 - **作用**: - 低于此版本的设备无法安装应用(如设为 `21` 则排除 Android 4.4 以下设备) - 使用更高版本 API 时需添加 `@RequiresApi` 注解或运行时版本检查 - 直接影响应用的市场覆盖率 - **计算公式**:覆盖率比例 ≈ $ \frac{\text{活跃设备中 ≥ minSdkVersion 的设备数}}{\text{总活跃设备数}} \times 100\% $ ### 3. `targetSdkVersion`(目标 SDK 版本) - **含义**:应用设计所针对的 Android 操作系统版本 - **关键作用**: - 触发新版系统的行为变更(如 Android 13 的通知权限) - 控制向前兼容性(系统会模拟旧版行为) - 影响应用商店推荐算法系统优化策略 - **示例**:设 `targetSdkVersion 33` 时: - Android 13+ 设备:启用新后台限制 - Android 12 及以下:保持旧行为 ```groovy // 标准配置示例 (build.gradle) android { compileSdkVersion 34 // 使用最新 SDK 编译 defaultConfig { minSdkVersion 23 // 支持 Android 6.0+(占全球设备 95%+) targetSdkVersion 34 // 适配 Android 14 新特性 } } ``` ### 三者关系 必须满足版本链式约束: $$ \text{minSdkVersion} \leq \text{targetSdkVersion} \leq \text{compileSdkVersion} $$ | 参数 | 影响阶段 | 设备影响 | 开发影响 | |---------------------|------------|--------------------------|--------------------------| | `compileSdkVersion` | 编译时 | 无 | 决定 API 可用性语法检查 | | `minSdkVersion` | 安装时 | 过滤不兼容设备 | 需处理 API 版本兼容逻辑 | | `targetSdkVersion` | 运行时 | 控制系统行为变更 | 需测试新版系统适配性 | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值