Android Studio 利用Gradle组织更清晰的打包脚本

简介: 前言我们最初写gradle脚本时候,通常的做法是把所有的打包脚本都写在了build.gradle文件中,这样做的容易引发的问题:项目中多个模块的build.gradle配置的依赖版本重复或compileSdkVersion等不统一;会导致一些依赖重复导致冲突;Android Support Library版本问题引发的一些列问题;影响 build.gradle 文件扩展性、可读性、以及难以维护等;针对以上问题,去寻找一个更清晰的打包系统,帮助开发者在组织打包脚本变得更简洁清晰。

前言

我们最初写gradle脚本时候,通常的做法是把所有的打包脚本都写在了build.gradle文件中,这样做的容易引发的问题:

  1. 项目中多个模块的build.gradle配置的依赖版本重复或compileSdkVersion等不统一;
  2. 会导致一些依赖重复导致冲突;
  3. Android Support Library版本问题引发的一些列问题;
  4. 影响 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中的打包组织架构。根据功能的不同,将打包系统分为多个脚本文件。
打包系统的组织结构如下:

img_26c66646d761c4a6ccbe89a1b8196da9.png
image.png

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
}
目录
相关文章
|
19天前
|
SQL 人工智能 Dart
Android Studio的插件生态非常丰富
Android Studio的插件生态非常丰富
33 1
|
19天前
|
Ubuntu Linux Android开发
Android Studio支持多种操作系统
Android Studio支持多种操作系统
39 1
|
19天前
|
前端开发 数据处理 Android开发
Flutter前端开发中的调试技巧与工具使用方法,涵盖调试的重要性、基本技巧如打印日志与断点调试、常用调试工具如Android Studio/VS Code调试器和Flutter Inspector的介绍
本文深入探讨了Flutter前端开发中的调试技巧与工具使用方法,涵盖调试的重要性、基本技巧如打印日志与断点调试、常用调试工具如Android Studio/VS Code调试器和Flutter Inspector的介绍,以及具体操作步骤、常见问题解决、高级调试技巧、团队协作中的调试应用和未来发展趋势,旨在帮助开发者提高调试效率,提升应用质量。
40 8
|
19天前
|
数据可视化 开发工具 Android开发
Android Studio
Android Studio
63 1
|
19天前
|
开发框架 前端开发 Android开发
安卓与iOS开发中的跨平台策略
在移动应用开发的战场上,安卓和iOS两大阵营各据一方。随着技术的演进,跨平台开发框架成为开发者的新宠,旨在实现一次编码、多平台部署的梦想。本文将探讨跨平台开发的优势与挑战,并分享实用的开发技巧,帮助开发者在安卓和iOS的世界中游刃有余。
|
21天前
|
缓存 前端开发 Android开发
安卓开发中的自定义视图:从零到英雄
【10月更文挑战第42天】 在安卓的世界里,自定义视图是一块画布,让开发者能够绘制出独一无二的界面体验。本文将带你走进自定义视图的大门,通过深入浅出的方式,让你从零基础到能够独立设计并实现复杂的自定义组件。我们将探索自定义视图的核心概念、实现步骤,以及如何优化你的视图以提高性能和兼容性。准备好了吗?让我们开始这段创造性的旅程吧!
22 1
|
6天前
|
搜索推荐 前端开发 API
探索安卓开发中的自定义视图:打造个性化用户界面
在安卓应用开发的广阔天地中,自定义视图是一块神奇的画布,让开发者能够突破标准控件的限制,绘制出独一无二的用户界面。本文将带你走进自定义视图的世界,从基础概念到实战技巧,逐步揭示如何在安卓平台上创建和运用自定义视图来提升用户体验。无论你是初学者还是有一定经验的开发者,这篇文章都将为你打开新的视野,让你的应用在众多同质化产品中脱颖而出。
34 19
|
19天前
|
IDE Java 开发工具
移动应用与系统:探索Android开发之旅
在这篇文章中,我们将深入探讨Android开发的各个方面,从基础知识到高级技术。我们将通过代码示例和案例分析,帮助读者更好地理解和掌握Android开发。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的信息和技巧。让我们一起开启Android开发的旅程吧!
|
6天前
|
JSON Java API
探索安卓开发:打造你的首个天气应用
在这篇技术指南中,我们将一起潜入安卓开发的海洋,学习如何从零开始构建一个简单的天气应用。通过这个实践项目,你将掌握安卓开发的核心概念、界面设计、网络编程以及数据解析等技能。无论你是初学者还是有一定基础的开发者,这篇文章都将为你提供一个清晰的路线图和实用的代码示例,帮助你在安卓开发的道路上迈出坚实的一步。让我们一起开始这段旅程,打造属于你自己的第一个安卓应用吧!
30 14
|
9天前
|
Java Linux 数据库
探索安卓开发:打造你的第一款应用
在数字时代的浪潮中,每个人都有机会成为创意的实现者。本文将带你走进安卓开发的奇妙世界,通过浅显易懂的语言和实际代码示例,引导你从零开始构建自己的第一款安卓应用。无论你是编程新手还是希望拓展技术的开发者,这篇文章都将为你打开一扇门,让你的创意和技术一起飞扬。