惰性 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")
}

当我想使用混淆的 aars(在发布模式下构建)测试我的应用程序时,问题就开始了。目前 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)?

Reference to same question in Gradle Forum

我知道我的回答有点晚了。

我遇到了类似的问题,我依靠本地 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 缓存),但只是说 :)