Android targetSdkVersion

本文详细解释了Android开发中关键的三个参数:compileSdkVersion, minSdkVersion和targetSdkVersion。它们分别决定了应用的编译环境、最低支持版本和目标兼容版本。理解这些参数对于确保应用在不同Android版本上的兼容性和性能至关重要。minSdkVersion定义了应用能运行的最低Android版本,而targetSdkVersion则关乎应用的行为和API一致性。compileSdkVersion则是编译时使用的SDK版本,允许使用该版本的新API。正确设置这三个版本可以避免兼容性问题并充分利用新功能。
部署运行你感兴趣的模型镜像

先抛出一个问题:
我们的应用开发的时候android最新版本是6.0,当一年过去之后,7.0发布了,那么我们的应用在7.0手机上是否还能运行?会奔溃吗?

根据我们的实际经验,觉得应该不会奔溃,可能有些功能会有问题,但是具体是那一块呢?又说不太好,这就涉及到了Android的向前兼容的问题了。

我们在创建App的时候经常会设置这几个参数

android {
  compileSdkVersion 23
  buildToolsVersion “23.0.1”
 
  defaultConfig {
    applicationId “com.example.checkyourtargetsdk"
    minSdkVersion 16
    targetSdkVersion 23
    versionCode 1
    versionName “1.0”
  }
}


其中著名的就是compileSdkVersion,minSdkVersion,targetSdkVersion。平时这些参数都是自动设置的,我们只需设置minSdkVersion,最低SDK版本,然后compileSdkVersion和targetSdkVersion可能是一致的。这就是我们平时使用AS的时候不注意的问题,平时操作习惯了,但是真的不知道这几个参数是什么意思。

minSdkVersion


最好理解的就是minSdkVersion了,就是我们的app能够运行的最小版本,如果选择16,那么就是Android 4.1 以及以上的设备才能运行我们app,如果小于这个版本,那么抱歉运行不了,我们不支持。这是应用程序支持api的下限。这也是应用商店判断这个应用是否能运行在设备上的一个依据之一。

在开发中也会根据这个下限去判断,是否可以用某个api方法,如果是下限之下的那么就会有警告,避免调用一些在新的版本已经改变或者过时的方法。

当我们引用了第三方的库,如果某几个库的minSdkVersion分别是API5,API10,API16的方法,那么我们的minSdkVersion最少就是16。

对于minSdkVersion的选择,我们应该看各个api的占比,不过因为基数太大了(十几亿)所以就算是0.7%也是个天文数字,所以我们需要根据自己应用的受众,以及是否需要适配低版本的需要,一般说来我们适配4.1以上,即minSdkVersion=16,不过还要根据自己的实际情况,去选择相应的版本号。

compileSdkVersion


compileSdkVersion是我们告诉Gradle,我们是用哪一版本的Android Sdk去编译程序的,可以使用这个版本的API,比如我们使用的是7.0的版本,compileSdkVersion=24,那么我们对于拍照裁剪图片等功能的操作,就可以使用FileProvider了。

我们需要注意的是:我们改变compileSdkVersion的版本号,本质上改变不了我们程序的运行,虽然可能会报错误❌或者警告⚠️,但compileSdkVersion 只会在编译期间起作用,因为环境是compileSdkVersion这个版本的SDK,所以你可以用一些这个版本的API,但是只是IDE给你的便利性帮助而已,帮助你检测代码,避免使用一些弃用的API。就算你用个低版本的compileSdkVersion,你依然可以那么写,但是可能会报错,报警告,但是你强制打包,其实也是没有问题的。IDE只是个工具,他的环境也只是工具的环境,不代表你应用运行时的表现。

所以希望大家用最新的sdk版本作为开发环境,compileSdkVersion设置成最新的,这样我们可以使用到最新SDK的API方法和机制。

如果我们使用了比如V4,V7包,有没有发现必须和compileSdkVersion的版本相匹配,比如我们compileSdkVersion = 26,那么V4,v7的版本也要相应的是26.xx.xx,首位的26必须一致,后两位没有要求,就是说明编译所依赖的SDK和依赖包必须是统一版本,不然两个不兼容,编译会通不过。同时也是为了使用该版本的新特性。

targetSdkVersion


targetSdkVersion是这哥三里面最难以理解的一个了,不过也是最有趣的一个。

targetSdkVersion的含义对于我们来说就有点陌生而熟悉了。

  1. 什么是目标设备SDK版本?
  2. 是和minSdkVersion相对应的上限吗?
  3. 如果我运行在比targetSdkVersion高的设备上,会出现什么?
  4. 如果是比targetSdkVersion低的设备呢?
     

