最低SDK版本/目标SDK版本与编译SDK版本之间有什么区别?

342

"min sdk version/target sdk version"和"compile sdk version"有什么区别?我知道什么是最低版本号和目标版本号,但是编译SDK版本是什么意思?

在Eclipse中,我有最低/最高和目标SDK版本,但在Android Studio中有这三个设置。


我目前正在开发一个应用程序,其中我将TargetSdkVersion设置为12,然后所有的布局都无法正常工作,但是当我将其改回23时,它就像魔术般地运行了。因此,我认为TargetSdk版本必须始终与编译版本相同。 - Shahid Sarwar
7个回答

342
最小sdk版本是您的应用程序可以运行的Android SDK的最早版本。通常这是由于早期API存在问题,缺乏功能或其他行为问题所致。 目标sdk版本是您的应用程序被指定要运行的版本。理想情况下,这是因为某种最佳运行条件。如果您要“为19版制作您的应用程序”,那么这就是指定的地方。它可能在较早或较新的版本上运行,但这是您的目标。这主要是为了指示您的应用程序在市场等方面的当前性能。 编译sdk版本是当您发布一个.apk文件时,您的IDE(或其他编译方式)用来制作您的应用程序的Android版本。这对于测试应用程序非常有用,因为开发应用程序时编译应用程序是一个普遍的需求。由于这将是编译APK的版本,它自然会是您发布的版本。同样,建议将其与目标SDK版本匹配。

1
我的编译SDK版本和目标SDK版本相同,都是21。当我在低于该API级别的设备上运行应用时,它会崩溃。作为一名新手Android开发者,我现在该怎么办? - prgmrDev
2
@prgmrDev 如果您的应用程序在低于21版本的设备上崩溃,您应该将最小SDK版本设置为21。这实际上不会修复您的应用程序在低于21版本的目标上的问题,它只是说明您的应用程序不支持较低版本。您还可以选择确定是什么导致了应用程序崩溃(在21版本中发生了什么变化),并添加支持以解决该依赖关系,但我怀疑这将是很多工作,并且不在Android初学者项目的范围内。 - Matt
2
如果我将minSdkVersion设置为14,targetSdkVersion设置为23,并将编译SDK设置为19会发生什么? - thadeuszlay
9
@thadeuszlay,你的问题不相关,因为你应该想一想,如果你的目标是在版本23上运行,那么如何可能用19来编译它!请遵循公式minSdkVersion <= targetSdkVersion <= compileSdkVersion。 - Asad
1
@Matt,我使用compileVersion 26时是否可能意外使用了一个在版本21(即min sdk)上不支持的功能或Java API?抱歉,我对一些基本概念还不是很理解。 - haart
8
我理解不了 "The target sdk version is the version your application was targeted to run on" 的意思。因为我不会针对特定的API级别,我必须让我的应用程序在多种API级别的设备上正常运行。"Target sdk version" 是指您的应用程序针对运行的版本。 - Mohsen Emami

254

Android minSdkVersion, targetSdkVersion, compileSdkVersion

公式如下:

minSdkVersion <= targetSdkVersion <= compileSdkVersion

minSdkVersion - 是一个标记,用于定义应用程序能够安装的最低Android版本。同时,它也被Lint用于防止调用不存在的API。此外,它还会对构建时间产生影响。因此,在开发过程中,您可以使用构建变体来覆盖minSdkVersion,将其设置为最大值。这将有助于利用Android团队为我们提供的所有改进,加快构建速度。例如,只有在使用特定版本的minSdkVersion时,才能使用Java 8的某些功能。

targetSdkVersion - 如果Android操作系统版本>= targetSdkVersion,它会告诉Android系统启用特定版本的功能。请注意,即使targetSdkVersion小于某个值,某些新行为也会默认启用,您应该阅读官方文档。

例如:

