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
因此我的问题如下:
- 如何解决上面的错误消息?我必须将 java class 移动到另一个文件夹吗?也许在构建脚本中配置某事?
- 如何确保 java 任务在 classes 实际编译后执行?
- 如果我想将任务 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
我正在尝试 运行 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
因此我的问题如下:
- 如何解决上面的错误消息?我必须将 java class 移动到另一个文件夹吗?也许在构建脚本中配置某事?
- 如何确保 java 任务在 classes 实际编译后执行?
- 如果我想将任务 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