Android版本对照表:从API级别到兼容性适配的实战指南
1. 为什么你需要一份自己的Android版本对照表?
在Android开发的日常里,无论是处理兼容性问题、查阅某个API的引入版本,还是为新项目设定最低支持版本,我们总绕不开一个核心问题:这个功能在哪个Android版本上才有?对应的SDK版本号是多少?编译版本(compileSdkVersion)和目标版本(targetSdkVersion)又该怎么设置?
官方文档当然有,但往往散落在各处,或者信息不够直观。更常见的情况是,我们在Stack Overflow、技术博客甚至同事的代码注释里,看到诸如“这个API需要API 21(Android 5.0)以上”的描述。对于新手来说,这些数字和代号(Lollipop, Pie)之间的对应关系,本身就是一道门槛。而对于老手,虽然可能记得住几个关键版本,但面对一些不那么常用的API或者需要精确追溯时,一份清晰、准确、附带关键信息的对照表,能极大提升效率,减少因版本混淆导致的低级错误。
因此,自己整理并维护一份“Android历来版本&SDK信息对照表”,远不止是简单的信息罗列。它是一个开发者对Android生态演进脉络的理解,是解决兼容性问题的“作战地图”。这份表格的价值在于,它将版本代号、版本号、API级别、发布时间、市场份额(如果关注)、以及最重要的——该版本引入的标志性特性或变更关联在一起。当你需要决定是否使用某个新API,或者解释为什么某个功能在旧设备上崩溃时,这张表就是你的第一参考。
2. 构建你的核心对照表:基础信息与关键特性
一份有价值的对照表,其核心骨架必须准确且信息密度高。下面是我根据官方资料和长期开发经验整理的核心表格,它不仅包含了基础对应关系,还提炼了每个版本最值得开发者关注的特性或变更点。这些“关键关注点”往往是代码兼容性问题的根源。
表1:Android版本、SDK(API级别)与关键特性对照表(截至Android 15)
| 版本代号 (Code Name) | 版本号 (Version) | API 级别 (API Level) | 发布日期 (约) | 关键关注点(对开发者的影响) |
|---|---|---|---|---|
| (无) | Android 1.0 | 1 | 2008年9月 | 系统诞生,奠定基础。 |
| (无) | Android 1.1 | 2 | 2009年2月 | 早期补丁版本。 |
| Cupcake | Android 1.5 | 3 | 2009年4月 | 支持第三方虚拟键盘、桌面小部件(Widget)雏形。 |
| Donut | Android 1.6 | 4 | 2009年9月 | 支持多种屏幕密度,CDMA网络。 |
| Eclair | Android 2.0 – 2.1 | 5 – 7 | 2009年10月 | 引入账户同步、HTML5浏览器支持、蓝牙2.1。 |
| Froyo | Android 2.2 – 2.2.3 | 8 | 2010年5月 | JIT编译提升性能,支持应用安装至SD卡,Cloud to Device Messaging (C2DM, 推送前身)。 |
| Gingerbread | Android 2.3 – 2.3.7 | 9 – 10 | 2010年12月 | 引入StrictMode, 改进电源管理,支持前置摄像头、NFC(API 9引入)。很多老旧设备停留于此版本。 |
| Honeycomb | Android 3.0 – 3.2.6 | 11 – 13 | 2011年2月 | 专为平板设计,引入Fragment(但直到API 14才在手机版本支持)、ActionBar、Loader。API设计对后世影响深远,但手机设备上无需直接兼容此系列。 |
| Ice Cream Sandwich | Android 4.0 – 4.0.4 | 14 – 15 | 2011年10月 | 统一手机与平板体验。Fragment正式成为支持库一部分(android-support-v4),RecyclerView和ViewPager的前身思想出现。Holo主题成为标准。 |
| Jelly Bean | Android 4.1 – 4.3.1 | 16 – 18 | 2012年7月 | “黄油计划”(Project Butter)显著提升UI流畅度。通知栏增强,支持可展开通知。Google Play services开始成为重要组件。多用户支持(平板), 蓝牙低功耗(BLE) API。 |
| KitKat | Android 4.4 – 4.4.4 | 19 – 20 | 2013年10月 | 沉浸式全屏模式,WebView基于Chromium独立更新。Transition Framework引入。getExternalFilesDir()行为变更, 访问外部存储需注意。ART运行时作为实验选项出现。 |
| Lollipop | Android 5.0 – 5.1.1 | 21 – 22 | 2014年11月 | Material Design设计语言。ART运行时正式取代Dalvik。JobScheduler引入。RecyclerView,CardView,Palette等进入支持库。权限模型重大变更(运行时权限在API 23才引入,但此版本开始铺垫)。 |
| Marshmallow | Android 6.0 – 6.0.1 | 23 | 2015年10月 | 运行时权限模型。这是Android权限系统的分水岭,所有targetSdkVersion>= 23的应用都必须处理。Doze和App Standby省电模式引入。指纹识别API (FingerprintManager)。 |
| Nougat | Android 7.0 – 7.1.2 | 24 – 25 | 2016年8月 | 多窗口模式。JIT编译器回归(与AOT结合的混合模式),提升应用安装速度和性能。通知分组。FileProvider引入(解决file://Uri共享的安全问题,非常重要)。 |
| Oreo | Android 8.0 – 8.1 | 26 – 27 | 2017年8月 | 后台执行限制(后台服务、广播接收器限制)。通知渠道 (Notification Channels)。Autofill框架。Adaptive Icons。install-apk权限变更(禁止未知来源应用安装)。 |
| Pie | Android 9 | 28 | 2018年8月 | 全面屏手势导航。限制非SDK接口(灰名单/黑名单), 大量使用@hideAPI的应用开始崩溃。ImageDecoder替代BitmapFactory。H.265/HEVC编码支持。 |
| Android 10 (Q) | Android 10 | 29 | 2019年9月 | 分区存储 (Scoped Storage) 引入(最初为可选适配,后成为强制)。深色主题系统级支持。Gesture Navigation成为默认。禁止访问设备标识符(如IMEI)的严格限制。 |
| Android 11 (R) | Android 11 | 30 | 2020年9月 | 分区存储强制执行(针对targetSdkVersion>= 30的应用)。一次性权限。后台位置访问权限对话框独立。Package Visibility(包可见性)限制。 |
| Android 12 (S) | Android 12 | 31 | 2021年10月 | Material You动态主题。更严格的应用休眠。Foreground Service启动限制。PendingIntent可变性标志强制要求。Bluetooth、Wi-Fi权限细化。 |
| Android 12L | Android 12.1 | 32 | 2022年3月 | 主要针对大屏设备(平板、折叠屏)优化,任务栏、分屏改进。对手机影响较小。 |
| Android 13 (T) | Android 13 | 33 | 2022年8月 | 运行时通知权限。更精细的媒体文件权限(照片/视频/音频)。Themed App Icons。后台使用身体传感器需单独权限。 |
| Android 14 (U) | Android 14 | 34 | 2023年10月 | 部分屏幕共享。Foreground Service类型需显式声明。grantUriPermissions行为变更。OpenJDK 17支持。安装目标API级别限制更严格。 |
| Android 15 (V) | Android 15 | 35 | 2024年(预计) | 边栏边活动, 隐私沙盒,Health Connect功能增强, 卫星通信支持改进。(截至当前为开发者预览版,特性可能变化) |
注意:上表中的“关键关注点”是我个人在开发和适配过程中认为最具影响力的变更。它不能替代完整的官方发布说明,但能帮你快速定位可能出问题的版本区域。例如,如果你的应用在Android 6.0+的设备上崩溃,首先应该怀疑权限问题;如果在Android 9+的设备上调用内部API失败,就要检查非SDK接口限制。
3. 超越表格:版本号在工程中的实战应用
仅仅记住这张表还不够,关键在于如何在真实的Android项目中运用这些信息。这主要涉及build.gradle文件中的三个关键配置,以及代码中的版本检查。
3.1compileSdkVersion、targetSdkVersion与minSdkVersion的三角关系
这是每个Android开发者都必须透彻理解的概念。它们共同定义了你的应用如何被编译、如何在新系统上运行,以及能在多老的设备上安装。
minSdkVersion:你的应用可以安装和运行的最低Android版本。它决定了你的应用能覆盖多少用户设备,也决定了你在代码中绝对不能使用高于此版本的API。例如,minSdkVersion设为21(Android 5.0),那么你就不能直接调用API 23(Android 6.0)引入的Context.checkSelfPermission()方法,除非进行运行时版本判断和降级处理。- 如何选择:需要权衡市场占有率(可通过官方Android分布数据查看)和开发成本。支持过老的版本意味着需要写更多的兼容代码和进行更多测试。目前(2024年),很多新应用将起点设为API 24(Android 7.0)或更高,以利用现代API并减少适配负担。
compileSdkVersion:编译你的应用时所使用的Android SDK版本。它决定了你在编码时可以使用哪些API和语法特性。你可以把它想象成你写代码时参考的“词典”。你可以使用compileSdkVersion34(Android 14)的API来编写代码,即使你的minSdkVersion是21。- 最佳实践:总是使用最新的稳定版SDK进行编译。这能让你使用最新的API进行开发,同时获得最新的编译时检查和优化。这不会影响你的应用在旧设备上的运行行为。
targetSdkVersion:你的应用期望运行在的Android版本。这是最重要的设置之一,它告诉系统:“我的应用已经为这个版本及以下的行为做好了准备”。系统会根据这个值来决定是否启用针对该版本引入的行为变更(Behavior Changes)。- 核心逻辑:如果
targetSdkVersion>= 某个引入了行为变更的API级别,那么你的应用在该版本及更高的设备上运行时,就会受到新行为规则的约束。反之,系统会启用“兼容模式”,沿用旧行为来保证你的应用不会意外崩溃。 - 举例:Android 6.0 (API 23) 引入了运行时权限。如果你的
targetSdkVersion< 23,即使在Android 10的设备上运行,系统也不会强制你使用新的权限申请流程(但用户依然可以在设置中关闭权限)。一旦你将targetSdkVersion提升到23或更高,你就必须在代码中处理运行时权限申请,否则相关功能会失败。 - 如何选择:在确保你的应用已经充分测试并适配了对应版本的所有行为变更后,应尽快将
targetSdkVersion更新到最新或次新版本。这不仅是应用商店(如Google Play)的要求,也能让你的应用在新系统上获得最佳的性能和安全体验。
- 核心逻辑:如果
一个典型的配置示例 (app/build.gradle.kts):
android { compileSdk = 34 // 使用最新的SDK编译,享受新API和工具链 defaultConfig { applicationId = "com.example.myapp" minSdk = 24 // 放弃对Android 6.0以下设备的支持,简化开发 targetSdk = 34 // 声明已适配Android 14的行为变更 ... } }3.2 代码中的版本判断与兼容处理
由于minSdkVersion通常低于compileSdkVersion,你会在代码中经常使用高版本API。这时,必须进行运行时版本检查,防止在低版本设备上调用不存在的API导致NoSuchMethodError或ClassNotFoundException。
标准做法是使用Build.VERSION.SDK_INT进行判断:
// 示例:在API 26(Android 8.0)及以上使用通知渠道 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // 创建通知渠道(此代码块只会在API 26+的设备上执行) val channel = NotificationChannel( "channel_id", "Channel Name", NotificationManager.IMPORTANCE_DEFAULT ) (getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager) .createNotificationChannel(channel) } // 对于API 26以下的设备,创建通知的代码无需渠道参数,走旧逻辑。对于需要复用的兼容性逻辑,可以将其封装在@RequiresApi注解标注的扩展函数或工具类中,并在调用处做好版本判断。
4. 从对照表到避坑指南:常见版本适配陷阱解析
有了对照表,我们就能系统性地排查一些棘手的兼容性问题。下面结合表格,分析几个高频“坑点”。
4.1 权限模型的两次巨变:API 23与API 30
API 23 (Android 6.0) 运行时权限:这是最著名的变更。在targetSdkVersion>= 23后,DANGEROUS级别的权限(如相机、位置、存储)必须在运行时向用户申请,而不能仅在清单文件中声明。很多应用在升级targetSdkVersion时忘记处理,导致功能在Android 6.0+设备上完全失效。
- 避坑:使用
ActivityResultContracts.RequestPermission()或第三方权限库(如PermissionsDispatcher,TedPermission)来优雅处理。务必编写权限被拒绝后的降级或引导逻辑。
API 30 (Android 11) 分区存储强制执行:虽然从API 29引入,但在API 30及以上的设备上,如果你的targetSdkVersion>= 30,则强制启用分区存储。这意味着应用默认只能访问自身的私有目录和特定类型的媒体文件,无法通过FileAPI随意访问外部存储根目录。
- 避坑:
- 使用
MediaStoreAPI访问公共媒体文件(图片、视频、音频)。 - 使用
Storage Access Framework(SAF) 让用户通过系统选择器授权访问特定目录或文件。 - 在
AndroidManifest.xml中申请MANAGE_EXTERNAL_STORAGE权限(此权限审核严格,仅用于文件管理器类应用,上架Google Play需声明)。 - 将文件保存在
Context.getExternalFilesDir()或Context.getExternalCacheDir(),这些位置无需权限。
- 使用
4.2 后台限制的逐步收紧:API 26与API 31+
从API 26开始,系统对后台行为的管理越来越严格。
API 26 (Android 8.0) 后台服务限制:不允许在后台创建Service,除非将其转为前台服务(必须显示通知)。这导致很多依赖后台服务的逻辑(如长期保活、定时任务)需要重构。
- 避坑:使用
JobScheduler、WorkManager(推荐,它是JobScheduler、Firebase JobDispatcher等的统一封装)或AlarmManager(用于精确闹钟)来替代后台服务执行延迟或周期任务。
API 31 (Android 12) 前台服务启动限制:在后台启动前台服务被进一步限制,会有数秒的延迟。这对于需要立即启动前台服务的场景(如来电提醒)是挑战。
- 避坑:使用
startForegroundService()启动服务后,必须在5秒内调用该服务的startForeground()方法,否则会引发ANR。对于需要从后台立即启动的场景,考虑使用高优先级FCM消息或SCHEDULE_EXACT_ALARM权限(需用户授权)。
4.3 非SDK接口限制:API 28的“灰黑名单”
在API 28之前,很多开发者通过反射或JNI调用@hide注解标记的隐藏API(非SDK接口)来实现一些特殊功能。从API 28开始,Google严格限制了这类调用,将其分为灰名单、黑名单等,调用黑名单接口会导致抛出异常。
- 避坑:彻底检查你的代码和依赖的第三方库,移除所有对非SDK接口的调用。如果确实需要,可以尝试寻找公开的替代API,或者评估是否真的需要此功能。在开发阶段,可以通过
adb shell settings put global hidden_api_policy 1临时禁用限制来测试,但绝不能作为发布版本的解决方案。
4.4 通知系统的演进:API 26与API 33
API 26 通知渠道:要求为每条通知分配一个渠道。用户可以在系统设置中按渠道管理通知(关闭、调整重要性)。如果没有创建渠道就发送通知,在API 26+的设备上通知将不会显示。
- 避坑:应用启动时(如
Application的onCreate中)创建所有需要的通知渠道。渠道一旦创建,部分属性(如名称、重要性)在系统设置中才能被用户修改,应用代码无法再更改。
API 33 运行时通知权限:在Android 13上,发送通知需要申请新的POST_NOTIFICATIONS权限。这又是一个运行时权限。
- 避坑:在向API 33+设备发送第一条通知前,务必检查并申请该权限。申请逻辑与其他运行时权限一致。对于
targetSdkVersion低于33的应用,系统会临时授予该权限。
5. 工具与资源:如何高效查询与验证版本信息
除了自己维护的表格,善用工具能让你事半功倍。
- Android官方文档 - 平台版本:这是最权威的信息源。搜索“Android API levels”或“Android version history”可以找到官方表格和每个版本的详细发布说明,其中“行为变更”部分是适配必读。
- Android Studio 的 IDE 支持:
- 代码提示:当你在代码中输入
Build.VERSION_CODES.时,IDE会自动补全所有版本代号常量,并悬浮提示对应的版本号。 @RequiresApi和@TargetApi注解:IDE会利用这些注解进行代码检查,提示你某段代码需要更高的API级别。- Lint 检查:Android Lint工具会扫描你的代码,发现潜在的平台兼容性问题,例如调用了高于
minSdkVersion的API,并给出警告或错误。
- 代码提示:当你在代码中输入
- 第三方市场分析工具:如
Firebase、友盟+等,可以提供你的应用实际用户设备的版本分布数据,为调整minSdkVersion提供数据支撑。 - 物理设备与模拟器:维护一个涵盖关键版本(如你的
minSdkVersion,targetSdkVersion, 以及几个中间重要版本如API 23, 29, 33)的测试设备矩阵。Android Studio自带的模拟器可以很方便地创建各种API级别的虚拟设备。
最后,保持这份对照表的更新。每个Android大版本发布时,花点时间更新表格,并重点阅读其“行为变更”文档,提前规划适配工作。将版本管理融入开发流程,而不是等到问题出现才去救火,这是一个资深Android开发者应有的习惯。
