Android Gradle from understanding to practice

Android Gradle from understanding to practice

Preface

The previous article gave an overview of Gradle and a brief introduction to the Groovy language. With the previous foundation, we can now learn more in detail how to configure our Build files in AndroidStudio to complete some specific functions and perform custom builds. This article will start with each gradle file, analyze what configurations we can make in each file, what role these configurations can play, and how to use gradle to meet custom build requirements.

Gradle file in Android Studio

When we create a new Android project, AndroidStudio will generate the following files for us by default, including Project build files, Module build files, Project configuration files, obfuscation rule files, etc. So what functions do these files have and what configurations can we make?

  • settings.gradle

include ':app'

By default, a newly created project only has the above statement, which is used to instruct Gradle which modules should be included when building the application. For most projects, this file may only have the above statement, but when we introduce other functional modules or business logic modules into our project, we need to add the corresponding modules in the include statement.

  • build.gradle

There are two build files, one for our Module and one for the Project.

In the Project, the following configuration is generated by default

  1. // Top - level build file where you can add configuration options common to   all sub-projects/modules.
  2.  
  3. buildscript {
  4. repositories {
  5. jcenter()
  6. }
  7. dependencies {
  8. classpath 'com.android.tools.build:gradle:2.2.3'  
  9.  
  10. // NOTE: Do not place your application dependencies here; they belong in the individual module build.gradle files
  11. }
  12. }

In the build file of the Project, we can add some configurations that are common to all sub-modules, without having to configure them in each sub-module separately. You can set the dependency repository to be jcenter or other dependency repositories. The default configuration options generated in the module are for the module itself when it is built.

  • gradle.properties

It is a configuration file for gradle, which can define some constants for build.gradle to use, such as version number. As our business grows, the build file will become larger and less maintainable. When we want to modify some content, we need to find them one by one. However, when we put some of the configuration constants in a separate file, the maintainability is improved compared with before. We can add some information such as the build SDK version to this file.

  1. COMPILE_SDK_VERSION = 23BUILD_TOOLS_VERSION = 23.0.1VERSION_CODE = 1

Then, we can reference it in the build file by directly using the variable name.

Configure the build

  • Build Type

Build types define certain properties that Gradle uses when building and packaging your app, and are typically configured for different stages of the development lifecycle. For example, a debug build type supports debugging options and signs your APK with a debug key, while a release build type compresses and obfuscates your APK and signs it with a release key for distribution. You must define at least one build type to build your app—Android Studio creates both debug and release build types by default. To get started customizing packaging settings for your app, learn how to configure build types.

