2013-11-25 20 views
17

我在做的类文件字节码转换得到dex'd看起来像这样在我的build.gradle文件中有一个自定义任务:访问sdk.dir值

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

回答

21

我没有看到一个已发布的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复制更多的代码来模仿它的行为,试图找到一个合理的默认值。

+0

大加赞赏,我是从gradle这个倦怠患:d II RC从过去调查这个问题,问题是sdk目录var在我的'afterEvaluate'后面实例化,并且因此它不可用。所以手动加载它可能是目前唯一的解决方案,并且这对于跨平台开发来说足够好。 – dskinner

+1

println“$ {android.getSdkDirectory()。getAbsolutePath()}”适用于1.5.0 –

15

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

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

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

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

为了完整起见,这里是如何得到ndk.dir变量,太:

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

适用于'1.3.1'。 –

+0

println“$ {android.getSdkDirectory()。getAbsolutePath()}”适用于1.5.0 –

0

用途:

String androidJar = android.getBootClasspath()[0] 

假设你正在使用SDK 21,这将设置'<路径到SDK > /platforms/android-21/android.jar'到变量androidjar(SDK版本选择自动执行)。

下一步将明显地与替换“类路径sdk.dir ......”等:

classpath androidJar 
4

由于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 
}