2016-02-29 71 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

相關問題