Android + Gradle:将目录列入文件

时间:2013-09-02 09:38:17

标签: android gradle

我正在尝试将ANT版本中的任务转换为Gradle:

<target name="index-assets" depends="copy-assets">
    <path id="assets.path">
        <!-- contexts (and surplus) -->
        <dirset id="assets.dirset" dir="assets/" defaultexcludes="yes"/>
        <!-- assets -->
        <fileset id="assets.fileset" dir="assets/" includes="**" excludes="asset.index" defaultexcludes="yes"/>
    </path>

    <pathconvert pathsep="${line.separator}" property="assets" refid="assets.path" dirsep="/">
        <mapper>
            <globmapper from="${basedir}/assets/*" to="*" handledirsep="yes"/>
        </mapper>
    </pathconvert>

    <echo file="assets/asset.index">${assets}</echo>

</target>

<target name="-pre-build" depends="index-assets"/>

我想我还没有完全掌握基本的Gradle概念,但这就是我尝试的内容:

task indexAssets << {

def assets = file("assets")
def contexts = files(assets)
inputs.file(assets)
outputs.file("assets/assets-gradle.index")

def tree = fileTree(dir: 'assets', include: ['**/*'], exclude: ['**/.svn/**', 'asset.index'])

contexts.collect { relativePath(it) }.sort().each { println it }
tree.collect { relativePath(it) }.sort().each { println it }
}
  1. 树很好,但只包含文件(叶子)路径
  2. 我似乎无法获得简单干净的目录列表(上下文)。我尝试了其他几个变种(树,包含/排除),但我要么在该目录中获得单个文件,要么在目录名称本身或者没有。我只想要一个简单的'assets'目录中的目录列表。
  3. 现在我只想尝试打印路径,但我也想知道以后将这些路径写入文件的正确方法(如ANT的echo文件)。

    更新
    这个groovy片段似乎做了那个部分(+ svn过滤器),但我宁愿找到一个更“Gradley”的方式来完成这个任务。它稍后作为预构建依赖项在构建变体的上下文中运行。 (注意:我必须指定'Project'作为此hack中路径的一部分,因为我猜我不在该项目的上下文中执行该任务?)

    def list = []
    def dir = new File("Project/assets")
    dir.eachDirMatch (~/^(?!\.svn).*/) { file ->
        list << file
    }
    
    list.each {
        println it.name
    }
    

1 个答案:

答案 0 :(得分:7)

好的,这是我到目前为止发现的最干净的方式。

如果FileTree收集模式能够做到这一点,我仍然会更开心,但这几乎是简洁的,甚至可能更明确和不言自明。

关键是fileTree.visit使用relativePath(见下文)
另外,我添加了任务上下文并添加了对相关构建步骤的依赖性,以及为每个变体构建编写实际资产索引文件。

你问,为什么需要这个?由于AssetManager非常慢,请参阅here和后面的答案线程(触发原始ANT目标)。

android {

task indexAssets {
    description 'Index Build Variant assets for faster lookup by AssetManager later'

    ext.assetsSrcDir = file( "${projectDir}/src/main/assets" )        
    ext.assetsBuildDir = file( "${buildDir}/assets" )

    inputs.dir assetsSrcDir
    //outputs.dir assetsBuildDir

    doLast {
        android.applicationVariants.each { target ->
            ext.variantPath = "${buildDir.name}/assets/${target.dirName}"
            println "copyAssetRec:${target.dirName} -> ${ext.variantPath}"

            def relativeVariantAssetPath = projectDir.name.toString() + "/" + ext.variantPath.toString()
            def assetIndexFile = new File(relativeVariantAssetPath +"/assets.index")
            def contents = ""

            def tree = fileTree(dir: "${ext.variantPath}", exclude: ['**/.svn/**', '*.index'])

            tree.visit { fileDetails ->
                contents += "${fileDetails.relativePath}" + "\n"
            }

            assetIndexFile.write contents
        }
    }
}

indexAssets.dependsOn {
    tasks.matching { task -> task.name.startsWith( 'merge' ) && task.name.endsWith( 'Assets' ) }
}

tasks.withType( Compile ) {
    compileTask -> compileTask.dependsOn indexAssets
}

    ...
}