---页首---

Android 工程配置文件全解

Android 工程配置文件全解


0. 版本基线(先对齐,再动手)

0.1 当前工具链版本矩阵

组件 版本 说明
Android Gradle Plugin (AGP) 9.4.0(2026-09 发布) 最新稳定版;Android Studio Quail 4 支持 AGP 7.1–9.4
Gradle 9.6.0(AGP 9.4 最低要求,也是默认) Gradle 9 分支最新为 9.8.0(2026-09-23),AGP 未强制时可取新
JDK 17 Gradle 9 运行 Daemon 要求 Java 17+;AGP 9.4 要求 17
SDK Build Tools 36.0.0 AGP 9.4 默认
NDK 28.2.13676358(r28c) 仅 NDK 项目需要
Kotlin Gradle Plugin (KGP) 2.2.10(AGP 9.x 运行时依赖) 低版本会被 Gradle 自动升级到 2.2.10
最高支持 API 37(Android 17 "Cinnamon Bun",2026-06-16 发布) 官方 build 指南模板当前示例仍写 compileSdk = 36
Android Studio Quail 4 = 2026.1.4(2026-09-01 发布稳定版) 内置 JBR,不需要单独装 JDK 也能启动 IDE

两条硬约束:

  1. Gradle 9 的 Daemon 必须 Java 17+。用 Java 11 会在任何任务执行前直接失败:Gradle requires JVM 17 or later。
  2. AGP 版本与 Gradle 版本强绑定。升级 AGP 必须先升 Gradle wrapper,否则报 Minimum supported Gradle version is 9.6.0。

0.2 事实来源

结论 来源
AGP 9.4 兼容矩阵(Gradle 9.6.0 / JDK 17 / Build Tools 36.0.0 / NDK 28.2) developer.android.com/build/releases/agp-9-4-0-release-notes
AGP 9.0 破坏性变更(newDsl / builtInKotlin / uniquePackageNames) developer.android.com/build/releases/agp-9-0-0-release-notes
settings.gradle.kts / build.gradle.kts 官方模板 developer.android.com/build
Gradle 9 要求 Java 17、配置缓存为首选模式 gradle.org 官方博客 + docs.gradle.org/current/userguide/upgrading_version_9
Android 17 = API 37 Android 官方版本说明

1. 工程文件树:每个文件干什么

MyApp/                              <- 项目根(rootProject)
├── settings.gradle.kts             [核心] 项目名 + 包含哪些模块 + 插件/依赖仓库策略
├── build.gradle.kts                [核心] 根项目脚本:声明各插件版本(apply false)
├── gradle.properties               [核心] Gradle 与 AGP 的全局开关(内存、并行、缓存、新 DSL)
├── gradle/
│   ├── libs.versions.toml          [推荐] 版本目录:所有依赖/插件版本集中一处
│   └── wrapper/
│       ├── gradle-wrapper.jar      包装器二进制(必须提交)
│       └── gradle-wrapper.properties  [核心] 锁定 Gradle 发行版 URL
├── gradlew / gradlew.bat           [核心] 包装器启动脚本(Windows 用 gradlew.bat)
├── local.properties                本机 SDK 路径,**不提交**(写进 .gitignore)
├── keystore/                       签名密钥,**不提交**
├── .gitignore                      忽略 build/、.gradle/、local.properties 等
└── app/                            应用模块(module)
    ├── build.gradle.kts            [核心] 模块构建配置:android{} + dependencies{}
    ├── proguard-rules.pro          混淆/R8 保留规则
    └── src/
        ├── main/
        │   ├── AndroidManifest.xml [核心] 组件声明、权限、入口 Activity
        │   ├── java/ 或 kotlin/    源码
        │   └── res/                资源(layout / values / drawable / mipmap)
        ├── debug/                  debug 变体专属资源与源码
        ├── release/                release 变体专属(如不同 manifest 占位符)
        ├── test/                   本地单元测试(JVM,无需设备)
        └── androidTest/            插桩测试(需要设备/模拟器)

读配置文件的顺序:gradle-wrapper.properties(Gradle 版本)→ gradle.properties(开关)→ settings.gradle.kts(模块与仓库)→ 根 build.gradle.kts(插件版本)→ app/build.gradle.kts(真正干活的地方)。
排查构建问题时也按这个顺序从外向内查。


