Issue
I am trying to generate some Android resources in a Gradle task.
I've written a task which parses an input file, and writes out an XML file to a location under the app's build
directory.
app/build.gradle
import groovy.xml.MarkupBuilder
task generateSomeAppResources {
ext.outputDir = new File(projectDir, "build/generated/res/values")
doFirst {
mkdir outputDir
new File(outputDir, "generated.xml").withWriter { writer ->
def destXml = new MarkupBuilder(new IndentPrinter(writer, " ", true, true))
destXml.setDoubleQuotes(true)
def destXmlMkp = destXml.getMkp()
destXmlMkp.xmlDeclaration(version: "1.0", encoding: "utf-8")
destXmlMkp.comment("Generated at ${new Date()}")
destXmlMkp.yield "\r\n"
destXml.resources() {
"string"("name": "generated_app_resource") {
destXmlMkp.yield("Some generated value for the app")
}
}
}
}
}
This works fine, and the generated output looks like I expect.
generated.xml
<?xml version="1.0" encoding="utf-8"?>
<!-- Generated at Wed Feb 12 12:46:12 GMT 2020 -->
<resources>
<string name="generated_app_resource">Some generated value for the app</string>
</resources>
I am struggling to get the Android build system to detect the generated file, though. Google's advice is
to write a task that outputs a generated resource directory structure with whatever you need, use BaseVariant.registerGeneratedResFolders()
But documentation on registerGeneratedResFolders()
is non-existent. After much tedious searching I found some example usages in the Play Services Plugin source, for example, so I tried to add something along those lines.
app/build.gradle
android.applicationVariants.all { variant ->
def files = project.files(generateSomeAppResources.outputDir)
files.builtBy(generateSomeAppResources)
variant.preBuildProvider.configure { dependsOn(generateSomeAppResources) }
variant.mergeResourcesProvider.configure { dependsOn(generateSomeAppResources) }
variant.registerGeneratedResFolders(files)
}
But I'm missing something. The generated resource shows up purple in Android Studio, meaning that the IDE thinks it exists...
...but the code fails to compile with an Unresolved reference: generated_app_resource
error.
I don't know what magic incantations are needed to make the Android build system pick up these resources. How do I get this to build?
Solution
To create resources, android requires
1) A resource directory above values
folder then you can add desired resources as per your requirement
2) Instruct the build process to add the generated resources while building R.java
So first configure your build resource task like:
task generateSomeAppResources {
ext.outputDir = new File(projectDir, "build/generated/res/custom/values")
print("path is "+projectDir)
doFirst {
mkdir outputDir
new File(outputDir, "strings.xml").withWriter { writer ->
def destXml = new MarkupBuilder(new IndentPrinter(writer, " ", true, true))
destXml.setDoubleQuotes(true)
def destXmlMkp = destXml.getMkp()
destXmlMkp.xmlDeclaration(version: "1.0", encoding: "utf-8")
destXmlMkp.comment("Generated at ${new Date()}")
destXmlMkp.yield "\r\n"
destXml.resources() {
"string"("name": "generated_app_resource") {
destXmlMkp.yield("Some generated value for the app")
}
}
}
}
}
now add the path in the build process using sourceSets
in build.gradle
(app) like
android {
//....
sourceSets {
main {
res.srcDirs += [
'build/generated/res/custom',
]
}
}
}
Additionally, add the task in the current build process as
gradle.projectsEvaluated {
preBuild.dependsOn('generateSomeAppResources')
} // no need of `android.applicationVariants.all...`
Now sync the project and it will work as expected.
Result:
Answered By - Pavneet_Singh
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.