从Android 6.0(API级别23)开始引入了“运行时权限”。如果您将targetSdkVersion设置为22或更低,您的应用程序在运行时不会向用户请求某些权限。
从Android 8.0(API级别26)开始,所有的通知必须分配到一个通道,否则将不会显示。在运行Android 7.1(API级别25)及更低版本的设备上,用户只能按应用程序管理通知(实际上每个应用程序在Android 7.1及更低版本上只有一个通道)。
从Android 9(API级别28)开始,基于Web的数据目录被进程分隔。如果targetSdkVersion为28+并且您在不同的进程中创建了多个WebView,您将会遇到java.lang.RuntimeException。

compileSdkVersion - 实际上它是SDK平台版本,并告诉Gradle使用哪个Android SDK进行编译。当您想要使用新功能或调试Android SDK的.java文件时,您应该注意compileSdkVersion。另一个例子是使用AndroidX,它强制使用compileSdkVersion - 级别28。 compileSdkVersion 不包含在您的APK中:它纯粹在编译时使用。更改compileSdkVersion不会改变运行时行为。它可以生成例如新的编译器警告/错误。因此,强烈建议您始终使用最新的SDK进行编译。您将获得对现有代码的新编译检查的所有好处,避免使用新弃用的API,并准备使用新的API。另一个事实是compileSdkVersion >= Support Library版本

你可以在这里阅读更多相关信息。 另外,我建议你看一下迁移到Android 8.0的示例。
[buildToolsVersion]

44
此处最佳答案是因为它实际上解释了targetSdkVersion和compileSdkVersion之间的实际区别。 - Dean Wild
@Manju,你可以在SO线程https://dev59.com/MF8d5IYBdhLWcg3wkSwV中找到更多信息。 - yoAlex5
@yoAlex5 你说的“Android系统开启特定行为更改”是什么意思?你能解释一下吗? - k_kumar
很好的回答!我只会再加上一句话关于 编译 SdkVersion - 你可以使用该API版本中包含的Android API特性,以及所有之前的版本。(引自下面Vinay John的回答) - Aleksandar
我们现在也有 minCompileSdk - Bitwise DEVS
显示剩余4条评论

98
min sdk version 指的是运行您的应用程序所需的Android操作系统的最低版本。 target sdk version 是创建应用程序要运行的Android版本。 compile sdk version 构建工具 用于编译和构建应用程序以发布、运行或调试的Android版本。
通常情况下,编译sdk版本目标sdk版本是相同的。

42
当利弊不相同时,该怎么办? - powder366

19

compileSdkVersion :compileSdkVersion是应用程序编译所依据的API版本。这意味着您可以使用包括该API版本中的Android API特性(以及所有先前版本中的特性)。如果您尝试使用API 16的特性但将compileSdkVersion设置为15,则会出现编译错误。如果您将compileSdkVersion设置为16,则仍然可以在API 15设备上运行应用。

minSdkVersion :min sdk版本是运行您的应用所需的Android操作系统的最低版本。

targetSdkVersion :目标sdk版本是您的应用程序的目标运行版本。


最干净和直截了当的解释!谢谢! - Aleksandar

10

参考- Paulina Sadowska 的 Medium 文章

  1. compileSdkVersion 定义 Gradle 编译应用所使用的 Android SDK 版本。

例如:

在 Android 12 中,也就是 SDK 版本 31,有一个新的 API 可以让我们轻松实现启动画面。在这个新的 API 中,可以使用以下属性自定义启动画面:

如果想在应用中使用该 API,首先必须:

i)  download SDK version 31 in Android Studio,
ii) and then: update compileSdkVersion to 31 in your app.

只有这样,您才能看到这些新属性。只有这样,您才能在代码中使用此新的闪屏API。

2.targetSdkVersion是一个属性,告诉系统应用程序设计和测试的Android版本。

如果用户在其设备上运行您的应用程序时,该设备的Android版本高于您的应用程序中定义的targetSdkVersion,则针对新的Android特性,系统可能会引入某些向后兼容行为,以确保您的应用程序仍然看起来和工作方式与您设计的一样。

例如:

在Android 12中,自定义通知的外观已更改。之前,它们可以使用整个通知区域,但在Android 12中,系统将标准模板应用于所有自定义通知,以使它们看起来更加一致。 如果您的targetSdkVersion低于31,则系统将假定您还没有测试该功能,并以旧方式显示通知,以最小化通知无法正确显示的风险。只有在将目标SDK版本更新为31后,才会使用新的通知外观。