2. 逐个配置文件

2.1 gradle/wrapper/gradle-wrapper.properties

决定用哪个 Gradle。改 AGP 版本后必须同步改这里。

distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-9.6.0-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
  • gradle-9.6.0-bin.zip vs -all.zip:bin 只有运行时(体积小,够用);all 带源码和文档(IDE 跳转 Gradle 源码时用)。
  • 升级命令(不要手改 URL,容易写错):
    gradlew.bat wrapper --gradle-version 9.6.0
    
  • Windows 上首次运行会下载到 %USERPROFILE%\.gradle\wrapper\dists\。公司网络走代理时在这里配 systemProp.http.proxyHost 到 gradle.properties(不是这个文件)。

2.2 settings.gradle.kts

官方当前模板(三个块各自职责不同,不要合并):

pluginManagement {
    // 插件(com.android.application 等)从哪里下载
    repositories {
        gradlePluginPortal()
        google()
        mavenCentral()
    }
}

dependencyResolutionManagement {
    // 业务依赖(androidx.*、第三方库)从哪里下载
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
    }
}

rootProject.name = "My Application"
include(":app")
// include(":feature-login")   // 多模块时逐个添加
  • FAIL_ON_PROJECT_REPOS = 强制所有模块统一用这里的仓库;模块里再写 repositories {} 会直接构建失败。多仓库治理的标准做法。
  • include(":app") 的 :app 对应目录 app/。路径与模块名不一致时:include(":feature:login") 配 project(":feature:login").projectDir = file("features/login")。
  • Kotlin DSL 里 include(":app") 的引号必须是双引号(单引号是 Char)。

2.3 根 build.gradle.kts

只声明版本,不应用(否则会把插件作用到根项目上):

plugins {
    id("com.android.application") version "9.4.0" apply false
    id("com.android.library")     version "9.4.0" apply false
    id("org.jetbrains.kotlin.android") version "2.4.10" apply false
}

