I believe you have used Gradle for your projects for a long time, but how do you use it? Most of my Gradle scripts have been in use since June last year or so. Some of them, such as the secure saving of signatures, have been done by myself recently and I think they are quite good.

Module type distinction

Java Library Module is a plugin for Android Library Module build.gradle.

Android application module:

apply plugin: 'com.android.application'
Copy the code

Android library module:

apply plugin: 'com.android.library'
Copy the code

Java library module:

apply plugin: 'java'Copy the code

Version Number Management

If only one Application Module is fine, what if we have multiple Modules? Is it tiring to change the version number every time?

The solution is to declare global variables in root. You can declare them in a separate gradle (e.g., create a dependency. Gradle) and apply from, or define them directly in root’s build.gradle.

Ext {applicationId = "com. XXX "buildToolsVersion = "23.0.2" compileSdkVersion = 23 minSdkVersion = 14 TargetSdkVersion = 23 versionCode = 1 versionName = "1.0.0" abortOnLintError = false checkLintRelease = false useJack = false abortOnLintError = false javaVersion = JavaVersion.VERSION_1_8 ... }Copy the code

Use rootproject.ext to reference a child module: rootproject.ext

android { compileSdkVersion rootProject.ext.compileSdkVersion buildToolsVersion rootProject.ext.buildToolsVersion defaultConfig { applicationId rootProject.ext.applicationId minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion  rootProject.ext.targetSdkVersion versionCode rootProject.ext.versionCode versionName rootProject.ext.versionName multiDexEnabled true } compileOptions { sourceCompatibility rootProject.ext.javaVersion sourceCompatibility rootProject.ext.javaVersion } packagingOptions { exclude 'LICENSE.txt' exclude 'META-INF/DEPENDENCIES' exclude 'META-INF/ASL2.0' exclude 'meta-INF /NOTICE' exclude' meta-INF /LICENSE'} lintOptions {abortOnError rootProject.ext.abortOnLintError checkReleaseBuilds rootProject.ext.checkLintRelease quiet true ignoreWarnings true // Some libraries have issues with this. disable 'InvalidPackage' // Lint gives this warning but SDK 20 would be Android L Beta. disable 'OldTargetApi' } ... }Copy the code

Dependency management

So many third-party library references, references in multiple modules, it is very hard to modify the version number, in case of a missed change (such as Gson) results in abnormal behavior, or even check the reason for a long time, the result is the keyboard dropped unexpectedly caused by the version number.

So, like the previous section, we need to define dependencies uniformly:

Def daggerVersion = "2.0.2" def retrofitVersion = "2.0.0-beta4" def supportVersion = "23.2.1" def rxBindingVersion = Def leakCanaryVersion = "1.3.1" def blockCanaryVersion = '1.1.4' project.ext {... libSupportAppcompat = "com.android.support:appcompat-v7:${supportVersion}" libSupportDesign = "com.android.support:design:${supportVersion}" libSupportRecyclerview = "com.android.support:recyclerview-v7:${supportVersion}" libSupportV4 = "Com. Android. Support: support - v4: ${supportVersion}" libRxAndroid = "IO. Reactivex: rxandroid: 1.1.0" libRxJava = "IO. Reactivex: rxjava: 1.1.1 libEventBus" = "org. Greenrobot: eventbus: 3.0.0" libJavaxAnnotation = "Javax.mail. Annotation: JSR - API: 1.0" libGson = "com. Google. Code. Gson: gson: 2.4" libRetrofit = "com.squareup.retrofit2:retrofit:${retrofitVersion}" libRetrofitConverterGson = "com.squareup.retrofit2:converter-gson:${retrofitVersion}" libRetrofitAdapterRxJava = "com.squareup.retrofit2:adapter-rxjava:${retrofitVersion}" libOkHttpLoggingInterceptor = "Com. Squareup. Okhttp3: logging - interceptor: 3.0.0 - RC1" libDagger = "com. Google. Dagger: a dagger: ${daggerVersion}" libDaggerCompiler = "com.google.dagger:dagger-compiler:${daggerVersion}" libGlide = "Com. Making. Bumptech. Glide: glide: 3.7.0" libRxBinding = "com. Jakewharton. Rxbinding: rxbinding: ${rxBindingVersion}" libRxBindingSupportV4 = "com.jakewharton.rxbinding:rxbinding-support-v4:${rxBindingVersion}" libRxBindingAppcompatV7 = "com.jakewharton.rxbinding:rxbinding-appcompat-v7:${rxBindingVersion}" libRxBindingDesign = "com.jakewharton.rxbinding:rxbinding-design:${rxBindingVersion}" libRxBindingRecyclerview = "Com. Jakewharton. Rxbinding: rxbinding recyclerview - v7: ${rxBindingVersion}" libRealm = "IO. Realm: realm - android: 0.87.5" debugDependencies = [ leakCanary: "com.squareup.leakcanary:leakcanary-android:${leakCanaryVersion}", blockcanary: "com.github.moduth:blockcanary-ui:${blockCanaryVersion}", ] releaseDependencies = [ leakCanary: "com.squareup.leakcanary:leakcanary-android-no-op:${leakCanaryVersion}", blockcanary: "com.github.moduth:blockcanary-no-op:${blockCanaryVersion}", ] }Copy the code

I can also remove all version numbers if I like, but my personal rule of practice is to keep them together unless I have more than one reference.

Module uses:

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    ...
    apt rootProject.ext.libDaggerCompiler
    compile rootProject.ext.libDagger
    compile rootProject.ext.libRxJava
    compile rootProject.ext.libRxAndroid
    compile rootProject.ext.libRxBinding
    compile rootProject.ext.libGlide
    provided rootProject.ext.libJavaxAnnotation
    compile rootProject.ext.libSupportAppcompat
    compile rootProject.ext.libSupportDesign
    compile rootProject.ext.libSupportRecyclerview
    compile rootProject.ext.libSupportV4
    debugCompile rootProject.ext.debugDependencies.leakCanary
    releaseCompile rootProject.ext.releaseDependencies.leakCanary
    debugCompile rootProject.ext.debugDependencies.blockCanary
    releaseCompile rootProject.ext.releaseDependencies.blockCanary
}Copy the code

Here I have also defined two maps specifically for some debug and release compile packages, see leakCanary and blockCanary references.

Signature management

Signature is a very sensitive thing, as long as you have the signature file and the corresponding password information, you can easily decomcompile and modify the source code and then sign for release, so how to save these sensitive information is very important.

In my personal practice, I have mainly done the following:

Local. properties Defines the keystore information file path:

keystore.props.file=.. /keystore.propertiesCopy the code

Keystore. Properties Saves keystore information:

store=.. /buildsystem/release.jks alias=xxx storePass=xxx pass=xxxCopy the code

Buildsystem saves:

$ ls
ci.gradle
debug.keystore
release.jksCopy the code

The application of the module signingConfigs:

signingConfigs { def Properties localProps = new Properties() localProps.load(new FileInputStream(file('.. /local.properties')) def properties keyProps = new properties () Debug keystore if (localProps[' keyProps. File ']) {keyProps. Load (new) FileInputStream(file(localProps['keystore.props.file']))) } else { keyProps["store"] = '.. /buildsystem/debug.keystore' keyProps["alias"] = 'android' keyProps["storePass"] = 'androiddebugkey' keyProps["pass"] = 'android' } debug { storeFile file(keyProps["store"]) keyAlias keyProps["alias"] storePassword keyProps["storePass"] KeyPassword keyProps["pass"]} release {// Use assert to ensure that the property is present. Avoid error packaging assert localProps['keystore.props. File ']; storeFile file(keyProps["store"]) keyAlias keyProps["alias"] storePassword keyProps["storePass"] keyPassword keyProps["pass"] } }Copy the code

Java8 support

The module of Android

apply plugin: 'me.tatarka.retrolambda'

android {
    compileOptions {
        sourceCompatibility rootProject.ext.javaVersion
        sourceCompatibility rootProject.ext.javaVersion
    }
}Copy the code

The module for Java:

SourceCompatibility = 1.8 targetCompatibility = 1.8Copy the code

Split APK

For details, please check our official Google documentation Apk Splits

My use:

splits {
    abi {
        enable true
        reset()
        include 'armeabi', 'x86' //, 'x86', 'armeabi-v7a', 'mips'
        universalApk false
    }
}Copy the code

Generally speaking, apK can be subcontracted to ABI and DENSITY according to the configuration of the script. There’s no need to keep an ARM-only JNI folder to reduce the size of the package. You may have to transfer an x86 package one day, and some emulators only support x86.

Of course, if the market can support these configurations, so much the better, users will download apK much less traffic.

The Module aar depend on

How can you use AAR dependencies to speed up compilation while still having the flexibility to modify the source code at any time?

The solution is the Module AAR dependency.

In your Library Module directory, open build/outputs/aar. Is there an AAR file? Place it under the Module directory and build. Gradle:

configurations.maybeCreate("default")
artifacts.add("default", file('lib_authorize-debug.aar'))
Copy the code

Annotate the original scripts, and you’re done. Isn’t that easy? If you want to use source dependencies again, uncomment them.

conclusion

This article will cover the various gradle practices during the development phase. I have no idea what the next one will be.