436 votes

Est-il possible de déclarer une variable dans Gradle utilisable en Java?

Est-il possible de déclarer une variable dans Gradle utilisable en Java? Fondamentalement je voudrais déclarer quelques vars dans le build.gradle et l'obtenir (évidemment) au temps de construction. Tout comme les macros pré-processeur en C / C ++ ...

Un exemple de déclaration serait quelque chose comme ça ...:

 android {
    debug {
        A_VAR_RETRIEVABLE_IN_JAVA = 42
    }
    release {
        A_VAR_RETRIEVABLE_IN_JAVA = 42+52
    }
}
 

Y a-t-il un moyen de faire quelque chose comme ça?

835voto

rciovati Points 5991

Générer des constantes Java

Version du plugin supérieure à 0.7.x (méthode actuelle)

 android {
    buildTypes {
        debug {
            buildConfigField "int", "FOO", "42"
            buildConfigField "String", "FOO_STRING", "\"foo\""
        }

        release {
            buildConfigField "int", "FOO", "52"
            buildConfigField "String", "FOO_STRING", "\"bar\""
        }
    }
}
 

Version du plugin inférieure à 0.7 (ancien)

 android {
    buildTypes {
        debug {
            buildConfig "public final static int FOO = 42;"
        }

        release {
            buildConfig "public final static int FOO = 52;"
        }
    }
}
 

Vous pouvez y accéder avec BuildConfig.FOO

Générer des ressources Android (depuis le plugin 0.8.3)

 android {
    buildTypes {
        debug{
            resValue "string", "app_name", "My App Name Debug"
        }
        release {
            resValue "string", "app_name", "My App Name"
        }
    }
}
 

Vous pouvez y accéder de la manière habituelle avec @string/app_name ou R.string.app_name

32voto

michael_n Points 980

Exemple d'utilisation des propriétés du système, définie dans la construction.gradle, lire à partir d'une application Java (suite de la question dans les commentaires):

Fondamentalement, l'aide de l' test tâche en build.gradle, avec la tâche de test méthode systemProperty réglage d'un système de propriété qui est passé au moment de l'exécution:

apply plugin: 'java'
group = 'example'
version = '0.0.1-SNAPSHOT'

repositories {
    mavenCentral()
    // mavenLocal()
    // maven { url 'http://localhost/nexus/content/groups/public'; }
}

dependencies {
    testCompile 'junit:junit:4.8.2'
    compile 'ch.qos.logback:logback-classic:1.1.2'
}

test {
  logger.info '==test=='
  systemProperty 'MY-VAR1', 'VALUE-TEST'
}

Et voici le reste de l'exemple de code (que vous pourriez probablement déduire, mais est inclus ici de toute façon): il obtient un système de propriété MY-VAR1, prévu au moment de l'exécution pour être mis à l' VALUE-TEST:

package example;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HelloWorld {
  static final Logger log=LoggerFactory.getLogger(HelloWorld.class);
  public static void main(String args[]) {
    log.info("entering main...");
    final String val = System.getProperty("MY-VAR1", "UNSET (MAIN)");
    System.out.println("(main.out) hello, world: " + val);
    log.info("main.log) MY-VAR1=" + val);
  }
}

Cas de test: si MY-VAR n'est pas définie, le test échoue:

package example;
...
public class HelloWorldTest {
    static final Logger log=LoggerFactory.getLogger(HelloWorldTest.class);
    @Test public void testEnv() {
        HelloWorld.main(new String[]{});
        final String val = System.getProperty("MY-VAR1", "UNSET (TEST)");
        System.out.println("(test.out) var1=" + val);
        log.info("(test.log) MY-VAR1=" + val);
        assertEquals("env MY-VAR1 set.", "VALUE-TEST", val);
    }
}

Exécuter (remarque: test en passant):

$ gradle cleanTest test
:cleanTest
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:compileTestJava UP-TO-DATE
:processTestResources UP-TO-DATE
:testClasses UP-TO-DATE
:test

BUILD SUCCESSFUL

J'ai trouvé que la partie la plus délicate est réellement obtenir la sortie de gradle... Donc, l'enregistrement est configuré ici (slf4j+logback), et le fichier journal affiche les résultats (sinon, exécutez gradle --info cleanTest test; il y a également des propriétés qui obtiennent la sortie standard de la console, mais, vous le savez, pourquoi?):

$ cat app.log
INFO Test worker example.HelloWorld - entering main...
INFO Test worker example.HelloWorld - main.log) MY-VAR1=VALUE-TEST
INFO Test worker example.HelloWorldTest - (test.log) MY-VAR1=VALUE-TEST

Si vous commentez "systemProperty..." (qui, d'ailleurs, ne fonctionne que dans un test de la tâche), puis:

example.HelloWorldTest > testEnv FAILED
    org.junit.ComparisonFailure at HelloWorldTest.java:14

Pour être complet, voici la logback config (src/test/resources/logback-test.xml):

<configuration>
    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
        <file>app.log</file>
        <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>%d %p %t %c - %m%n</pattern>
        </layout>
 </appender>
 <root level="info">
     <appender-ref ref="FILE"/>
</root>
</configuration> 

Fichiers:

  • build.gradle
  • src/main/java/example/HelloWorld.java
  • src/test/java/example/HelloWorldTest.java
  • src/test/resources/logback-test.xml

1voto

Dev Points 5487

Vous pourriez écrire un fichier lors de la build et lire ce fichier lors de l’exécution et avoir le code de se comporter en conséquence.

Une autre possibilité est que vous pourriez générer la source pour une classe java à la compilation qui contient une constante qui est référencée par votre code.

La première façon est plus souple car elle permet de reconfigurer sans recompiler.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X