Unified management of dependent versions

1.1 Create a file in the root directoryconfig.gradlefile

ext {

    android = [
            compileSdkVersion: 23,
            buildToolsVersion: "23.0.3",
            applicationId: "com.example.lizejun.repogradle",
            minSdkVersion: 14,
            targetSdkVersion: 23,
            versionCode: 1,
            versionName: "1.0".testInstrumentationRunner: "android.support.test.runner.AndroidJUnitRunner"
    ]

    dependencies = [
            "support-v4"  : 'com. Android. Support: support - v4:23.2.0'."support-v7"  : 'com. Android. Support: appcompat - v7:23.2.0']}Copy the code

Store dependencies for android. Store dependencies for android. Store dependencies for Android.

1.2 In the root directorybuild.gradleNew:

apply from: "config.gradle"
Copy the code

1.3 Each in the root directoryModuleorLibraryIn thebuild.gradleFile, reference the correspondingkey:

android {
    compileSdkVersion rootProject.ext.android.compileSdkVersion
    buildToolsVersion rootProject.ext.android.buildToolsVersion
    defaultConfig {
        applicationId rootProject.ext.android.applicationId
        minSdkVersion rootProject.ext.android.minSdkVersion
        targetSdkVersion rootProject.ext.android.targetSdkVersion
        versionCode rootProject.ext.android.versionCode
        versionName rootProject.ext.android.versionName
        testInstrumentationRunner rootProject.ext.android.testInstrumentationRunner
    }
}

dependencies {
    compile rootProject.ext.dependencies["support-v7"]}Copy the code

2. Check dependencies

2.1 Viewing Tools

The dependency tree can be viewed using Android Studio’s Gradle View plugin:

View -> Tool Windows -> Gradle View

2.2 Viewing Commands

Alternatively, we can use the following command:

./gradlew -q app:dependencies
Copy the code

Similar results can be obtained:

(*)
Gradle

Identifiers

Because multiple top-level dependencies may contain the same child dependencies at different versions, you need to use the necessary operators to manage the child dependencies in order to select the appropriate version.

3.1 Transitive

Default is true, which means gradle automatically adds child dependencies to form a multi-layer tree. Set to false, you need to manually add each dependency.

3.1.1 Unified designationTransitive

configurations.all {
    transitive = false
}

dependencies {
    compile rootProject.ext.dependencies["support-v7"]}Copy the code

As a result, you can see that the previous child dependencies are gone:

3.1.2 Specify separatelyTransitive

dependencies {
    compile ('com. Android. Support: appcompat - v7:23.2.0') {
        transitive = false}}Copy the code

3.2 Force

Used to force a version of a module:

configurations.all {
    resolutionStrategy {
        force 'com. Android. Support: support - v4:23.1.0'}}Copy the code

Print it later and find that the package version it depends on has changed to 23.1.0:

3.3 exclude

This identifier is used to set the specified module not to compile

3.3.1 Configuring a Module globally

configurations {
    all *.exclude group : 'com.android.support', module: 'support-v4'
}
Copy the code

At this point, the dependency is:

exclude
group
module

3.3.2 Separate to a moduleexclude

    compile ('com. Android. Support: appcompat - v7:23.2.0') {
        exclude group : 'com.android.support', module: 'support-v4'
    }
Copy the code

I’m going to get the same result as above

4. Version conflict

4.1 Version Conflict in the Same Configuration

If different versions of a module are dependent on the same configuration, the latest version is used by default. Gradle does not report errors during synchronization.

Five,GradleBreak down

Basic configuration: Android projects in AS usually have at least two build.gradle modules, one for Project and one for Module. Since a Project can have multiple modules, there is a build.gradle for each Module.

5.1 ProjectUnder thebuild.gradle

// Top-level build file where you can add configuration options common to all sub-projects/modules.
apply from: "config.gradle"

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com. Android. Tools. Build: gradle: 1.3.1'
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}
Copy the code
  • buildscriptUnder therepositoriesisgradleResources required by the script itself,
  • allprojectsUnder therepositoriesResources required by all modules of the project.

5.2 the modulebuild.gradle

