如何在Android Studio中使用Gradle生成Java源代码?

时间:2016-02-29 16:18:54

标签: android-studio gradle android-gradle

作为使用NDK的Android应用程序的一部分,我需要将一些常量从C / C ++世界导出到Java中。出于显而易见的原因,我宁愿自动化。我使用Android Studio并支持NDK。

如何在应用程序构建时由Gradle运行的shell脚本动态生成一些.java文件?理想情况下,此.java文件将位于某个构建中介目录中,并且不必位于应用程序源目录中。

作为示例,shell脚本将生成此Java源:

public enum Type {
  FOO,
  BAR
}

来自这个C ++源代码:

enum class Type {
  FOO,
  BAR
}

此处参考Gradle文件的简化版本我将从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'

1 个答案:

答案 0 :(得分: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'