Gradle script to generate proguard dictionaries each build
programming
android
,
gradle
,
groovy
,
proguard
Gradle task to generate proguard dictonary
Always overwrite existing generated dictionary
def dictDest = new File('build/builddict.txt')
tasks.register('genDict') {
outputs.file(dictDest)
doLast {
if (dictDest.exists()) return
def r = new Random()
println(r)
def begin = r.nextInt(1000) + 0x0100
def end = begin + 0x40000
println("end: " + end)
def chars = (begin..end)
.findAll { Character.isValidCodePoint(it) && Character.isJavaIdentifierPart(it) }
.collect { String.valueOf(Character.toChars(it)) }
println("chars: " + chars)
int max = chars.size()
println(max)
def start = []
def dict = []
for (int i = 0; i < max; i++) {
char c = chars.get(i).charAt(0)
if (Character.isJavaIdentifierStart(c)) {
start << String.valueOf(c)
}
}
println(start.size())
def f = outputs.files.getSingleFile()
f.getParentFile().mkdirs()
f.withWriter("UTF-8") {
it.write(start.join(System.lineSeparator()))
it.write()
}
}
}
Prevent overwriting existing generated dictionary
// tell others this file cannot be replaced (final)
final def dictDest = project.file("build/builddict.txt")
tasks.register("genDict") {
// prevent duplicate
println "$dictDest exists ${dictDest.exists()}"
if (!dictDest.exists()) {
outputs.file(dictDest)
doLast {
def r = new Random()
println(r)
def begin = r.nextInt(1000) + 0x0100
def end = begin + 0x40000
println("end: " + end)
def chars = (begin..end)
.findAll { Character.isValidCodePoint(it) && Character.isJavaIdentifierPart(it) }
.collect { String.valueOf(Character.toChars(it)) }
println("chars: " + chars)
int max = chars.size()
println(max)
def start = []
def dict = []
for (int i = 0; i < max; i++) {
char c = chars.get(i).charAt(0)
if (Character.isJavaIdentifierStart(c)) {
start << String.valueOf(c)
}
}
println(start.size())
def f = outputs.files.getSingleFile()
f.getParentFile().mkdirs()
f.withWriter("UTF-8") {
it.write(start.join(System.lineSeparator()))
it.write()
}
}
}
}
run manual with ./gradlew genDict
or bash ./gradlew genDict
but you can automated generator dictionary using afterEvaluate
afterEvaluate {
// each variant depends on `genDict` task
android.applicationVariants.all { variant ->
if (variant.name.endsWith('Release'))
variant.javaCompileProvider.configure {
dependsOn 'genDict'
}
}
}
in new API Androig Gradle Plugin v8
afterEvaluate {
// each variant depends on `genDict` task
android.applicationVariants.configureEach { variant ->
if (variant.name.endsWith('Release'))
variant.javaCompileProvider.configure {
dependsOn 'genDict'
}
}
}
in your proguard rules dont forget put
-obfuscationdictionary build/dict.txt
-classobfuscationdictionary build/dict.txt
-packageobfuscationdictionary build/dict.txt
My working scripts
put in app/build.gradle
def dictDest = new File('.', 'build/builddict.txt')
tasks.register('genDict') {
outputs.file(dictDest)
doLast {
// prevent rewrite
if (dictDest.exists()) return
def r = new Random()
println(r)
def begin = r.nextInt(1000) + 0x0100
def end = begin + 0x40000
println("end: " + end)
def chars = (begin..end)
.findAll { Character.isValidCodePoint(it) && Character.isJavaIdentifierPart(it) }
.collect { String.valueOf(Character.toChars(it)) }
println("chars: " + chars)
int max = chars.size()
println(max)
def start = []
def dict = []
for (int i = 0; i < max; i++) {
char c = chars.get(i).charAt(0)
if (Character.isJavaIdentifierStart(c)) {
start << String.valueOf(c)
}
}
println(start.size())
def f = outputs.files.getSingleFile()
f.getParentFile().mkdirs()
f.withWriter("UTF-8") {
it.write(start.join(System.lineSeparator()))
it.write()
}
}
}
// generate proguard dictionary on preBuild task (debug variant included)
//tasks.named("preBuild") {
// dependsOn(tasks.named("genDict"))
//}
afterEvaluate {
// each variant depends on `genDict` task
android.applicationVariants.configureEach { variant ->
// apply online variant with `release` substring
if (variant.name.toLowerCase().contains('release'))
variant.javaCompileProvider.configure {
dependsOn 'genDict'
}
}
}