首先targetSdkVersion是android向前兼容的主要方式,怎么说呢?官方是这样说的:

除非更新targetSdkVersion,否则不改变应用的行为。 这允许您在处理行为更改之前使用新的API(如您更新过的compileSdkVersion)
简单的说就是你的应用已经针对这个版本的手机,做了充分的兼容性处理和测试性处理,比如 if(Build.VERSION.SDK_INT >= 23) { ... } ,这样针对不同的SDK版本做不同的处理,这就说明我们不能随便的改变targetSdkVersion得值,我们必须做好充足的兼容性处理和测试处理才行。

在 Android 4.4 (API 19)以后,AlarmManager 的 set() 和 setRepeat() 这两个 API 的行为发生了变化。在 Android 4.4 以前,这两个 API 设置的都是精确的时间,系统能保证在 API 设置的时间点上唤醒 Alarm。因为省电原因 Android 4.4 系统实现了 AlarmManager 的对齐唤醒,这两个 API 设置唤醒的时间,系统都对待成不精确的时间,系统只能保证在你设置的时间点之后某个时间唤醒。虽然api的名字没有改变,但是功能结果已经发生改变,我们设置targetSdkVersion为16,Android4.4之前,那么我们在Android4.4之后运行会出现什么呢?难道就不能用了吗?不准确了吗?
当然不是,系统通过targetSdkVersion来保证Android的向前兼容性,在Android4.4之后的设备上,系统会判断你的targetSdkVersion是否小于19,如果小于的话,那就按照19之前的api方法,如果大于等于19,那么就按照之后的api方法来走,保证了程序运行的一致性。也就是向前兼容性。

但是还有一个问题:

Android 6.0新增加了动态权限申请,我们的targetSdkVersion是5.0,如果我们运行在Android 6.0的设备上怎么办?
因为我们这个可以向前兼容,向后不行啊,如果你的代码里处理了Android 6.0的动态权限处理,那么可以的,如果没呢?你想啥呢大哥?更新应用处理呗~~

targetSdkVersion 的大部分更新变化都会记录在VERSION_CODES,所有的细节也会在每个版本的平台亮点写明。

targetSdkVersion保证的是api的一致性。
所以一般minSdkVersion <targetSdkVersion<= compileSdkVersion
不随意更改targetSdkVersion,更改targetSdkVersion必须做好兼容。

Gradle和SDK版本


所以设置正确的compileSdkVersion,minSdkVersion和targetSdkVersion很重要。正如Gradle和Android Studio的世界中的那样,这些值通过包含在我们模块的build.gradle文件中(也可通过Android Studio中的Project Structure选项获得)集成到工具系统中:

android { 
  compileSdkVersion 23
   buildToolsVersion“23.0.1” 
 
  defaultConfig { 
    applicationId“com.example.checkyourtargetsdk” 
    minSdkVersion 7 
    targetSdkVersion 23
     versionCode 1 
    versionName“1.0” 
  } 
}
compileSdkVersion是一个编译时的事情(TMD这谁知道),是与我们的构建工具版本一起使用的Android设置之一。

minSdkVersion和targetSdkVersion不同于compileSdkVersion,因为它们包含在APK中。查看生成的AndroidManifest.xml

<uses-sdk android:targetSdkVersion =“23”android:minSdkVersion =“16”/>


理清楚这些后,下次更改这些参数的时候,就不会犯一些低级错误了。但是其中的更细节的东西,需要看android编译原理和运行原理了,任重而道远,这只是一个结果论。
 

您可能感兴趣的与本文相关的镜像

Stable-Diffusion-3.5

Stable-Diffusion-3.5

图片生成
Stable-Diffusion

Stable Diffusion 3.5 (SD 3.5) 是由 Stability AI 推出的新一代文本到图像生成模型,相比 3.0 版本,它提升了图像质量、运行速度和硬件效率

