Android + gradle: injecting a task into build - android

I have a custom script which runs on the source (.java) and AndroidManifest.xml.
I'd like to execute this script as part of the gradle build process at the start of the assembleRelease task (maybe just after app:preBuild).
Any idea of how I can go about doing this?
I know I can do something like this to exec the script:
task DoStuff(type:Exec) {
workingDir 'path/to/script'
commandLine 'python3', 'do_stuff.py'
}
But I'm not sure where to put that, etc...

You can add a custom action to assembleRelease with doFirst method:
assembleRelease.doFirst {
//invoke python script but there's no access to `workingDir` or `commandLine`
//because it's an action not a task
}
or define dependency:
assembleRelease.dependsOn DoStuff
assembleRelease.mustRunAfter DoStuff //this might be redundant

Related

Gradle Custom Task With Input

I have to create a gradle custom task in KOTLIN with different args as input.
So based on the args, the custom task should run other tasks.
e.g: I want to run:
./gradlew ci type=release distribution=true version=1.2.2
OR
./gradlew ci type=debug distribution=true version=1.2.2
This command should run tasks: clean, assembleRelease OR assembleDebug (based on type param) and also another task to distribute the artifact (already have this one) if the distribute param is true.
Question 1: Is there any way to create a custom task that runs other tasks based on external params?
Question 2: Is there any way to inject the args? (the above commands are not valid I think)
You can pass properties with -P command and here is an example.
task passP() {
if (customProp.equals("myProp")) {
println customProp
}
}
this will only print if you execute the following command Gradle -PcustomProp=myProp passP
Now that you can pass parameters, You can clean, assembleRelease OR assembleDebug according to the passed parameters.
There Are two ways you can achieve that.
First way :
Make a gradle custome task to execute another gradle command which do not look neat. but the code will look like this
task passP(type: Exec) {
commandLine("cmd", "/c")
if (customProp.equals("clean")) {
args "gradle clean"
}
}
This will execute a normal clean if you passed clean as a parameter.
The second way :
You would be using finializeBy keyword
You can call the 3 tasks according to the passed parameters.
The code will be something like this (not tested) :
task passP() {
if (customProp.equals("clean")) {
tasks.named("clean") { finalizedBy("passP") }
if (customProp.equals("debug")) {
tasks.named("assembleDebug ") { finalizedBy("passP") }
}
}
The first way work 100%, But am not sure about the second one, As am only used to use finalizedBy out side of the custom task scope.

How to add gradle's task parameter in Android Studio?

We are going to debug our Android app by adding some properties in app.properties and pre-process it in the Kotlin codes.
We wrote build.gradle like:
task dailytest {
doLast {
File testProperty = new File('assets/app.properties')
testProperty.append("\ndaily_test=true")
testProperty.append("\nfps_sample_interval_ms=")
testProperty.append(fps_sample_interval_ms)
testProperty.append("\ndrop_stack_sample_interval_ms=")
testProperty.append(drop_stack_sample_interval_ms)
testProperty.append("\nmin_drop_count_to_log=")
testProperty.append(min_drop_count_to_log)
}
}
And we compile it in command line using:
./gradlew dailytest -Pfps_sample_interval_ms="100" -Pdrop_stack_sample_interval_ms="100" -Pmin_drop_count_to_log="1" :connectedAndroidTest -Pandroid.testInstrumentationRunnerArguments.class=com.myapp.sub.MainActivityTest#test_click_shelf
I was wondering if maybe we could run this test case in Android Studio by adding some confirmations?
We did try to add ::dailytest in the Before launch part, but we couldn't manage to find a way to add the custom parameters.
You can have an afterEvaluate block in your build.gradle to run your task when you build your app, something like this:
afterEvaluate {
lint.dependsOn dailytest
}

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.

Best way to add a code generation step in the build process?

I have a python script that modifies a part of a java class (add static fields) according to another file.
What is the best way to add it in the Gradle build process (My script requires pyton3 (so it would be better to tell the user if he doesn't have it) and need to be executed before the java compilation) ?
I'm not certain what the best way to run python from gradle is, but one candidate is to use the exec task:
task runPython(type:Exec) {
workingDir 'path_to_script'
commandLine /*'cmd', '/c'*/ 'python', 'my_script.py'
}
You might have to add cmd and /c on windows. You can also parse/assert on stdout for success conditions. See here for more about Exec.
As for ensuring that this task always runs before compileJava, you have to add this task as a dependsOn for the compileJava task:
compileJava.dependsOn runPython
alternate syntax:
compileJava{
dependsOn runPython
}
When compileJava dependsOn runPython, runPython is executed first everytime compileJava is invoked.

How to change Gradle install tasks

I want to edit gradle task named installDebug. Where is the task (or script) located? Maybe this script is located in binary code and I'm not change that?
Really, I want run edit something option for adb.
Example: My task must contain:
Run adb like "adb connect 192.168.1.2:5555"
Run "debugInstall" gradles task, directly.
Do something, like - adb then open apk on my adb server..
What I should do:
Edit debugTask if possible?
Or edit build.grade and make own task script?
All the tasks are located in build.gradle script itself or in the plugin that is applied at the beginning of the script.
installDebug task is provided by as far as I remember android plugin. Every single task consists of actions that are executed sequentially. Here's the place to start.
You can extend a task adding action to the beginning of at the end of internal actions list.
So:
//this piece of code will run *adb connect* in the background
installDebug.doFirst {
def processBuilder = new ProcessBuilder(['adb', 'connnect', '192.168.1.2:5555'])
processBuilder.start()
}
installDebug.doLast {
//Do something, like - adb then open apk on my adb server..
}
Here, two actions were added to installDebug task. If you run gradle installDebug, first action will be run, then the task itself and finally the second action that is defined. That's all in general.
You can add a task to your build.gradle, and call it in command line.
This is what I have done :
task adbConnect(type: Exec) {
commandLine 'adb', 'connect', '192.168.200.92'
}
then I call gradle adbConnect connectedCheck, but you can use gradle adbConnect debugInstall

Categories

Resources