如何在Android Studio中将复制任务运行到assets文件夹

30

到目前为止,我已经将以下内容添加到了我的"build.gradle"文件的末尾

task copyFiles(type: Copy)

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

现在我只需要一些帮助来使得这个任务在编译安卓源代码之前每次都能被执行。我可以手动从命令行运行复制任务,但我想在点击 Android Studio 中的“运行”时自动运行它。

有了下面的建议,我已经添加了

clean.dependsOn copyFiles
clean.mustRunAfter copyFiles

加入这个修改后,我可以通过重新构建 -> 运行来运行我的复制任务。这比没有好,但跳过重新构建步骤会更好。

这是我在使用 Android Studio 的整个 build.gradle 文件。

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

这些答案中有没有解决你的问题? - Christopher Francisco
这些答案中没有一个能在Android Studio 1.4上运行(mac osx,我很快会有一个Windows电脑在线,我计划再次检查这个问题)。 即使是文档中提到的方法也无法将文件夹复制或同步到另一个文件夹...如果我发现其他情况,我会更新这个问题。 - Hunter-Orionnoir
7个回答

21

我在我的Android Gradle构建系统中进行自定义文件资产复制的方法

preBuild.dependsOn copyFiles

1
什么是"preBuild"的定义?我在很多地方看到这个答案,但对我来说从来没有起作用过。我正在使用Android Studio 1.4,不知道这是否有区别。 - Hunter-Orionnoir
我解决了。我想是这样的。我的环境没有定义preBuild,所以我自己定义了一个,并使用它来确保任务copyFiles被触发。 - Hunter-Orionnoir
什么是 preBuild?它是 Android Studio 中 Gradle 生命周期的一部分吗? - IgorGanapolsky
这对我可行。preBuild任务应该由Android Studio自动定义。 - Adam Yaxley
那行代码应该放在哪里? - Scorb

13

这是我正在使用的模块的build.gradle文件,它成功地将我想要作为预先构建任务复制的文件复制了过来。"into"是按照Java中的File类建模的,因此应该很熟悉如何使用它。结尾处的两行是可选的 - 在调用gradle clean时它将运行copyFiles任务:

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

你为什么写成 from file?那是一个目录! - IgorGanapolsky
1
@IgorGanapolsky 你说得对,我已经移除了 'file' 关键字,感谢您指出。 - Phileo99
2
我遇到了一个错误:在项目':app'中找不到属性'preBuild'。 - IgorGanapolsky

7

我曾经遇到过与你类似的问题,以下是我解决它的方法:

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"
}

问题在于,Android Studio似乎在单击运行时调用特定的assemble任务,比如"assembleDebug",因此您需要确保使所有assemble任务依赖于您的复制任务。

当我尝试使用您的添加构建时,出现了以下错误(可能是因为2013年和2020年之间的更改):>在项目“:app”中找不到路径为“:app:assembleDebug”的任务。 - Ellen Spertus

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()
    }
}

2
请在您的build.gradle文件中添加以下内容:
tasks.whenTaskAdded { task ->
    if (task.name == 'assemble') {
        task.dependsOn copyFiles
    }
}

在我的情况下,我在res/values/strings.xml中操纵一些“token”值,然后将其复制到${project_root}/build/filtered-resources中,以解决项目清理问题。
为了正确使用这个被操纵过的资源,android.sourceSets.res应该被重新定义为已复制的文件夹。
对于您的情况,请将assets文件夹与您的www资源复制到${PROJECT_ROOT}/build/your/desired/location,并将android.sourceSets.assets指向它。

感谢您的回答。目前我无法测试它,因为该项目已经进化/降级,并且在Android Studio中根本无法工作。 - Svikaren
今天设法尝试了这个。但不幸的是对我不起作用。我没有改变android.sourceSets.assets或我的复制任务的目标。这对任务运行是否相关?我知道我的复制任务已经按照我的要求工作。我只需要实际调用它。 - Svikaren
这对我来说似乎有效。我将条件更改为 if (task.name == 'assembleRegularRelease') { ... }。基本上,我为每个 assemble 任务类型都有一个不同的复制任务。 - shoke
由于某些原因,这对我没有起作用。最终我使用了 assembleDebug.dependsOn copyFiles assembleRelease.dependsOn copyFiles - Cypress Frankenfeld
小心使用 assembleassemble 依赖于 assembleDebugassembleRelease。如果你在它上面添加了一个依赖(即与 assembleDebug 平级的依赖),当文件被复制时,APK 可能已经生成。assemble* 太晚了,无法将资源/资产放入 APK 中。 - TWiStErRob

1

我在项目中使用以下复制任务将字符串复制到另一个目录:

task copyStringsUniversal(type: Copy) {
    from 'src/main/res/values'
    include 'strings.xml'
    include 'array.xml'
    into 'src/universal/res/values'
}
build.dependsOn copyStringsUniversal

-1

将以下代码添加到你的 build.gradle 文件中:

assemble.dependsOn copyFiles
assemble.mustRunAfter copyFiles

assemble 可以是任何任务。

编辑:我添加了 mustRunAfter 部分,以确保在运行其他 assemble 依赖项之前先运行 copyFiles 任务。


1
我已经尝试了您的建议,对于汇编任务和“构建”任务都进行了尝试,但是我的copyFiles任务似乎无论如何都没有运行。然而,通过将其放在“清理”任务上,我可以通过首先进行重建,然后启动来运行我的copyFiles。 - Svikaren
1
这对我没用。我在build.gradle中添加了这两行,但似乎我的复制任务从未运行。 - Cypress Frankenfeld

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接