在项目评估后访问build.gradle中的sdk.dir值

时间:2013-11-25 21:33:04

标签: android android-studio

我的build.gradle文件中有一个自定义任务,它在获取dex'd之前对类文件进行字节码转换,如下所示:

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()
        }
    }
}

以上问题是classpath sdk.dir + ...行,其中sdk.dir未得到适当评估。为了实现这一目标,我目前必须对android.jar的路径进行硬编码。

如果您可以使用适当的值来回答android-19,并根据项目配置访问特定于平台的android.jar,那么

奖励积分。 :d

4 个答案:

答案 0 :(得分:22)

我没有看到已发布的API将sdk.dir暴露给您的构建文件,因此我只是将https://android.googlesource.com/platform/tools/build/+/d69964104aed4cfae5052028b5c5e57580441ae8/gradle/src/main/groovy/com/android/build/gradle/internal/Sdk.groovy中的代码填充为手动读取它。至于替换android-19,如果我读取android.compileSdkVersion,我会得到那个确切的字符串。我不确定这是否是已发布的API,因此在未来版本的Android Gradle插件中可能会发生变化和破坏。

话虽如此,这对我有用:

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"
    }
}

如果没有local.properties,则此代码将失败。如果您关心这种情况,可以从Sdk.groovy复制更多代码,以模仿其在尝试找到合理默认值时的行为。

答案 1 :(得分:17)

有一种更简单的方法,虽然没有记录,所以它可能没有得到官方的支持。

println "${android.getSdkDirectory().getAbsolutePath()}"

奇怪的是,这种方法似乎只适用于某些版本的gradle插件。它在Scott上面提交的提交中不可用。如果上面的代码不起作用,那么试试这个:

println "${android.plugin.getSdkFolder().getAbsolutePath()}"

为了完整起见,以下是如何获取ndk.dir变量:

println "${android.plugin.getNdkFolder().getAbsolutePath()}"

答案 2 :(得分:5)

从android gradle插件v2.1.2开始,这就是我在gradle脚本中使用的内容:

android.ndkDirectory.path
android.sdkDirectory.path

例如,明确启动ndk-build

task ndkBuild(type: Exec) {
    commandLine android.ndkDirectory.path+'/ndk-build', '-C', file('src/main').absolutePath
}

答案 3 :(得分:1)

使用:

String androidJar = android.getBootClasspath()[0]

假设您使用的是SDK 21,这会将'< path-to-SDK> /platforms/android-21/android.jar'设置为变量 androidJar (执行SDK版本选择)自动地)。

下一步显然是用:

替换'classpath sdk.dir ...'等
classpath androidJar