// Declare the plugin to indicate that this is an Android application; Library apply plugin com.android. Library apply plugin'com.android.application'/ / need to configure the Android build process parameters Android {/ / compile version compileSdkVersion pileSdkVersion / / buildTool version at rootProject.ext.android.com BuildToolsVersion rootProject. Ext. Android. BuildToolsVersion / / the default configuration, at the same time to debug and release versions defaultConfig {applicationId rootProject.ext.android.applicationId minSdkVersion rootProject.ext.android.minSdkVersion targetSdkVersion rootProject.ext.android.targetSdkVersion versionCode rootProject.ext.android.versionCode versionName rootProject.ext.android.versionNametestInstrumentationRunner rootProject. Ext. Android. TestInstrumentationRunner} / / configure the debug and release versions of some parameters, such as confusion, signature buildTypes configuration, etc Release Version Release {minifyEnabledfalseProguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'}} dependencies {compile fileTree(dir)'libs', include: ['*.jar'])
    compile rootProject.ext.dependencies["support-v7"]
    androidTestCompile('com. Android. Support. Test. Espresso: espresso - core: 2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    testCompile 'junit: junit: 4.12'
}
Copy the code

The following explains the parameters that need to be configured during the Android build process:

  • compileSdkVersion: tellgradleUse thatAndroid SDKCompiling your application and modifying it will not change the runtime behavior because it will not be included in the final versionAPK; Therefore, the latest is recommendedSDKCompile; If you are usingSuppport Library, thencompileSdkVersionIt must be greater than or equal to its large version number.
  • minSdkVersion: Minimum runnable requirements of the application; It must be greater than or equal to the value of the library you depend onminSdkVersion;
  • targetSdkVersion:AndroidProvides an important basis for forward compatibility. (targetSdkVersion is the main way Android provides forward compatibility) Because withAndroidA system upgrade, someapiOr the behavior of the module may change, but to ensure that the oldAPKThe behavior is compatible with the previous, as long asAPKthetargetSdkVersionConstant. So even though thisAPKInstall in newAndroidSystemically, then the behavior is the same as the old system behavior. The system is calling somethingapiOr module, will check the call firstAPKthetargetSdkVersionTo determine what behavior to perform.

MinSdkVersion and targetSdkVersion will eventually be included in the final APK file. If you look at the generated AndroidManifest.xml, you will see:

<uses-sdk android:targetSdkVersion="23" android:minSdkVersion="Seven" />
Copy the code

So, the general rule we follow is:

minSdkVersion (lowest possible) <= targetSdkVersion == compileSdkVersion (latest SDK)
Copy the code

5.3 gradleThe relevant documents

  • gradle.propertiesConfiguration file, can define some constants forbuild.gradleFor example, you can configure signature informationkeystoreLocation, password,keyaliasAnd so on.
  • settings.gradleUsed to configure multiple modules if your project has twoBrowserandScannerSDK, then it is necessary to:
include ':Browser'
include ':ScannerSDK'
project(':ScannerSDK').projectDir = new File(settingsDir, './ScannerSDK/')
Copy the code
  • gradleThere are two files in the folder,gradle-wrapper.jarandgradle-wrapper.properties, specified in the lattergradleVersion.
distributionUrl=https\://services.gradle.org/distributions/gradle-2.8-all.zip
Copy the code
  • gradlewandgradlew.bat, respectively,LinuxandwindowsUnder batch files, their role is based ongradle-wrapper.propertiesIn the filedistributionUrlDownload the correspondinggradleVersion so even if the environment is not installedgradleYou can also compile.

5.4 gradlewarehouse

Gradle has three types of repositories: Maven/Ivy/Local flat.

maven{
    url  "..."
}
ivy{
    url  "..."
}
flatDir{
    dirs 'xxx'
}
Copy the code

Some warehouses have nicknames:

repositories{
    mavenCentral()
    jcenter()
    mavenLocal()
}
Copy the code

5.5 gradletask

With the following instructions, you can see the supported tasks:

./gradlew tasks
Copy the code

6. Frequently asked Questions

6.1 Importing a Local FileJarpackage

Import a single JAR file:

compile files('libs/xxx.jar')
Copy the code

Import multiple JAR files for libs:

compile fileTree(dir: 'libs', include: ['*.jar'])
Copy the code

6.2 the importmavenlibrary

compile 'groupId:artifactId:version'
Copy the code

6.3 the importProject

Before importing, you need to include modules such as the ScannerSDK module from settings.gradle:

compile project(':ScannerSDK')
Copy the code

6.4 Declaration of A Third Partymavenlibrary

If some library files are not in the central repository, but in a specific location, they need to be added to the allProjects node of the build.gradle Project or directly to a module:

allprojects {
    repositories {
        maven {
            url 'address'}}}Copy the code

6.5 Relying on Third Partiesaar

compile 'com. Aaa. XXX: core: @ 1.0.1 aar'
Copy the code