6
在之前的答案中有很多好的解释,但没有一个链接到官方文档。如果感兴趣,请参见https://developer.android.com/guide/topics/manifest/uses-sdk-element,其中包括:
  • minSdkVersion:

如果系统的API级别低于此属性中指定的值,Android系统将阻止用户安装应用程序。

另外:如果您使用NDK运行本地代码,minSdkVersion也会影响NDK的API可用性。(https://developer.android.com/ndk/guides/sdk-versions

  • targetSdkVersion:
此属性通知系统,您已经针对目标版本进行了测试,并且系统不应启用任何兼容性行为以保持您的应用程序与目标版本的向前兼容性。该应用程序仍然能够在旧版本(最低 minSdkVersion)上运行。
随着每个新版本的推出,Android 的某些行为甚至外观可能会发生变化。但是,如果平台的 API 级别高于您的应用程序的 targetSdkVersion 声明的版本,则系统可能会启用兼容性行为,以确保您的应用程序继续按照您的预期工作。您可以通过指定 targetSdkVersion 与其运行的平台的 API 级别匹配来禁用此类兼容性行为。例如,将此值设置为“11”或更高版本,在 Android 3.0 或更高版本上运行时,系统可以将新默认主题(Holo)应用于您的应用程序,并在运行更大屏幕时禁用屏幕兼容性模式(因为对 API 级别 11 的支持隐含着对更大屏幕的支持)。
所以假设您开发的应用程序是针对目标API进行开发的,并且已经测试了所有内容,看起来/表现得像您预期的那样,尤其是如果您想使用此API中引入的功能。此外,您的代码应该能够处理没有该新功能的平台(最低minSdkVersion),例如优雅地处理您使用的缺失API等。但是,即使是更新的Android版本也可能会采取一些措施来保持您的应用程序运行,否则可能会破坏或者看起来更加奇怪,如果操作系统没有启用“兼容性行为”的话。
参见https://developer.android.com/studio/build
  • compileSdkVersion

compileSdkVersion指定Gradle应使用哪个Android API级别来编译您的应用程序。这意味着您的应用程序可以使用包括该API级别及以下的API功能。

理想情况下,您应该将目标版本和编译版本设置为最高版本,并且当然您不必使用任何新功能。但是,您可能希望保持目标版本为您已经发布的旧版本,同时使用较新的编译版本以获得更好的警告/错误信息,直到您准备更新目标版本。在过去,通过 Android Gradle 插件升级,它还可以让用户在其代码中使用较新的 Java 语言特性,而与目标 Android API 独立。
最后,不要忘记谷歌更近期的目标API级别要求,如果您希望仍然可供使用较新操作系统的Play商店用户,则要求您在特定日期发布面向最新API级别的构建。这是为了激励应用开发社区提供更新的性能/安全增强功能(例如,在请求位置信息时提供更多隐私选项)。
自 Android 9 发布以来,每个版本都列出了会影响所有应用程序的行为变更,而不管你的targetSdkVersion是什么(例如,这里是 Android 12 的),以及当你专门针对它时会发生什么变化(例如,行为变更:针对 Android 12 的应用程序)。当下一个版本处于预览状态时,即使您还没有准备好针对该版本进行更新,也可以开始检查您的应用程序与即将发布的版本的兼容性,即使只是通过使用任何兼容模式而无需更改compileSdkVersion兼容性框架工具可以帮助您完成此操作并迁移至使用新 API。

0

这里有一个简单易懂的方法 -

minSdkVersion 应该设置得更低,以便在安装应用程序的 Android 设备上获得最大覆盖范围。

compileSdkVersion 在开发应用程序时是必需的,以使用最新和优化的 Android API。

tarketSkdVersion 是您想要运行应用程序的 Android 操作系统的最新/版本,以实现 Android 资源的完全优化。

注意- 如果有错误,请纠正我。谢谢


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接