AGP 9.0 起的重大变化 —— 内置 Kotlin:
android.builtInKotlin 默认值在 AGP 9.0 从 false 翻到 true。

  • 含义:不再需要应用 org.jetbrains.kotlin.android(kotlin-android)插件,Kotlin 编译由 AGP 内置提供。
  • 官方 9.0 release notes 明确:kotlin-android 插件与新 DSL 不兼容,必须迁移到内置 Kotlin 或通过 android.builtInKotlin=false 选择停用。
  • 冲突提示:developer.android.com/build 的模板页面(本文抓取时)仍列出了 org.jetbrains.kotlin.android 插件。以 release notes 为准;新建项目时直接沿用 Android Studio 生成的文件,不要手抄旧博客。
  • 若要指定比内置更高的 KGP 版本(如 2.4.10),官方给的方式是在 buildscript { dependencies { classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:KGP_VERSION") } } 中声明。

2.4 gradle.properties(性能与行为开关)

# ---- Gradle 运行时 ----
org.gradle.jvmargs=-Xmx4096m -XX:MaxMetaspaceSize=1024m -Dfile.encoding=UTF-8
org.gradle.parallel=true
org.gradle.caching=true
org.gradle.configuration-cache=true
org.gradle.daemon=true

# ---- Kotlin ----
kotlin.code.style=official

# ---- Android / AGP ----
android.useAndroidX=true
android.nonTransitiveRClass=true
android.enableJetifier=false

# ---- AGP 9 默认已开启,仅在需要临时回退时显式写 ----
# android.builtInKotlin=false
# android.newDsl=false
# android.uniquePackageNames=false

配置缓存(configuration cache)说明:Gradle 9.0 起它是首选执行模式——gradle init 新建的项目默认开启,未开启的构建结束时会收到建议;但存量项目仍默认关闭。计划在 Gradle 10 成为唯一模式。开启后常见报错是 invocation of 'Task.project' at execution time is unsupported,属于插件不兼容,逐个修或用 org.gradle.configuration-cache=false 临时关闭。

2.5 gradle/libs.versions.toml(版本目录,推荐)

AGP 7.4 起官方推荐的依赖管理方式,替代散落在各模块的硬编码版本号。

[versions]
agp = "9.4.0"
kotlin = "2.4.10"
coreKtx = "1.17.0"
appcompat = "1.8.0"
material = "1.13.0"
junit = "4.13.2"

[libraries]
androidx-core-ktx = { module = "androidx.core:core-ktx", version.ref = "coreKtx" }
androidx-appcompat = { module = "androidx.appcompat:appcompat", version.ref = "appcompat" }
material = { module = "com.google.android.material:material", version.ref = "material" }
junit = { module = "junit:junit", version.ref = "junit" }

[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
android-library = { id = "com.android.library", version.ref = "agp" }

配合根 build.gradle.kts:

plugins {
    alias(libs.plugins.android.application) apply false
    alias(libs.plugins.android.library) apply false
}

模块内:

plugins { alias(libs.plugins.android.application) }
dependencies { implementation(libs.androidx.core.ktx) }

注意:TOML 里的 - 在 Kotlin DSL 中变成 .(androidx-core-ktx → libs.androidx.core.ktx)。

2.6 app/build.gradle.kts(真正干活的文件)

按官方模板结构(AGP 9.4 时代):

plugins {
    id("com.android.application")
}

android {
    namespace = "com.example.myapp"     // 1 资源与 R 类的包名
    compileSdk = 37                     // 2 用哪个 API 编译(AGP 9.4 最高支持 37)

    defaultConfig {
        applicationId = "com.example.myapp"   // 3 应用唯一 ID,与 namespace 可不同
        minSdk = 23                           // 4 最低可安装的系统版本
        targetSdk = 37                        // 5 应用已适配到的 API(强烈建议显式写)
        versionCode = 1
        versionName = "1.0"
        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
    }

    signingConfigs {                    // 6 签名(详见 §4)
        create("release") {
            storeFile = file("../keystore/release.jks")
            storePassword = System.getenv("KEYSTORE_PASSWORD") ?: ""
            keyAlias = System.getenv("KEY_ALIAS") ?: ""
            keyPassword = System.getenv("KEY_PASSWORD") ?: ""
        }
    }

    buildTypes {
        getByName("release") {
            signingConfig = signingConfigs.getByName("release")
            isMinifyEnabled = true                 // R8 代码缩减
            isShrinkResources = true               // 资源缩减
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro"
            )
        }
        // debug 类型已内置:可调试 + 自动打 debug 签名,不需要显式声明
    }

    // 多风味(可选):变体名 = flavor + BuildType,如 freeDebug / paidRelease
    // 完整机制(笛卡尔积、源码集合并、变体过滤、依赖匹配)见 product-flavors.md
    flavorDimensions += "tier"
    productFlavors {
        create("free") { dimension = "tier"; applicationIdSuffix = ".free" }
        create("paid") { dimension = "tier"; applicationIdSuffix = ".paid" }
    }

    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_17
        targetCompatibility = JavaVersion.VERSION_17
    }
    // AGP 9 内置 Kotlin 场景下,jvmTarget 通过 kotlin{} 块设置
    kotlin { jvmToolchain(17) }

    buildFeatures {
        // compose = true        // Jetpack Compose 项目
        viewBinding = true       // ViewBinding
    }

    packaging {
        resources {
            excludes += "/META-INF/{AL2.0,LGPL2.1}"   // 常见的 license 冲突去重
        }
    }
}

dependencies {
    implementation(project(":lib"))                  // 模块依赖
    implementation("androidx.core:core-ktx:1.17.0")
    implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))
    testImplementation("junit:junit:4.13.2")
    androidTestImplementation("androidx.test.ext:junit:1.2.1")
}

五组容易混淆的 ID / 版本,一张表说清:

字段 作用 是否等于其它字段
namespace R 类、BuildConfig 的包名;资源引用用 可与 applicationId 不同
applicationId 设备上/商店里的唯一标识 改名 = 换了一个新应用
compileSdk 编译时可用的 API 上限 只是编译期,不影响运行行为
minSdk 可安装的最低系统版本 决定商店可见范围
targetSdk 声明"已适配到"的 API 决定系统是否启用新行为

