Es posible declarar una variable en Gradle utilizable en Java?


¿Es posible declarar una variable en Gradle utilizable en Java ? Básicamente me gustaría declarar algunos vars en la construcción.gradle y luego obtenerlo (obviamente) en el tiempo de compilación. Al igual que un pre-procesador macros en C/C++...

Un ejemplo de declaración sería algo así ... :

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

¿Hay alguna manera de hacer algo así ?

Author: rciovati, 2013-06-19

5 answers

Generar constantes Java

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

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

Puedes acceder a ellos con BuildConfig.FOO

Generar recursos de Android

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

Puede acceder a ellos de la manera habitual con @string/app_name o R.string.app_name

 681
Author: rciovati,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-07 12:47:31

Un ejemplo de uso de una clave de aplicación Api en una aplicación Android (Java y XML)

gradle.propiedades

AppKey="XXXX-XXXX"

construir.gradle

buildTypes {
//...
    buildTypes.each {
        it.buildConfigField 'String', 'APP_KEY_1', AppKey
        it.resValue 'string', 'APP_KEY_2', AppKey
    }
}

Uso en código java

Log.d("UserActivity", "onCreate, APP_KEY: " + getString(R.string.APP_KEY_2));

BuildConfig.APP_KEY_1

Uso en código xml

<data android:scheme="@string/APP_KEY_2" />
 76
Author: Denis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-26 15:58:42

Ejemplo usando propiedades del sistema, establecido en build.gradle, leído desde la aplicación Java (siguiendo la pregunta en los comentarios):

Básicamente, usando la tarea test en build.gradle, con el método de tarea de prueba systemProperty estableciendo una propiedad del sistema que se pasa en tiempo de ejecución:

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

Y aquí está el resto del código de ejemplo( que probablemente podría inferir, pero se incluye aquí de todos modos): obtiene una propiedad del sistema MY-VAR1, que se espera que en tiempo de ejecución se establezca en 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);
  }
}

Caso de prueba: si MY-VAR no está configurado, la prueba debe fallar:

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

Ejecutar (nota: la prueba está pasando):

$ 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

He encontrado que la parte difícil es en realidad obtener la salida de gradle... Por lo tanto, el registro se configura aquí (slf4j + logback), y el archivo de registro muestra los resultados (alternativamente, run gradle --info cleanTest test; también hay propiedades que obtienen stdout a la consola, pero, ya sabes, por qué):

$ 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 comentas "systemProperty... " (que, por cierto, solo funciona en una tarea test), entonces:

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

Para completitud, aquí está la configuración de logback (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> 

Archivos:

  • build.gradle
  • src/main/java/example/HelloWorld.java
  • src/test/java/example/HelloWorldTest.java
  • src/test/resources/logback-test.xml
 28
Author: michael,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-07 21:09:15

Puede crear un campo de configuración de compilación que se puede anular mediante variables de entorno del sistema durante la compilación:

Fallback se usa durante el desarrollo, pero puede anular la variable cuando ejecuta la compilación en Jenkins u otra herramienta.

En tu app build.gradle :

buildTypes {
        def serverUrl =  '\"' + (System.getenv("SERVER_URL")?: "http://default.fallback.url.com")+'\"'
        debug{
            buildConfigField "String", "SERVER_URL", serverUrl
        }
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            buildConfigField "String", "SERVER_URL", serverUrl
        }
    } 

La variable estará disponible como BuildConfig.SERVER_URL.

 9
Author: Boris Treukhov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-28 18:16:29

La respuesta de Rciovati es completamente correcta Solo quería agregar un dato más que también puede crear variables para cada tipo de compilación dentro de la porción de configuración predeterminada de su compilación.gradle. Esto se vería así:

android {
    defaultConfig {
        buildConfigField "String", "APP_NAME", "\"APP_NAME\""
    }
}

Esto le permitirá tener acceso a través de

BuildConfig.App_NAME

Solo quería tomar nota de este escenario también si desea una configuración común.

 0
Author: s.pike,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-25 14:14:31