Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to correctly generate an XML resource file during build?

I need a raw XML file ("raw" as in accessible through @raw/filename) to be generated during the build process.

I've been trying to accomplish this using a custom Gradle task hooked on preBuild. This task would then gather all requirements needed and generate the file under build/intermediates/res/main/raw.

It's all good up to this point; I could see the file being properly generated. However, I couldn't seem to access it from any other XML resource files that I have.

I've tried changing the target directory to build/generated/source/res/main/raw but the problem persists.

Changing it to src/main/res/raw worked but then I'd have to exclude the generated file from git – I don't want that. Plus, it seems weird to have generated source files reside within the same directory as their written counterparts.

Below is a simplified snippet of my custom task:

task(generateChangelogXml) {
    def source = new File(rootProject.projectDir, "CHANGELOG")
    def targetDir = new File(projectDir, "/build/intermediates/res/main/raw")
    def target = new File(targetDir, "changelog_latest.xml")

    def versionName = ""
    def releaseDate = ""
    def changes = new ArrayList<String>()

    def reader = new BufferedReader(new FileReader(source))
    def currLine = ""
    while ((currLine = reader.readLine()) != null) {
        // Truncated for brevity
    }

    target.withWriter { writer ->
        writer.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n")
        writer.write("<changelog bulletedList=\"true\">\n")
        writer.write("    <changelogversion changeDate=\"\" versionName=\"$versionName\">\n")
        changes.forEach { change ->
            writer.write("        <changelogtext>$change</changelogtext>\n")
        }
        writer.write("    </changelogversion>\n")
        writer.write("</changelog>\n")
    }
}
preBuild.dependsOn(generateChangelogXml)

Am I missing something here?

like image 759
Hadi Satrio Avatar asked Feb 15 '18 07:02

Hadi Satrio


People also ask

What is resource in XML?

XML files that contain simple values, such as strings, integers, and colors. Whereas XML resource files in other res/ subdirectories define a single resource based on the XML filename, files in the values/ directory describe multiple resources.

What is resource file in Android Studio?

In Android, a resource is a localized text string, bitmap, layout, or other small piece of noncode information that your app needs. At build time, all resources get compiled into your application. The resources locates inside res directory of your app.


1 Answers

Okay, so after reading more on the matter I came to learn that we really can't rely on existing folders (be it in generated or intermediates) to put our generated files in as they might be overridden by other tasks and/or not readable at all.

The solution? Why, just create a folder of our own! As an example, this is what I'm ended up using:

def generatedResDir = new File("$buildDir/generated/local/main/res")

Then, just use it as the base directory for every generated resource files. If you're like me and are looking to generate a raw XML, then do this:

def targetDir = new File("$generatedResDir/raw")
def target = new File(targetDir, "changelog_latest.xml")

Last but definitely not least, add generatedResDir as a source directory by doing so:

sourceSets {
    main {
        res {
            srcDirs += generatedResDir
        }
    }
}

You should now able to generate any files of your choosing without problems.

like image 174
Hadi Satrio Avatar answered Nov 14 '22 18:11

Hadi Satrio