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?
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With