当前位置: 首页 > 面试题库 >

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

苏波涛
2023-03-14
问题内容

我正在尝试从构建过程的build.gradle脚本asp艺术中运行Java类的静态main方法。我正在将Android Studio
1.0.2与Android / Gradle插件’com.android.tools.build:gradle:1.0.0’结合使用

我要在构建期间运行其主要html" target="_blank">方法的Java类位于… \ 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文件的相关部分,该文件试图执行上述类的main方法(实际任务定义位于依赖项之前的最后):

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

我收到以下错误消息:

错误:找不到或加载主类de.myapp.gradle.ConfigureCustomer

因此,我的问题如下:

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

configureCustomer

我也尝试添加类路径:

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

但是让我得到的只是gradle build错误消息,上面写着:

在SourceSet容器上找不到属性“ main”

因此,显然在Android Studio的Gradle中不存在“
sourceSets.main.runtimeClasspath”。也许它的名字有所不同。尽管我也尝试过这样设置类路径:

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

我也尝试过这个:

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

这些都不起作用,上述错误仍然存​​在:

错误:找不到或加载主类de.myapp.gradle.ConfigureCustomer


问题答案:

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

回顾一下-这是我要执行其主要方法的Java类:

软件包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项目中的想法。取而代之的是,我将该类设为一个单独的项目,构建了一个jar文件,并将其放在我正在构建的android项目的libs文件夹中。

更新04.02.2015

我对上述内容做了一些修改,以使用javaexec方法而不是JavaExec Task类型:

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

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



 类似资料:
  • 问题内容: 我正在尝试从构建过程的build.gradle脚本asp艺术中运行Java类的静态main方法。我正在将Android Studio 1.0.2与Android / Gradle插件’com.android.tools.build:gradle:1.0.0’结合使用 我要在构建期间运行其主要方法的Java类位于… \ trunk-gradle \ myproject \ src \ m

  • 操作步骤: 菜单栏: Refactor —> Move... 快捷键: Mac: fn + F6 (可能会跟系统快捷键冲突)

  • 我试图将Sonarqube从5.6.6(LTS)升级到6.4,但在web上遇到了这个异常。日志文件,数据库迁移失败后消息: 我查看了DUPLICATIONS_INDEX表,没有找到ID列。 我最近从5.4升级到了5.6.6,工作很好。 有解决办法吗?考虑将数据库恢复到5.6.6,并尝试升级到6.0,然后升级到6.1直到6.4。 更新: 我尝试了6.0版本,并在sonar.log文件上获得了一个巨大

  • 问题内容: 我很了解Java。哪些警告和资源将帮助我尽可能轻松地跨过另一端(C#)。 问题答案: 最大提示:请使用go一词中的.NET命名约定。这样,您将不断被提示使用的是哪种语言。(听起来很愚蠢,但这确实有帮助。)尽可能多地接受该语言的习惯用法。 有许多专门针对您所处地区的人们的书籍-在亚马逊上搜索“ C#for Java”,您将获得很多成功。值得 仔细 阅读以确保您不认为C#和Java中的功能

  • 我的目标是创建一个抽象类,它的静态方法必须被实现,但是由于静态方法不能被抽象,我有一些问题。 这就是我提出的解决方案: 我写这篇文章是因为我找不到任何等价的答案,这让我想知道这在Java中是否是惯用的。

  • 这是我在实体的源代码模型中的内容: 这是我在实体的目标模型中得到的: 如您所见,我将关系从多个更改为一个,从更改为。 但现在我有以下错误: 我不知道如何解决这个问题。有什么想法吗? 这是我设置核心数据堆栈的方式: