Group no. : 172852230

Android Studio uses Gradle to build projects. Gradle is based on the Groovy language, so you can build normal Android projects without learning Groovy. When we create an Android project, we include two Android build.gradle configuration details, as shown below:

Build. Gradle file for Project:

The corresponding build.gradle code is as follows:

// Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript Google () {// From Android Studio3.0, Google () configuration is new, You can refer to jCenter (), an open source project on Google, which is a github code-managed repository that declares the jCenter () configuration, Can be easily quoted dependencies on open source projects jcenter} {the classpath 'com. Android. View the build: gradle: 3.0.0' / / / / this is a android plugin gradle, NOTE: Do not place your application dependencies here; They belong // in the individual module build.gradle files}} allprojects {// For example, the project's Maven repository {Google () jCenter ()}} // When running Gradle Clean, execute the task defined here. // This task inherits from Delete and deletes the build directory in the root directory. Delete. Delete (rootProject.builddir). // Gradle uses groovy to call method without adding (). task clean(type: Delete) { delete rootProject.buildDir }Copy the code
  • The buildScript {} closure contains the dependencies needed for gradle script execution, the corresponding Maven libraries and plugins, respectively.

  • Inside the AllProjects {} closure are dependencies that the project itself needs, such as maven libraries that the project needs.

  • Task Clean (type: Delete){} Is a task defined here when running Gradle Clean. This task inherits from Delete and deletes the build directory in the root directory. Buildscript contains the repositories closure and Dependencies closure.

Repositories {} closure: Configure the remote repository

This closure declares the configuration of JCenter () and Google (). Jcenter is a code managed repository that hosts many Android open source projects. After configuring JCenter, we can easily reference the open source projects on JCenter in our projects. Google () configuration has been added from Android Studio3.0 to reference open source projects on Google.

Dependencies {} closure: Configures the build tool

This closure declares a Gradle plug-in using classpath. Since Gradle is not just used to build Android projects, we introduce the plugin to build Android projects, where ‘3.0.0’ is the version number of the plug-in, which can be adjusted according to the latest version number.

Build. Gradle file for Module

As can be seen from the content of the file, it is mainly divided into three parts, as shown in the figure below:

1. Apply Plugin:

Declaration is Android / / / / com. Android. Application says this is an application module / / com. Android. The library identifier - this is a library module / / and the difference between: Apply plugin: 'com.android.application'Copy the code

The first line of the file uses the Apply Plugin to indicate that a plug-in has been applied, which typically has two values:

  • ‘com.android.application’, indicating that the module is an application module that can be run directly, packaged as an.apk file

  • ‘com.android.library’, which means that this module is a library module and can only be run as a code library attached to other application modules, packaged as an. Aar file

2. Android {} closures:

This closure is used to configure the various properties that the project builds:

