30

So far I have added the following to the end of my "build.gradle"

task copyFiles(type: Copy)

copyFiles {
    description = 'Copies html5 files from the common library...'
    from '../../www'
    into 'assets/www'
    include('**/*')
}

Now I just need some help on how o make this task get executed everytime (before) compiling the android source. I can run the copy task manually from command line, but Id like to have it run when I click "run" in android studio.

With the help of suggestion below, I have added

clean.dependsOn copyFiles
clean.mustRunAfter copyFiles

And with this addition I can get my copy task to run by doing rebuild -> run. It's better than nothing but it would be nice to skip the rebuild step.

Here is the whole build.gradle that im using with android studio.

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:0.5.+'
    }
}


apply plugin: 'android'

dependencies {
    compile files('/libs/acra-4.3.0.jar')
}

android {
    compileSdkVersion 17
    buildToolsVersion "17"

    defaultConfig {
        minSdkVersion 8
        targetSdkVersion 17
    }
    sourceSets {
        main {
            manifest.srcFile 'AndroidManifest.xml'
            java.srcDirs = ['src','libs']
            resources.srcDirs = ['src']
            aidl.srcDirs = ['src']
            renderscript.srcDirs = ['src']
            res.srcDirs = ['res']
            assets.srcDirs = ['assets']
        }

        instrumentTest.setRoot('tests')
    }
}


task copyFiles(type: Copy)

copyFiles {
    description = 'Copies html5 files from the common library...'
    from '../../www'
    into 'assets/www'
    include('**/*')
}

clean.dependsOn copyFiles
clean.mustRunAfter copyFiles
Svikaren
  • 301
  • 1
  • 3
  • 5
  • did any of these answers solved your problem? – Christopher Francisco Sep 12 '15 at 18:42
  • None of these answers, plus many others worked on Android Studio 1.4 (mac osx, I've got a windows box coming online soon too I plan on double checking this with) Even the documented way did not copy or sync folder to folder... I will update this if I find out otherwise. – Hunter-Orionnoir Oct 14 '15 at 06:53

7 Answers7

21

This way I do custom copying of file assets in my android-gradle build system

preBuild.dependsOn copyFiles
AdamVe
  • 3,236
  • 2
  • 18
  • 13
13

Here is the module's build.gradle that I am using which successfully copies the files that I wanted as a pre-build task. The "into" is modelled after the File class in Java, so it should be familiar on how to use it. The two lines at the end is optional - it will run the copyFiles task when invoking gradle clean:

android {
.....
}

task copyFiles(type: Copy) {
    description = 'copying some file(s)....'
    from 'src/main'
    into project(':Path:To:ModuleFrom:Settings.gradle').file('./res')
    include 'file1.suffix'
    include '**/*.html'
}

project.afterEvaluate {
    preBuild.dependsOn copyFiles
}

clean.dependsOn copyFiles
clean.mustRunAfter copyFiles
Phileo99
  • 5,581
  • 2
  • 46
  • 54
7

I had a very similar problem to yours and I was able to solve it as follows:

android.buildTypes.all{ buildType ->    
    task "${buildType.name}CopyFiles" (type: Copy)
    "${buildType.name}CopyFiles" {
        description = 'Copies html5 files from the common library...'
        from '../../www'
        into 'assets/www'
        include('**/*')
    }

    tasks.getByPath(":${project.name}:assemble${buildType.name.capitalize()}").dependsOn "${buildType.name}CopyFiles"
}

The problem is, that Android Studio seems to call a specific assemble task like assembleDebug when you click on run, that's why you have to make sure to make all assemble tasks depend on your copy task.

r4C9rAyrd6A1
  • 96
  • 1
  • 4
  • I got this error when I tried building with your addition (probably because of changes between 2013 and 2020): > Task with path ':app:assembleDebug' not found in project ':app'. – Ellen Spertus Mar 18 '20 at 18:38
3
task myCopyToAssets(type: Copy) {
    def toDir = rootProject.file('app/assets')
    from (rootProject.file('app/usb')) {
        include 'libhotplug.so'
    }
    into toDir
}



tasks.whenTaskAdded { task ->
    //println task.getName()
    if (task.name == 'assembleDebug' || task.name == 'assembleRelease') {
        println 'myCopy'
        myCopyToLibs.execute()
        myCopyToAssets.execute()
    }
}
KunMing Xie
  • 1,613
  • 17
  • 15
2

Try this below your build.gradle:

tasks.whenTaskAdded { task ->
    if (task.name == 'assemble') {
        task.dependsOn copyFiles
    }
}

In my case I manipulate some 'token' values inside res/values/strings.xml, and then copy it into ${project_root}/build/filtered-resources due to project cleaning issue.

To work correctly with this manipulated resource, android.sourceSets.res should be redefined to copied folder.

For your case copy assets folder with your www resource into ${PROJECT_ROOT}/build/your/desired/location, and asign android.sourceSets.assets point to it.

Intae Kim
  • 309
  • 1
  • 5
  • Thank you for the answer. At the moment I can not test it because the project has evolved/degraded and is currently not working at all in Android Studio. – Svikaren Aug 07 '13 at 09:28
  • Managed to try this today. But unfortunately it does not work for me. I did not change the android.sourceSets.assets or the destination of my copy task. Is that relevant for the task to get run? I know my copy task works as I want already. I just need it to actually get called. – Svikaren Aug 08 '13 at 15:04
  • This seemed to work for me. I changed the conditional to `if (task.name == 'assembleRegularRelease') { ... }`. I basically have a different copy task for each assemble task type. – b.lyte Jul 02 '14 at 18:48
  • For some reason, this didn't work for me. I ended up using `assembleDebug.dependsOn copyFiles assembleRelease.dependsOn copyFiles` – Cypress Frankenfeld Jul 09 '14 at 15:36
  • Be careful with `assemble`! `assemble` depends on `assembleDebug` and `assembleRelease`. If you add one more dependency on it (i.e. sibling to `assembleDebug`), the APK might have already been generated when the files are copied. `assemble*` is too late to put resources/assets into the APK. – TWiStErRob Jan 15 '19 at 11:59
1

I use the following copy task in my project to copy strings into another directory:

task copyStringsUniversal(type: Copy) {
    from 'src/main/res/values'
    include 'strings.xml'
    include 'array.xml'
    into 'src/universal/res/values'
}
build.dependsOn copyStringsUniversal
luckyhandler
  • 10,651
  • 3
  • 47
  • 64
-1

Add this line to your build.gradle file:

assemble.dependsOn copyFiles
assemble.mustRunAfter copyFiles

where assemble can be any task.

Edit: I added the mustRunAfter bit to make sure the copyFiles task is run before any of the other assemble dependencies.

myanimal
  • 3,580
  • 26
  • 26
  • 1
    I've tried your suggestion on both the assemble task and the "build" task but my copyFiles task does not seem to get run anyway. However, by putting it on the "clean" task I can get my copyFiles to run by first doing a rebuild, and then launching. T – Svikaren Jul 17 '13 at 11:36
  • 1
    This didn't work for me. I added those two lines to my build.gradle, but it looks like my copy task never ran. – Cypress Frankenfeld Jul 09 '14 at 14:37