I have a custom task in my build.gradle file that does bytecode transformations on class files before getting dex'd that looks like this:
task droidcook(type: JavaExec) { main 'org.tsg.android.asm.Main' } afterEvaluate { project -> android.applicationVariants.each { variant -> variant.javaCompile.doLast { project.tasks.droidcook.configure { classpath variant.javaCompile.classpath classpath "build/classes/" + variant.dirName classpath sdk.dir + "/platforms/android-19/android.jar" classpath "compile-libs/droidcook.jar" args "build/classes/" + variant.dirName args "com.example" // args "-debug" // args "-asmifier" } project.tasks.droidcook.execute() } } }
The issue with the above is the classpath sdk.dir + ...
line where sdk.dir
isn't evaluated appropriately. To get this working, I currently have to hard code the path to the android.jar
.
Bonus points if you can answer with an appropriate value to replace android-19
with for accessing a platform specific android.jar
based on project configuration. :D
The app level build. gradle file is located inside your project folder under app/build. gradle.
In a multi-project gradle build, you have a rootProject and the subprojects. The combination of both is allprojects. The rootProject is where the build is starting from. A common pattern is a rootProject has no code and the subprojects are java projects.
I don't see a published API to expose sdk.dir to your build file, so I just cribbed the code from https://android.googlesource.com/platform/tools/build/+/d69964104aed4cfae5052028b5c5e57580441ae8/gradle/src/main/groovy/com/android/build/gradle/internal/Sdk.groovy to read it manually. As for replacing android-19, if I read android.compileSdkVersion I get that exact string. I'm not sure that this is a published API either, so it may be subject to change and breakage in future versions of the Android Gradle plugin.
With that said, this works for me:
afterEvaluate { def rootDir = project.rootDir def localProperties = new File(rootDir, "local.properties") if (localProperties.exists()) { Properties properties = new Properties() localProperties.withInputStream { instr -> properties.load(instr) } def sdkDir = properties.getProperty('sdk.dir') def androidJarPath = sdkDir + "/platforms/" + android.compileSdkVersion + "/android.jar" print androidJarPath + "\n" } }
If there's no local.properties, this code is going to fail. If you care about that case, you can copy more code from Sdk.groovy to mimic its behavior in trying to find a reasonable default.
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