How to Declare a Variable in Gradle Usable in Java

Is it possible to declare a variable in Gradle usable in Java?

Here are two ways to pass value from Gradle to use in Java;

Generate Java Constants

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

You can access them with BuildConfig.FOO

Generate Android resources

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

You can access them in the usual way with @string/app_name or R.string.app_name

Using java variable in build.gradle

Using a Java source file to manage the version of your project is backwards. You should let your build system—in this case, Gradle—manage the version. When you update the version in Gradle you should have setup the build in such a way that the new version is propagated throughout the project.

Within the build script this is easily accomplished; you simply have to reference the version property everywhere you need it. The concept isn't any different than passing data around in your application. Remember that, in Gradle, the build script is written in Groovy or Kotlin and normal programming logic applies (the build script is essentially an object which implements both org.gradle.api.Project and org.gradle.api.Script).

The more difficult part is making sure your application can see the version without having to update the version in both the build script and the source code. There are, however, a number of ways to accomplish this, such as:

  1. Create a properties file as a resource and use the processResources Gradle task to inject the project's version into said properties file. Then read the resource at runtime to get the application version.
  2. Create a custom Gradle task which generates a properties file as a resource. Then read the resource at runtime to get the application version.
  3. Create a custom Gradle task which generates the Java source file (e.g. AppVersion.java) that represents your application's version.
  4. Use the jar Gradle task to set the Implementation-Version attribute of the manifest. Then read this attribute at runtime to get the application's version.
  5. If using Java 9+ and modules then you can have the compileJava Gradle task set the module version. Then you can read the module version at runtime.

You might also want to consider keeping the version in the gradle.properties file and reading it from there into your build script (Gradle provides an API for this). That way when you update the version the build script doesn't have to be recompiled (at least that's the case with the Kotlin DSL).

Is it possible to declare a variable in Gradle usable in C++ and Java in Android NDK?

I do not think you can access the declarations directly from c++. I can think of two other ways - either use a Java method to return the declarations you want (a method for each or an array, it is up to you), or pass the declarations to the compiler using LOCAL_CPPFLAGS with -D for each declaration, for example -Dapp_name="My App Name Debug" (you can set it directly to any variable that is available during the gradle build. You may have to change the way you build your JNI code for that.

How to declare / change Java variables via gradle script

Thanks to @PeterNiederwieser I solved my problem:

In my gradle.build I use:

task usernameMaxio(type: Copy) {
from 'src/main/resources/properties'
into 'build/resources/main/properties'
expand([
username: 'Maxio'
])
}

and I access it via:

Properties properties = new Properties();
ClassLoader loader = Thread.currentThread().getContextClassLoader();
InputStream stream = loader.getResourceAsStream("properties/app.properties");
try {
properties.load(stream);
} catch (IOException | NullPointerException e) {
WebOptionPane.showMessageDialog(null, "Couldn't read app.properties", "Fehler",
WebOptionPane.ERROR_MESSAGE);
e.printStackTrace();
return;
}
name = properties.getProperty("username");

And in my app.properties:

username=${username}

Is it possible to declare a variable in gradle productFlavors and use it in Java?

Yes, like this:

productFlavors {
f1 {
buildConfigField "boolean", "aBoolean", "true"
buildConfigField "String", "aString", "foo"
}
f2 {
buildConfigField "boolean", "aBoolean", "false"
buildConfigField "String", "aString", "bar"
}
}

then at runtime you can access them like:

if (BuildConfig.aBoolean) {
// do something
}

build gradle variables to be used in code depending on flavor AND build type

In build.gradle for your app, one way you could achieve this would be:

buildTypes {
debug {
productFlavors.flavor1.buildConfigField "String", "app_name", "\"App 1 Debug\""
productFlavors.flavor2.buildConfigField "String", "app_name", "\"App 2 Debug\""
}
release {
productFlavors.flavor1.buildConfigField "String", "app_name", "\"App 1\""
productFlavors.flavor2.buildConfigField "String", "app_name", "\"App 2\""
}
}

Note that you'll want to define your productFlavors{} block before your buildTypes.



Related Topics



Leave a reply



Submit