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:
- 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. - Create a custom Gradle task which generates a properties file as a resource. Then read the resource at runtime to get the application version.
- Create a custom Gradle task which generates the Java source file (e.g.
AppVersion.java
) that represents your application's version. - Use the
jar
Gradle task to set theImplementation-Version
attribute of the manifest. Then read this attribute at runtime to get the application's version. - 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
The Asynctask API Is Deprecated in Android 11. What Are the Alternatives
Android/Java - Date Difference in Days
Do Line Endings Differ Between Windows and Linux
Calling Awt Frame Methods from Subclass
Get Generic Type of Class At Runtime
Change Private Static Final Field Using Java Reflection
Why Don't Java Generics Support Primitive Types
Floating Point Arithmetic Not Producing Exact Results
How to Read a Text File in Android
How to Count the Number of Documents Under a Collection in Firestore
Javafx on Linux Is Showing a "Graphics Device Initialization Failed For: Es2, Sw"
How to Create a File and Write to It
When Do You Use Java'S @Override Annotation and Why