Shared dependency version
Some libraries are meant to be split into modules. Usually, if we use couple of them, we should use all the modules in the same version. An example of such approach could be Google Play Services, AppCompat and design libraries or Retrofit. You should ensure that you’re using the same version of those library modules, otherwise you’ll get in trouble. There is a trick that will help you maintain that.
In the project build.gradle define section like this:
ext { supportLibraryVersion = '23.1.1' playServicesVersion = '8.3.0' retrofitVersion = '2.0.0-beta4' }
“ext” is not an obligatory name. It’s just a name of the section I came up with. You could use any. Define this section in the root of project’s build. gradle.
Now in your app build. gradle you could add your dependencies like this:
compile "com.android.support:appcompat-v7:$rootProject.ext.supportLibraryVersion" compile "com.android.support:design:$rootProject.ext.supportLibraryVersion" compile "com.android.support:cardview-v7:$rootProject.ext.supportLibraryVersion" compile "com.android.support:recyclerview-v7:$rootProject.ext.supportLibraryVersion" compile "com.google.android.gms:play-services-plus:$rootProject.ext.playServicesVersion" compile "com.google.android.gms:play-services-location:$rootProject.ext.playServicesVersion" compile "com.google.android.gms:play-services-gcm:$rootProject.ext.playServicesVersion" compile "com.squareup.retrofit2:retrofit:$rootProject.ext.retrofitVersion" compile "com.squareup.retrofit2:adapter-rxjava:$rootProject.ext.retrofitVersion" compile "com.squareup.retrofit2:converter-gson:$rootProject.ext.retrofitVersion"
That’s it. Simple, right? Now you can easily change your library versions without missing any and getting yourself in troubles.
SDK and build tools
The same way we just defined shared library versions we could setup values like:
- compileSdkVersion
- buildToolsVersion
- minSdkVersion
- targetSdkVersion
Just add them to the ext section we defined earlier in the project’s build.gradle:
ext { compileSdkVersion = 23 buildToolsVersion = "23.0.1" minSdkVersion = 16 targetSdkVersion = 23 }
Then use it in your app’s build.gradle:
android { compileSdkVersion rootProject.ext.compileSdkVersion buildToolsVersion rootProject.ext.buildToolsVersion defaultConfig { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion versionCode getAutoVersionCode() versionName getAutoVersionName() } }
Flavors
Flavors are a useful way to differentiate built types. You could use separate flavor if there is production and stage (dev) backend available. Right now I’m gonna assume you already know what the flavors are and skip the basics. Let’s take the example with an URL to production and stage API. Instead doing some conditions in the code you setup buildConfig field in your app build.gradle. Let’s have a look at some example of flavors:
productFlavors { prod { applicationId = "com.jacek.myapp" buildConfigField "String", "API_URL", "\"http://myapp/api/\"" } stage { applicationId = "com.jacek.myapp.stage" buildConfigField "String", "API_URL", "\"http://stage.myapp/api/\"" } }
applicationId
You should specify that. This way your prod and stage app could exist on the device in parallel not overwriting themselves.
buildConfigField
It can be some simple constant that you want to access from java code like:
BuildConfig.SERVER_URL
It’s enclosed with escaped “, otherwise currently it might not be treated as a String later. You could make numeric fields without them though. You can now use this String field to send requests to the api.
Shared BuildConfig fields
If for some reason you want to have a buildConfig field that has the same value for every flavor, you don’t have to keep it in each of it. You could do it like this:
defaultConfig { minSdkVersion 15 targetSdkVersion 23 versionCode getAutoVersionCode() versionName getAutoVersionName() buildConfigField "boolean", "MONITOR_CRASHES", "true" buildConfigField "int", "DEFAULT_PAGE_SIZE", "10" buildConfigField "String", "SOME_SHARED_KEY", "\"sdfsdfjejj211e#!\"" }
Conclusion
With all the pros and cons of Gradle, I’d vote for it. Surely the cases presented here are not everything you could do to improve your work process.
You know some other cool use cases? Don’t hesitate to share it in the comments section. I’d love to see them all!