Default build mode

  1. defaultConfig { applicationId "com.chenjensen.gradlelearn"  
  2. minSdkVersion 14
  3. targetSdkVersion 24
  4. versionCode 1
  5. versionName "1.0"  
  6. testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" }

We can configure it in buildType according to our own needs, such as only performing obfuscation operations on the released version and not on the debug version.

  1. buildTypes { release { minifyEnabled false  
  2. proguardFiles getDefaultProguardFile( 'proguard-android.txt' ), 'proguard-rules.pro'  
  3. } debug {
  4.             
  5. }
  6. }
  • Product flavor

Product flavors represent different versions of your app that you can release to your users, such as free and paid versions of your app. You can customize product flavors to use different code and resources while sharing and reusing parts that are common to all versions of your app. Product flavors are optional and you must create them manually. We can configure the settings we need in the productFlavors {} code block. Product flavors support the same properties as defaultConfig because defaultConfig actually belongs to the ProductFlavor class. This means that you can provide base configuration for all flavors in the defaultConfig {} code block, and each flavor can override any default values, such as applicationId.

ApplicationId is used as the package name of our APK to distinguish different packages. The package field in the manifest is used to name the package name of the resource class. The R class file generated by *** is located under this package. If the code in other packages needs to reference resources, it can be called through this path.

For example

  1. productFlavors { demo { applicationId "com.example.myapp.demo"  
  2. versionName "1.0-demo"  
  3. }
  4. full { applicationId "com.example.myapp.full"  
  5. versionName "1.0-full"  
  6. }
  7. }

By configuring the product flavor, we can release different application packages for different application markets. For different application packages, we can configure them in detail, such as specific SDK versions. The different application market distribution allows us to collect download rates for different application markets.

  • Dependencies

The build system manages project dependencies from your local file system and from remote repositories. This saves you from having to manually search, download, and copy binary packages of dependencies into your project directory.

There are three ways to add dependencies in Android

  1. //Depends on our local module
  2. compile project( ":mylibrary" ) //remote binary dependencies
  3. compile 'com.android.support:appcompat-v7:25.1.0'  
  4. //Local binary dependency mode will detect the jar files in our local libs
  5. compile fileTree(dir: 'libs' , include: [ '*.jar' ]) //javaTest dependencies
  6. testCompile 'junit:junit:4.12' //AndroidTest dependency
  7. androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2'  

When we add a dependency that depends on other dependencies, and we want to remove one of them, the compile method can accept a closure parameter, and we can use this closure to remove some of the dependencies.

  1. androidTestCompile( 'com.android.support.test.espresso:espresso-core:2.2.2' , {
  2. exclude group : 'com.android.support' , module: 'support-annotations'  
  3. })

Through the compile configuration, Gradle adds the dependencies of this configuration to the classpath and the APK of the application. In addition to the compile configuration, there is also apk, provided.

  • apk

Specifies runtime-only dependencies that Gradle needs to package with your app's APK. You can use this configuration with JAR binary dependencies, but not with other library module dependencies or AAR binary dependencies.

  • provided

Specifies compile-time dependencies that Gradle does not package with your app's APK. This helps reduce the size of your APK if the dependency is not required at runtime. You can use this configuration with JAR binary dependencies, not with other library module dependencies or AAR binary dependencies.

  • sign

The build system can specify signing settings in a build configuration and can automatically sign your APK during the build process. The build system signs debug builds by using a default key and certificate with known credentials to avoid password prompts at build time. The build system does not sign release builds unless a signing configuration is explicitly defined for this build. If you don't have a release key, you can generate one as described in Signing Your App. Because debug certificates are created by the build tools and are insecure by design, most app stores, including the Google Play Store, do not accept APKs signed with debug certificates for release.

Signed Application

App upgrades: When the system installs an update to an app, it compares the certificates in the new version and the existing version. If the certificates match, the system allows the update. If the new version is signed with a different certificate, the app must be assigned a different package name - in this case, the user installs the new version as a brand new app.

App modularity: Android allows multiple APKs signed with the same certificate to run in the same process (if the app requests this) so that the system treats them as a single app. In this way, your app can be deployed in modules and users can update each module independently.

When you create a signing configuration, Android Studio adds your signing information to the module's build.gradle file in plain text. If you are working with a team or open sourcing your code, you should move this sensitive information out of the build file to prevent it from being easily accessed by others. To do this, create a separate properties file to store security information. Then get the configuration of the external file locally, and then keep our key configuration file when publishing the code.

  • Create a file named keystore.properties in the root directory of the project.
  1. storePassword=myStorePasswordkeyPassword=mykeyPasswordkeyAlias=myKeyAliasstoreFile=myStoreFileLocation
  • In the module's build.gradle file, add the code to load the keystore.properties file before the android {} block.
  1. def keystorePropertiesFile = rootProject.file( "keystore.properties" )// Initialize a new Properties() object called keystoreProperties.def keystoreProperties = new Properties()// Load your keystore.properties file into the keystoreProperties object.keystoreProperties. load (new FileInputStream(keystorePropertiesFile))
  • Use the syntax keystoreProperties['property name'] to reference properties stored in keystoreProperties. Modify the signingConfigs block of your module's build.gradle file to use this syntax to reference the signing information stored in keystoreProperties.
  1. android { signingConfigs { config { keyAlias ​​keystoreProperties[ 'keyAlias' ]
  2. keyPassword keystoreProperties[ 'keyPassword' ]
  3. storeFile file(keystoreProperties[ 'storeFile' ])
  4. storePassword keystoreProperties[ 'storePassword' ]
  5. }
  6. }
  7. ...
  8. }
  • ProGuard

The build system allows you to specify a different ProGuard rules file for each build variant. The build system can run ProGuard during the build process to compress and obfuscate classes. Code compression is provided by ProGuard, which detects and removes unused classes, fields, methods, and properties in the packaged application, including unused items in the built-in code base (this makes it a useful tool for working around the 64k reference limit as a workaround). ProGuard can also optimize bytecode, remove unused code instructions, and obfuscate remaining classes, fields, and methods with short names. Obfuscated code can make your APK difficult to reverse engineer. For a more detailed introduction to ProGuard, please refer to the previous article on project building.

Enable code compression

minifyEnabled true

Enable ProGuard rules

proguardFiles getDefaultProguardFile('proguard-android.txt'),

'proguard-rules.pro'

  1. The getDefaultProguardFile('proguard-android.txt') method gets the default ProGuard settings from the Android SDK tools/proguard/ folder.
  2. The proguard-rules.pro file is used to add custom ProGuard rules. By default, this file is located in the module root directory

After each execution of ProGuard, the following files will be generated

  • dump.txt Internal structure of all class files in APK.
  • mapping.txt provides translation between original and obfuscated class, method, and field names.

seeds.txt

Lists the classes and members that are not obfuscated.

usage.txt

Lists the code that was removed from the APK.

These files are stored in <module-name>/build/outputs/mapping/release/.

For some classes, we don't want to confuse them, so we need to add a line of -keep code in the ProGuard configuration file. For example:

  1. -keep public class MyClass

<<:  [Valuable Experience] Android Performance Optimization: Memory Optimization Practice

>>:  The third session of the Aiti Tribe Technical Clinic

Recommend

How important is marketing in international trade?

Due to the basic attributes of OEM, there is litt...

Momo Live Personal Anchor Membership Operation Guide

Personal anchor membership operation guide Indivi...

Snapchat porn leak source found

An anonymous developer of a third-party Snapchat ...

Douyin store operation: Don’t cross these red line rules!

With the advent of the 5G era, ByteDance's qu...

A "magic box" that turns kitchen waste into treasure

During the epidemic, batches of catering chefs an...

The hard-working red blood cells are just like you who work hard...

When it comes to red blood cells, readers will de...

Why do the holidays go by so fast?

Author: The Nutcracker Studio Many people have th...