Android的工作室摇篮:执行静态Java方法(从迁移到ANT摇篮) [英] Android Studio Gradle: Execute static Java Method (Migration from ANT to Gradle)

查看:291
本文介绍了Android的工作室摇篮:执行静态Java方法(从迁移到ANT摇篮)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从构建过程中我的build.gradle脚本的ASP技术运行一个Java类的静态主要方法。我使用的Andr​​oid 1.0.2工作室与Android /摇篮插件com.android.tools.build:gradle:1.0.0

Java类我想在生成位于... \\干线gradle这个运行的主要方法\\ MyProject中的\\ src \\主\\ java的\\日\\ MyApp的\\ gradle这个

 包de.myapp.gradle;公共类ConfigureCustomer {    公共静态无效的主要(字串[] args){
        字符串服务器= ARGS [0];
        串顾客= ARGS [1];
        的System.out.println(的String.format(配置客户%s与服务器%S,客户的服务器));
    }
}

在我使用Ant来调用Java方法如下:

 < java的failonerror =是类名=de.myapp.gradle.ConfigureCustomer>
    <&类路径GT;
        <路径位置=$ {} base.dir /斌/班//>
    < /类路径>
    < ARG行=$ {}客户/>
    < ARG行=$ {}服务器/>
< / JAVA>

但我现在迁移到Groovy中,所以这里是我的项目的build.gradle文件的相关部分试图执行上面的类的主要方法(实际任务定义为只是依赖月底前):

 应用插件:'com.android.application
安卓{    project.ext.set(客户,)
    project.ext.set(服务器,)    dexOptions {
        preDexLibraries = FALSE
    }    compileSdkVersion 19
    buildToolsVersion21.1.2    defaultConfig {
//默认配​​置
    }
    signingConfigs {
        发布 {
//发布配置构建
        }
    }
    buildTypes {        调试{
            服务器=测试
        }        发布 {
            服务器=释放
        }
    }    productFlavors {
        customerA {
            顾客=一个
        }
        customerB {
            顾客=b的
        }
        customerC {
            客户=C
        }
    }
}任务(configureCustomer,键入:JavaExec){
    的println运行客户配置......
    主要='de.myapp.gradle.ConfigureCustomer
    ARGS客户,服务器
}依赖{
    //依赖设置
}

所以,现在当我运行通过命令行下面(视窗):

  graldew configureCustomer

我收到以下错误信息:


  

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


我的问题,因此如下:


  1. 我如何管理来解决上述错误信息?我有我的java类移动到另一个文件夹?在构建素文字也许配置做某事?

  2. 如何确保类实际上已经编译后执行java任务?

  3. 如果我想执行任务configureCustomer作为另一个任务的一部分,我会简单的写在我的Gradle的任务定义以下行?


  

configureCustomer


我也尝试添加类路径:

 任务(configureCustomer,键入:JavaExec){
    的println运行客户配置......
    主要='de.myapp.gradle.ConfigureCustomer
    CLASSPATH = sourceSets.main.runtimeClasspath
    ARGS客户,服务器
}

但是,所有这让我在一个gradle这个生成错误消息说:


  

在SourceSet容器找不到财产主


所以显然是sourceSets.main.runtimeClasspath并不Android Studio中的摇篮存在。也许它的命名不同。虽然我也试着设置类路径是这样的:

  CLASSPATH ='$ {projectDir.getAbsolutePath()} \\\\ \\\\构建\\\\中间体类\\\\'+客户+'\\\\释放

和我也试过这样的:

  CLASSPATH ='$ {projectDir.getAbsolutePath()} \\\\ \\\\构建\\\\中间体类\\\\'+客户+'\\\\ \\\\发布德\\\\ \\\\的MyApp gradle这个'

其中无工作,从上面的错误仍然存​​在:


  

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



解决方案

我终于找到的东西,为Android /摇篮工作,但越来越似乎有很多更复杂,比它应有的水平。

因此​​,对于回顾 - 在这里是Java类,其主要的方法,我想执行:

包de.myapp.gradle;

 公共类ConfigureCustomer {    公共静态无效的主要(字串[] args){
        串顾客= ARGS [0];
        串的versionName = ARGS [1];
        的System.out.println(的String.format(配置客户%s与%的versionName的,客户的versionName));
    }
}