6.6 Exporting libraries asaar

First, your project must be a library project, and then configure it in build.gradle:

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

After that, enter the project and run gradle:

./gradlew assembleRelease
Copy the code

The aar generated is placed in the /build/output/ AAR file

6.7 Referencing the Localaar

First, copy the AAR file to the appropriate directory, and then declare the Flat repository in the build.gradle module:

repositories{
   flatDir{
      dirs 'Relative path to build. Gradle as root'}}Copy the code

We then rely on the AAR module under dependencies:

dependencies{
    compile (name:'xxx',ext:'aar')}Copy the code

Seven, multi-version packaging

Before we get there, let’s take a look at some basic concepts:

  • buildTypes:Building type.Android StudiotheGradleComponents are provided by defaultdebugandreleaseTwo default configurations, mainly used for whether to obfuscate and whether to debug.
  • productFlavors:Product channelsIn a real release, depending on the channel, you might need to use different package names, or even different code.
  • buildVaiants: eachbuildTypesandproductFlavorsTo form abuildvariant.

BuildTypes and productFlavors discussed above can be configured using the Build. gradle Android tag in each Module.

Let’s look at productFlavors, which can be used to read different files and replace different strings.

7.1 Reference different code

We will create two new directories in the app/ SRC directory, one for each Flavor, and create a file with the same name, constant. Java, and assign different values to one of the constants in the file.

  • constantFlavor1:
package com.example.lizejun.repogradle;

public class Constant {
    public static final String NAME = "flavor1";
}
Copy the code
  • constantFlavor2:
package com.example.lizejun.repogradle;

public class Constant {
    public static final String NAME = "flavor2";
}
Copy the code

Add the following lines to the Android TAB of our build.gradle app to make each Flavor reference to a different Constant file:

    sourceSets {
        constantFlavor1 {
            java.srcDirs =  ['src/constantFlavor1'.'src/constantFlavor1/java'.'src/constantFlavor1/java/']
        }
        constantFlavor2 {
            java.srcDirs =  ['src/constantFlavor2'.'src/constantFlavor2/java'.'src/constantFlavor2/java/']
        }
    }

    productFlavors {
        constantFlavor1 {}
        constantFlavor2 {}
    }
Copy the code

After that, we can get the following different installation packages. The two APKs will get different values if they reference NAME:

7.2 the custombuildConfigclass

If we just need to define some simple values, we can use the buildConfig class:

    productFlavors {
        constantFlavor1 {
            buildConfigField "boolean"."BOOLEAN_VALUE"."true"
        }
        constantFlavor2 {
            buildConfigField "boolean"."BOOLEAN_VALUE"."false"}}Copy the code

7.3 a placeholder

    productFlavors {
        constantFlavor1 {
            buildConfigField "boolean"."BOOLEAN_VALUE"."true"
            manifestPlaceholders = [label:"constantFlavor1"]
        }
        constantFlavor2 {
            buildConfigField "boolean"."BOOLEAN_VALUE"."false"
            manifestPlaceholders = [label:"constantFlavor2"]}}Copy the code

After that, we reference it in androidmanifest.xml:

android:label="${label}"
Copy the code

7.4 Signature Configuration

First, under the Android tag, we use signingConfigs to configure the different signature types

    signingConfigs {
        eng {
            keyAlias 'androiddebugkey'
            keyPassword 'android'
            storeFile file('debug.keystore')
            storePassword 'android'
        }
        prd {
            keyAlias 'androiddebugkey'
            keyPassword 'android'
            storeFile file('debug.keystore')
            storePassword 'android'}}Copy the code

We then reference the corresponding signature configuration in each branch of buildTypes:

    buildTypes {
        debug {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.eng
        }
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.prd
        }
    }
Copy the code

7.5 depend on

Sometimes we need to reference different dependencies under different buildTypes, such as the memory leak detection tool. We want to check for memory leaks at debug and generate ICONS on the desktop when they happen, but we don’t want to do that at release, so we can write:

debugCompile 'com. Squareup. Leakcanary: leakcanary - android: 1.5'
releaseCompile 'com. Squareup. Leakcanary: leakcanary - android - no - op: 1.5'
Copy the code

This way, the Release version will not generate memory leak ICONS on the desktop.


For more articles, please visit mineAndroidKnowledge combing series:

  • Android knowledge comb directory: www.jianshu.com/p/fd82d1899…
  • Personal homepage: lizejun.cn
  • Personal knowledge summary directory: lizejun.cn/categories/