Execute android build tasks in custom tasks - android

I wanted to remove the project makefile and write some nice gradle tasks.
I need to execute the following tasks, in this order:
Clean
Increment version
Build
Upload
#1, #3 and #4 are tasks from android and plugin (bintray) while #2 is a custom task. Here is what I have so far:
task releaseMajor {
doLast {
clean.execute()
build.execute()
incrementVersion.execute()
bintrayUpload.execute()
}
}
The run order was not so great as I think clean was run after build. And binrayUpload was running without flavor (release). I've also tried to use dependsOn without success (order not working).
I couldn't find in Gradle doc how to do this properly. When execute in the right order, from CLI, everything works perfectly.

Use mustRunAfter, or finalizedBy for finer order control:
task releaseMajor (dependsOn: ['clean', 'build', 'incrementVersion', 'bintrayUpload'])
build.mustRunAfter clean
incrementVersion.mustRunAfter build
bintrayUpload.mustRunAfter incrementVersion

Tried this
task clean {
println 'clean task executing'
}
task incrementVersion (dependsOn:"clean"){
println 'incrementVersion task executing'
}
task building (dependsOn:"incrementVersion"){
println 'build task executing'
}
task bintrayUpload (dependsOn:"building") {
println 'bintrayUpload task executing'
}
The output was
clean task executing
incrementVersion task executing
build task executing
bintrayUpload task executing
and executed ./gradlew bintryUpload

Related

Gradle build one task start to execute all task

Running one task in gradle (Android) - runs all tasks (clean, etc.) - how to make it run only one single task?
task testTask() {
dependsOn copyAssets, Debug1
}
Start this
PS Q:\AndroidProject\mark\android> ./gradlew copyAssets
Configure project :gg:android
:android: Q:\AndroidProject\mark\gg\android\build.gradle
Configure project :gg:awtold
gg:awt:android: Q:\AndroidProject\mark\gg\awtold\build.gradle
Configure project :gg:common
gg:common: Q:\AndroidProject\mark\gg\common\build.gradle
Configure project :
sdfasdf (this print in another task )
call in CAF ( and this )
call removed (and this )
Task :testTask NO-SOURCE

How to add custom gradle task after generating classes.dex file during android build

I am trying to add one gradle task after generating classes.dex in android build.
i tried with dexRelease/dexDebug task that I got it from the below thread
Gradle task for classes.dex CRC calculation
but during Configuration phase, I can able to see the task but it's not executing.
i have added some logs in the doLast but its not printing. thats how i confirmed that its not executing.
tasks.all { task ->
if (task.name == 'dexRelease') {
println "-NAME: "+ task.name
//task.finalizedBy taskAfterDex
}
}
task taskAfterDex(type:Exec) {
println "taskAfterDex configured"
doLast {
println "taskAfterDex executed"
}
}
is dexRelease/dexDebug is the right task to detect the classes.dex generation?
or I need to use some other task to check dex generation
i have asked another question here related this.
How to execute a gradle task after android dexDebug or dexRelease task
but first i nee dto know why dexRelease is not executing / is it the right task to check the dex generation
am checking the dex file in the below location during the build process.
/app/build/intermediates/dex/debug

Android Gradle - how to run task after app installation

