Gradle Android 插件:挂接到 post-编译所有产品口味的任务
Gradle Android Plugin: Hook into post-compile task for all product flavors
我需要执行我自己的代码(通过 javaexec),在我的 android 项目被 gradle 编译之后但在它被打包成 apk 之前(并且在事实上,在资源被移动到它们的最终目的地之前)。所以我用了:
gradlew tasks --all
获取可用任务列表。我使用的是产品口味,所以几乎所有任务的名称都介于两者之间,例如:
assembleFlavorA
或
installFlavorB
等...
我现在能做的是在编译开始之前通过挂接到 preBuild 任务来执行我自己的任务:
preBuild <<{
//Do some stuff
}
以上是为每个构建变体调用的,这正是我想要的。
但是,当我尝试对 assemble 任务或构建任务进行相同操作时:
assemble <<{
//Get's never executed
}
build <<{
//Get's never executed
}
无论我正在构建哪种产品风格,以上代码都不会执行。查看 releaseFlavorA 的依赖列表:
myapp:assembleFlavorARelease - Assembles the Release build for flavor FlavorA [library:bundleRelease]
myapp:checkFlavorAReleaseManifest
myapp:compileFlavorAReleaseAidl
myapp:compileFlavorAReleaseJava
myapp:compileFlavorAReleaseNdk
myapp:compileFlavorAReleaseRenderscript
myapp:dexFlavorARelease
myapp:generateFlavorAReleaseAssets
myapp:generateFlavorAReleaseBuildConfig
myapp:generateFlavorAReleaseResValues
myapp:generateFlavorAReleaseResources
myapp:generateFlavorAReleaseSources
myapp:lintVitalFlavorARelease - Runs lint on just the fatal issues in the FlavorARelease build
myapp:mergeFlavorAReleaseAssets
myapp:mergeFlavorAReleaseResources
myapp:packageFlavorARelease
myapp:preFlavorADebugBuild
myapp:preFlavorAReleaseBuild
myapp:preAltdorfDebugBuild
myapp:preAltdorfReleaseBuild
myapp:preBerlinDebugBuild
myapp:preBerlinReleaseBuild
myapp:preBuild
myapp:prepareFlavorAReleaseDependencies
myapp:prepareComAndroidSupportAppcompatV71910Library - Prepare com.android.support:appcompat-v7:19.1.0
myapp:prepareTrunkGradleLibraryUnspecifiedLibrary - Prepare trunk-gradle:library:unspecified
myapp:processFlavorAReleaseJavaRes
myapp:processFlavorAReleaseManifest
myapp:processFlavorAReleaseResources
myapp:validateReleaseSigning
myapp:zipalignFlavorARelease
我只看到 preBuild 但 assemble 和构建都没有,这很奇怪,因为它在 运行
时显示
gradlew tasks
但是上面列表中的大多数方法都是特定于风味的,我不想执行相同的任务 20 次,因为我有 20 种不同的风味...那么一旦编译完成,我该如何执行必要的任务已完成,但尚未为所有口味打包 APK?类似于:
//I know there is no task called "postCompile" - so anything post compiling and pre-packaging would be fine
postCompile << {
//Do something that needs to be done for all flavors
}
编辑
因此,我在构建 customerA 时重新检查了命令行输出,例如通过:
gradlew assembleCustomerARelease
C:\Users\user\workspace\android\trunk-gradle>gradlew assembleCustomerARelease
:library:compileLint
:library:copyReleaseLint UP-TO-DATE
:library:mergeReleaseProguardFiles UP-TO-DATE
:library:preBuild
:library:preReleaseBuild
:library:checkReleaseManifest
:library:preDebugBuild
:library:preDebugTestBuild
:library:prepareComAndroidSupportAppcompatV71910Library UP-TO-DATE
:library:prepareReleaseDependencies
:library:compileReleaseAidl UP-TO-DATE
:library:compileReleaseRenderscript UP-TO-DATE
:library:generateReleaseBuildConfig UP-TO-DATE
:library:generateReleaseAssets UP-TO-DATE
:library:mergeReleaseAssets UP-TO-DATE
:library:generateReleaseResValues UP-TO-DATE
:library:generateReleaseResources UP-TO-DATE
:library:mergeReleaseResources UP-TO-DATE
:library:processReleaseManifest UP-TO-DATE
:library:processReleaseResources UP-TO-DATE
:library:generateReleaseSources UP-TO-DATE
:library:compileReleaseJava UP-TO-DATE
:library:processReleaseJavaRes UP-TO-DATE
:library:packageReleaseJar UP-TO-DATE
:library:compileReleaseNdk UP-TO-DATE
:library:packageReleaseJniLibs UP-TO-DATE
:library:packageReleaseLocalJar UP-TO-DATE
:library:packageReleaseRenderscript UP-TO-DATE
:library:packageReleaseResources UP-TO-DATE
:library:bundleRelease UP-TO-DATE
:myapp:preBuild
Path to customer file: C:\Users\user\workspace\android\trunk-gradle\myapp\src\CustomerA\res\xml\customer.xml
Selected server: release
:myapp:preCustomerAReleaseBuild
:myapp:checkCustomerAReleaseManifest
:myapp:preCustomerADebugBuild
:myapp:preCustomerBDebugBuild
:myapp:preCustomerBReleaseBuild
:myapp:preCustomerCDebugBuild
:myapp:preCustomerCReleaseBuild
:myapp:prepareComAndroidSupportAppcompatV71910Library UP-TO-DATE
:myapp:prepareTrunkGradleLibraryUnspecifiedLibrary UP-TO-DATE
:myapp:prepareCustomerAReleaseDependencies
:myapp:compileCustomerAReleaseAidl UP-TO-DATE
:myapp:compileCustomerAReleaseRenderscript UP-TO-DATE
:myapp:generateCustomerAReleaseBuildConfig UP-TO-DATE
:myapp:generateCustomerAReleaseAssets UP-TO-DATE
:myapp:mergeCustomerAReleaseAssets UP-TO-DATE
:myapp:generateCustomerAReleaseResValues UP-TO-DATE
:myapp:generateCustomerAReleaseResources UP-TO-DATE
:myapp:mergeCustomerAReleaseResources UP-TO-DATE
:myapp:processCustomerAReleaseManifest UP-TO-DATE
:myapp:processCustomerAReleaseResources UP-TO-DATE
:myapp:generateCustomerAReleaseSources UP-TO-DATE
:myapp:compileCustomerAReleaseJava UP-TO-DATE
:myapp:lintVitalCustomerARelease
//Some logoutput from the dex-ing task not really relevant in this case
:myapp:dexCustomerARelease UP-TO-DATE
:myapp:processCustomerAReleaseJavaRes UP-TO-DATE
:myapp:validateReleaseSigning
:myapp:packageCustomerARelease UP-TO-DATE
:myapp:zipalignCustomerARelease UP-TO-DATE
:myapp:assembleCustomerARelease
BUILD SUCCESSFUL
Total time: 25.451 secs
所以根据上面的构建输出,我假设 preBuild 实际上发生在编译阶段之后?因为它列在 compileReleaseJava 和其他编译任务之后。如果是这种情况,那么 "preBuild" 就足以满足我的要求。
更新 04.02.2015
问题仍然悬而未决,但我已更改我的代码以不再依赖它。我没有尝试使用必须首先由我的项目编译的 java class,而是为该 class 创建了另一个项目,它生成了一个 jar 文件,我认为它可以使用- 详情可在此处找到:
但是 - 我认为知道这个问题的答案可能仍然很有趣。
您不能像这样扩展 assemble 和构建任务,因为它们在 Gradle 的执行阶段之前被适当的构建变体相关任务替换。例如:assemble 变为 assembleRelease.
不过,当构建图放在一起时,您仍然可以连接到构建过程。如果你想在打包任务之前执行你自己的代码,你可以使用这个片段:
task doStuff << {
// Do stuff
}
tasks.whenTaskAdded { theTask ->
if (theTask.name.contains('package')) {
theTask.dependsOn 'doStuff'
}
}
此代码不会区分构建变体;如有必要,您可以在 if 条件下执行此操作。
我需要执行我自己的代码(通过 javaexec),在我的 android 项目被 gradle 编译之后但在它被打包成 apk 之前(并且在事实上,在资源被移动到它们的最终目的地之前)。所以我用了:
gradlew tasks --all
获取可用任务列表。我使用的是产品口味,所以几乎所有任务的名称都介于两者之间,例如:
assembleFlavorA
或
installFlavorB
等...
我现在能做的是在编译开始之前通过挂接到 preBuild 任务来执行我自己的任务:
preBuild <<{
//Do some stuff
}
以上是为每个构建变体调用的,这正是我想要的。 但是,当我尝试对 assemble 任务或构建任务进行相同操作时:
assemble <<{
//Get's never executed
}
build <<{
//Get's never executed
}
无论我正在构建哪种产品风格,以上代码都不会执行。查看 releaseFlavorA 的依赖列表:
myapp:assembleFlavorARelease - Assembles the Release build for flavor FlavorA [library:bundleRelease]
myapp:checkFlavorAReleaseManifest
myapp:compileFlavorAReleaseAidl
myapp:compileFlavorAReleaseJava
myapp:compileFlavorAReleaseNdk
myapp:compileFlavorAReleaseRenderscript
myapp:dexFlavorARelease
myapp:generateFlavorAReleaseAssets
myapp:generateFlavorAReleaseBuildConfig
myapp:generateFlavorAReleaseResValues
myapp:generateFlavorAReleaseResources
myapp:generateFlavorAReleaseSources
myapp:lintVitalFlavorARelease - Runs lint on just the fatal issues in the FlavorARelease build
myapp:mergeFlavorAReleaseAssets
myapp:mergeFlavorAReleaseResources
myapp:packageFlavorARelease
myapp:preFlavorADebugBuild
myapp:preFlavorAReleaseBuild
myapp:preAltdorfDebugBuild
myapp:preAltdorfReleaseBuild
myapp:preBerlinDebugBuild
myapp:preBerlinReleaseBuild
myapp:preBuild
myapp:prepareFlavorAReleaseDependencies
myapp:prepareComAndroidSupportAppcompatV71910Library - Prepare com.android.support:appcompat-v7:19.1.0
myapp:prepareTrunkGradleLibraryUnspecifiedLibrary - Prepare trunk-gradle:library:unspecified
myapp:processFlavorAReleaseJavaRes
myapp:processFlavorAReleaseManifest
myapp:processFlavorAReleaseResources
myapp:validateReleaseSigning
myapp:zipalignFlavorARelease
我只看到 preBuild 但 assemble 和构建都没有,这很奇怪,因为它在 运行
时显示gradlew tasks
但是上面列表中的大多数方法都是特定于风味的,我不想执行相同的任务 20 次,因为我有 20 种不同的风味...那么一旦编译完成,我该如何执行必要的任务已完成,但尚未为所有口味打包 APK?类似于:
//I know there is no task called "postCompile" - so anything post compiling and pre-packaging would be fine
postCompile << {
//Do something that needs to be done for all flavors
}
编辑 因此,我在构建 customerA 时重新检查了命令行输出,例如通过:
gradlew assembleCustomerARelease
C:\Users\user\workspace\android\trunk-gradle>gradlew assembleCustomerARelease
:library:compileLint
:library:copyReleaseLint UP-TO-DATE
:library:mergeReleaseProguardFiles UP-TO-DATE
:library:preBuild
:library:preReleaseBuild
:library:checkReleaseManifest
:library:preDebugBuild
:library:preDebugTestBuild
:library:prepareComAndroidSupportAppcompatV71910Library UP-TO-DATE
:library:prepareReleaseDependencies
:library:compileReleaseAidl UP-TO-DATE
:library:compileReleaseRenderscript UP-TO-DATE
:library:generateReleaseBuildConfig UP-TO-DATE
:library:generateReleaseAssets UP-TO-DATE
:library:mergeReleaseAssets UP-TO-DATE
:library:generateReleaseResValues UP-TO-DATE
:library:generateReleaseResources UP-TO-DATE
:library:mergeReleaseResources UP-TO-DATE
:library:processReleaseManifest UP-TO-DATE
:library:processReleaseResources UP-TO-DATE
:library:generateReleaseSources UP-TO-DATE
:library:compileReleaseJava UP-TO-DATE
:library:processReleaseJavaRes UP-TO-DATE
:library:packageReleaseJar UP-TO-DATE
:library:compileReleaseNdk UP-TO-DATE
:library:packageReleaseJniLibs UP-TO-DATE
:library:packageReleaseLocalJar UP-TO-DATE
:library:packageReleaseRenderscript UP-TO-DATE
:library:packageReleaseResources UP-TO-DATE
:library:bundleRelease UP-TO-DATE
:myapp:preBuild
Path to customer file: C:\Users\user\workspace\android\trunk-gradle\myapp\src\CustomerA\res\xml\customer.xml
Selected server: release
:myapp:preCustomerAReleaseBuild
:myapp:checkCustomerAReleaseManifest
:myapp:preCustomerADebugBuild
:myapp:preCustomerBDebugBuild
:myapp:preCustomerBReleaseBuild
:myapp:preCustomerCDebugBuild
:myapp:preCustomerCReleaseBuild
:myapp:prepareComAndroidSupportAppcompatV71910Library UP-TO-DATE
:myapp:prepareTrunkGradleLibraryUnspecifiedLibrary UP-TO-DATE
:myapp:prepareCustomerAReleaseDependencies
:myapp:compileCustomerAReleaseAidl UP-TO-DATE
:myapp:compileCustomerAReleaseRenderscript UP-TO-DATE
:myapp:generateCustomerAReleaseBuildConfig UP-TO-DATE
:myapp:generateCustomerAReleaseAssets UP-TO-DATE
:myapp:mergeCustomerAReleaseAssets UP-TO-DATE
:myapp:generateCustomerAReleaseResValues UP-TO-DATE
:myapp:generateCustomerAReleaseResources UP-TO-DATE
:myapp:mergeCustomerAReleaseResources UP-TO-DATE
:myapp:processCustomerAReleaseManifest UP-TO-DATE
:myapp:processCustomerAReleaseResources UP-TO-DATE
:myapp:generateCustomerAReleaseSources UP-TO-DATE
:myapp:compileCustomerAReleaseJava UP-TO-DATE
:myapp:lintVitalCustomerARelease
//Some logoutput from the dex-ing task not really relevant in this case
:myapp:dexCustomerARelease UP-TO-DATE
:myapp:processCustomerAReleaseJavaRes UP-TO-DATE
:myapp:validateReleaseSigning
:myapp:packageCustomerARelease UP-TO-DATE
:myapp:zipalignCustomerARelease UP-TO-DATE
:myapp:assembleCustomerARelease
BUILD SUCCESSFUL
Total time: 25.451 secs
所以根据上面的构建输出,我假设 preBuild 实际上发生在编译阶段之后?因为它列在 compileReleaseJava 和其他编译任务之后。如果是这种情况,那么 "preBuild" 就足以满足我的要求。
更新 04.02.2015
问题仍然悬而未决,但我已更改我的代码以不再依赖它。我没有尝试使用必须首先由我的项目编译的 java class,而是为该 class 创建了另一个项目,它生成了一个 jar 文件,我认为它可以使用- 详情可在此处找到:
但是 - 我认为知道这个问题的答案可能仍然很有趣。
您不能像这样扩展 assemble 和构建任务,因为它们在 Gradle 的执行阶段之前被适当的构建变体相关任务替换。例如:assemble 变为 assembleRelease.
不过,当构建图放在一起时,您仍然可以连接到构建过程。如果你想在打包任务之前执行你自己的代码,你可以使用这个片段:
task doStuff << {
// Do stuff
}
tasks.whenTaskAdded { theTask ->
if (theTask.name.contains('package')) {
theTask.dependsOn 'doStuff'
}
}
此代码不会区分构建变体;如有必要,您可以在 if 条件下执行此操作。