首页 文章

是否可以在Gradle中声明一个可用于Java的变量?

提问于
浏览
354

是否可以在Gradle中声明一个可用于Java的变量?基本上我想在build.gradle中声明一些变量,然后在构建时获取它(显然) . 就像C / C中的预处理器宏一样......

宣言的一个例子就是那样......:

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

有没有办法做那样的事情?

7 回答

  • 1

    rciovati的答案是完全正确的我只是想再添加一个小工具,你也可以在build.gradle的默认配置部分为每个构建类型创建变量 . 这看起来像这样:

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

    这将允许您访问通过

    BuildConfig.App_NAME
    

    如果你想要一个通用的配置,也只是想记下这个场景 .

  • 0

    使用系统属性的示例,在build.gradle中设置,从Java应用程序中读取(跟随注释中的问题):

    基本上,使用 build.gradle 中的 test 任务,使用测试任务方法 systemProperty 设置在运行时传递的系统属性:

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

    以下是示例代码的其余部分(您可以推断,但无论如何都包含在此处):它获取系统属性 MY-VAR1 ,在运行时期望设置为 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);
      }
    }
    

    测试用例:如果未设置 MY-VAR ,则测试应该失败:

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

    运行(注意:测试正在通过):

    $ 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
    

    我发现棘手的部分实际上是从gradle获取输出...所以,这里配置了日志记录(slf4j logback),日志文件显示结果(或者,运行 gradle --info cleanTest test ;还有一些属性可以获取stdout到控制台,但是,你知道,为什么):

    $ 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
    

    如果您注释掉“ systemProperty... ”(其中,顺便说一下,只能在 test 任务中使用),那么:

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

    为完整起见,这是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>
    

    文件:

    • build.gradle

    • src/main/java/example/HelloWorld.java

    • src/test/java/example/HelloWorldTest.java

    • src/test/resources/logback-test.xml

  • 28

    您可以在构建期间通过系统环境变量创建可覆盖的构建配置字段:

    在开发时使用Fallback,但是当您在Jenkins或其他工具上运行构建时,可以覆盖变量 .

    在你的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
            }
        }
    

    该变量将以 BuildConfig.SERVER_URL 的形式提供 .

  • 10

    生成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"
            }
        }
    }
    

    您可以使用 BuildConfig.FOO 访问它们

    生成Android资源

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

    您可以使用 @string/app_nameR.string.app_name 以常规方式访问它们

  • 78

    我正在使用

    buildTypes.each {
        it.buildConfigField 'String', 'GoogleMapsApiKey', "\"$System.env.GoogleMapsApiKey\""
    }
    

    它基于Dennis's answer但是从环境变量中获取它 .

  • 704

    我正在使用此代码并且工作得非常好 .

    def baseUrl = '\"http://patelwala.com/myapi/"'
    def googleServerKey = '\"87171841097-opu71rk2ps35ibv96ud57g3ktto6ioio.apps.googleusercontent.com"'
    android {
      buildTypes {
      release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            buildConfigField 'String', 'BASE_URL', baseUrl
            buildConfigField 'String', 'web_client_id', googleServerKey
        }
        releasedebug {
            initWith debug
            buildConfigField 'String', 'BASE_URL', baseUrl
            buildConfigField 'String', 'web_client_id' ,googleServerKey
        }
        debug {
    
            buildConfigField 'String', 'BASE_URL', baseUrl
            buildConfigField 'String', 'web_client_id', googleServerKey
        }
     }
    }
    

    }

  • 1

    在Android应用程序中使用Api App Key的示例(Java和XML)

    gradle.properties

    AppKey="XXXX-XXXX"
    

    的build.gradle

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

    在java代码中的用法

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

    在xml代码中的用法

    <data android:scheme="@string/APP_KEY_2" />
    

相关问题