Transcoder项目构建分析
一、项目架构
1. 模块结构
Transcoder项目采用多模块架构,包含三个主要模块:
-
lib: 核心库模块
- Maven坐标:
io.deepmedia.community:transcoder-android - 包名:
io.deepmedia.transcoder - 核心功能实现
- 构建产物:
- transcoder-android-0.11.2.aar
- transcoder-android-0.11.2-sources.jar
- transcoder-android-0.11.2-javadoc.jar
- transcoder-android-0.11.2.pom
- Maven坐标:
-
lib-legacy: 遗留兼容模块
- Maven坐标:
com.otaliastudios:transcoder - 包名:
com.otaliastudios.transcoder - 兼容层实现
- 构建产物:
- transcoder-0.11.2.aar
- transcoder-0.11.2-sources.jar
- transcoder-0.11.2-javadoc.jar
- transcoder-0.11.2.pom
- Maven坐标:
-
demo: 示例应用模块
- 展示库的使用方法
- 测试和验证功能
- 构建产物:demo-debug.apk, demo-release.apk
2. 依赖关系
demo
├── :lib
│ ├── com.otaliastudios.opengl:egloo:0.6.1
│ └── androidx.annotation:annotation:1.8.2
├── com.google.android.material:material:1.12.0
└── androidx.appcompat:appcompat:1.7.0
lib-legacy
└── :lib (api)
lib
├── com.otaliastudios.opengl:egloo:0.6.1
└── androidx.annotation:annotation:1.8.2
3. 兼容性设计
lib-legacy模块通过巧妙的设计实现向后兼容:
- 无源码设计:仅包含构建配置,所有功能委托给lib模块
- API透明转发:使用
api依赖确保完整暴露lib模块的API - 包名保持:维护原有的包名空间
- Maven坐标兼容:保留原始的groupId和artifactId
二、构建系统设计
1. 插件体系
1.1 Android Gradle Plugin (AGP)
- 完整名称:com.android.library
- 版本:8.2.2
- 配置位置:build.gradle.kts
- 主要任务:
assembleDebug: 构建调试版本assembleRelease: 构建发布版本bundleDebugAar: 打包调试AARbundleReleaseAar: 打包发布AARgenerateDebugBuildConfig: 生成调试构建配置generateReleaseBuildConfig: 生成发布构建配置
- 配置示例:
plugins {
id("com.android.library") version "8.2.2"
id("org.jetbrains.kotlin.android") version "1.9.0"
}
android {
namespace = "io.deepmedia.transcoder"
compileSdk = 34
defaultConfig {
minSdk = 21
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"))
}
}
}
1.2 Deployer插件
- 完整名称:io.deepmedia.tools.deployer
- 版本:0.8.0
- 配置位置:build.gradle.kts
- 主要任务:
publishToMavenLocal: 发布到本地Maven仓库publishToSonatype: 发布到Maven CentralpublishToGitHub: 发布到GitHub PackagessignReleasePublication: 对发布构件进行签名
- 配置示例:
plugins {
id("io.deepmedia.tools.deployer") version "0.8.0"
}
projectInfo {
groupId = "io.deepmedia.community"
artifactId = "transcoder-android"
release.version = "0.11.2"
description = "Android video transcoder"
url = "https://github.com/natario1/Transcoder"
developer {
id = "natario1"
name = "Mattia Iavarone"
email = "mat.iavarone@gmail.com"
}
}
content {
component {
fromSoftwareComponent("release")
docs(javadocs)
kotlinSources()
}
}
deployer {
nexusSpec("release") {
repository = "https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/"
auth.user = secret("SONATYPE_USER")
auth.password = secret("SONATYPE_PASSWORD")
}
githubSpec {
auth.token = secret("GITHUB_TOKEN")
owner = "natario1"
repository = "Transcoder"
}
signing {
key = secret("SIGNING_KEY")
password = secret("SIGNING_PASSWORD")
}
}
1.3 Dokka插件
- 完整名称:org.jetbrains.dokka
- 版本:1.9.20
- 配置位置:lib/build.gradle.kts
- 主要任务:
dokkaJavadoc: 生成Javadoc格式文档dokkaJavadocJar: 打包Javadoc为JAR文件
- 配置示例:
plugins {
id("org.jetbrains.dokka") version "1.9.20"
}
dependencies {
dokkaPlugin("org.jetbrains.dokka:android-documentation-plugin:1.9.20")
}
val javadocs = tasks.register<Jar>("dokkaJavadocJar") {
dependsOn(tasks.dokkaJavadoc)
from(tasks.dokkaJavadoc.flatMap { it.outputDirectory })
archiveClassifier.set("javadoc")
}
2. 构建流程
2.1 基础构建阶段 (AGP)
- 编译源代码
- 输入:src/main/java, src/main/kotlin
- 输出:build/intermediates/javac, build/tmp/kotlin-classes
- 处理资源文件
- 输入:src/main/res, src/main/assets
- 输出:build/intermediates/compiled_local_resources
- 生成AAR文件
- 输入:编译后的类文件和处理后的资源
- 输出:build/outputs/aar/lib-release.aar
2.2 文档生成阶段 (Dokka)
- 解析源代码注释
- 输入:src/main/java, src/main/kotlin
- 输出:build/dokka/html
- 生成API文档
- 输入:解析后的文档数据
- 输出:build/dokka/javadoc
- 打包为javadoc.jar
- 输入:build/dokka/javadoc
- 输出:build/libs/lib-javadoc.jar
2.3 发布准备阶段 (Deployer)
- 配置Maven POM信息
- 输入:projectInfo配置
- 输出:build/publications/release/pom-default.xml
- 整合构建产物
- 输入:
- AAR:build/outputs/aar/lib-release.aar
- 源码:build/libs/lib-sources.jar
- 文档:build/libs/lib-javadoc.jar
- 输出:build/publications/release
- 输入:
- 生成元数据文件
- 输入:整合后的构建产物
- 输出:
- MD5:*.md5
- SHA1:*.sha1
- SHA256:*.sha256
- 签名:*.asc
2.4 部署阶段 (Deployer)
- 验证构件完整性
- 检查所有必需文件是否存在
- 验证校验和
- 验证签名
- 处理认证信息
- 读取环境变量中的密钥
- 配置仓库认证信息
- 执行上传操作
- 上传所有构件和元数据
- 验证上传结果
3. 关键编译命令
3.1 完整构建命令
# 清理构建目录
./gradlew clean
# 构建所有模块
./gradlew build
# 构建并发布到本地Maven仓库
./gradlew publishToMavenLocal
# 构建并发布到Maven Central
./gradlew publishToSonatype
# 构建并发布到GitHub Packages
./gradlew publishToGitHub
3.2 单模块构建命令
# 构建lib模块
./gradlew :lib:build
# 构建lib-legacy模块
./gradlew :lib-legacy:build
# 构建demo模块
./gradlew :demo:build
3.3 文档生成命令
# 生成HTML文档
./gradlew dokkaHtml
# 生成Javadoc
./gradlew dokkaJavadoc
# 生成Markdown文档
./gradlew dokkaGfm
4. 关键任务分析
4.1 AGP核心任务
assembleDebug
├── compileDebugKotlin
├── compileDebugJavaWithJavac
├── processDebugManifest
├── processDebugResources
└── packageDebugAssets
assembleRelease
├── compileReleaseKotlin
├── compileReleaseJavaWithJavac
├── processReleaseManifest
├── processReleaseResources
└── packageReleaseAssets
bundleReleaseAar
├── assembleRelease
├── bundleLibRuntimeToJar
└── copyDebugJniLibsProjectAndLocalJars
4.2 Dokka任务链
dokkaHtmlJar
├── dokkaHtml
│ └── koltinSourcesJar
└── jarHtml
dokkaJavadocJar
├── dokkaJavadoc
│ └── koltinSourcesJar
└── jarJavadoc
dokkaGfmJar
├── dokkaGfm
│ └── koltinSourcesJar
└── jarGfm
4.3 Deployer任务链
deployLocal
├── generatePomFileForReleasePublication
├── publishReleasePublicationToLocalRepository
└── signReleasePublication
deployToSonatype
├── generatePomFileForReleasePublication
├── publishReleasePublicationToSonatypeRepository
└── signReleasePublication
deployToGitHub
├── generatePomFileForReleasePublication
├── publishReleasePublicationToGitHubPackagesRepository
└── signReleasePublication
4.4 发布相关任务
publish
├── publishToMavenLocal
│ └── deployLocal
├── publishToSonatype
│ └── deployToSonatype
└── publishToGitHub
└── deployToGitHub
signReleasePublication
├── generatePomFileForReleasePublication
└── signAllReleasePublications
generatePomFileForReleasePublication
├── bundleReleaseAar
└── dokkaJavadocJar
4.5 任务输入输出
assembleRelease任务
- 输入:
- src/main/java/
- src/main/kotlin/
- src/main/res/
- src/main/assets/
- AndroidManifest.xml
- 输出:
- build/intermediates/aar_main_jar/release/classes.jar
- build/intermediates/compile_library_classes_jar/release/classes.jar
- build/intermediates/runtime_library_classes_jar/release/classes.jar
- build/intermediates/packaged_res/release/
- build/intermediates/library_manifest/release/
dokkaJavadocJar任务
- 输入:
- src/main/java/
- src/main/kotlin/
- build/tmp/kapt3/stubs/
- 输出:
- build/dokka/javadoc/
- build/libs/lib-javadoc.jar
deployLocal任务
- 输入:
- build/outputs/aar/lib-release.aar
- build/libs/lib-javadoc.jar
- build/libs/lib-sources.jar
- build/publications/release/pom-default.xml
- 输出:
- build/inspect/[group]/[artifact]/[version]/
- transcoder-android-0.11.2.aar (lib模块)
- transcoder-android-0.11.2.pom
- transcoder-android-0.11.2-javadoc.jar
- transcoder-android-0.11.2-sources.jar
- transcoder-0.11.2.aar (lib-legacy模块)
- transcoder-0.11.2.pom
- transcoder-0.11.2-javadoc.jar
- transcoder-0.11.2-sources.jar
- *.md5
- *.sha1
- *.sha256
- *.asc
- build/inspect/[group]/[artifact]/[version]/
注意:输出路径是通过Deployer插件的localSpec配置指定的:
localSpec {
directory.set(rootProject.layout.buildDirectory.get().dir("inspect"))
signing {
key = absent()
password = absent()
}
}
4.6 任务配置示例
Dokka任务配置
tasks.named<org.jetbrains.dokka.gradle.DokkaTask>("dokkaHtml") {
outputDirectory.set(buildDir.resolve("dokka/html"))
dokkaSourceSets {
configureEach {
includeNonPublic.set(false)
skipDeprecated.set(false)
reportUndocumented.set(true)
skipEmptyPackages.set(true)
}
}
}
tasks.register<Jar>("dokkaJavadocJar") {
dependsOn(tasks.dokkaJavadoc)
from(tasks.dokkaJavadoc.flatMap { it.outputDirectory })
archiveClassifier.set("javadoc")
}
Deployer任务说明
Deployer插件会根据配置自动生成以下发布任务:
-
deployLocal: 发布到本地Maven仓库- 自动依赖:generatePomFileForReleasePublication
- 自动依赖:publishReleasePublicationToLocalRepository
- 自动依赖:signReleasePublication
- 执行命令:
./gradlew deployLocal
-
deployToSonatype: 发布到Maven Central- 自动依赖:generatePomFileForReleasePublication
- 自动依赖:publishReleasePublicationToSonatypeRepository
- 自动依赖:signReleasePublication
- 执行命令:
./gradlew deployToSonatype
-
signReleasePublication: 对发布构件进行签名- 自动依赖:generatePomFileForReleasePublication
- 自动配置:在生成POM文件后执行
这些任务都是由Deployer插件根据projectInfo和deployer配置块自动生成的,不需要手动注册。只需要在build.gradle.kts中配置好相关信息,插件就会自动创建和配置这些任务。
三、插件协作机制
1. AGP与Dokka协作
- 共享源代码目录结构
- 支持Android构建变体
- 处理Android资源引用
2. Dokka与Deployer协作
- 文档生成任务集成
- 构件打包协调
- 发布流程整合
3. AGP与Deployer协作
- 软件组件共享
- 构建变体处理
- 构件生成同步
四、发布策略
1. 多仓库支持
- 本地Maven仓库
- Maven Central
- GitHub Packages
2. 构件管理
- AAR文件
- 源代码JAR
- 文档JAR
- POM文件
- 元数据文件
3. 版本控制
- 版本号管理
- 版本号应用
- 版本更新流程
总结
1. 架构设计优势
- 清晰的模块结构,职责分明
- 优雅的兼容性解决方案
- 合理的依赖管理策略
2. 构建系统特点
- 三大核心插件协同工作
- 完善的任务依赖链
- 清晰的执行流程
3. 发布流程亮点
- 多仓库支持
- 完整的构件集
- 安全的认证机制
4. 最佳实践启示
- 模块化设计促进代码复用
- 自动化构建提高效率
- 标准化发布流程保证质量
- 完善的文档支持易于维护
这些特点使得Transcoder项目不仅具有良好的可维护性和可扩展性,也为其他Android库项目提供了值得借鉴的最佳实践。