惰性 Android 依赖项。如何在 gradle 依赖解析之前构建 AARs 库
Lazy Android dependencies. How to build AARs libraries before gradle dependency resolution
我有一个闭源库组的简化项目架构:
- app
> references library1, library2
- library1
- library2
> references library3
- library3
所有 3 个库都生成 aar
个文件,这些文件可以像往常一样在应用程序依赖项中引用。
dependencies {
implementation project(":library1")
implementation project(":library2")
}
当我想使用混淆的 aar
s(在发布模式下构建)测试我的应用程序时,问题就开始了。目前 Android 插件忽略了这一点,所以我发现的唯一方法是使用预构建的 aars 来做到这一点。
dependencies {
//for debug build just use the local project
debugImplementation project(":library1")
debugImplementation project(":library2")
//for release build use manually added aar in libs folder
releaseImplementation (name: 'library1-release', ext: 'aar')
releaseImplementation (name: 'library2-release', ext: 'aar')
//i need to add library3 too otherwise it will not find
//method referenced there because aar are not bundled togheter
//by default
releaseImplementation (name: 'library3-release', ext: 'aar')
}
这很好用。
为此,我创建了一个像这样的小脚本(在 app/scripts/build-aar.sh 中)
//move from scripts folder to root project folder
cd "$(dirname "$BASH_SOURCE")/../../"
//assembleRelease all the aar (which enables Proguard obfuscation)
./gradlew clean assembleRelease --info &&
//copy them in the app libs folder
cp -rf library1/build/outputs/aar/library1-release.aar app/libs/library1-release.aar
cp -rf library2/build/outputs/aar/library2-release.aar app/libs/library2-release.aar
cp -rf library3/build/outputs/aar/library3-release.aar app/libs/library3-release.aar
这种方法的问题是我需要对 git 中的所有 aar 进行版本控制,否则当我 select "Release" 作为构建变体时,应用程序无法编译。
虽然我会git忽略 libs 文件夹中的所有 aar,并在应用程序搜索它的依赖项之前即时构建它们。
我试过这样的东西:
applicationVariants.all { variant ->
if (variant.buildType.name == "release") {
variant.preBuildProvider.configure {
dependsOn(buildReleaseAar)
}
}
}
task buildReleaseAar {
dependsOn (
':library1:assembleRelease',
':library2:assembleRelease',
':library3:assembleRelease'
)
doLast {
//copy the aars from build folders in app/libs folder
}
}
但是之前已经检查了依赖项,所以如果 libs 文件夹中没有 aars,我什至无法再同步项目。
解决这个问题的伪逻辑应该是:
1) 有一个依赖项的新任务,如 (obfuscatedAar)
2) 执行此任务以检查 libs 文件夹中是否有 aar,如果没有则 运行 在所有 3 个库上进行 assembleRelease 并将生成的 AAR 复制到那里
像这样:
configurations {
releaseObfuscatedAar
}
dependencies {
//other implementations libs
//for debug build just use the local project
debugImplementation project(":library1")
debugImplementation project(":library2")
releaseObfuscatedAar('library1')
releaseObfuscatedAar('library2')
releaseObfuscatedAar('library3')
}
//and some other task that build the aar before checking if
//dependency is present
Questions:
- Is this possible?
- Is this a good approach to test my proguard-rules added in libraries projects (and be sure I didn't broke public API when
obfuscation is on)?
我知道我的回答有点晚了。
我遇到了类似的问题,我依靠本地 maven 存储库解决了它,这是位于 ~/.m2
.
中的默认存储库
我一开始的方法基本上是让我的 :app:assemble${variant.name}
任务依赖于 :my-library:publishToMavenLocal
。
这种方法可行,但在库将其 aar
置于本地 Maven 存储库之前,仍会评估 dependencies {...}
块。此外,如果您只是在 Android Studio/IntelliJ.
中同步项目,assemble
任务就不是 运行
因此这就是我最后所做的:
tasks.getByPath(":prepareKotlinBuildScriptModel").dependsOn(":library:publishToMavenLocal")
这使得在同步项目时本地 Maven 存储库中会填充您的 aar
,因此在后面的步骤中会满足对这些 aar
的依赖。
如果您想尝试一下,请不要忘记在 repositories {...}
闭包中添加 mavenLocal()
。
当然,这个解决方案是有代价的,那就是每次同步都要部署本地maven。就我而言,它相对较快(由于 gradle 缓存),但只是说 :)
我有一个闭源库组的简化项目架构:
- app
> references library1, library2
- library1
- library2
> references library3
- library3
所有 3 个库都生成 aar
个文件,这些文件可以像往常一样在应用程序依赖项中引用。
dependencies {
implementation project(":library1")
implementation project(":library2")
}
当我想使用混淆的 aar
s(在发布模式下构建)测试我的应用程序时,问题就开始了。目前 Android 插件忽略了这一点,所以我发现的唯一方法是使用预构建的 aars 来做到这一点。
dependencies {
//for debug build just use the local project
debugImplementation project(":library1")
debugImplementation project(":library2")
//for release build use manually added aar in libs folder
releaseImplementation (name: 'library1-release', ext: 'aar')
releaseImplementation (name: 'library2-release', ext: 'aar')
//i need to add library3 too otherwise it will not find
//method referenced there because aar are not bundled togheter
//by default
releaseImplementation (name: 'library3-release', ext: 'aar')
}
这很好用。
为此,我创建了一个像这样的小脚本(在 app/scripts/build-aar.sh 中)
//move from scripts folder to root project folder
cd "$(dirname "$BASH_SOURCE")/../../"
//assembleRelease all the aar (which enables Proguard obfuscation)
./gradlew clean assembleRelease --info &&
//copy them in the app libs folder
cp -rf library1/build/outputs/aar/library1-release.aar app/libs/library1-release.aar
cp -rf library2/build/outputs/aar/library2-release.aar app/libs/library2-release.aar
cp -rf library3/build/outputs/aar/library3-release.aar app/libs/library3-release.aar
这种方法的问题是我需要对 git 中的所有 aar 进行版本控制,否则当我 select "Release" 作为构建变体时,应用程序无法编译。
虽然我会git忽略 libs 文件夹中的所有 aar,并在应用程序搜索它的依赖项之前即时构建它们。
我试过这样的东西:
applicationVariants.all { variant ->
if (variant.buildType.name == "release") {
variant.preBuildProvider.configure {
dependsOn(buildReleaseAar)
}
}
}
task buildReleaseAar {
dependsOn (
':library1:assembleRelease',
':library2:assembleRelease',
':library3:assembleRelease'
)
doLast {
//copy the aars from build folders in app/libs folder
}
}
但是之前已经检查了依赖项,所以如果 libs 文件夹中没有 aars,我什至无法再同步项目。
解决这个问题的伪逻辑应该是:
1) 有一个依赖项的新任务,如 (obfuscatedAar)
2) 执行此任务以检查 libs 文件夹中是否有 aar,如果没有则 运行 在所有 3 个库上进行 assembleRelease 并将生成的 AAR 复制到那里
像这样:
configurations {
releaseObfuscatedAar
}
dependencies {
//other implementations libs
//for debug build just use the local project
debugImplementation project(":library1")
debugImplementation project(":library2")
releaseObfuscatedAar('library1')
releaseObfuscatedAar('library2')
releaseObfuscatedAar('library3')
}
//and some other task that build the aar before checking if
//dependency is present
Questions:
- Is this possible?
- Is this a good approach to test my proguard-rules added in libraries projects (and be sure I didn't broke public API when obfuscation is on)?
我知道我的回答有点晚了。
我遇到了类似的问题,我依靠本地 maven 存储库解决了它,这是位于 ~/.m2
.
我一开始的方法基本上是让我的 :app:assemble${variant.name}
任务依赖于 :my-library:publishToMavenLocal
。
这种方法可行,但在库将其 aar
置于本地 Maven 存储库之前,仍会评估 dependencies {...}
块。此外,如果您只是在 Android Studio/IntelliJ.
assemble
任务就不是 运行
因此这就是我最后所做的:
tasks.getByPath(":prepareKotlinBuildScriptModel").dependsOn(":library:publishToMavenLocal")
这使得在同步项目时本地 Maven 存储库中会填充您的 aar
,因此在后面的步骤中会满足对这些 aar
的依赖。
如果您想尝试一下,请不要忘记在 repositories {...}
闭包中添加 mavenLocal()
。
当然,这个解决方案是有代价的,那就是每次同步都要部署本地maven。就我而言,它相对较快(由于 gradle 缓存),但只是说 :)