targetSdk 有个 AGP 9.0 的行为变更:属性 android.sdk.defaultTargetSdkToCompileSdkIfUnset 从 false 变为 true —— 不写 targetSdk 时,默认值由原来的 minSdk 改为 compileSdk。所以必须显式写 targetSdk,否则一次 compileSdk 升级会静默改变应用的运行时行为。

2.7 local.properties

## Windows 下反斜杠必须转义,或用正斜杠
sdk.dir=C\:\\Users\\admin\\AppData\\Local\\Android\\Sdk
sdk.dir=C:/Users/admin/AppData/Local/Android/Sdk
  • 由 Android Studio 首次打开项目时自动生成,必须写进 .gitignore(含本机绝对路径)。
  • 命令行构建找不到 SDK 时,也可用环境变量 ANDROID_HOME 或 ANDROID_SDK_ROOT 代替该文件。

2.8 AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_LOCAL_NETWORK" />  <!-- API 37 新增 -->

    <application
        android:name=".MyApplication"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/Theme.MyApp"
        android:allowBackup="false"
        android:usesCleartextTraffic="false">

        <activity
            android:name=".MainActivity"
            android:exported="true">          <!-- API 31+ 必须显式声明 -->
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>
  • package 属性已移除:AGP 7.3 起包名由 build.gradle.kts 的 namespace 提供,Manifest 里不要再写 package="..."。
  • <uses-sdk> 不要手写:minSdk / targetSdk 由 Gradle 注入,手写会被覆盖并触发警告。
  • android:exported="true":targetSdk 31+ 起,带 intent-filter 的组件必须显式声明。

2.9 proguard-rules.pro

-keepclassmembers class * extends androidx.appcompat.app.AppCompatActivity { ... }
-keep class com.example.myapp.model.** { *; }      // Gson/反射解析的 model 必须保留
-keepattributes Signature, *Annotation*, InnerClasses, EnclosingMethod
-keepclassmembers,allowoptimization enum * { public static **[] values(); public static ** valueOf(java.lang.String); }
-dontwarn okhttp3.**

判断规则:只有被反射、序列化、JNI 或 AndroidManifest 间接引用的代码需要 keep。R8 报错时先跑 gradlew :app:analyzeReleaseR8Config(AGP 9.3+ 新增的独立任务,不跑完整打包就能出报告)。

2.10 .gitignore(Android 标准)

*.iml
.gradle/
/local.properties
/.idea/
.DS_Store
build/
captures/
.externalNativeBuild/
.cxx/
local.properties
keystore/
*.jks
*.keystore

2.11 签名密钥与环境变量

不要把密码写进 build.gradle.kts(会被提交到仓库)。两种做法:

  1. keystore.properties(加入 .gitignore)+ 在脚本里读取:
    val ksProps = java.util.Properties().apply {
        rootProject.file("keystore.properties").takeIf { it.exists() }?.inputStream()?.use { load(it) }
    }
    
  2. 从环境变量读(CI 友好,本文 §2.6 示例即此方式):System.getenv("KEYSTORE_PASSWORD")。

生成密钥:

keytool -genkey -v -keystore keystore\release.jks -keyalg RSA -keysize 2048 -validity 10000 -alias mykey

3. AGP 9.0 破坏性变更清单(升级必读)

AGP 8 → 9 是这几年来最大的一次断裂。如果你的项目是从 AGP 8 升上来的,以下每一条都可能让构建直接失败。

变更 默认行为 影响 处理
android.newDsl false → true 旧的 Variant API(android.applicationVariants、variantFilter)不再可用 迁移到 androidComponents { onVariants {} } / beforeVariants {};临时停用 android.newDsl=false(AGP 10 会移除该停用开关)
android.builtInKotlin false → true 不需要 org.jetbrains.kotlin.android 插件;该插件与新 DSL 不兼容 删掉 kotlin-android 插件;Kotlin 版本由 AGP 内置 KGP 2.2.10 提供
android.uniquePackageNames false → true 每个 library 模块必须有唯一 namespace 补齐 namespace;冲突时临时 android.uniquePackageNames=false
android.sdk.defaultTargetSdkToCompileSdkIfUnset false → true 未写 targetSdk 时,默认值从 minSdk 变为 compileSdk 显式写 targetSdk
CommonExtension 泛型参数 移除 CommonExtension<*, *, *, *, *, *> 编译不过 改为 CommonExtension,defaultConfig {} 改为 defaultConfig.apply {}
Variant API 重命名 — targetSdkVersion → targetSdk、minSdkVersion → minSdk、ComponentBuilder.enabled → enable 按新名改
wearApp 配置 移除 嵌入式 Wear OS 应用构建失败 改用独立 Wear 模块
密度分包(DensitySplit) 移除 splits { density {} } 失效 改用 Android App Bundle
androidDependencies / sourceSets 报告任务 移除 相关命令失效 用 gradlew :app:dependencies
android.defaults.buildfeatures.aidl / renderscript 移除 属性无效 在模块里 buildFeatures { aidl = true }
android.r8.integratedResourceShrinking 设置即报错 资源缩减已始终作为 R8 一部分运行 删除该属性

