Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Gradle, is it possible to create a boolean build config field based on other build config field?

In Gradle, how to create a boolean build config field based on other build config field?

For example:

buildConfigField BOOLEAN, TEST_A, "false"
buildConfigField BOOLEAN, TEST_B, "false"
buildConfigField BOOLEAN, TEST_C, TEST_A && TEST_B
like image 889
Boon Avatar asked May 24 '17 14:05

Boon


People also ask

What is build Config field?

BuildConfigField. Gradle allows buildConfigField lines to define constants. These constants will be accessible at runtime as static fields of the BuildConfig class. This can be used to create flavors by defining all fields within the defaultConfig block, then overriding them for individual build flavors as needed.

How is BuildConfig generated?

There's a class called BuildConfig. java which is automatically generated by the build system. This class is updated automatically by Android's build system (like the R class). It already contains a static final boolean called DEBUG, which is normally set to true.

What is BuildConfig android?

BuildConfig is a class containing static constants that is included in every Android application. BuildConfig includes some default fields such as DEBUG and FLAVOR but you can also add custom values via build. gradle .

What is BuildConfig flavor?

BuildConfig.FLAVOR gives you combined product flavor. So if you have only one flavor dimension: productFlavors { normal { } admin { } } Then you can just check it: if (BuildConfig. FLAVOR.


2 Answers

This code, written inside your android.defaultConfig block, does exactly that:

  buildConfigField("boolean", "TEST_A", "false");
  buildConfigField("boolean", "TEST_B", "false");
  buildConfigField("boolean", "TEST_C", "TEST_A && TEST_B");

This results in the following lines in your BuildConfig.java:

  public static final boolean TEST_A = false;
  public static final boolean TEST_B = false;
  public static final boolean TEST_C = TEST_A && TEST_B;

One interesting thing to note when declaring build config values in this way, if you look at how BuildConfig.java is structured, you can see that the fields declared in a specific build type (e.g. android.buildTypes.debug) appear before the fields declared in the default config.

So in the example provided, if you want TEST_C to be dependent on the actual build type, you need to declare TEST_A and TEST_B at the build type level, not at the default level.

like image 143
Richard Le Mesurier Avatar answered Sep 25 '22 16:09

Richard Le Mesurier


It's not pretty, but this sort of thing worked for me:

android { 

    ...

    defaultConfig { 

        ...

        buildConfigField "boolean", "A", "false"
        buildConfigField "boolean", "B", "false"
        println "value of A:" + buildConfigFields.get("A").value
        println "value of B:" + buildConfigFields.get("B").value

        boolean AandB = Boolean.valueOf(buildConfigFields.get("A").value) && Boolean.valueOf(buildConfigFields.get("B").value)
        println "value of AandB:" + AandB

        buildConfigField "boolean", "C", String.valueOf(AandB);
        println "value of C:" + buildConfigFields.get("C").value
    }
}

When you build the project you should see this in Android Studio's gradle console:

value of A:false
value of B:false
value of AandB:false
value of C:false

I believe the reason this works at all is because the stuff inside the defaultConfig configuration closure here gets delegated to an instance of ProductFlavor which extends DefaultProductFlavor which extends BaseConfigImpl which contains the public method "getBuildConfigFields".

However, I don't see "getBuildConfigFields" officially documented as a method on ProductFlavor, and I worry that it might not always be available for our use.

Also notice that buildConfigFields.get() give you an instance of ClassField:

public interface ClassField {
    @NonNull
    String getType();

    @NonNull
    String getName();

    @NonNull
    String getValue();

    @NonNull
    String getDocumentation();

    @NonNull
    Set<String> getAnnotations();
}

hence the need to get its value and convert from String to Boolean by calling Boolean.valueOf().

like image 21
albert c braun Avatar answered Sep 23 '22 16:09

albert c braun