Android项目框架思考--配置文件
很早就想写一些相关的技术文档,一来锻炼自己的书写能力,二来也能记录自己的成长痕迹。每过一段时间写一篇技术文章,希望自己能够一直坚持下去。
一个合适的框架能够让项目开发顺畅,代码条理清晰、功能实现效率提升,以及运行时减少很多人为水平原因的错误。
为了能够让项目多人并行快速高质量开发,在开发前期我们可以做很多事情来较少后期重复的工作量,本次梳理一下一个项目的配置信息如何统一管理。一个项目中包含application以及其他作为lib库的module,他们的build.gradle都有一些配置信息,将配置信息统一化,一方面便于后期快速更改项目的编译环境,另一方方面也能快速的使他人接入开发,不会因为电脑环境变量的改变而花费很多时间来回修改mudle的配置参数。
我们通过AndroidStudio创建一个默认的项目时,其配置文件大题如下:
application中的build.gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 26
defaultConfig {
applicationId "com.kotlin.anonyper.testapplication"
minSdkVersion 15
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
compileOptions {
targetCompatibility 1.8
sourceCompatibility 1.8
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
}
module中的build.gradle
apply plugin: 'com.android.library'
android {
compileSdkVersion 26
defaultConfig {
minSdkVersion 15
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:26.1.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
可以看到上面,每一个build.gradle中都有compileSdkVersion、defaultConfig等信息(在module中有一些参数是非必要),加上我们直接从网络上下载的第三方module他们的配置参数很大可能和上面的不一样,这样就导致同一个项目在不同的电脑上都需要一个一个的module去调整配置信息,而这个过程对于新手来说稍不留神就是非常痛苦的。所以我们可以将这些共同的参数提取出来,写到同一个地方。
项目的根目录下有一个叫做gradle.properties的文件,我们可以在这里写一些项目所需要的公共参数,以便于不同的module来使用:
gradle.properties样例
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx10248m -XX:MaxPermSize=256m
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
###################################################
############# gradle 优化(确实快了不少) #############
###################################################
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Settings specified in this file will override any Gradle settings
# configured through the IDE.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# The Gradle daemon aims to improve the startup and execution time of Gdradle.
# When set to true the Gradle daemon is to run the build.
# TODO: disable daemon on CI, since builds should be clean and reliable on servers
org.gradle.daemon=true
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx10248m -XX:MaxPermSize=256m
org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
org.gradle.parallel=true
# Enables new incubating mode that makes Gradle selective when configuring projects.
# Only relevant projects are configured which results in faster builds for large multi-projects.
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:configuration_on_demand
org.gradle.configureondemand=true
# 版本编译配置
ANDROID_BUILD_MIN_SDK_VERSION=15
ANDROID_BUILD_TARGET_SDK_VERSION=26
ANDROID_BUILD_SDK_VERSION=26
ANDROID_BUILD_TOOLS_VERSION=26.0.0
# 版本号、包名等配置
APPLICATION_ID=com.kotlin.anonyper.testapplication
ANDROID_BUILD_VER_CODE=1
ANDROID_BUILD_VER_NAME=1.0
# 签名证书配置
STORE_FILE=/Users/Documents/tianqismart/xxx.jks
STORE_PASSWORD=xxx1234
KEY_ALIAS=xxxx
KEY_PASSWORD=xxx1234
#平台参数配置
GAODE_APPKEY=b5743c922cb683eff0d090272b4aa571
JPUSH_APPKEY=1d732d903966481323ca4c7f
# 解决RN64位兼容
android.useDeprecatedNdk=true
#java版本
JAVA_VERSION=1.8
#gradle版本
GRADLE_VERSION=3.0.1
在appliciton的build.gradle中使用
apply plugin: 'com.android.application'
//key为 gradle.properties里定义的变量
//编译的sdk版本
def ANDROID_BUILD_SDK_VERSION = project.getProperties().get("ANDROID_BUILD_SDK_VERSION")
if (ANDROID_BUILD_SDK_VERSION == null) {
ANDROID_BUILD_SDK_VERSION = "26" //给出默认值
}
//app min sdk version
def ANDROID_BUILD_MIN_SDK_VERSION = project.getProperties().get("ANDROID_BUILD_MIN_SDK_VERSION")
if (ANDROID_BUILD_MIN_SDK_VERSION == null) {
ANDROID_BUILD_MIN_SDK_VERSION = "15" //给出默认值
}
//app target sdk version
def ANDROID_BUILD_TARGET_SDK_VERSION = project.getProperties().get("ANDROID_BUILD_TARGET_SDK_VERSION")
if (ANDROID_BUILD_TARGET_SDK_VERSION == null) {
ANDROID_BUILD_TARGET_SDK_VERSION = "1" //给出默认值
}
//app version code
def ANDROID_BUILD_VER_CODE = project.getProperties().get("ANDROID_BUILD_VER_CODE")
if (ANDROID_BUILD_VER_CODE == null) {
ANDROID_BUILD_VER_CODE = "1" //给出默认值
}
//app version name
def ANDROID_BUILD_VER_NAME = project.getProperties().get("ANDROID_BUILD_VER_NAME")
if (ANDROID_BUILD_VER_NAME == null) {
ANDROID_BUILD_VER_NAME = "1.0" //给出默认值
}
//编译的tools版本
def ANDROID_BUILD_TOOLS_VERSION = project.getProperties().get("ANDROID_BUILD_TOOLS_VERSION")
if (ANDROID_BUILD_TOOLS_VERSION == null) {
ANDROID_BUILD_TOOLS_VERSION = "26.0.0" //给出默认值
}
//app的包名
def ANDROID_APPLICATION_ID = project.getProperties().get("APPLICATION_ID")
if (ANDROID_APPLICATION_ID == null) {
ANDROID_APPLICATION_ID = "com.kotlin.anonyper.testapplication" //给出默认值
}
//高德key
def GAODE_APPKEY = project.getProperties().get("GAODE_APPKEY")
//极光key
def JPUSH_APPKEY = project.getProperties().get("JPUSH_APPKEY")
//签名文件地址
def STORE_FILE = project.getProperties().get("STORE_FILE")
if (STORE_FILE == null) {
STORE_FILE = "/Users/Documents/tianqismart/xxx.jks" //给出默认值
}
//签名文件的密码
def STORE_PASSWORD = project.getProperties().get("STORE_PASSWORD")
if (STORE_PASSWORD == null) {
STORE_PASSWORD = "xxxx1234" //给出默认值
}
//签名文件别名
def KEY_ALIAS = project.getProperties().get("KEY_ALIAS")
if (KEY_ALIAS == null) {
STORE_PASSWORD = "xxxx" //给出默认值
}
//编译文件别名对应的密码
def KEY_PASSWORD = project.getProperties().get("KEY_PASSWORD")
if (KEY_PASSWORD == null) {
KEY_PASSWORD = "xxxx1234" //给出默认值
}
android {
compileSdkVersion Integer.parseInt(ANDROID_BUILD_SDK_VERSION as String)
defaultConfig {
applicationId ANDROID_APPLICATION_ID
minSdkVersion Integer.parseInt(ANDROID_BUILD_MIN_SDK_VERSION as String)
targetSdkVersion Integer.parseInt(ANDROID_BUILD_TARGET_SDK_VERSION as String)
versionCode Integer.parseInt(ANDROID_BUILD_VER_CODE as String)
versionName ANDROID_BUILD_VER_NAME
manifestPlaceholders = [
GAODE_APPKEY : GAODE_APPKEY,
JPUSH_PKGNAME: ANDROID_APPLICATION_ID,
JPUSH_APPKEY : JPUSH_APPKEY, //JPush上注册的包名对应的appkey.
]
}
signingConfigs {
release {
//签名
storeFile file(STORE_FILE)
storePassword STORE_PASSWORD
keyAlias KEY_ALIAS
keyPassword KEY_PASSWORD
}
}
buildTypes {
debug {
buildConfigField "boolean", "LOG_DEBUG", "true"
shrinkResources false
signingConfig signingConfigs.release
minifyEnabled false
}
release {
// 不显示Log
buildConfigField "boolean", "LOG_DEBUG", "false"
//是否混淆
minifyEnabled true
// 移除无用的resource文件
shrinkResources false
//
debuggable false
jniDebuggable false
zipAlignEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
}
ompileOptions {
sourceCompatibility JAVA_VERSION
targetCompatibility JAVA_VERSION
}
}
allprojects {
repositories {
maven { url "https://maven.google.com" }
jcenter()
mavenCentral()
flatDir {
dirs 'libs'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
}
里面的默认值可以给,可以不写。不写的话就必须在gradle.properties文件中配置了用到的参数。
module中的build.gradle
apply plugin: 'com.android.library'
def ANDROID_BUILD_SDK_VERSION = project.getProperties().get("ANDROID_BUILD_SDK_VERSION")
if (ANDROID_BUILD_SDK_VERSION == null) {
ANDROID_BUILD_SDK_VERSION = "26" //给出默认值
}
//app min sdk version
def ANDROID_BUILD_MIN_SDK_VERSION = project.getProperties().get("ANDROID_BUILD_MIN_SDK_VERSION")
if (ANDROID_BUILD_MIN_SDK_VERSION == null) {
ANDROID_BUILD_MIN_SDK_VERSION = "15" //给出默认值
}
//app target sdk version
def ANDROID_BUILD_TARGET_SDK_VERSION = project.getProperties().get("ANDROID_BUILD_TARGET_SDK_VERSION")
if (ANDROID_BUILD_TARGET_SDK_VERSION == null) {
ANDROID_BUILD_TARGET_SDK_VERSION = "1" //给出默认值
}
//app version code
def ANDROID_BUILD_VER_CODE = project.getProperties().get("ANDROID_BUILD_VER_CODE")
if (ANDROID_BUILD_VER_CODE == null) {
ANDROID_BUILD_VER_CODE = "1" //给出默认值
}
//app version name
def ANDROID_BUILD_VER_NAME = project.getProperties().get("ANDROID_BUILD_VER_NAME")
if (ANDROID_BUILD_VER_NAME == null) {
ANDROID_BUILD_VER_NAME = "1.0.0" //给出默认值
}
//编译的tools版本
def ANDROID_BUILD_TOOLS_VERSION = project.getProperties().get("ANDROID_BUILD_TOOLS_VERSION")
if (ANDROID_BUILD_TOOLS_VERSION == null) {
ANDROID_BUILD_TOOLS_VERSION = "26.0.0" //给出默认值
}
android {
compileSdkVersion Integer.parseInt(ANDROID_BUILD_SDK_VERSION as String)
defaultConfig {
minSdkVersion Integer.parseInt(ANDROID_BUILD_MIN_SDK_VERSION as String)
targetSdkVersion Integer.parseInt(ANDROID_BUILD_TARGET_SDK_VERSION as String)
versionCode Integer.parseInt(ANDROID_BUILD_VER_CODE as String)
versionName ANDROID_BUILD_VER_NAME
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:26.1.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
多个module时候配置同上。这样我们就将相关的参数都统一到一个文件中,以后切换、修改参数也只需要修改一个地方其他地方都会同步过来。
以上只是简单的抽离了配置的参数,其实引入的第三方lib的版本也可以统一在一个地方配置,同时除了将配置信息统一写到gradle.properties中之外,也可以将参数写在项目根目录的build.gradle中,如下:
// Top-level build file where you can add configuration options common to all sub-projects/modules.
def GRADLE_VERSION = project.getProperties().get("GRADLE_VERSION")
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath "com.android.tools.build:gradle:${GRADLE_VERSION}"
}
}
allprojects {
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
ext {
// Sdk and tools
compileSdkVersion = 26
supportLibraryVersion = '26.1.0'
constraintLayoutVersion = '1.1.3'
//其他参数
}
上面的ext里面就是参数的配置,具体使用方法:
compileSdkVersion Integer.parseInt("$rootProject.ext.compileSdkVersion" as String)
或者:
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "com.android.support:appcompat-v7:$rootProject.ext.supportLibraryVersion"
}