从源码构建到发布PhotoAffix:Gradle构建流程完全指南
PhotoAffix 是一款开源的 Android 图片拼接应用,支持将多张照片横向或纵向拼成一张长图。本文带你完整走通它的 Gradle 构建流程:克隆源码、看懂多模块工程结构、执行构建命令、理解版本号与发布逻辑,适合刚接触 Android 构建的新手。
1️⃣ 克隆项目,准备工作环境
开始前你需要:
- 🖥️ 一台安装了 JDK 的电脑(该项目基于 Kotlin 1.3 时代的技术栈,JDK 8 最稳妥)
- 📶 可访问依赖仓库的网络(首次构建会下载大量依赖)
克隆仓库:
git clone https://gitcode.com/gh_mirrors/ph/photo-affix
项目自带 Gradle Wrapper(gradlew / gradlew.bat),它会按 gradle/wrapper/gradle-wrapper.properties 自动下载匹配版本的 Gradle,你不需要手动安装 Gradle。
2️⃣ 看懂多模块工程:PhotoAffix 的 Gradle 目录结构
PhotoAffix 是一个典型的 多模块 Gradle 工程,由 settings.gradle 注册了 6 个子模块:
| 模块 | 目录 | 职责 |
|---|---|---|
app | app/ | 应用主模块,唯一的 com.android.application 模块 |
engine | engine/ | 核心引擎:图片拼接(StitchEngine)、尺寸计算、Bitmap 处理 |
viewcomponents | viewcomponents/ | 自定义视图:正方形图片框、圆点、设置面板等 |
prefs | prefs/ | 应用偏好设置(基于 RxKPrefs) |
dialogs | dialogs/ | 关于、图片尺寸、间距等对话框 |
utilities | utilities/ | 工具扩展:IO、协程、Dp 转换、注入器等 |
为什么要拆模块? 好处是:引擎(engine)可以独立编写单元测试(见 engine/src/test/ 下的 StitchEngineTest.kt、AffixEngineTest.kt 等),各模块职责清晰、互不污染,构建时 Gradle 也能按依赖顺序增量编译。
3️⃣ 统一版本管理:dependencies.gradle 是"版本仓库"
打开根目录的 dependencies.gradle,你会看到所有版本号都集中在一个 versions 映射里:
- 构建参数:
minSdk 16、compileSdk 28、buildTools 28.0.3 - 发布参数:
publishVersion 0.7.1、publishVersionCode 27 - 技术栈:Android Gradle Plugin
3.3.1、Kotlin1.3.30、Dagger2.21、Glide4.9.0等
每个模块的 build.gradle 都通过 apply from: '../dependencies.gradle' 引入这份配置,然后引用 versions.kotlin、versions.dagger 之类的键。
💡 这种"单一事实来源"的做法意味着:升级一个依赖只需改一处,全项目保持一致,非常适合学习多模块管理。
4️⃣ 根构建脚本:build.gradle 做了什么
根目录的 build.gradle 负责三件事:
- 加载构建插件(
buildscript块):声明 Google / JCenter 仓库,并引入 Android Gradle Plugin、Kotlin 插件、Spotless 格式化插件和 Versions 插件——版本全部来自versions.gradlePlugin等统一配置。 - 声明依赖仓库(
allprojects块):所有模块从google()、mavenCentral()、jcenter()、jitpack.io拉取依赖。 - 关闭 Javadoc 任务:
tasks.withType(Javadoc).all { enabled = false },加快构建速度。
另外还有两个小脚本值得了解:
- versionsPlugin.gradle:配置
dependencyUpdates任务,检查依赖是否有新版本,并自动过滤掉 alpha / beta / rc 等不稳定版本; - spotless.gradle:配置代码格式检查,Kotlin 用 ktlint、Java 用 google-java-format,并统一文件头的 LICENSE 头。
全局开关在 gradle.properties 中:android.useAndroidX=true 与 android.enableJetifier=true,这是 AndroidX 迁移项目的标准配置。
5️⃣ 模块依赖关系:app 如何组装整个应用
各模块通过 implementation project(':xxx') 互相引用,依赖关系如下:
app ──► engine / viewcomponents / dialogs / utilities / prefs
engine ──► prefs + utilities
viewcomponents ──► prefs + utilities
例如 app/build.gradle 中声明了对 5 个库模块的依赖,并引入 Dagger 依赖注入(kapt 编译器)。engine/build.gradle 则通过 api 暴露协程库,供上层模块使用。
应用入口在 app/src/main/AndroidManifest.xml:声明了 MainActivity、图片共享的 FileProvider,以及支持"从其他应用发送多张图片"的 SEND_MULTIPLE 意图过滤器——这正是 PhotoAffix 接收外部图片的来源。
6️⃣ 一键构建:新手最常用的 4 条 Gradle 命令
在项目根目录执行(Windows 用 gradlew.bat):
./gradlew assembleDebug # 🏗️ 构建调试包,产出 APK
./gradlew test # 🧪 运行 app 与 engine 的单元测试
./gradlew spotlessCheck # 🔍 检查代码格式是否合规
./gradlew dependencyUpdates # 📦 检查依赖库可用更新
- 构建成功后,APK 位于
app/build/outputs/apk/debug/,直接装到手机上即可体验; test任务会执行 MainPresenterTest.kt 等测试,使用 JUnit + Mockito + Truth;- 格式不符时,运行
./gradlew spotlessApply可自动修复。
7️⃣ 版本号与发布流程
PhotoAffix 的发布参数同样集中在 dependencies.gradle:publishVersion(面向用户显示的 0.7.1)与 publishVersionCode(递增的整数 27,Google Play 用它判断版本新旧)。
app/build.gradle 的 defaultConfig 把它们写进 APK 元数据:
applicationId:com.afollestad.photoaffix,应用的唯一标识;versionName/versionCode:决定商店中的版本展示与升级判断。
正式发布时,开发者执行 ./gradlew assembleRelease 打出签名 APK,仓库中的 apk/PhotoAffix.apk 就是构建产物示例;配合应用商店渠道即可分发给用户。
8️⃣ 新手常见问题 FAQ
❓ 首次构建特别慢? 正常现象。Gradle 首次运行要下载 Gradle 发行版与全部依赖,之后构建会明显变快(可开启 Gradle 守护进程与增量构建)。
❓ 什么是 kapt? kotlin-kapt 插件让 Kotlin 支持注解处理器(如 Dagger 的代码生成)。你在 build.gradle 中会看到 kapt 'com.google.dagger:dagger-compiler:...' 这类依赖。
❓ 构建报 Java 版本错误? 该项目使用较老的 AGP 3.3.1 / Kotlin 1.3.30,建议使用 JDK 8 构建,过新的 JDK 可能不兼容。
❓ 如何确认依赖版本是否统一? 全项目共用 dependencies.gradle 的 versions 映射,升级依赖时只需修改这一处,再跑一次 ./gradlew assembleDebug 验证即可。
🎉 恭喜!你已经完整走通了 PhotoAffix 的 Gradle 构建流程:从克隆源码、读懂 6 个模块的分工、统一版本管理,到一键产出 APK 并理解版本号发布机制。试着把 versionName 改成 0.7.2 再构建一次,你就完成了自己的第一次"发版"。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考