SigningConfigs {}
SigningConfigs {keyAlias 'test' keyPassword '123456' storeFile file('test.keystore') StorePassword '123456'} debug {// Development environment keyAlias 'test' keyPassword '123456' storeFile file('test.keystore') storePassword '123456' } }Copy the code

You can add signature configuration manually, or you can select APP through Project Structure and click Singing to add, as shown in the following figure:

After the signature configuration is complete, it will be easy to package with the signature. There will be two types of Debug and Release in the Build Variants of the Module. You can choose either Type to package and they will use their own keys to package. Perform the Run app or Build – > Build apk will automatically in the module name/app/Build/outputs/apk path generated apk file. Another way to package is Build->Generate Signed APK by filling in the signature information to Generate an APK.

2.2 compileSdkVersion: Set the Android version to be used for compilation

BuildToolsVersion: ** Sets the build tool version to use at compile time. Android Studio3.0 removes this configuration

DefaultConfig {} :
CompileSdkVersion 27// Set Android version defaultConfig {applicationId "com.billy. Myapplication "// Project package name minSdkVersion 16 / / project minimum compatible versions targetSdkVersion 27 / / project target version versionCode 1 / / version number versionName testInstrumentationRunner version "1.0" / / name "Android. Support. The test. The runner. AndroidJUnitRunner" / / indicates that unit tests are conducted to use AndroidJUnitRunner}Copy the code
  • ApplicationId: Specifies the package name for the project.

  • MinSdkVersion: Specifies the lowest compatible version of the project. If the device is smaller than this version or larger than maxSdkVersion(usually not used), the application will not be installed. The value 16 indicates the lowest compatible version of Android 4.1.

  • TargetSdkVersion: Specify the target version of the project, indicating that sufficient testing has been done on the target version. The system will start some latest features for the target system for the application. The behavior change of the Android system platform will take effect only when the attribute value of targetSdkVersion is set to be greater than or equal to the API version of the system platform. For example, if you specify a targetSdkVersion value of 22, it indicates that the application has been fully tested on Android5.1 at most, and new features such as system runtime permissions on Android6.0 (corresponding to targetSdkVersion 23) will not be enabled.

  • VersionCode: indicates the version number. Generally, this value can only be increased each time the package goes online, but cannot be seen after the package.

  • VersionName: indicates the versionName, which is displayed in the application market.

  • TestInstrumentationRunner “android. Support. The test. The runner. AndroidJUnitRunner” suggests to use AndroidJUnitRunner unit test.

BuildTypes {} closure

This closure specifies the main configuration for generating the installation file. It usually contains two child closures. One is the DEBUG closure, which specifies the configuration for generating the beta installation file. The other is the Release closure, which specifies the configuration to generate the official installation file. The main difference is that the default attribute configuration is different. The following figure shows the attribute configuration supported by the two modes:

BuildTypes {// Production/test environment configuration release {// Production environment buildConfigField(" Boolean ", "LOG_DEBUG", BuildConfigField ("String", "URL_PERFIX", ""https://release.cn/"")// Set the URL prefix minifyEnabled false// Whether to obfuscate the code proguardFiles getDefaultProguardFile('proguard-android.txt'), PseudoLocalesEnabled False pseudoLocalesEnabled in APK ZipAlignEnabled true// Whether to perform ZIP alignment optimization on APK packages, reduce ZIP size, VersionNameSuffix 'test'// Add a suffix to applicationId, } debug {// Test environment buildConfigField(" Boolean ", "LOG_DEBUG", "true") "URL_PERFIX", ""https://test.com/"")// Set the URL prefix minifyEnabled false// Whether to obfuscate the code proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'// Specifies the confused rule file signingConfig SigningConfigs. debug// Sets the signature information debuggable false// Whether breakpoint debugging jniDebuggable is supported ZipAlignEnabled true// Enable ZIP alignment optimization for APK packages, reduce ZIP size, PseudoLocalesEnabled False pseudoLocalesEnabled false pseudoLocalesEnabled False pseudoLocalesEnabled False VersionNameSuffix 'test'// adds a suffix to applicationId, which is generally not used much}}Copy the code
Release {} closures and debug{} closures can be configured with the same parameters. The main difference is that the default properties are configured differently:
  • MinifyEnabled: indicates whether the code is confused. True indicates that the code is confused. False indicates that the code is not confused. The default value is false.

  • ProguardFiles: TXT file and proguard-rules.pro file. The proguard-Android. TXT file is the default obturation file, which defines some common obturation rules. The proGuard-rules.pro file is located at the root of the current project, where you can define some project-specific obfuscation rules.

  • BuildConfigField: Used to address differences between Beta and Release services or control Log printing requirements. For example: configure buildConfigField(” Boolean “, “LOG_DEBUG”, “true”), which accepts three non-empty arguments, the first to determine the type of the value, the second to specify the name of the key, and the third: Buildconfig.log_debug will be called at buildconfig.log_debug.

  • Debuggable: indicates whether breakpoint debugging is supported. Release is false by default and debug is true by default.

  • JniDebuggable: indicates whether NDK code can be debugged. LLDB is used for C and C ++ code debugging. Release is false by default

  • SigningConfig: Sets the signature information, using SigningConfigs. release or SigningConfigs. debug to configure the corresponding signature, but before adding this configuration, you must add the signingConfigs closure to add the corresponding signature information.

  • RenderscriptDebuggable: indicates whether rendering scripts are enabled for some C-written rendering methods. Default is false.

  • RenderscriptOptimLevel: indicates the rendering level. The default is 3.

  • PseudoLocalesEnabled: Whether to generate a pseudoLocalesEnabled in APK to help internationalization.

  • ApplicationIdSuffix: this suffix is the same as defaultConfig, which adds a suffix to applicationId.

  • VersionNameSuffix: adds the suffix of the version name. It is rarely used.

  • ZipAlignEnabled: indicates whether to perform ZIP alignment optimization on APK packages to reduce ZIP size and increase operating efficiency. Release and DEBUG are both true by default.

2.6 sourceSets{} closure: configure directory pointing
SrcDirs = ['libs']// Specify lib library directory}}Copy the code

JniLibs. SrcDirs = [‘libs’] to create the jniLibs folder in the Android view of Android Studio. JniLibs in Android view and LIbs in Project view point to the same folder (app→libs), as shown below:

2.7 packagingOptions{} closures: configuration related to packaging

As more and more third-party libraries are relied upon in a project, it is possible to have the same (name) file in two dependent libraries. If so, Gradle will give you an error (warning) when packing. To exclude duplicate files, use the following methods:

PackagingOptions {//pickFirsts is used for packing errors when there are duplicate files so that the configuration uses the first matching file to package into the APK // means that if there are duplicate meta-INF files in the APK, only the first one is used PickFirsts = [' meta-INF /LICENSE'] //merges why merge duplicate files when there are duplicate files and then package them into apK // This is a default value merges = [] this will remove the silent recognition value So we add merge 'meta-INF /LICENSE' after the default as follows. This is done with butterknife and Dagger2 at the same time. Gradle prompts you to do the same for similar problems. exclude 'META-INF/services/javax.annotation.processing.Processor' }Copy the code
ProductFlavors {} closure: Multiple options configuration

This configuration is often used. When adapting to multiple channels, you need to do some special processing for specific channels, such as setting different package names and application names. We can use productFlavors to create a package that contains information about the channel. For example:

Android {productFlavors {wandoujia {// Manifestplaceholder = [UMENG_CHANNEL_VALUE: "Wandoujia "] // The use of the manifestplaceholder is introduced in the subsequent section, AndroidManifest [UMENG_CHANNEL_VALUE: "Xiaomi "] applicationId "com.wiky.gradle. Xiaomi"} _360 {Manifestplaceholder = [UMENG_CHANNEL_VALUE: "_360"]} / /... }}Copy the code

Of course, there are more concise ways:

android { productFlavors { wandoujia {} xiaomi {} _360 {} //... } productFlavors. All {/ / bulk changes, similar to a sequential traversal flavor - > flavor. ManifestPlaceholders = [UMENG_CHANNEL_VALUE: name]}}Copy the code

Gradlew assembleRelease After configuration, enter gradlew assembleRelease in the Terminal command line window to start the package./ Gradlew assembleRelease is the corresponding command in Mac. Of course, if you want the Debug version of the package, change the assembleRelease directive to assembleDebug. The resulting package will still be in app/build/ Outputs /apk with the default naming format app-Wandoujia-release-unsigned. Apk, which you will find in the Build Variants of the Module. Android Studio3.0 requires defaultConfig {targetSdkVersion: *** minSdkVersion: *** versionCode: FlavorDimensions “versionCode”} flavorDimensions “versionCode”}

2.9 lintOptions{} closures: code scan analysis

Lint is a code scan analysis tool provided by Android Studio that can help us find structure/quality problems and provide solutions without requiring us to write test cases by hand.

Lint has a description and level for every problem found (much like testing found bugs), making it easy to locate the problem and resolve it in order of severity.

// The program will check lint at compile time and stop build if there are any errors, LintOptions {abortOnError false // checkReleaseBuilds will not be stopped if errors are reported. False // checkReleaseBuilds will be checked if releases are packed.Copy the code

< span style = “box-sizing: border-box! Important;

This closure defines the dependencies of a project, which typically have three types of dependencies: local, library, and remote. Local dependencies can add dependencies to local JAR packages or directories, library dependencies can add dependencies to library modules in a project, and remote dependencies can add dependencies to open source projects on jcener libraries. From Android Studio3.0, compile into the library is no longer used, but through API and implementation, API is exactly the same as the previous compile, library introduced with API can be used throughout the project, The library introduced by implementation can only be used by the corresponding Module, but not by other modules. Since compile dependency was used in the previous project, the situation is that Module coupling is too high, which is not conducive to project disassembly. After the use of implementation, although it is complicated to use, it can reduce the coincidence and improve security.

Implementation fileTree(include: ['*.jar'], implementation fileTree: 'libs') / / local jar package depends on implementation' com. Android. Support: appcompat - v7:27.1.1 '/ / remote depend on implementation 'com. Android. Support. The constraint, the constraint - layout: 1.1.2' testImplementation junit: junit: '4.12' test cases library / / statement AndroidTestImplementation 'com. Android. Support. Test: runner: 1.0.2' androidTestImplementation 'com. Android. Support. Test. Espresso: espresso - core: 3.0.2'}Copy the code
  • implementation fileTree(include: [‘*.jar’], dir: ‘libs’) : implementation fileTree is a local dependency declaration that adds all.jar files from the libs directory to the project build path.

  • Implementation ‘com. Android. Support: appcompat – v7:27.1.1’ : Implementation statement for remote rely on the statement, ‘com. Android. Support: appcompat – v7:27.1.1’ in distance dependent libraries, a standard format, which com. Android. Some support for the domain name, used to distinguish between different company’s library; Appcompat-v7 is the component name that distinguishes different libraries within the same company. 27.1.1 is the version number used to distinguish different versions of the same library. With this statement, Gradle checks to see if the library has been cached before building a project. If not, the library is automatically downloaded online and added to the project’s build path.

  • TestImplementation and androidTestImplementation: test case library said statement.

The complete build.gradle configuration is as follows:

Declaration is Android / / / / com. Android. Application says this is an application module / / com. Android. The library identifier - this is a library module / / and the difference between: The first can run directly, and the second can run the Apply plugin attached to another application: 'com.android.application' android {signingConfigs {release {// online environment keyAlias 'test' keyPassword '123456' StoreFile file('test.jks') storePassword '123456'} debug {// Development environment keyAlias 'test' keyPassword '123456' storeFile File ('test.jks') storePassword '123456'}} compileSdkVersion 27// Set Android version defaultConfig {applicationId "Com.billy. Myapplication "// Project package name minSdkVersion 16// The least compatible version targetSdkVersion 27// Project target version versionCode 1// Version number versionName "1.0"/name/version flavorDimensions testInstrumentationRunner "versionCode" "Android. Support. The test. The runner. AndroidJUnitRunner" / / indicates that unit tests are conducted to use AndroidJUnitRunner} buildTypes release {{/ / production/test environment configuration / / Production environment buildConfigField(" Boolean ", "LOG_DEBUG", "false")// Configure Log logs buildConfigField("String", "URL_PERFIX", ""https://release.cn/"")// Set the URL prefix minifyEnabled false// Whether to obfuscate the code proguardFiles getDefaultProguardFile('proguard-android.txt'), PseudoLocalesEnabled False pseudoLocalesEnabled in APK ZipAlignEnabled true// Whether to perform ZIP alignment optimization on APK packages, reduce ZIP size, ApplicationIdSuffix 'test'// Adds a suffix to applicationId, which is not commonly used versionNameSuffix 'test'// adds a suffix to versionName, } debug {// Test environment buildConfigField(" Boolean ", "LOG_DEBUG", "true") "URL_PERFIX", ""https://test.com/"")// Set the URL prefix minifyEnabled false// Whether to obfuscate the code proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'// Specifies the confused rule file signingConfig SigningConfigs. debug// Sets the signature information debuggable false// Whether breakpoint debugging jniDebuggable is supported ZipAlignEnabled true// Enable ZIP alignment optimization for APK packages, reduce ZIP size, PseudoLocalesEnabled False pseudoLocalesEnabled false pseudoLocalesEnabled False pseudoLocalesEnabled False VersionNameSuffix 'test'// adds a suffix to versionName, SrcDirs = ['libs']// Specify lib library directory}} packagingOptions{// Package configuration PickFirsts is used when there are duplicate files in the apK. The configuration will use the first matching file to package into the APK = [' meta-inf/LICENSE '] / / merges why when duplicate files Combine the duplicate files Then packaged into apk / / this is the default worth merges = [] this will remove the silent recognition value So we use this way below Add the merge after the default value 'meta-INF /LICENSE' // This is done with butterknife and Dagger2 at the same time. Gradle prompts you to do the same for similar problems. exclude 'META-INF/services/javax.annotation.processing.Processor' } productFlavors { wandoujia {} xiaomi {} _360 {} } ProductFlavors. All {/ / bulk changes, similar to a sequential traversal flavor - > flavor. ManifestPlaceholders = [IFLYTEK_CHANNEL: Name]} // The program will check lint at compile time and stop build if there are any errors, LintOptions {abortOnError false}} lintOptions {abortOnError false} lintOptions {abortOnError false Implementation fileTree(include: ['*.jar'], dir: implementation fileTree(include: ['*.jar']) 'libs') / / local jar package depends on implementation' com. Android. Support: appcompat - v7:27.1.1 '/ / remote depend on implementation 'com. Android. Support. The constraint, the constraint - layout: 1.1.2' testImplementation junit: junit: '4.12' test cases library / / statement AndroidTestImplementation 'com. Android. Support. Test: runner: 1.0.2' androidTestImplementation 'com. Android. Support. Test. Espresso: espresso - core: 3.0.2'}Copy the code

A scan of attention is the biggest support

** Pay attention to the public number [blog special good], focus on independent developers, focus on danniu experience sharing **

* * * *