I need to copy some files to the Android App folder (data/data/...) after installing the app via Gradle. This has to be done at every debug build before the app gets started and thus I assumed I could find a gradle task that could be executed after the installation (but before the run command).
It works somewhat fine for other tasks when doing something like
tasks.whenTaskAdded { task ->
if (task.name == 'build') {
task.dependsOn taskXYZ
}
}
They then get executed before my build task is executed.
However, since I need that to happen after the install process (and before the running of the app) I was hoping for something like this:
tasks.whenTaskAdded { task ->
if (task.name.startsWith('install')){
println ">>>>>>>>> " + task.name
task.finalizedBy taskXYZ
}
But sadly, this does not work.
In the build output I can see that this executed pretty much at the start.
Executing tasks: [:app:assemblePlayStoreStagingDebug] in project /Users/...
> Configure project :app
###########################
TASK XYZ WAS EXECUTED HERE!
###########################
---> installPlayStoreStagingDebug
> Task :app:preBuild UP-TO-DATE
> Task :app:prePlayStoreStagingDebugBuild
> Task :app:compilePlayStoreStagingDebugAidl UP-TO-DATE
...
> Task :app:stripPlayStoreStagingDebugDebugSymbols UP-TO-DATE
> Task :app:packagePlayStoreStagingDebug
> Task :app:assemblePlayStoreStagingDebug
BUILD SUCCESSFUL in 6s
33 actionable tasks: 6 executed, 27 up-to-date
It looks like the task did not get executed at the expected time. What I need is something like this:
Task Build
Task Install
Task XYZ
Task run App
But how can I achieve this?
Solutions like this one
Android run Gradle task after app install
Don't seem to work for the install task.
----- EDIT -----
I tried it the other way around and - instead of using gradle tasks - I tried to change the run configuration of AS by adding an "external tool" call in the "before launch" settings.
https://developer.android.com/studio/run/rundebugconfig#definingbefore
However, when selecting for instance a shell script there, it won't get executed (for instance I was creating a file or directory in that script so I could see whether it was executed at all). It doesn't seem to be that error=13 permission problem. So if gradle tasks are not a solution, perhaps anyone knows a solution with this option!
In gradle you can use the mustRunAfter task, this does not create dependencies between the tasks but forces one task to be after a list of other tasks in the build sequence.
An example:
task taskY {
mustRunAfter "taskX"
}
https://gradle.github.io/kotlin-dsl-docs/api/org.gradle.api/-task/must-run-after.html

Run grade tasks inside a task without dependsOn

Assume that I have set of tasks executed from the cmd line and it works:
gradle processReleaseManifest compileReleaseSources run assembleRelease
Here run is the task which I Defined.
So My requirement is that I need to create a task which executes the above mentioned 4 tasks,
like say new task abc, runs the above mentioned tasks in the same order,
I know I cannot use dependsOn in this case because,processReleaseManifest compileReleaseSource when used in the build gradle it shows,
Could not get unknown property 'assembleRelease' for project ':app' of type org.gradle.api.Project.
So what is the solution?
You can, as #lu.koerfer's answer indicates use strings in the dependsOn list to refer to tasks that are defined further down in the build file.
In other words, this works:
task foo {}
task bar(dependsOn: [foo]) {}
and this also works:
task bar(dependsOn: ['foo']) {}
task foo {}
Now as for getting the tasks to run in the order you want things are not quite as straight forward. The dependsOn property only tells the task which tasks need to run before the task itself runs. It does not tell gradle to run the tasks in the order defined in the dependsOn clause.
An example:
task one {}
task two {}
task three {}
task run(dependsOn: [one, two, three]) {}
results in the following output when run:
~> gradle run
:one UP-TO-DATE
:three UP-TO-DATE
:two UP-TO-DATE
:run UP-TO-DATE
BUILD SUCCESSFUL
...note the fact that we are not running in the order one, two, three, run.
In other words, the command line invocation forces the tasks to run in the order defined whereas the dependsOn is a set and has no ordering.
There are a few ways you can get the tasks to run in the order you want. One is to define dependencies on the tasks (this is probably the common path):
task one {}
task two(dependsOn: ['one']) {}
task three(dependsOn: ['two']) {}
task run(dependsOn: [one, two, three]) {}
which results in:
~> gradle run
:one UP-TO-DATE
:two UP-TO-DATE
:three UP-TO-DATE
:run UP-TO-DATE
BUILD SUCCESSFUL
another is to use the task ordering constructs added in later versions of gradle.
Also, if you need to add a task dependency to a task which was defined somewhere earlier in the file, you can do so via:
task foo {}
someTaskDefinedFurtherUp.dependsOn 'foo'
which adds the task foo to the dependencies of someTaskDefinedFurtherUp.
You need to pass the task names as strings to the dependsOn method, because at the time you call it, the task objects haven't been created yet. However, if you pass strings, the task names will be evaluated later:
task abc {
dependsOn 'processReleaseManifest', 'compileReleaseSources', 'run', 'assembleRelease'
}
As it may be possible but very complicated to specify the task dependencies and ordering via dependsOn and mustRunAfter / shouldRunAfter, I'll propose another possible solution:
You can invoke Gradle from Gradle and specify the tasks in same way you would via command line:
task abc(type: GradleBuild) {
tasks = ['processReleaseManifest', 'compileReleaseSources', 'run', 'assembleRelease']
}
This will call Gradle again from the current build and execute the tasks in the specified order.

Why can't I use gradle task connectedDebugAndroidTest in my build script?

I can refer to connectedCheck task (which came from android plugin) from my build script:
connectedCheck.finalizedBy AndroidShowTestResults
But trying to use connectedDebugAndroidTest (which came from android plugin too)
connectedDebugAndroidTest.finalizedBy AndroidShowTestResults
gives me
Error:(48, 0) Could not find property 'connectedDebugAndroidTest' on project ':app'.
And if I try
task connectedDebugAndroidTest << {print '123'}
it curses me with
Error:Cannot add task ':app:connectedDebugAndroidTest' as a task with that name already exists.
I don't undestand why I cannot refer to connectedDebugAndroidTest?
Available gradle tasks are shown below:
The android plugin defers the addition of several tasks especially those that have buildType or flavor names in them till a very late stage of the configuration phase. Which in turn means if you try to refer to these yet-to-be-added-tasks by name, you're likely to see a "does not exist" type error messages. If you want to add dependencies around deferred-created tasks, you should wait until configuration is complete:
gradle.projectsEvaluated {
connectedDebugAndroidTest.finalizedBy AndroidShowTestResults
}
Alternatively, you can add a listener to task-graph events, so you can do stuff as soon as a certain task is added to task-graph:
tasks.whenTaskAdded { task ->
if (task.name == 'connectedDebugAndroidTest') {
task.finalizedBy AndroidShowTestResults
}
}
Try
task connectedTest(dependsOn: ["connectedDebugAndroidTest"]){
}
connectedTest.finalizedBy "AndroidShowTestResults"
I think you should try to open test and rebuild.

Categories

Resources