AGP 10(预告):新 Variant API 强制启用,不允许 opt-out;动态功能模块与基础模块的变体维度必须严格 1:1,否则构建失败。


4. 构建变体与产物

变体名规则:<productFlavor><BuildType>(首字母大写拼 BuildType),例如 freeDebug / paidRelease。
对应的 Gradle 任务:assembleFreeDebug、installPaidRelease、testFreeDebugUnitTest。

gradlew.bat :app:tasks --group android      :: 列出所有 Android 相关任务
gradlew.bat :app:tasks --all                :: 列出全部任务(含每个变体的)

产物路径:

产物 路径
Debug APK app/build/outputs/apk/debug/app-debug.apk
Release APK app/build/outputs/apk/release/app-release.apk
AAB(上架用) app/build/outputs/bundle/release/app-release.aab
混淆映射 app/build/outputs/mapping/release/mapping.txt
Lint 报告 app/build/reports/lint-results.html
单元测试报告 app/build/reports/tests/testDebugUnitTest/index.html

5. 常见构建错误 → 原因

报错关键片段 原因 处理
Minimum supported Gradle version is 9.6.0 AGP 9.4 与 Gradle 版本不匹配 gradlew.bat wrapper --gradle-version 9.6.0
Gradle requires JVM 17 or later JAVA_HOME 指向 JDK 11/8 装 JDK 17 并在 Studio 里指定,或设 org.gradle.java.home
Could not determine the dependencies of null / 插件找不到 settings.gradle.kts 缺 google() 或 gradlePluginPortal() 补仓库
Plugin [id: 'kotlin-android'] ... incompatible AGP 9 内置 Kotlin 与 kotlin-android 插件冲突 删除该插件;或 android.builtInKotlin=false
'applicationVariants' is not accessible AGP 9 新 DSL 关闭了旧 API 改用 androidComponents { onVariants {} };或 android.newDsl=false
Namespace not specified 模块未声明 namespace android { namespace = "..." }
INSTALL_FAILED_VERSION_DOWNGRADE 装的包 versionCode 更低 adb install -r -d app.apk 或先卸载
INSTALL_FAILED_UPDATE_INCOMPATIBLE 签名不同 先 adb uninstall <pkg>
usesCleartextTraffic 警告(targetSdk 37) Android 17 计划移除该属性 改用 network security config
Task.project at execution time is unsupported 配置缓存不兼容的插件 --no-configuration-cache 临时绕过,再逐个替换插件
Windows 上 File has been truncated / 文件被占用 Gradle daemon 或 Studio 持有文件句柄 gradlew.bat --stop 后重试

6. 上手动线(新机器 / 新项目)

  1. 装 Android Studio Quail 4(自带 JBR,能直接开 IDE)。
  2. 命令行构建另需 JDK 17(Gradle Daemon 要求),设 JAVA_HOME(或只在 gradle.properties 写 org.gradle.java.home)。
  3. 设 ANDROID_HOME 指向 SDK 目录,并把 platform-tools 加进 PATH(adb 全靠它)。
  4. 新建项目时用 Android Studio 模板生成,不要手抄网络上的旧配置(AGP 9 的写法和 AGP 8 差异很大)。
  5. 首次构建用 gradlew.bat :app:assembleDebug --scan(或至少加 --info),把依赖下载和任务耗时看清楚。
posted @ 2026-10-19 14:03  20190311  阅读(30)  评论(0)    收藏  举报
---页脚---