The last time we talk about the principle of gradle, mainly partial theoretical knowledge, train in this Android Gradle series - Principle chapter . This time we come to the real point, just to consolidate the knowledge points before the next.
android
Android has a closure at the gradle.build app module, the main configuration are provided here. Example, the default configuration items: defaultConfig; signature-related: signingConfig; construct variants: buildTypes; product style: productFlavors; Source set configuration: sourceSets like.
defaultConfig
For defaultConfig fact, it is also a productFlavor, but here is used to provide default settings, if after productFlavor no special configuration specified will use the default defaultConfig configuration.
public class DefaultConfig extends BaseFlavor {
@Inject
public DefaultConfig(
@NonNull String name,
@NonNull Project project,
@NonNull ObjectFactory objectFactory,
@NonNull DeprecationReporter deprecationReporter,
@NonNull Logger logger) {
super(name, project, objectFactory, deprecationReporter, logger);
}
}
public abstract class BaseFlavor extends DefaultProductFlavor implements CoreProductFlavor {
...
}
复制代码
We can see defaultConfig super parent is DefaultProductFlavor. And defines a number of configuration we often see in DefaultProductFlavor in: VersionCode, VersionName, minSdkVersion, targetSdkVersion and applicationId and so on.
With the above basis, then defaultConfig variables we want to configure obvious.
defaultConfig {
applicationId "com.idisfkj.androidapianalysis"
minSdkVersion 16
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
复制代码
signingConfigs
signingConfig is used to configure keyStore, we can configure different keyStore for different versions, for example,
signingConfigs {
config { //默认配置
storeFile file('key.store')
storePassword 'android123'
keyAlias 'android'
keyPassword 'android123'
}
dev { //dev测试版配置
storeFile file('xxxx')
storePassword 'xxx'
keyAlias 'xxx'
keyPassword 'xxx'
}
}
复制代码
Some might say it unsafe passwords are in clear text, are exposed to go. Yes, if this item posted to remote, these keys will leak out. So to be safe, we can feed them some special treatment.
- Get keys by environmental variables
storePassword System.getenv("KSTOREPWD")
keyPassword System.getenv("KEYPWD")
复制代码
- Obtain keys from the command line
storePassword System.console().readLine("\nKeystore password: ")
keyPassword System.console().readLine("\nKey password: ")
复制代码
The above two are Android Develop official website provides, but after testing will be reported null abnormalities, checked the information said gradle is not supported (if successful can tell me), so it is recommended that the following method
Created in the root directory of the project (settings.gradle same level) keystore.properties documents, we conducted a secret key stored in this file, it supports key-value model of key data
storePassword = android123
keyPassword = android123
复制代码
After the password is read therein, provided by reading afterEvaluate callback build.gradle
afterEvaluate {
def propsFile = rootProject.file('keystore.properties')
def configName = 'config'
if (propsFile.exists() && android.signingConfigs.hasProperty(configName)) {
def props = new Properties()
props.load(new FileInputStream(propsFile))
android.signingConfigs[configName].keyPassword = props['keyPassword']
android.signingConfigs[configName].storePassword = props['storePassword']
}
}
复制代码
We have read the password via dynamic, so before the signingConfigs in will not have to configure password
signingConfigs {
config {
storeFile file('key.store')
keyAlias 'android'
}
}
复制代码
The final step, in order to ensure the safety of the secret key, add ignore configuration keystore.properties in .gitignore protected from exposure to upload to the remote storage keys.
buildTypes
Construction of variant is mainly used to configure the shrinkResources: whether resources need to compress, zipAlignEnabled: compression are aligned, minifyEnabled: whether the code to be confused with signingConfig: Signature configuration and so on. When creating a new project, there is a release default configuration, but we may need more than the actual development of different configurations, such as debug mode, in order to debug method, generally do not need to be code obfuscation, compression processing. Or outer mode, the different needs of signatures configuration, the final configuration may be such that:
buildTypes {
debug {
minifyEnabled false
zipAlignEnabled false
shrinkResources false
signingConfig signingConfigs.config
}
outer {
minifyEnabled false
zipAlignEnabled false
shrinkResources false
signingConfig signingConfigs.outConfig
}
release {
minifyEnabled true
zipAlignEnabled true
shrinkResources true
signingConfig signingConfigs.config
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
复制代码
After the Sync Now, open Gradle Android Studio on the right to find app-> Tasks-> build, find and have added assembleDebug assembleOuter building task.
productFlavors
A project may have different versions of the environment, such as the official version of the development features in the development version, the project line. Data Developer Edition with the official version of api request may be different, in this case we can use to build different products productFlavor style, you can see the following dev and prod Configuration
flavorDimensions "mode"
productFlavors {
dev {
applicationIdSuffix ".dev"
dimension "mode"
manifestPlaceholders = [PROJECT_NAME: "@string/app_name_dev",
APP_ID : "21321843"]
buildConfigField 'String', 'API_URL', '"https://dev.idisfkj.android.com"'
buildConfigField 'String', 'APP_KEY', '"3824yk32"'
}
prod {
applicationIdSuffix ".prod"
dimension "mode"
manifestPlaceholders = [PROJECT_NAME: "@string/app_name",
APP_ID : "12932843"]
buildConfigField 'String', 'API_URL', '"https://prod.idisfkj.android.com"'
buildConfigField 'String', 'APP_KEY', '"32143dsk2"'
}
}
复制代码
For determining whether a same app, app applicationId phone system according to identify the default applicationId is packageName. To make the dev and prod the version can co-exist on a cell phone, you can add the suffix applicationId by applicationIdSuffix, change that uniquely identifies the installation package.
There may be configured by manifestPlaceholders AndroidManifest variables may be used, e.g. app show different names depending on the style of the product
Dev prod network using the different request api host, may be provided buildConfigField, so that we can obtain BuildConfig code
fun getApiUlr(): String {
return BuildConfig.API_URL
}
复制代码
BuildConfig herein will return your build style products according to different values, which is located build-> generated-> source-> buildConfig-> variant thereof, substantially as follows:
public final class BuildConfig {
public static final boolean DEBUG = Boolean.parseBoolean("true");
public static final String APPLICATION_ID = "com.idisfkj.androidapianalysis.dev";
public static final String BUILD_TYPE = "debug";
public static final String FLAVOR = "devMinApi21";
public static final int VERSION_CODE = 20001;
public static final String VERSION_NAME = "1.0-minApi21";
public static final String FLAVOR_mode = "dev";
public static final String FLAVOR_api = "minApi21";
// Fields from product flavor: dev
public static final String API_URL = "https://dev.idisfkj.android.com";
public static final String APP_KEY = "3824yk32";
}
复制代码
After the Sync Now, open Gradle Android Studio on the right to find app-> Tasks-> build, discover newly added assembleDev and assembleProd building task.
flavorDimensions is used to set the multi-dimensional, the example above shows only one dimension, the dimension of the form mode. We've added a dimension api, build different versions of minSkdVerison apk
flavorDimensions "mode", "api"
productFlavors {
dev {
applicationIdSuffix ".dev"
dimension "mode"
manifestPlaceholders = [PROJECT_NAME: "@string/app_name_dev",
APP_ID : "21321843"]
buildConfigField 'String', 'API_URL', '"https://dev.idisfkj.android.com"'
buildConfigField 'String', 'APP_KEY', '"3824yk32"'
}
prod {
applicationIdSuffix ".prod"
dimension "mode"
manifestPlaceholders = [PROJECT_NAME: "@string/app_name",
APP_ID : "12932843"]
buildConfigField 'String', 'API_URL', '"https://prod.idisfkj.android.com"'
buildConfigField 'String', 'APP_KEY', '"32143dsk2"'
}
minApi16 {
dimension "api"
minSdkVersion 16
versionCode 10000 + android.defaultConfig.versionCode
versionNameSuffix "-minApi16"
}
minApi21 {
dimension "api"
minSdkVersion 21
versionCode 20000 + android.defaultConfig.versionCode
versionNameSuffix "-minApi21"
}
}
复制代码
gradle created construct variants thereof equal number of each style of style number and dimension of the product of the number you build type configuration, the number of construct variants of the above example is 12. When naming each corresponding to construct a variant or in Gradle apk, belonging to a higher priority product style style dimensions displayed first, followed by lower priority dimension style product, then followed by the type of construct. The priority order determination flavorDimensions with the value as the basis to construct the above configuration example:
构建 变体: [dev, prod] [minApi16, minApi21] [debug, outer, release] 对应 apk: app- [dev, prod] - [minApi16, minApi21] - [debug, outer, release] .apk
Construct variants have so many, but sometimes we do not all need, for example, you do not need mode for the dev, api for the variant minApi16, then you can use the method to filter variantFilter
variantFilter { variant ->
def names = variant.flavors*.name
if (names.contains("minApi16") && names.contains("dev")) {
setIgnore(true)
}
}
复制代码
You go back to app-> Tasks view variant, you will find has devMinApi16 relevant variations filtered.
Not only can you filter construct variants can also change the default output apk name. For example, you want to change the name of apk buildType to release, then you can use android.applicationVariants.all
android.applicationVariants.all { variant ->
if (variant.buildType.name == buildTypes.release.name) {
variant.outputs.all {
outputFileName = "analysis-release-${defaultConfig.versionName}.apk"
}
}
}
复制代码
Such package name in release are based on analysis starts
sourceSets
Android Studio will help us create a default set the main source directory (located in app / src / main), used to store shared resources between all build variants. So you can change the default configuration by setting the main source collection. For example now you want to change the path res into src / custom / res
sourceSets {
main {
res.srcDirs = ['src/custom/res']
}
}
复制代码
Such targeting res resource path on the lower src / custom / res, of course, you can also modify other configurations, e.g. java, assets, jni like.
If you configure multiple paths, namely the path set:
sourceSets {
main {
res.srcDirs = ['src/custom/res', 'scr/main/res']
}
}
复制代码
Then you have to have the same name can not guarantee that each file. Only the presence of one of the directories.
You can also view the default configuration path so build variants: Click the right gradle-> app-> android-> sourceSets, you will see the following information
------------------------------------------------------------
Project :app
------------------------------------------------------------
androidTest
-----------
Compile configuration: androidTestCompile
build.gradle name: android.sourceSets.androidTest
Java sources: [app/src/androidTest/java]
Manifest file: app/src/androidTest/AndroidManifest.xml
Android resources: [app/src/androidTest/res]
Assets: [app/src/androidTest/assets]
AIDL sources: [app/src/androidTest/aidl]
RenderScript sources: [app/src/androidTest/rs]
JNI sources: [app/src/androidTest/jni]
JNI libraries: [app/src/androidTest/jniLibs]
Java-style resources: [app/src/androidTest/resources]
...
复制代码
The above is the default path androidTest variants thereof, it is first to find the corresponding construct variants default location, if not found, then the default configuration of the main current source. That is, the resources under the familiar app / src / main path.
Because it is constructed with variants to search, so it has a priority:
- src / modeApiDebug: Construction of variants
- src / debug: Construction type
- src / modeApi: product style
- src / main: the default main source
To create the source set, as shown in the app / src under the new Right, but it will help you to create java source files in the folder set, the other must create one by yourself
We set a custom debug source, so go after Target Source Set Select debug, and then click End finish. Then you will see the debug folder under the src
Now that you have set debug the source directory, assuming you make the app name in the Android debug now to show the essence of record debug (the default Android is the essence of record). Then you can right-debug new values
Strings.xml new directory in the values, then the configuration in which app_name
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Android精华录debug</string>
</resources>
复制代码
Finally, when you go to build debug related variants, the name of the app show you install Android will be the essence of record debug.
Therefore, by modifying the configuration mian source or other current source variations set, loading can be achieved according to different data sources variant. Such systematic configured to load the resource will be more convenient to configure and test the version of the project.
dependencies
for third party dependencies dependent configuration item and closing the package, if you have set variant of the above configuration, you will be able to rely on third-party libraries selectively According to a variant
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
//根据变体选择性依赖
outerImplementation '...'
prodMinApi21Implementation '...'
}
复制代码
About dependencies, this is just a simple configuration, and then I will be alone to write an article out of a systematic configuration dependencies, and interested can pay attention.
gradle related configuration, there are many, here is just tip of the iceberg, but my advice is to learn according to your actual needs and research, I believe you will have unexpected growth.
Finally, attach the source address: github.com/idisfkj/and...
Blog address: www.rousetime.com/
series
Reproduced in: https: //juejin.im/post/5cefccf0e51d4577790c1c2c