Android 应用的 `targetSdkVersion` 从 34 升级到 36 时,不仅涉及 SDK 版本的提升,还需要同步调整多个相关配置和代码逻辑,以确保应用在新版本系统上的兼容性、稳定性与安全性。以下是需要同步修改和注意的内容: ### 3.1 编译 SDK 版本和构建工具版本 升级 `targetSdkVersion` 时,通常也应同步更新 `compileSdkVersion` 和 `buildToolsVersion` 至对应版本,以确保使用最新的 API 和构建工具特性。例如: ```groovy android { compileSdkVersion 36 buildToolsVersion "36.0.0" // 或更高版本 defaultConfig { minSdkVersion 21 targetSdkVersion 36 versionCode 1 versionName "1.0" } } ``` 此做法有助于减少编译时的兼容性问题,并利用新版本 SDK 提供的优化功能[^2]。 ### 3.2 权限模型更新 Android 13(API 33)引入了更细粒度的运行时权限模型,例如 `READ_MEDIA_IMAGES`、`READ_MEDIA_VIDEO`、`READ_MEDIA_AUDIO` 等。如果应用需要访问媒体文件,必须根据具体类型申请权限,而不能继续使用 `READ_EXTERNAL_STORAGE`。此外,从 Android 14(API 34)开始,部分权限的使用场景也进一步受限,例如后台位置权限的获取需明确声明用途并获得用户确认[^2]。 ### 3.3 PendingIntent 的不可变性标志 从 Android 12(API 31)开始,`PendingIntent` 必须明确指定是否可变。在 `targetSdkVersion` 36 的应用中,所有创建 `PendingIntent` 的地方都应使用 `FLAG_IMMUTABLE` 或 `FLAG_MUTABLE` 标志,否则系统会抛出异常。例如: ```java PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE); ``` 该变更提高了应用的安全性,防止 PendingIntent 被恶意篡改。 ### 3.4 通知权限的强制请求 Android 13 引入了通知权限(`POST_NOTIFICATIONS`),即使应用之前默认允许发送通知,现在也必须在运行时请求用户授权。否则,通知将不会显示。例如: ```java if (ContextCompat.checkSelfPermission(context, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.POST_NOTIFICATIONS}, REQUEST_CODE); } ``` 此变更增强了用户对通知的控制能力,开发者需在适当时机主动请求权限。 ### 3.5 前台服务类型声明 Android 10(API 29)引入了前台服务类型的细分,如 `FOREGROUND_SERVICE_TYPE_LOCATION`、`FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK` 等。在 `targetSdkVersion` 36 中,必须为每个前台服务指定具体类型,否则系统将抛出异常。例如: ```java startForeground(NOTIFICATION_ID, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION); ``` 这有助于系统更有效地管理资源并提升用户体验。 ### 3.6 后台启动 Activity 的限制 从 Android 10 开始,系统限制了应用在后台启动 Activity 的行为。在 `targetSdkVersion` 36 中,应用必须通过 `PendingIntent` 或 `ActivityService` 启动前台界面,并且只能在用户明确交互后执行。否则系统将阻止操作并抛出异常。这一限制旨在提升用户体验并防止恶意行为[^2]。 ### 3.7 存储访问适配 尽管作用域存储(Scoped Storage)从 Android 10(API 29)开始引入,但在 `targetSdkVersion` 36 中仍需确保应用完全适配。应使用 `MediaStore`、`Storage Access Framework` 或 `app-specific directories` 来访问文件,避免直接操作共享存储路径。对于访问其他应用的文件,必须通过 `Intent` 或 `ContentResolver` 获取授权访问。 ### 3.8 Gradle 配置统一管理 为了统一管理多个模块的 `targetSdkVersion` 和依赖库版本,可以在项目根目录下创建 `config.gradle` 文件,并在各模块的 `build.gradle` 中引用该配置。例如: ```groovy // config.gradle ext { android = [ compileSdkVersion: 36, buildToolsVersion: "36.0.0", minSdkVersion : 21, targetSdkVersion : 36, versionCode : 1, versionName : "1.0" ] } ``` 然后在模块的 `build.gradle` 文件中应用该配置: ```groovy apply from: "../config.gradle" android { compileSdkVersion rootProject.ext.android.compileSdkVersion buildToolsVersion rootProject.ext.android.buildToolsVersion defaultConfig { minSdkVersion rootProject.ext.android.minSdkVersion targetSdkVersion rootProject.ext.android.targetSdkVersion versionCode rootProject.ext.android.versionCode versionName rootProject.ext.android.versionName } } ``` 此方式可集中管理配置,减少版本不一致带来的问题[^1]。 ### 3.9 依赖库版本兼容性检查 升级 `targetSdkVersion` 后,需检查项目中使用的第三方库是否兼容 API 36。部分库可能仍依赖旧版本的 SDK 或未适配新的权限模型、通知机制等。建议更新到最新版本的依赖库,并测试其行为是否符合预期。例如: ```groovy dependencies { implementation 'androidx.core:core-ktx:1.10.0' implementation 'androidx.appcompat:appcompat:1.6.1' implementation 'com.google.android.material:material:1.9.0' } ``` ### 3.10 用户交互行为变更 Android 12(API 31)对用户交互行为进行了限制,例如在没有用户直接触发的情况下,禁止启动前台 Activity。在 `targetSdkVersion` 36 中,所有启动 Activity 的操作都应确保是用户主动行为,否则将被系统阻止。开发者应检查应用中所有启动 Activity 的逻辑,确保符合新规则。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值