Android Studio Gradle:执行静态 Java 方法(从 ANT 迁移到 Gradle)

Android Studio Gradle: Execute static Java Method (Migration from ANT to Gradle)

我正在尝试 运行 java class 的静态主要方法,来自我的 build.gradle 脚本 asp 构建过程的艺术。我正在使用 Android Studio 1.0.2 和 Android/Gradle 插件 'com.android.tools.build:gradle:1.0.0'

java class 我想在构建期间 运行 其主要方法位于 ...\trunk-gradle\myproject\src\main\java\de\myapp\gradle

package de.myapp.gradle;

public class ConfigureCustomer {

    public static void main(String[] args){
        String server = args[0];
        String customer = args[1];
        System.out.println(String.format("Configuring customer %s with server %s", customer, server));
    }
}

在我使用 ANT 调用那个 java 方法之前,如下所示:

<java failonerror="yes" classname="de.myapp.gradle.ConfigureCustomer ">
    <classpath>
        <path location="${base.dir}/bin/classes/"/>
    </classpath>
    <arg line="${customer}"/>
    <arg line="${server }"/>
</java>

但现在我正在迁移到 Groovy,所以这里是我项目的 build.gradle 文件的相关部分,它试图执行上述 class 的主要方法(实际任务定义在依赖项之前的末尾):

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

    project.ext.set("customer", "")
    project.ext.set("server", "")

    dexOptions {
        preDexLibraries = false
    }

    compileSdkVersion 19
    buildToolsVersion "21.1.2"

    defaultConfig {
//Default configuration
    }


    signingConfigs {
        release {
//Configuration for release builds
        }
    }


    buildTypes {

        debug{
            server = "test"
        }

        release {
            server = "release"
        }
    }

    productFlavors {
        customerA{
            customer = "a"
        }
        customerB{
            customer = "b"
        }
        customerC{
            customer = "c"
        }
    }
}

task (configureCustomer,  type: JavaExec) {
    println 'Running customer configuration...'
    main = 'de.myapp.gradle.ConfigureCustomer'
    args customer, server
}

dependencies {
    //Dependency settings
}

所以现在当我 运行 通过命令行执行以下操作时 (windows):

graldew configureCustomer

我收到以下错误消息:

Error: Could not find or load main class de.myapp.gradle.ConfigureCustomer

因此我的问题如下:

  1. 如何解决上面的错误消息?我必须将 java class 移动到另一个文件夹吗?也许在构建脚本中配置某事?
  2. 如何确保 java 任务在 classes 实际编译后执行?
  3. 如果我想将任务 configureCustomer 作为另一个任务的一部分执行,我是否可以简单地在 gradle 的任务定义中写入以下行?

configureCustomer

我还尝试添加 class路径:

task (configureCustomer,  type: JavaExec) {
    println 'Running customer configuration...'
    main = 'de.myapp.gradle.ConfigureCustomer'
    classpath = sourceSets.main.runtimeClasspath
    args customer, server
}

但是我得到的只是一条 gradle 构建错误消息:

Could not find property "main" on SourceSet container

显然 "sourceSets.main.runtimeClasspath" 在 Android Studio 的 Gradle 中不存在。也许它的名字不同。虽然我也试过像这样设置 classpath:

classpath = '${projectDir.getAbsolutePath()}\build\intermediates\classes\' + customer + '\release'

我也试过这个:

classpath = '${projectDir.getAbsolutePath()}\build\intermediates\classes\' + customer + '\release\de\myapp\gradle'

None 其中有效,上面的错误仍然存​​在:

Error: Could not find or load main class de.myapp.gradle.ConfigureCustomer

我终于找到了适用于 Android/Gradle 的东西,但到达那里似乎比应该的要复杂得多。

所以回顾一下 - 这是 Java class 我想执行的主要方法:

包 de.myapp.gradle;

public class ConfigureCustomer {

    public static void main(String[] args){
        String customer = args[0];
        String versionName = args[1];
        System.out.println(String.format("Configuring customer %s with versionName %s", customer, versionName ));
    }
}

我想为每种风格执行上面的操作,并且只针对发布版本(不是调试版本),所以这是我的任务定义(你仍然必须让你的任务依赖于 gradle构建任务以便执行 - 我为此目的依赖于 preBuild 任务):

android {
//Build type setup, signing configuration and other stuff
}

//After the android block my task definition follows:

task buildPrintout(type: JavaExec) {
    android.applicationVariants.all { variant ->
    //Runt he java task for every flavor
        variant.productFlavors.each { flavor ->
            println "Triggering customer configuration for flavor " + flavor.name
            if (variant.buildType.name.equals('release')) {
                //Run the java task only for release builds
                //Cant find the runtime classpath in android/gradle so I'll directly link to my jar file here. The jarfile contains the class I want to run (with the main method)
                classpath += files("libs/my-jarfile.jar")
                //This is the fully qualified name of my class, including package name (de.myapp.gradle) and the classname (ConfigureCustomer)
                main = "de.myapp.gradle.ConfigureCustomer"
                //Pass in arguments - in this case the customer's name and the version name for the app (from AndroidManifest.xml)
                args flavor.name, variant.versionName
            }
        }
    }
}

您会注意到我放弃了将我的 Class 集成到我即将构建的 android 项目中的想法。相反,我将那个 class 设为一个单独的项目,构建了一个 jar 文件并将其放入我正在构建的 android 项目的 libs 文件夹中。

更新 04.02.2015

我稍微修改了上面的内容以使用 javaexec 方法而不是 JavaExec 任务类型:

preBuild.doFirst {
    android.applicationVariants.all { variant ->
        variant.productFlavors.each { flavor ->
            if (variant.buildType.name.equals('release')) {
                javaexec {
                    println "Triggering customer build for flavor " + flavor.name
                    classpath += files("libs/my-jarfile.jar")
                    main = "de.myapp.gradle.ConfigureCustomer"
                    args flavor.name, variant.versionName
                }
                println "Done building customer for flavor " + flavor.name
            }
        }
    }
}

还有另一种变体,我们在可重用(首选)任务中定义 javaexec,然后将其作为依赖项添加到 preBuild 任务:

//Define our custom task and add the closures as an action
    task buildCustomer << {
        android.applicationVariants.all { variant ->
            variant.productFlavors.each { flavor ->
                if (variant.buildType.name.equals('release')) {
                        javaexec {
                            println "Triggering customer build for flavor " + flavor.name
                            classpath += files("libs/my-jarfile.jar")
                            main = "de.myapp.gradle.ConfigureCustomer"
                            args flavor.name, variant.versionName
                        }
                        println "Done building customer for flavor " + flavor.name
                }
            }
        }        
    }
    //Make preBuild depend on our task
    preBuild.dependsOn buildCustomer

如果您有任何问题,请告诉我,我会尽力解答。

改变类路径的配置方式

classpath(files('build/intermediates/classes/release',"${android.getSdkDirectory().getAbsolutePath() + '/platforms/' + android.compileSdkVersion + '/android.jar'}"))

适用于 android gradle 1.5