Gradle: How to run custom task after an Android Library is built? - android

I have an Android Library, it's generating a debug.aar and a release.aar, I need to copy the release.aar to another folder as a reference to other part of the project.
What I've done now is in this Android Library build.gradle I defined a task:
task copyAARToCommonLibs(type: Copy) {
from('../build/outputs/aar') {
include '*-release.arr'
}
into '../SomeSampleApps/libs'
}
I'm trying to run this task after the arr is generated, which I assume is assembleRelease stage, so I tried do this in this build.gradle
assembleRelease.doLast{
copyAARToCommonLibs
}
I build the overall project using
gradle build
But this task is running at the very beginning of the whole process.
I also tried this:
applicationVariants.all { variant ->
variant.assemble.doLast {
copyAARToCommonLibs
}
}
inside android{} property(I guess that's what it's called?)
Running gradle build, got this error: Could not find property 'applicationVariants'
I then came across this snippet:
tasks.withType(JavaCompile) { compileTask -> compileTask.dependsOn copyAARToCommonLibs }
But it seems this makes the task to run after compiling, I don't know exactly how to modify this to run after assemble.
Could someone please correct me where I did wrong and how can I get this copy task work after the .arr file is generated?

It seems that finalizedBy might be helpful.
assembleRelease.finalizedBy(copyAARToCommonLibs)
Mind the fact that in the following way you won't define a dependency:
assembleRelease.doLast {
copyAARToCommonLibs
}
actually.. it does exactly nothing. You need to execute the task:
assembleRelease.doLast {
copyAARToCommonLibs.execute()
}
but running task in the following way is discouraged and very bad practice.
You can also try:
assembleRelease.doLast {
copy {
from('../build/outputs/aar') {
include '*-release.aar'
}
into '../AscendonSDKSamples/libs'
}
}

I went with finalizedBy() but had to include it within an afterEvaluate...
afterEvaluate {
if (gradle.startParameter.taskNames.contains(":app:assembleFatReleaseInternal")) {
play.enabled = true
play.commit = true
play.track = "internal"
play.releaseStatus = "completed"
play.releaseName = versionName
generateFatReleaseInternalBuildConfig.dependsOn set_build_date
assembleFatReleaseInternal.finalizedBy(uploadCrashlyticsSymbolFileFatReleaseInternal)
uploadCrashlyticsSymbolFileFatReleaseInternal.finalizedBy(publishFatReleaseInternal)
}
}
This worked well for automating the upload of native symbols to Fabric / Crashlytics and other things such as automated play store publishing.

Because android studio add task by dynamic,so assembleRelease will not be recognized.
Just add hook after task added event happens.
tasks.whenTaskAdded {
theTask ->
if (theTask.name.contains('externalNativeBuild')) {
theTask.doLast{
println "[*] begin to copy file."
}
}
// println theTask.name
}

Related

Android - Starting custom gradle task after build

Using Gradle 7.0.2 with the new Android Gradle Plugin I try to start a copy task which copies a file in the build folder.
The script looks something like this
androidComponents {
onVariants(selector().withBuildType("debug"), {
def copyTestTask = tasks.register("copyTest", Copy) {
from(file('../../local/test.txt'))
into(buildDir)
logger.lifecycle("DEST: $buildDir")
}
// build.dependsOn copyTestTask
// tasks.getByPath(':app:processDebugResources') {
// it.dependsOn(copyTestTask)
// }
})
}
The comments are my first tries to add to copy task in my assembleDebug/assembleRelease build. They do not call my copy task.
My questions:
What is the correct way to set the dependency to my task?
Which build task should depend on my copy job?

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
}

Gradle Run Custom Task after all package-variant-Release task

My Customtask unzips the apk and collects sha1 for some file, so I have created my task but I want to execute it every time any apk(any built or any variant) is generated, dont know how to trigger my task exactly after apk is created. Please help.
Some thing like the following
android {
task customTask {}
afterEvaluate {
package<VariantName>Release.finalizedBy(customTask)
}
}
After each of the variant apk is generated I need to run my custom task. I am able to do this for one variant by explicitly specifying the task name like
afterEvaluate {
packageDbRelease.finalizedBy(customTask)
}
But I have 5 more variants like packageARRelease etc after which I want to run my same custom task.
You need to create a task for each build variant:
android {
applicationVariants.all { variant
task "customTaskFor${variant.name.capitalize()}" {
// configure your task
}
tasks["package${variant.name.capitalize()}Release"].finalizedBy "customTaskFor${variant.name.capitalize()}"
}
}

Getting flavor in gradle task

I want to process generated .apk after gradle build. However, the place where the generated file resides depends on product flavor and build type. So how can I get those in the task?
Here's the relevant section of build.gradle:
productFlavors {
normal { }
tinybuild {}
}
// The following two blocks copy the generated .apk to server so that tablet you're working on can download it fast
task copyDebugAPK(type: Exec) {
workingDir "$projectDir/.."
commandLine 'python', 'myscript.py', 'script parameter'
}
afterEvaluate {
packageNormalDebug.finalizedBy(copyDebugAPK)
packageTinybuildDebug.finalizedBy(copyDebugAPK)
}
I could simply declare multiple tasks, one for each flavor / build, but I'm pretty sure that even using the script in flavor / build-type-dependent context should provide me with the relevant fields right within the task. Am I wrong?
Edit: after Robert's suggestion, I modified my task like so:
task copyDebugAPK(type: Exec) {
android.applicationVariants.all { variant ->
print("${com.android.build.OutputFile.ABI}")
print("${variant.name}")
print("${variant.flavorName}")
print("${variant.versionName}")
workingDir "$projectDir/.."
commandLine 'python', 'myscript.py', '${variant.name}'
}
}
However, no prints are being printed. I also added the variables to script input, but they are not resolved.

How to copy debug assets for unit tests

I have an android library gradle project. And I need to copy some files to assets folder for robolectric unit tests.
To do it I've defined a copy task:
task copyDebugAssets(type: Copy) {
from "${projectDir}/somewhere"
into "${buildDir}/intermediates/bundles/debug/assets"
}
but I can't add this task as a dependency for processDebugResources task:
processDebugResources.dependsOn copyDebugAssets
because of this error:
Could not get unknown property 'processDebugResources' for object of type com.android.build.gradle.LibraryExtension.
Now I have to manually execute this task before unit test:
./gradlew clean copyDebugAssets test
How can I solve it?
The android plugin adds several tasks dynamically. Your .dependsOn line doesn't work because at the time gradle is trying to process this line, processDebugResources task yet available. You should tell gradle to add the dependency as soon as the upstream task is available:
tasks.whenTaskAdded { task ->
if (task.name == 'processDebugResources') {
task.dependsOn copyDebugAssets
}
}
Why copy? Configure where the assets should be pulled from:
android {
// other cool stuff here
sourceSets {
androidTest {
assets.srcDirs = ['../testAssets']
}
}
}
(replacing ../testAssets with a path to where the assets should come from)
I have used this successfully with androidTest for instrumentation testing. AFAIK, it should work for test or any other source set.

Categories

Resources