Is it possible to use some external reference or variable in build.gradle files?
I have several build.gradle files in my app source files, including the one for module app, module base, module player, etc. (it depends on the structure of your code and the names of your packages).
Inside of each of these files is the following or similar structure:
defaultConfig {
minSdkVersion 23
targetSdkVersion 28
versionCode 1
versionName "1.0.001"
}
Is there any way I can code this the way that I don't have to change these values in every file? Is it possible to use some external reference or variable and that way I can edit my versionCode, versionName, etc. just on one place?
In your Project gradle
ext {
minSdkVersion = 14
targetSdkVersion = 26
compileSdkVersion = 26
buildToolsVersion = '26.0.2'
// App dependencies
supportLibraryVersion = '26.1.0'
mockitoVersion = '1.10.19'
roomVersion = "1.0.0"
}
In your App gradle
android {
compileSdkVersion rootProject.ext.compileSdkVersion
buildToolsVersion rootProject.ext.buildToolsVersion
defaultConfig {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
.
.
}
}
dependencies {
// App's dependencies, including test
compile "com.android.support:appcompat-v7:$rootProject.supportLibraryVersion"
}
Go to File/Project structure/app/flavors then you can get versionCode, versionName, etc then change them what you want and it effects all of your Files.
Check this Image
Yes it is.
In your project-level Gradle config (the one in the root of your project, outside any module folders), you can define variables under the buildscript block:
ext.thisVersionCode = 1
ext.thisVersionName = "1.0.001"
Then you should be able to reference them from your module-level configs:
defaultConfig {
versionCode = rootProject.ext.thisVersionCode
versionName = rootProject.ext.thisVersionName
}
You can define variables in top level build.gradle file and then reference these variables in each module's build.gradle - that way youll be changing them only once in one file.
to give you an example,this is top level file https://github.com/Ejstn/android-starter/blob/master/build.gradle
and this one is module level file: https://github.com/Ejstn/android-starter/blob/master/app/build.gradle
You can also declare whole dependency as variable like in this google's app: https://github.com/google/santa-tracker-android/blob/master/build.gradle
Related
Based on this answer, I realized that we can use Gradle variables (I'm not familiar with Gradle of course, so excuse my terminology) to make some consistencies across many Android projects.
For example, I want to change the android closure configuration from this:
android {
compileSdkVersion 27
buildToolsVersion '27.0.3'
defaultConfig {
minSdkVersion 16
targetSdkVersion 27
versionCode 1
versionName "1.0"
}
}
To this:
android {
compileSdkVersion configurationVariables.sdk
buildToolsVersion configurationVariables.buildToolsVersion
defaultConfig {
minSdkVersion configurationVariables.minSdk
targetSdkVersion configurationVariables.targetSdk
versionCode 1
versionName "1.0"
}
}
However, I get this error:
Error:(5, 0) startup failed: build file
'path_to_android\build.gradle': 5: Statement labels may not be used in
build scripts. In case you tried to configure a property named
'buildToolsVersion', replace ':' with '=' or ' ', otherwise it will
not have the desired effect. # line 5, column 24.
buildToolsVersion: configurationVariables.buildToolsVersion
How can I use variables to centralize my build configuration across projects and modules?
Update: I'm defining my configurationVariables as follow:
ext {
configurationVariables = [
sdk = 27,
buildToolsVersion = "27.0.3",
minSdk = 16,
targetSdk = 27
]
}
I write this in a config.gradle file and use apply from to import it in the build.gradle of the root project to apply it on all subprojects.
your config file structure store value as a varible. Generally this structure is use to store variable.Your config file should be like this
ext {
sdk = 27
buildToolsVersion = "27.0.3"
minSdk = 16
targetSdk = 27
}
and you use this variable as
compileSdkVersion sdk
buildToolsVersion buildToolsVersion
I haven't use array for storing this variable but as you given in another answer link they store array variable with colon(:) and you are directly storing values. I am not sure but try to use colon like this if you want to use an array :
ext {
configurationVariables = [
sdk : 27,
buildToolsVersion : "27.0.0",
minSdk : 16,
targetSdk : 27
]
}
My build.gradle file contains this line:
targetSdkVersion 26
I would prefer it to be like this:
targetSdkVersion Build.VERSION_CODES.o
Is that possible? It would seem much cleaner/safer, but this syntax doesn't work.
The target SDK version appears in multiple projects [...] It would be nice to define this in one place for all usage instances
So we're talking about defining project-wide accessible build time values.
Put this in your root project build.gradle:
ext {
compileSdkVersion = 26
buildToolsVersion = "26.0.0"
minSdkVersion = 17
targetSdkVersion = 26
supportLibVersion = "26.0.0"
playServicesVersion = "10.2.6"
}
And now you can reference these values in your module build.gradle like so:
android {
compileSdkVersion rootProject.ext.compileSdkVersion
buildToolsVersion rootProject.ext.buildToolsVersion
defaultConfig {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
// ...
}
// ...
}
dependencies {
compile "com.android.support:design:$supportLibVersion"
compile "com.google.firebase:firebase-messaging:$playServicesVersion"
// ...
}
// ...
I think you can even omit the rootProject.ext. prefix as long the result name does not conflict with a DSL member name.
In Groovy you can use variables in strings as long as you use double quotes.
Is that possible?
No, sorry. Build is a Java class that exists in the Android framework. It is not available to Gradle.
I'd like to change the path for where my assets live. This is because these assets will change often and are shared with other apps (i.e. iOS app) in another build folder. How can I do this?
To change the asset path you can tell your project to point to a different directory using the sourceSets command in your apps build.gradle file.
Here's how the build.gradle file looks like:
android {
compileSdkVersion 23
buildToolsVersion "23.0.1"
defaultConfig {
minSdkVersion 19
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
sourceSets {
main {
assets.srcDirs = ['../../../build/android-assets']
}
}
...
After updating Android Studio to 1.0, I see this error:
Error: Library projects cannot set applicationId. applicationId is set
to 'com.super.app' in default config.
I updated the Gradle plugin as suggested but I did not understand how to fix this.
Based on this info:
ApplicationId in Library Projects
You cannot use applicationId to customize the package of a library project. The package name has to be fixed in library projects (and specified as packageName in the manifest). The Gradle plugin did not enforce this restriction earlier.
Removing applicationId variable from the library's build.gradle file should resolve the issue.
Thanks to Joel for his correct answer: I need to remove only 1 line from te .gradle file:
defaultConfig {
applicationId "com.super.app" <---- remove this line
minSdkVersion 15
targetSdkVersion 19
versionCode 1
versionName "1.0"
}
becomes
defaultConfig {
minSdkVersion 15
targetSdkVersion 19
versionCode 1
versionName "1.0"
}
and my AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.super.app">
...
This is the right solution if you don't need to rename the package name of your app. To rename it you need to use "flavours":
android {
...
productFlavors {
flavor1 {
applicationId 'com.super.superapp'
}
}
Libraries can't set applicationId and if you are working in a multi-module project and picking up flavors from a separate file , none of the above answers will work. For a modularized app, you need the following steps -
Create a flavors.gradle file in project root directory
ext.flavorConfig = { // 1
flavorDimensions "pricing"
productFlavors {
free {
dimension "pricing"
ext.myApplicationIdSuffix = '.free' // 2
}
paid {
dimension "pricing"
ext.myApplicationIdSuffix = '.paid'
}
}
productFlavors.all { flavor -> // 3
if (flavor.hasProperty('myApplicationIdSuffix') && isApplicationProject()) {
flavor.applicationIdSuffix = flavor.myApplicationIdSuffix
}
}
}
def isApplicationProject() { // 4
return project.android.class.simpleName.startsWith('BaseAppModuleExtension')
}
In 1 we export a closure so that we can use it in our modules’ build.gradle files.
In 2 we define a custom myApplicationIdSuffix property. We cannot simply have applicationIdSuffix as it is not possible to use it in library modules (build would fail if you did).
In 3 we iterate over created flavors and set applicationIdSuffix if we detect that it’s an application module only.
4 is a way to check where this closure is being used.
All that’s left is to use this closure in our modules’ build.gradle files. E.g. in application module this would look like this:
apply plugin: 'com.android.application'
apply from: "${rootProject.projectDir}/flavors.gradle"
android {
// other config...
with flavorConfig
}
If this isn't clear, you can check out this article for better understanding.
Just incase it helps some one :
When i imported an eclipse project into android studio,i got an error ::
"Error:Application and test application id cannot be the same"
Strange though,but i looked into the build.gradle and found the two placeholders,one for the application and other for testapplication.
I removed the testApplicationId from that as is suggested in this post and this helped me resolve the issue.
Note: This explaination is not related to the errors posted in this question,but might help someone who is getting a similar error.
You cannot define applicationId for your lib.
But incase you want to use an identifier in your build file, which will give you, your library package name, you can define a variable for the module and then use the value as required.
eg : Library's build.gradle
apply plugin: 'com.android.library'
def libraryGroupId = 'com.google.example'
def libraryArtifactId = project.getName()
def libraryVersion = '1.1'
Also, you can use the value below as needed in your build file itself in lib.
android {
compileSdkVersion 28
defaultConfig {
minSdkVersion 21
targetSdkVersion 28
versionCode 1
versionName "$libraryVersion"
resValue "string", "Library", libraryGroupId"
}
}
I recently switched from Eclipse to Android Studio (for test purposes) with an production project and it feel really great. I like the gradle way very much.
In Android Studio the project structure looks (simplified) something like this
+RandomProject
|-+Random
| |- build.gradle (lets call it build2)
| |- [...]
|- build.gradle (lets call it build1)
|- [..]
The build1 file has the following content by default:
// Top-level build file where you can add configuration options common to all sub-projects/modules.
I wonder if its possible/a good practice to specify the versionName and versionCode in that (build1) file, so that it is going to be "inherited" to the build2 file. (and if so, how?)
Thanks for the input.
You can do it with ExtraPropertiesExtension.
RandomProject\build.gradle
// Top-level build file where you can add configuration options common to all sub-projects/modules.
ext.compileSdkVersion=19
ext.buildToolsVersion="19"
ext.versionName="1.0.7"
ext.versionCode=7
RandomProject\Random\build.gradle
android {
compileSdkVersion rootProject.compileSdkVersion
buildToolsVersion rootProject.buildToolsVersion
defaultConfig {
versionName rootProject.versionName
versionCode rootProject.versionCode
}
}
The New Build System site now has a tip about this. It's similar to Sergii's answer, but subtly different:
In the root project's build.gradle:
ext {
compileSdkVersion = 19
buildToolsVersion = "19.0.1"
}
in all the android modules:
android {
compileSdkVersion rootProject.ext.compileSdkVersion
buildToolsVersion rootProject.ext.buildToolsVersion
}