前言
我们最初写gradle
脚本时候,通常的做法是把所有的打包脚本都写在了build.gradle
文件中,这样做的容易引发的问题:
- 项目中多个模块的
build.gradle
配置的依赖版本重复或compileSdkVersion
等不统一; - 会导致一些依赖重复导致冲突;
-
Android Support Library
版本问题引发的一些列问题; - 影响 build.gradle 文件扩展性、可读性、以及难以维护等;
针对以上问题,去寻找一个更清晰的打包系统,帮助开发者在组织打包脚本变得更简洁清晰。
方式一
抽取统一的依赖
在根目录新建一个config.gradle
文件,里面键入要统一的依赖:
ext {
android = [
compileSdkVersion: 23,
buildToolsVersion: "23.0.3",
minSdkVersion : 15,
targetSdkVersion : 22,
versionCode : 1,
versionName : "1.0"
]
dependencies = [
"gson" : "com.google.code.gson:gson:2.6.2",
"eventbus" : 'org.greenrobot:eventbus:3.0.0',
"butterknife" : 'com.jakewharton:butterknife:7.0.1',
"support-design" : 'com.android.support:design:24.1.1',
"support-appcompatV7": 'com.android.support:appcompat-v7:24.1.1',
"support-percent" : 'com.android.support:percent:24.1.1',
"support-multidex" : 'com.android.support:multidex:1.0.1',
"glide" : 'com.github.bumptech.glide:glide:3.7.0',
"support-v4" : 'com.android.support:support-v4:24.1.1',
"okhttp3" : 'com.squareup.okhttp3:okhttp:3.3.1',
"nineoldandroids" : 'com.nineoldandroids:library:2.4.0'
]
}
然后在根目录的build.gradle
文件里面头部新增一句引用apply from: "config.gradle"
在module里面开始应用:
compileSdkVersion rootProject.ext.android.compileSdkVersion //android{}节点
compile rootProject.ext.dependencies["support-appcompatV7"] //dependencies{}节点
clean一下去External Libraries看看,是不是还有重复的,如果还有,说明前面config里面的依赖其他地方还有遗漏的,全局搜索一下在同样方式替换一下就好了。
方式二(更优方式)
此方式参照开源架构Android-CleanArchitecture
中的打包组织架构。根据功能的不同,将打包系统分为多个脚本文件。
打包系统的组织结构如下:
ci.gradle
文件如下:
def ciServer = 'TRAVIS'
def executingOnCI = "true".equals(System.getenv(ciServer))
// Since for CI we always do full clean builds, we don't want to pre-dex
// See http://tools.android.com/tech-docs/new-build-system/tips
subprojects {
project.plugins.whenPluginAdded { plugin ->
if ('com.android.build.gradle.AppPlugin'.equals(plugin.class.name) || 'com.android.build.gradle.LibraryPlugin'.equals(plugin.class.name)) {
project.android.dexOptions.preDexLibraries = !executingOnCI
}
}
}
dependencies.gradle
,里面键入要统一的依赖
allprojects {
repositories {
jcenter()
}
}
ext {
//Android
androidBuildToolsVersion = "24.0.1"
androidMinSdkVersion = 15
androidTargetSdkVersion = 21
androidCompileSdkVersion = 21
//Libraries
daggerVersion = '2.8'
butterKnifeVersion = '7.0.1'
recyclerViewVersion = '21.0.3'
rxJavaVersion = '2.0.2'
rxAndroidVersion = '2.0.1'
javaxAnnotationVersion = '1.0'
javaxInjectVersion = '1'
gsonVersion = '2.3'
okHttpVersion = '2.5.0'
androidAnnotationsVersion = '21.0.3'
arrowVersion = '1.0.0'
//Testing
robolectricVersion = '3.1.1'
jUnitVersion = '4.12'
assertJVersion = '1.7.1'
mockitoVersion = '1.9.5'
dexmakerVersion = '1.0'
espressoVersion = '2.0'
testingSupportLibVersion = '0.1'
//Development
leakCanaryVersion = '1.3.1'
presentationDependencies = [
daggerCompiler: "com.google.dagger:dagger-compiler:${daggerVersion}",
dagger: "com.google.dagger:dagger:${daggerVersion}",
butterKnife: "com.jakewharton:butterknife:${butterKnifeVersion}",
recyclerView: "com.android.support:recyclerview-v7:${recyclerViewVersion}",
rxJava: "io.reactivex.rxjava2:rxjava:${rxJavaVersion}",
rxAndroid: "io.reactivex.rxjava2:rxandroid:${rxAndroidVersion}",
javaxAnnotation: "javax.annotation:jsr250-api:${javaxAnnotationVersion}"
]
presentationTestDependencies = [
mockito: "org.mockito:mockito-core:${mockitoVersion}",
dexmaker: "com.google.dexmaker:dexmaker:${dexmakerVersion}",
dexmakerMockito: "com.google.dexmaker:dexmaker-mockito:${dexmakerVersion}",
espresso: "com.android.support.test.espresso:espresso-core:${espressoVersion}",
testingSupportLib: "com.android.support.test:testing-support-lib:${testingSupportLibVersion}",
]
domainDependencies = [
javaxAnnotation: "javax.annotation:jsr250-api:${javaxAnnotationVersion}",
javaxInject: "javax.inject:javax.inject:${javaxInjectVersion}",
rxJava: "io.reactivex.rxjava2:rxjava:${rxJavaVersion}",
arrow: "com.fernandocejas:arrow:${arrowVersion}"
]
domainTestDependencies = [
junit: "junit:junit:${jUnitVersion}",
mockito: "org.mockito:mockito-core:${mockitoVersion}",
assertj: "org.assertj:assertj-core:${assertJVersion}"
]
dataDependencies = [
daggerCompiler: "com.google.dagger:dagger-compiler:${daggerVersion}",
dagger: "com.google.dagger:dagger:${daggerVersion}",
okHttp: "com.squareup.okhttp:okhttp:${okHttpVersion}",
gson: "com.google.code.gson:gson:${gsonVersion}",
rxJava: "io.reactivex.rxjava2:rxjava:${rxJavaVersion}",
rxAndroid: "io.reactivex.rxjava2:rxandroid:${rxAndroidVersion}",
javaxAnnotation: "javax.annotation:jsr250-api:${javaxAnnotationVersion}",
javaxInject: "javax.inject:javax.inject:${javaxInjectVersion}",
androidAnnotations: "com.android.support:support-annotations:${androidAnnotationsVersion}"
]
dataTestDependencies = [
junit: "junit:junit:${jUnitVersion}",
assertj: "org.assertj:assertj-core:${assertJVersion}",
mockito: "org.mockito:mockito-core:${mockitoVersion}",
robolectric: "org.robolectric:robolectric:${robolectricVersion}",
]
developmentDependencies = [
leakCanary: "com.squareup.leakcanary:leakcanary-android:${leakCanaryVersion}",
]
}
项目 project 目录下 build.gradle
中开头加入
apply from: 'buildsystem/ci.gradle'
apply from: 'buildsystem/dependencies.gradle'
...
模块 module 目录下的 build.gradle
中
apply plugin: 'com.android.library'
android {
def globalConfiguration = rootProject.extensions.getByName("ext")
compileSdkVersion globalConfiguration.getAt("androidCompileSdkVersion")
buildToolsVersion globalConfiguration.getAt("androidBuildToolsVersion")
defaultConfig {
minSdkVersion globalConfiguration.getAt("androidMinSdkVersion")
targetSdkVersion globalConfiguration.getAt("androidTargetSdkVersion")
versionCode globalConfiguration.getAt("androidVersionCode")
}
...
}
dependencies {
def domainDependencies = rootProject.ext.domainDependencies
def domainTestDependencies = rootProject.ext.domainTestDependencies
provided domainDependencies.daggerCompiler
provided domainDependencies.javaxAnnotation
compile domainDependencies.dagger
compile domainDependencies.rxJava
testCompile domainTestDependencies.junit
testCompile domainTestDependencies.mockito
}