我要执行如上的味道,只对发布版本(不调试版本),所以这是我的任务定义(你仍然必须让你的任务依赖的gradle这个建设任务之一,所以它的执行 - 我视preBuild任务这个目的):

 安卓{
//构造类型的设置,签约配置和其他的东西
}//后android的块我的任务定义如下:任务buildPrintout(类型:JavaExec){
    android.applicationVariants.all {变种 - >
    //为每一种滋味欠幅脉冲,他java任务
        variant.productFlavors.each {味 - >
            的println触发客户配置味+ flavor.name
            如果(variant.buildType.name.equals('释放')){
                //运行Java任务只对发布版本
                //不能找到在机器人/ gradle这个运行时类路径,所以我会直接链接到我的jar文件在这里。 jar文件包含了我想要运行的类(主要方法)
                类路径+ =文件(库/我-jarfile.jar)
                //这是我的类的全名,包括包名(de.myapp.gradle)和类名(ConfigureCustomer)
                主要=de.myapp.gradle.ConfigureCustomer
                //传入的参数 - 在这种情况下,客户的名称和应用(从AndroidManifest.xml中)的版本名称
                ARGS flavor.name,variant.versionName
            }
        }
    }
}

您会注意到我甩有集成在Android项目,我要建造我的课的想法。相反,我做了一个班一个独立的项目,建成一个jar文件,并在Android项目我建立的libs文件夹放弃了它。

更新2015年2月4日

我稍微修改上面使用javaexec方法,而不是JavaExec任务类型:

  $ P $ {pBuild.doFirst
    android.applicationVariants.all {变种 - >
        variant.productFlavors.each {味 - >
            如果(variant.buildType.name.equals('释放')){
                javaexec {
                    的println触发客户建立味+ flavor.name
                    类路径+ =文件(库/我-jarfile.jar)
                    主要=de.myapp.gradle.ConfigureCustomer
                    ARGS flavor.name,variant.versionName
                }
                的println完成建立客户对味+ flavor.name
            }
        }
    }
}

和这里是又一变型中,在这里我们定义内的可重复使用的javaexec(它是preferred)任务,我们再加入作为依赖于preBuild任务:

  //定义我们的自定义任务,并添加关闭作为一个动作
    任务buildCustomer<< {
        android.applicationVariants.all {变种 - >
            variant.productFlavors.each {味 - >
                如果(variant.buildType.name.equals('释放')){
                        javaexec {
                            的println触发客户建立味+ flavor.name
                            类路径+ =文件(库/我-jarfile.jar)
                            主要=de.myapp.gradle.ConfigureCustomer
                            ARGS flavor.name,variant.versionName
                        }
                        的println完成建立客户对味+ flavor.name
                }
            }
        }
    }
    //使preBuild取决于我们的任务
    preBuild.dependsOn buildCustomer

如果您有任何问题,让我知道,我会尽力回答。

I am trying to run the static main method of a java class from my build.gradle script asp art of the build process. I am using Android Studio 1.0.2 with the Android/Gradle Plugin 'com.android.tools.build:gradle:1.0.0'

The java class whose main method I want to run during the build resides in ...\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));
    }
}

Before I used ANT to call that java method as follows:

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

But now I am migrating to Groovy, so here is the relevant part of my project's build.gradle file that tries to execute the main method of above class (actual task definition is at the end just before the dependencies):

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
}

So now when I run the following via the command line (windows):

graldew configureCustomer

I get the following error message:

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

My questions hence are as follows:

  1. How do I manage to fix the error message above? Do I have to move my java class to another folder? Maybe configure sth in the build scipt?
  2. How can I make sure the java task is executed after the classes have actually been compiled?
  3. If i wanted to execute the task configureCustomer as part of another task, would I simply write the following line in my gradle's task definition?

configureCustomer

I also tried to add the classpath:

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

But all that got me was a gradle build error message saying:

Could not find property "main" on SourceSet container

So apparently "sourceSets.main.runtimeClasspath" does not exist in Android Studio's Gradle. Maybe it's named differently. Though I also tried setting the classpath like this:

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

and I also tried this:

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

None of which worked, the error from above persists:

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

解决方案

I finally found something that works for Android/Gradle but getting there seemed a lot more complicated, than it should have been.

So for recap - here is the Java class whose main method I'd like to execute:

package 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 ));
    }
}

I want to execute the above for each flavor and only for release builds (not debug builds) so here is my task definition (you'd still have to make your task depend on one of the gradle build tasks so it's executed - I am depending on the preBuild task for this purpose):

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
            }
        }
    }
}

You'll notice that I dumped the idea of having my Class integrated in the android project I am about to build. Instead I made that one class a separate project, built a jar file and dropped it in the libs folder of the android project i am building.

UPDATE 04.02.2015

I have slightly modified the above to use the javaexec method instead of the JavaExec Task type:

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
            }
        }
    }
}

And here is yet another variation, where we define the javaexec within a reusable (which is preferred) task, that we then add as a dependency to the preBuild task:

//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

If you have any questions let me know and I'll try to answer them.

这篇关于Android的工作室摇篮:执行静态Java方法(从迁移到ANT摇篮)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