20

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?

Opal
  • 81,889
  • 28
  • 189
  • 210
nieschumi
  • 551
  • 1
  • 5
  • 21

3 Answers3

27

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'
   }
}
Opal
  • 81,889
  • 28
  • 189
  • 210
  • 2
    Both `finalizedBy` and `doLast { task detail }` work for me, thank you so much! – nieschumi Oct 01 '15 at 15:50
  • 2
    Just to prevent someone from getting inexplicable errors, there is a small typo in `include '*-release.arr'`, which should obviously be: `include '*-release.aar` – fast3r Jun 27 '16 at 14:31
  • I get an error: `access to finalizedBy exceeds its access rights` – IgorGanapolsky Jul 27 '16 at 15:33
  • 20
    When I try this, I get the following: **Could not get unknown property 'assembleRelease' for project 'LibraryProjectName' of type org.gradle.api.Project.**. Is there a way to fix it? – Ankit Mittal Sep 21 '17 at 06:50
  • 2
    @AnkitMittal Wrap it in afterEvaluate eg ... afterEvaluate { assembleRelease.finalizedBy { copyaarfile } } – Ashish Rawat Aug 10 '20 at 19:42
7

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.

ShellDude
  • 579
  • 6
  • 12
  • This addition of `afterEvaluate` is essential. But I think that usually you will have both **assembleFatDebug** and **assembleFatRelease** defined, so `else` may be wrong here. Only one of the **assemble** tasks will eventually be invoked because you choose the build configuration. The other one is either disabled or dormant. – Alex Cohn Apr 16 '20 at 07:18
  • 1
    good call... taking a look at some of my existing Gradle scripts I am using gradle.startParameter.taskNames.contains(). – ShellDude Apr 18 '20 at 19:45
2

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
    }
jdir.s
  • 97
  • 8