Как управлять порядком выполнения задачи в build.gradle Android studio?

#android #gradle

#Android #gradle

Вопрос:

Я использую Android Studio 4.1 и Gradle 6.7.1

(Обратите внимание, что «mergeReleaseAssets» не является моей пользовательской задачей, это часть системных задач, и я не знаю, где найти определение «mergeReleaseAssets»)

Я хочу установить задачу «mergeReleaseAssets» для выполнения после «MyTask», как показано ниже:

 ...
> Task :app:myTask
...
(no matter how many tasks in the middle should be ok)
...
> Task :app:mergeReleaseAssets
...
 

Определение задачи в build.gradle:

 ...
task myTask {
    doLast {
        println String.format("put something in the assets")
    }
}
tasks.withType(JavaCompile) { t -> t.finalizedBy myTask }
...
 

При создании проекта, нажав Меню -> «Сборка» -> «Перестроить проект», порядок выполнения задач не всегда одинаков, кажется, что задачи выполняются параллельно.

Вывод сборки в первый раз:

 Executing tasks: [clean, :app:assembleRelease] in project /home/testproject

> Task :clean UP-TO-DATE
> Task :app:clean UP-TO-DATE
> Task :app:preBuild UP-TO-DATE
> Task :app:preReleaseBuild UP-TO-DATE
> Task :app:compileReleaseAidl NO-SOURCE
> Task :app:compileReleaseRenderscript NO-SOURCE
> Task :app:generateReleaseBuildConfig
> Task :app:checkReleaseAarMetadata
> Task :app:generateReleaseResValues
> Task :app:generateReleaseResources
> Task :app:createReleaseCompatibleScreenManifests
> Task :app:extractDeepLinksRelease
> Task :app:processReleaseMainManifest
> Task :app:processReleaseManifest
> Task :app:processReleaseManifestForPackage
> Task :app:mergeReleaseResources
> Task :app:processReleaseResources
> Task :app:mergeReleaseNativeDebugMetadata NO-SOURCE
> Task :app:mergeReleaseShaders
> Task :app:javaPreCompileRelease

> Task :app:compileReleaseJavaWithJavac
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.

> Task :app:myTask
> Task :app:compileReleaseSources
> Task :app:lintVitalRelease
> Task :app:compileReleaseShaders NO-SOURCE
> Task :app:generateReleaseAssets UP-TO-DATE
> Task :app:mergeReleaseAssets
> Task :app:compressReleaseAssets
> Task :app:dexBuilderRelease
> Task :app:checkReleaseDuplicateClasses
> Task :app:processReleaseJavaRes NO-SOURCE
> Task :app:collectReleaseDependencies
> Task :app:sdkReleaseDependencyData
> Task :app:mergeReleaseJniLibFolders
> Task :app:mergeReleaseNativeLibs
> Task :app:stripReleaseDebugSymbols NO-SOURCE
> Task :app:validateSigningRelease
> Task :app:mergeReleaseJavaResource
> Task :app:desugarReleaseFileDependencies
> Task :app:mergeExtDexRelease
> Task :app:mergeDexRelease
> Task :app:packageRelease
> Task :app:assembleRelease

Deprecated Gradle features were used in this build, making it incompatible with Gradle 7.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/6.7.1/userguide/command_line_interface.html#sec:command_line_warnings

BUILD SUCCESSFUL in 2m 0s
32 actionable tasks: 30 executed, 2 up-to-date

Build Analyzer results available
 

Вывод сборки во второй раз:

 Executing tasks: [clean, :app:assembleRelease] in project /home/testproject

> Task :clean UP-TO-DATE
> Task :app:clean UP-TO-DATE
> Task :app:preBuild UP-TO-DATE
> Task :app:preReleaseBuild UP-TO-DATE
> Task :app:compileReleaseAidl NO-SOURCE
> Task :app:compileReleaseRenderscript NO-SOURCE
> Task :app:generateReleaseBuildConfig
> Task :app:checkReleaseAarMetadata
> Task :app:generateReleaseResValues
> Task :app:generateReleaseResources
> Task :app:javaPreCompileRelease
> Task :app:createReleaseCompatibleScreenManifests
> Task :app:extractDeepLinksRelease
> Task :app:processReleaseMainManifest
> Task :app:processReleaseManifest
> Task :app:processReleaseManifestForPackage
> Task :app:mergeReleaseNativeDebugMetadata NO-SOURCE
> Task :app:mergeReleaseShaders
> Task :app:compileReleaseShaders NO-SOURCE
> Task :app:generateReleaseAssets UP-TO-DATE
> Task :app:mergeReleaseAssets
> Task :app:compressReleaseAssets
> Task :app:checkReleaseDuplicateClasses
> Task :app:processReleaseJavaRes NO-SOURCE
> Task :app:mergeReleaseResources
> Task :app:processReleaseResources
> Task :app:mergeReleaseJavaResource

> Task :app:compileReleaseJavaWithJavac
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.

> Task :app:desugarReleaseFileDependencies
> Task :app:myTask
> Task :app:compileReleaseSources
> Task :app:lintVitalRelease
> Task :app:dexBuilderRelease
> Task :app:collectReleaseDependencies
> Task :app:sdkReleaseDependencyData
> Task :app:mergeReleaseJniLibFolders
> Task :app:validateSigningRelease
> Task :app:mergeReleaseNativeLibs
> Task :app:stripReleaseDebugSymbols NO-SOURCE
> Task :app:mergeExtDexRelease
> Task :app:mergeDexRelease
> Task :app:packageRelease
> Task :app:assembleRelease

Deprecated Gradle features were used in this build, making it incompatible with Gradle 7.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/6.7.1/userguide/command_line_interface.html#sec:command_line_warnings

BUILD SUCCESSFUL in 1m 54s
32 actionable tasks: 30 executed, 2 up-to-date

Build Analyzer results available
 

Как вы можете видеть, в первый раз порядок «MyTask» -> … -> «mergeReleaseAssets».
Но во второй раз он изменился на «mergeReleaseAssets» -> … -> «MyTask».

И затем я пытаюсь установить зависимость задачи в build.gradle:

 project.getTasks().getByName("mergeReleaseAssets").dependsOn(myTask)
//This also not work
//project.getTasks().getByName(":app:mergeReleaseAssets").dependsOn(myTask)
 

Но Android studio показывает ошибку:

 Task with name "mergeReleaseAssets" not found in project ':app'

//Or this error if using ":app:mergeReleaseAssets":
Task with name ":app:mergeReleaseAssets" not found in project ':app'
 

Пожалуйста, помогите, спасибо.

Комментарии:

1. вы должны попытаться обернуть создание зависимости в afterEvaluate замыкание; действительно, если mergeReleaseAssets это задача, динамически создаваемая одним плагином, она может быть недоступна во время настройки вашего проекта. попробуйте : project.afterEvaluate{ project.getTasks().getByName("mergeReleaseAssets").dependsOn(myTask) }

2. Привет, @M.Ricciuti, я попробовал ваше решение, оно работает. Спасибо. Пожалуйста, напишите свой комментарий в качестве ответа, и я приму ваш ответ.

Ответ №1:

Проблема в том, что mergeReleaseAssets задача создается динамически, поэтому вы не можете ссылаться на нее непосредственно в своем build.gradle скрипте.

Одним из решений является использование Project.afterEvaluate перехвата жизненного цикла, как описано здесь

 project.afterEvaluate{ 
    // at this stage, task 'mergeReleaseAssets' has been declare, you can reference it to perform additional configuration
    project.getTasks().getByName("mergeReleaseAssets").dependsOn(myTask) 
}