Android SDK Platform 25 缺失排查与构建配置指南

发布时间:2026/11/4 15:04:19
Android SDK Platform 25 缺失排查与构建配置指南 简介面向需要适配 Android 7.1.1API 25的移动应用开发者与测试人员这份 Android SDK 平台包提供本地开发环境所需的平台组件可用于创建、编译和调试对应版本的应用也适合作为维护旧版本兼容、复现系统行为的离线参考对具备一定 Android 基础的中级开发者更实用。压缩包共约 2000 个文件、大小 81.47MB以 png 图像资源、xml 配置与布局描述、ttf 字体、html 文档及 jar 库为主并含少量 ini、txt、properties、aidl 等辅助文件整体呈现典型 SDK 目录结构。已有 731 人学习说明其在 Android 版本适配场景中具有一定参考价值。解压后可获得系统映像、平台库、头文件与源码、构建工具及 API 参考文档帮助读者理解 App Shortcuts、Night Light、Image Picker API 和 Daydream 支持等 7.1.1 特性并用于模拟器测试、接口查阅和项目调试也能为多窗口模式适配与电池优化排查提供依据适合作为离线 SDK 组件补充。1. 一个不到 100MB 的平台包能把整条构建流水线卡死克隆一个还在维护的存量工程第一次 Sync 就红屏报错直指platforms/android-25目录不存在——机器上 33、34 都躺着偏偏少这个。Android SDK platform-25 就是 Android 7.1.1 对应的编译期平台包解压后核心只有一个android.jar。它不参与运行只负责在编译那一刻告诉 GradleAPI 25 这层有哪些类、哪些方法、哪些资源属性可以引用。需要它的人很集中维护 targetSdk 焊在 25 的老工程、给定制设备做适配、要在本地复现某次历史构建。装错了不是应用跑不起来是代码根本编不过——这也是它最容易被低估的地方。2. 拆开 android-25 目录五类文件各管一段链路2.1 android.jar 是桩不是实现把平台包解开目录结构长这样$ANDROID_HOME/platforms/android-25/ ├── android.jar # 编译期 API 桩代码 ├── data/ │ ├── res/ # 编译期资源表aapt 校验资源引用靠它 │ ├── fonts/ # 布局预览用的字体 │ └── layoutlib.jar # XML 布局预览的渲染引擎 ├── optional/ │ └── org.apache.http.legacy.jar ├── templates/ # 新建 Activity 等模板 ├── uiautomator.jar # UiAutomator v1 的类 └── source.properties # 包元数据android.jar里的方法体几乎全是throw new RuntimeException(Stub!)它只提供签名。运行时真正执行的是设备上的framework.jar两者版本必须对得上否则就是NoSuchMethodError这一类运行期崩。很多新手看到Stub!会以为是包损坏其实是设计如此。data/res容易被忽略但它决定了你能不能写出android:style/Theme.Material.Light这种系统资源引用。aapt 在编译期拿这份资源表做符号解析表里没有的直接报resource not found。optional/org.apache.http.legacy.jar是 API 23 移除 Apache HttpClient 之后留下的兼容层。如果老代码里还有org.apache.http.*的调用编译会过但运行崩必须在build.gradle里显式加useLibrary org.apache.http.legacy才能把这份 jar 打进 dex。2.2 platform、build-tools、system-image 是三件事这三个东西被混为一谈是老项目上最常见的认知偏差。组件典型路径职责版本是否绑定 APISDK Platformplatforms/android-25编译期类与资源定义是一个 API 一个目录Build Toolsbuild-tools/25.0.3aapt、d8、zipalign、apksigner否可高于 APISystem Imagesystem-images/android-25/google_apis/x86模拟器运行镜像是但和编译无关Platform Toolsplatform-tools/adbadb、fastboot否全局一份build-tools版本号和 API level 不是锁死的。用 30.x 的 build-tools 编compileSdkVersion 25完全合法只是新版本 d8 的 desugar 策略和老库可能有出入。反过来装了 platform-25 不等于能开模拟器模拟器要的是 system-image那是另一个几百 MB 的包。我见过有人在 CI 里装了一堆 system-image结果编译依然报缺 platform就是没分清这两条链。2.3 为什么偏偏是 25Nougat 的行为分界线API 24 带来多窗口API 25 补上静态/动态 Shortcut、android:roundIcon圆形图标和 VR 相关接口而 API 26 才是真正的分水岭——后台执行限制、通知渠道、自适应图标全砸在这一版上。关键在于这些限制是按targetSdkVersion生效的。targetSdk 停在 25 的应用装到 8.0 以上设备系统仍然走兼容路径后台 Service 还能照旧起通知不需要渠道。存量工程把 targetSdk 焊死 25本质是在买这张行为豁免券。但这张券有代价拿不到新特性也过不了应用市场的新一轮合规审查。compileSdkVersion和targetSdkVersion要分开看。前者决定你能调用哪些 API后者决定运行时系统套哪套策略。锁 25 的工程完全可以在 compileSdk 上抬到更高来满足依赖库要求只是抬了之后要重新验证一遍 API 25 设备上的行为这是另一笔账。3. 装到机器上命令行、离线落位与环境变量3.1 sdkmanager 装包引号不能省新版命令行工具放在cmdline-tools/latest/bin下先把它加进 PATH# 先固定 SDK 根目录后面所有命令都基于它 export ANDROID_HOME$HOME/Android/Sdk export PATH$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools:$PATH # 确认仓库里这个包的确切包名避免拼错 sdkmanager --list | grep -E platforms;android-25|build-tools;25 # 只装编译需要的两样不连带下载镜像 sdkmanager --sdk_root$ANDROID_HOME platforms;android-25 build-tools;25.0.3 # license 未接受时会停在交互提示非交互环境必须预先处理 yes | sdkmanager --licenses包名里的分号是 shell 的命令分隔符所以platforms;android-25外面的双引号是硬性要求。不加引号的后果是 shell 把android-25当成第二条命令去执行报command not found而真正的报错信息被淹没很多人在这里绕半天。这是踩坑率最高的一行命令。--sdk_root建议每次都显式带上。机器上同时存在 Android Studio 自带 SDK 和命令行安装的 SDK 时sdkmanager 可能按自己的探测逻辑选一个你以为装到了 A 路径实际落在 B 路径Studio 那边永远提示缺失。加上参数就没有歧义。3.2 断网机器的手工落位内网构建机拿不到外网时只能把平台包 zip 拷进去手动展开。这里有两个必须守住的细节目标目录名必须是android-25以及元数据文件必须齐全。# 目录名固定为 android-25不能改成 platform-25 mkdir -p $ANDROID_HOME/platforms/android-25 unzip -q platform-25_r03.zip -d $ANDROID_HOME/platforms/ # 检查元数据确认 API level 和修订号 grep -E AndroidVersion.ApiLevel|Pkg.Revision|Platform.Version \ $ANDROID_HOME/platforms/android-25/source.properties # 让 sdkmanager 重新扫描并列出已安装包 sdkmanager --list_installed | grep android-25source.properties的内容大致是这几行Pkg.DescAndroid SDK Platform 25 Pkg.Revision3 AndroidVersion.ApiLevel25 AndroidVersion.CodeName Platform.Version7.1.1较新版本的 sdkmanager 除了source.properties还会在目录下写一份package.xml作为安装凭据。手工解压通常只有前者此时--list_installed可能不列这个包Android Studio 也会反复弹install missing platform。处理办法有两种用同版本 sdkmanager 对同一路径再执行一次--install让它补齐元数据或者从一台已正常安装的机器上把package.xml一并拷过来。3.3 ANDROID_HOME 与 PATH 固定下来环境变量每次开新终端就丢是最隐形的坑。写进 shell 配置文件# ~/.zshrc 或 ~/.bashrc export ANDROID_HOME$HOME/Library/Android/sdk # macOS 默认位置Linux 换路径 export PATH$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools:$ANDROID_HOME/build-tools/25.0.3:$PATHANDROID_SDK_ROOT已经不被推荐和ANDROID_HOME同时设置且指向不同目录时会互相打架报出来的错还特别绕。统一只用ANDROID_HOME一个变量能省掉一类排查。Windows 上的默认位置是%LOCALAPPDATA%\Android\Sdk。路径里带中文、空格、括号时sdkmanager 在某些版本上会解析失败SDK 根目录尽量放在纯英文短路径下比如D:\android-sdk。4. 让编译真正走通Gradle 配置与产物验证4.1 三处版本号的对齐关系工程侧的配置必须和已安装的包一一对应Groovy DSL 写法android { // 必须能找到 platforms/android-25 这个目录 compileSdkVersion 25 // 必须能找到 build-tools/25.0.3 这个目录可高于 API 版本 buildToolsVersion 25.0.3 defaultConfig { minSdkVersion 21 // 与 compileSdk 解耦决定运行期系统走哪套兼容策略 targetSdkVersion 25 versionCode 1 versionName 1.0 } }Kotlin DSL 里对应的是compileSdk 25AGP 4.x 之后compileSdkVersion这个属性名被compileSdk取代抄老教程时容易对不上。真正麻烦的是 AGP 自身的版本约束。新版本 AGP 对compileSdk有下限要求锁 25 的工程如果顺手把 AGP 升到最新会在配置阶段直接失败报的是compileSdk 过低而不是缺包容易误判。维护这类工程时AGP 大版本要跟着项目锁不能跟着教程走。还有一条隐性的版本传导AAR 依赖的 manifest 里带着自己的compileSdkVersionGradle 会取所有依赖里的最大值作为实际编译版本。所以你写 25但如果某个 AndroidX 库声明要求 28构建就会报requires libraries and applications that depend on it to compile against version 28 or later。这不是配置写错是依赖在倒逼升级。4.2 多平台共存时的查找顺序ls $ANDROID_HOME/platforms # android-25 android-33 android-34多个平台并存本身没问题Gradle 按compileSdkVersion去对应目录取android.jar。查找顺序上local.properties里的sdk.dir优先级高于环境变量而这个文件通常不进版本库——换一台机器后它可能还残留着旧路径指向一个根本不存在的 SDK。排查明明装了却找不到时先看这个文件。# local.properties不进版本库 sdk.dir/Users/xxx/Library/Android/sdk缓存也会骗人。改完 SDK 路径后如果还是报旧错可以加重跑一次依赖刷新./gradlew clean assembleDebug --refresh-dependencies --stacktrace--stacktrace建议常开缺包类错误的真实路径往往藏在异常的 caused by 里只看第一层基本判断不出是 platform 缺失还是 build-tools 缺失。4.3 用 aapt 和 apkanalyzer 验证产物编译过了不代表编对了。用 build-tools 里的 aapt 反查 APK 的 manifest 信息# 看 APK 实际写入的 sdk 版本字段 $ANDROID_HOME/build-tools/25.0.3/aapt dump badging \ app/build/outputs/apk/debug/app-debug.apk \ | grep -E sdkVersion|targetSdkVersion # 用 apkanalyzer 交叉验证两个工具口径更可靠 $ANDROID_HOME/cmdline-tools/latest/bin/apkanalyzer manifest target-sdk \ app/build/outputs/apk/debug/app-debug.apk正常输出里sdkVersion:21是 minSdktargetSdkVersion:25是目标版本。注意 aapt 的 badging 输出通常不直接打印 compileSdk要看platformBuildVersionCode字段得用aapt dump xmltree展开 manifest 才行$ANDROID_HOME/build-tools/25.0.3/aapt dump xmltree \ app-debug.apk AndroidManifest.xml | grep -i platformBuild这一步的价值在于区分我以为按 25 编的和实际按 25 编的。多人协作时某个成员本地 SDK 路径串到了另一个版本编出来的包在 25 设备上行为异常只看构建日志是很难发现的。5. 装完还报错五类翻车现场与排查路径5.1 报错说找不到 Build Tools 25.0.3现象构建报Failed to find Build Tools revision 25.0.3但platforms/android-25明明在。原因只装了 platform没装 build-tools。这两个是独立包sdkmanager 不会连带安装。很多人看到报错里带25就以为装过了。解决执行sdkmanager build-tools;25.0.3。或者干脆把buildToolsVersion从构建脚本里删掉让 AGP 用它的默认值——只要默认值不低于项目里的最低要求编译照样能过。5.2 依赖解析失败提示找不到 support 库现象Could not find com.android.support:appcompat-v7:25.3.1。原因support 库发布在独立的 maven 仓库上老工程的repositories块里只有jcenter()或mavenCentral()而 jcenter 早已只读并逐步下线根本拉不到这批构件。解决在repositories里补上相应仓库并放在列表前面优先命中repositories { google() mavenCentral() jcenter() // 仅作为兜底不要再依赖它 }5.3 Studio 反复提示安装缺失的平台现象命令行--list_installed能看到Android Studio 的 SDK 面板却标红一直弹安装提示。原因三个可能——目录名被改成了platform-25而非android-25package.xml缺失导致 sdkmanager 不认这个安装local.properties的sdk.dir指向了另一个 SDK 路径装的和用的不是同一个。解决先核对目录名和source.properties里的AndroidVersion.ApiLevel25再确认sdk.dir与实际安装路径一致最后把package.xml补齐。5.4 报 Unsupported class file major version现象Gradle 启动阶段直接崩报Unsupported class file major version 61之类。原因老版本 AGP 跑在 JDK 17 上不兼容。老工程配套的 AGP 和 Gradle 版本通常只认 JDK 8 或 11。解决为这个工程单独指定 JDK不要动全局设置# gradle.properties org.gradle.java.home/Library/Java/JavaVirtualMachines/jdk-11.jdk/Contents/Home5.5 依赖逼着你把 compileSdk 抬上去现象报Dependency xxx requires libraries and applications that depend on it to compile against version 28 or later。原因这是 4.1 里说的版本传导。某个 AAR 声明了更高的 compileSdkGradle 取最大值后与你的 25 冲突。解决两条路。降依赖版本把这类库钉在支持 25 的老版本上或者承认这个工程已经不适合继续锁 25把 compileSdk 抬上去同时重新验证 targetSdk 25 在低版本设备上的行为。第二条路意味着分支策略要调整不是一个 build 配置能解决的事。6. 把 platform-25 固化进 CI 和团队环境手工装一次能跑换台机器又崩这是存量工程最典型的复发问题。我现在的做法是在仓库里放一个 SDK 引导脚本CI 和新人本地共用同一份#!/usr/bin/env bash set -euo pipefail SDK_ROOT${ANDROID_HOME:-/opt/android-sdk} # 批量接受 license避免非交互环境卡在 y/n yes | sdkmanager --sdk_root$SDK_ROOT --licenses /dev/null # 只安装这条构建链真正需要的三样 sdkmanager --sdk_root$SDK_ROOT \ platform-tools \ platforms;android-25 \ build-tools;25.0.3 # 装完立刻断言不要让错误延后到 Gradle 阶段才暴露 test -x $SDK_ROOT/platform-tools/adb test -f $SDK_ROOT/platforms/android-25/android.jar grep -q AndroidVersion.ApiLevel25 \ $SDK_ROOT/platforms/android-25/source.properties脚本最后这三行断言是关键。缺包的错误如果留到 Gradle 阶段日志会被包在几层异常里排查成本翻几倍。在安装环节就地失败报错信息和补救动作是一一对应的。再往前走一步可以把sdk.dir从local.properties里彻底拿掉构建时用环境变量注入避免每个人的本地路径互相污染# 不写 local.properties直接靠环境变量驱动 export ANDROID_HOME/opt/android-sdk ./gradlew assembleDebug在 CI 镜像里预先烤好platforms/android-25和build-tools/25.0.3后把这两个目录打成层缓存流水线每次省下的不是几十秒下载时间而是网络抖动带来的随机失败。还有一个判断习惯值得说当你发现自己在为一个 API 25 的工程不断找还能兼容的老版本依赖时就该停下来评估这条分支的寿命了。锁版本是为了让存量代码稳定交付不是为了让技术栈停在原地。我一般会设一个明确的时间点到点就把这类工程整体抬到新版本重测一遍而不是一年一年地往上打补丁。从那以后我每次给老工程配环境第一件事都是先跑一遍那个断言脚本确认android.jar、source.properties、build-tools三样东西都在正确的位置再打开 IDE。这个顺序看起来啰嗦但它把最容易玄学化的那类报错压缩成了一次可复现的检查。希望帮到你。本文还有配套的精品资源点击获取

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询