Preface
When we first wrote gradle scripts, we usually wrote all the packaged scripts in the build.gradle file, which is easy to cause problems.
- Dependent version duplication of build.gradle configuration or inconsistency of compileSdkVersion of multiple modules in the project;
- It will lead to some dependency duplication and conflict.
- Some column problems caused by Android Support Library version problems;
- It affects the extensibility, readability and maintenance of build.gradle files.
To solve these problems, find a clearer packaging system to help developers organize packaging scripts more concise and clear.
One way
Extract Unified Dependency
Create a new config.gradle file in the root directory, and type the dependencies you want to unify:
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' ] }
Then add a new quotation from apply: "config. gradle" in the header of the build.gradle file in the root directory
Start applying in module:
compileSdkVersion rootProject.ext.android.compileSdkVersion //android {} node compile rootProject.ext.dependencies["support-appcompatV7"] //dependencies {} node
Go to External Libraries to see if there is any duplication. If there is one, it means that the dependencies in the previous config are still missing from other places. It would be better to replace them in the same way by global search.
Mode 2 (Better Way)
This approach refers to the Packaging Organization Architecture in the open source architecture Android-Clean Architecture. According to the different functions, the packaging system is divided into several script files.
The organizational structure of the packaging system is as follows:
The ci.gradle file is as follows:
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, where you type the dependencies you want to unify
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}", ] }
Start with build.gradle in the project project directory
apply from: 'buildsystem/ci.gradle' apply from: 'buildsystem/dependencies.gradle' ...
build.gradle in the module module directory
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 }