多人协作时gradle配置优化

我们都知道android项目采用的是一套gradle构建机制通过android studio,我们可以很方便的对gradle进行配置从而灵活高效的完成项目的编译和打包。一般android的项目构建配置如下:


gradle配置

从图中我们可以看到,主要是.gradle文件和.properties文件。我们分别来看些配置文件的内容和用途。

  • 第一个是项目根目录下的脚本配置文件,用行话来说就是rootProject的build.gradle。它的内容如下:
// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.1.2'
        

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        google()
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

这里主要定义了android插件的版本号,以及你项目中一些依赖库的仓库地址。这里android插件的版本号一般跟开发者本机所安装的android studio插件版本号一致。所以在多人协作的时候,由于每个开发人员所使用的android studio版本不一致,而导致在使用持续集成工具打包时需要频繁提交对该文件的修改,这样会造成提交日志的冗余,因为这些提交并没有包含多少有效信息,同时每个开发者在同步版本库的配置时都要重新修改一次这个文件也比较繁琐。

  • 第二个是项目中一个模块的脚本配置文件,用行话来说就是subProject的build.gradle。它的内容如下:
apply plugin: 'com.android.application'

android {
    compileSdkVersion 27
    defaultConfig {
        applicationId "com.xiaofei.gradleconfigtest"
        minSdkVersion 15
        targetSdkVersion 27
        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:27.1.1'
    implementation 'com.android.support.constraint:constraint-layout:1.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的编译和打包配置,比如compileSdkVersion定义了编译项目使用的android版本,targetSdkVersion定义了项目可以兼容的最高android系统版本,implementation 'com.android.support:appcompat-v7:27.1.1'定义了该模块依赖的support包的版本号。这里同样会存在多人协作时配置不一致的情况,比如compileSdkVersion,targetSdkVersion等。

  • 第三个为gradle工具自身的一些配置,如位置,发布地址等。内容如下:
#Sat May 19 19:44:18 CST 2018
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip

该文件我们一般不会将它放到版本管理中

  • 第四个为项目混淆配置文件,一般在对外发布app时为了防止应用代码被破解会使用proguard工具将项目代码进行混淆处理。
  • 第五个为项目的属性配置文件,主要是对一些内置属性进行配置,如jvm参数等。内容如下:
# 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.
org.gradle.jvmargs=-Xmx1536m
# 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构建的初始化阶段告诉gradle该项目包含多少个module。内容如下:
include ':app'

  • 第七个为项目的属性配置文件,一般为android sdk的路径,ndk的路径等。内容如下:
## This file is automatically generated by Android Studio.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file should *NOT* be checked into Version Control Systems,
# as it contains information specific to your local configuration.
#
# Location of the SDK. This is only used by Gradle.
# For customization when using a Version Control System, please read the
# header note.
sdk.dir=C\:\\Users\\Administrator\\AppData\\Local\\Android\\Sdk

由于build.gradle文件中一些配置在多人协作时会被频繁修改,所以我们需要将这些配置提取出来使得每个开发者的修改不影响到版本库中的配置,有以下两种方法:

  • 将这些配置,如android插件版本(com.android.tools.build:gradle:3.1.2),compileSdkVersion等,放到gradle.properties中。为什么要放到gradle.properties中,因为该文件中的配置在项目构建时会被自动加载,而且我们并不会将gradle.properties放到版本管理中,可以随意修改而不影响其他开发者。具体做法参考如下:

项目根目录的build.gradle文件

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    
    repositories {
        google()
        jcenter()
    }
    dependencies {
        def ver = '3.1.2'//版本库中的默认配置,一般只有管理员才能修改
        if (hasProperty('androidPluginVer')) {//如果配置文件中定义了该属性,则使用,否则使用默认配置
            ver = getProperty('androidPluginVer')
        }
        classpath "com.android.tools.build:gradle:$ver"
        

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        google()
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

模块的build.gradle文件

apply plugin: 'com.android.application'

android {
    def sdkVer = 26 //版本库中的默认配置,一般只有管理员才能修改
    if (hasProperty('sdkVersion')) {//如果配置文件中定义了该属性,则使用,否则使用默认配置
        sdkVer = getProperty('sdkVersion')
    }
    compileSdkVersion sdkVer
    defaultConfig {
        applicationId "com.xiaofei.activityhide"
        minSdkVersion 15
        targetSdkVersion sdkVer
        versionCode 1
        versionName "1.0"
        if (rootProject.hasProperty("developer")) {
            versionName = developer
        }
        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'
    implementation 'com.android.support.constraint:constraint-layout:1.1.0'
    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'
}

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.
org.gradle.jvmargs=-Xmx1536m

# 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
#android插件版本号,一般与android studio版本号一致
androidPluginVer=3.1.2
#编译sdk版本号
sdkVersion=26

  • 将这些配置放到一个单独的配置文件中,如me.properties中,该文件不放到版本管理中,然后在项目根目录的build.gradle中加载该属性文件从里面取出配置。该做法和第一种做法的区别是修改me.properites之后android studio工具不会强制要求你做一次同步操作(sync project with gradle files)。具体参考做法如下:
    项目根目录的build.gradle文件
// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath "com.android.tools.build:gradle:$androidPluginVer"
        

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        google()
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

ext {
    loadPropertyFile = { name ->
        Properties properties = new Properties()
        InputStream is = null
        try {
            is = new FileInputStream(name)
            properties.load(is)
        } catch (Throwable tr) {
            tr.printStackTrace()
            println tr.getMessage()
        } finally {
            if (is != null) {
                try {
                    is.close()
                } catch (Throwable tr) {
                    tr.printStackTrace()
                }
            }
        }

        return properties
    }

    Properties myProperties = loadPropertyFile('me.properties')
    androidPluginVer = '3.1.2'//版本库中的默认配置,一般只有管理员才能修改
    if (myProperties.hasProperty('androidPluginVer')) {//如果配置文件中定义了该属性,则使用,否则使用默认配置
        androidPluginVer = myProperties.getProperty('androidPluginVer')
    }
}

me.properties文件,放在项目根目录下。

#android插件版本号,一般与android studio版本号一致
androidPluginVer=3.1.2

通过以上两种方法就可以灵活的管理自己的个人配置,而不再担心与版本库的配置发生冲突啦。

参考文档

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,919评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,567评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,316评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,294评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,318评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,245评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,120评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,964评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,376评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,592评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,764评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,460评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,070评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,697评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,846评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,819评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,665评论 2 354

推荐阅读更多精彩内容