2016-02-29 60 views
0

作为使用NDK的Android应用程序的一部分,我需要将一些常量从C/C++世界导出到Java中。出于显而易见的原因,我宁愿有这种自动化。我正在使用Android Studio和NDK支持。如何生成在Android Studio中使用Gradle构建Java源代码?

如何从shell脚本中随时生成一些.java文件,每当应用程序构建时,该脚本将由Gradle运行?理想情况下,这个.java文件将放置在某个构建中介体目录中,并且不必位于应用程序源目录中。

举个例子,shell脚本会产生这样的Java源:

public enum Type { 
    FOO, 
    BAR 
} 

从这个C++源:

enum class Type { 
    FOO, 
    BAR 
} 

仅供参考这里的摇篮的简化版本文件我开始from Android Studio:

apply plugin: 'com.android.model.application' 

model { 

    compileOptions.with { 
     sourceCompatibility = JavaVersion.VERSION_1_7 
     targetCompatibility = JavaVersion.VERSION_1_7 
    } 

    android { 
     compileSdkVersion = 23 
     buildToolsVersion = "23.0.2" 

     defaultConfig.with { 
      applicationId = "..." 
      minSdkVersion.apiLevel = 18 
      targetSdkVersion.apiLevel = 23 
     } 

     defaultConfig.multiDexEnabled = true 
    } 

    android.ndk { 
     platformVersion = "18" 
     moduleName = "jni" 
     ... 
    } 

    android.buildTypes { 
     release { 
      minifyEnabled = false 
      proguardFiles.add(file('proguard-rules.txt')) 
      ndk.with { 
       CFlags.add("-Werror") 
       cppFlags.add("-Werror") 
      } 
     } 
    } 

    android.productFlavors { 
     create("arm7") { 
      ndk.abiFilters.add("armeabi-v7a") 
     } 
    } 

} 

repositories { 
    ... 
} 

dependencies { 
    ... 
} 

apply plugin: 'com.google.gms.google-services' 

回答

0

您可以将生成的文件写入$buildDir/generatedJava然后将该目录添加为源文件夹。然后使任务javaCompile取决于您生成源的任务。像这样的东西可以一build.gradle

def outputJavaFile = new File("$buildDir.absolutePath/generatedJava", 'MyEnum.java') 
task generateSources(type: Exec) { 
    def source = $/ 
package com.example; 
public enum Something { 
    One, 
    Two 
} 
/$ 

    if (!outputJavaFile.parentFile.exists()) { 
     outputJavaFile.parentFile.mkdirs() 
    } 
    outputJavaFile.withWriter { 
     it << source 
    } 
} 

compileJava.dependsOn outputJavaFile 

sourceSets { 
    main { 
     java { 
      srcDirs 'src/main/java', outputJavaFile.absolutePath 
     } 
    } 
} 

// if the goal is to generate the source from a script then just call the script 
// inside the Exec closure 
task shellScriptToGenerateSources(type: Exec) { 
    commandLine 'myShellScript.sh' 
} 
// then make compileJava depend on the task that runs the script 
compileJava.dependsOn shellScriptToGenerateSources 

编辑内部使用:要应用相同的逻辑来更新的build.gradle文件可能是这个样子

apply plugin: 'com.android.model.application' 

// define an output folder for our generated .java files 
def GENERATED_JAVA_OUTPUT = "$buildDir/generatedJava" 
// if the goal is to generate the source from a script then just call the script 
// inside the Exec closure 
task shellScriptToGenerateSources(type: Exec) { 
    commandLine 'myShellScript.sh' 
} 
// then make compileJava depend on the task that runs the script 
compileJava.dependsOn shellScriptToGenerateSources 

model { 

    compileOptions.with { 
     sourceCompatibility = JavaVersion.VERSION_1_7 
     targetCompatibility = JavaVersion.VERSION_1_7 
    } 

    android { 
     compileSdkVersion = 23 
     buildToolsVersion = "23.0.2" 

     defaultConfig.with { 
      applicationId = "..." 
      minSdkVersion.apiLevel = 18 
      targetSdkVersion.apiLevel = 23 
     } 

     defaultConfig.multiDexEnabled = true 
    } 

    android.ndk { 
     platformVersion = "18" 
     moduleName = "jni" 
     ... 
    } 

    android.buildTypes { 
     release { 
      minifyEnabled = false 
      proguardFiles.add(file('proguard-rules.txt')) 
      ndk.with { 
       CFlags.add("-Werror") 
       cppFlags.add("-Werror") 
      } 
     } 
    } 

    android.productFlavors { 
     create("arm7") { 
      ndk.abiFilters.add("armeabi-v7a") 
     } 
    } 

    // let android know that our java sources shoudl also consider the generated java for the compiler 
    android.sourceSet { 
     main { 
      java { 
       srcDir(GENERATED_JAVA_OUTPUT) 
      } 
     } 
    } 
} 

repositories { 
    ... 
} 

dependencies { 
    ... 
} 

apply plugin: 'com.google.gms.google-services' 
+1

感谢。如何通过运行shell脚本而不是定义java源代码? – Pol

+0

请参阅编辑。我添加了一个如何在'type:Exec'闭包中运行脚本的例子。您只需使脚本指向'sourceSets.main.java.srcDirs'中定义的dir。如果您的脚本以非零值退出,“shellScriptToGenerateSources”任务将失败。 – JBirdVegas

+0

再次感谢。我只是很难将你的Gradle示例与Android Studio使用的格式进行协调(请参阅我的更新问题) - 如何将更改合并到Android Studio Gradle文件中? – Pol

相关问题