Android 开发之 Gradle那些事儿(三)

自定义构建出的文件名
在android代码块下,使用注入替换的方式,可以自定义构建出的文件名,比每次都出来默认的app-debug.apk或者app-release.apk要友好且清晰。具体代码如下:

//自定义生成的apk名称
applicationVariants.all { variant ->
    variant.outputs.each { output ->
        if (!variant.buildType.name.equals('debug')) {
            def outputFile = output.outputFile
            //这里修改文件名
            def fileName = "GradleDemo-V"+defaultConfig.versionCode+"-"+buildTime()+"-"+getSvnRevision()+".apk"
            output.outputFile = new File(rootProject.buildDir.path, fileName)
        }
    }
}

效果如图:


Android 开发之 Gradle那些事儿(三)_第1张图片
这里写图片描述

多渠道打包
我个人不建议在gradle里用最古老的多渠道打包方法(清单文件里建meta-data,再用productFlavors里面配各种渠道值来动态替换清单文件里的渠道号占位变量。)
原因很明显:配置麻烦,构建非常非常慢,打出来20个包估计得半小时。

我个人也不建议在gradle里直接配 packNg或者walle,因为我个人认为打包生成的文件,本质上是一个压缩包,对于一个压缩包的处理或者生成一堆压缩包,不应该是gradle的工作。我们应该把 构建出安装包 和 一个包分身出多个 这两个作为不同类型的任务(比如我们可以把多渠道分身的任务交给运营或者测试,哈哈哈,可以减轻我们任务节约我们的时间啦,也不用每次给他们花好长时间发几十个包)

我个人建议使用packNg、AndroidMultiChannelBuildTool 或者 walle 的命令行工具在电脑上单独做分身多渠道的任务。团队分享内我已经写了相关教程以及批处理脚本。(另外随着Android7.0的出现,我们推荐使用walle,因为它速度快,使用方便,支持对v2签名包的分身多渠道打包)

多模块组件化配置
在gradle.properties配置一个isModule配置项,取值为true或false。
true代表使用组件化模式,有些独立的模块可以单独拎出来编译打包或者单独做单元测试,不同模块可以分开维护。
false代表集成模式,还是以app模块作为工程的主模块,主模块依赖各个业务模块(都作为library)。

这里写图片描述

在独立出业务模块的build.gradle里,读取isModule配置值,做不同的模块配置选项

Android 开发之 Gradle那些事儿(三)_第2张图片
这里写图片描述
Android 开发之 Gradle那些事儿(三)_第3张图片
这里写图片描述

对于各模块的build.gradle除了读取isModule做不同配置外,还有一个比较方便的方案是:把各个模块的build.gradle公共配置,抽到一个公共配置文件里,方便统一修改和统一管理,在各模块的build.gradle中使用apply from:读取(缺点:必须使用AS的Project视图,才能查看到我们的公共配置文件)。

Android 开发之 Gradle那些事儿(三)_第4张图片
这里写图片描述

我们在项目更目录下新建CommonConf文件夹,添加modulesCommonConfig.gradle,在modules2中apply。

实际运行效果图:


Android 开发之 Gradle那些事儿(三)_第5张图片
这里写图片描述

打开不同模块的app:


Android 开发之 Gradle那些事儿(三)_第6张图片
app主模块
Android 开发之 Gradle那些事儿(三)_第7张图片
module2模块

关于组件化模式和集成模式清单文件的问题:
当独立模块作为一个独立组件编译运行时(com.android.application),它是要有入口activity的;相反如果用集成模式编译它将作为主模块依赖的库(com.android.library),它的清单文件和资源将会在编译打包时做混合,如果有了不同的application属性或者多个入口activity,就会冲突报错。
但是我们如果每次都去手动修改清单文件,这将是很麻烦的,我们可以创建两个有差异的清单文件,一个给组件化模式用,一个给集成模式用。然后在模块的build.gradle中,根据isModule标志,设定使用不同的清单文件。
例子如下(可以把这个代码块写在每个模块的build.gradle里,也可以写在各模块的公共配置文件里,然后用apply from:读取使用):

Android 开发之 Gradle那些事儿(三)_第8张图片
这里写图片描述

我会把Demo地址添加在文章的最后。

一些杂项配置

compileOptions {
    //指定编译用的java版本
    sourceCompatibility JavaVersion.VERSION_1_7
    targetCompatibility JavaVersion.VERSION_1_7
}

dexOptions {
    //让它不要对Lib做preDexing
    preDexLibraries = false
    //开启incremental dexing,优化编译效率,这个功能android studio默认是关闭的
    incremental true
    //增加java堆内存大小
    javaMaxHeapSize "4g"
}

//默认的一些文件路径的配置
sourceSets {
    main {
        assets.srcDirs = ['assets']    //资源文件
        jni.srcDirs 'src/main/jni'     //jni文件
        jniLibs.srcDir 'src/main/jniLibs' //jni库
    }
}
packagingOptions {
    //打包排除掉,不想添加到apk中的文件
    exclude 'META-INF/DEPENDENCIES.txt'
    exclude 'META-INF/LICENSE.txt'
    exclude 'META-INF/NOTICE.txt'
    exclude 'META-INF/NOTICE'
    exclude 'META-INF/LICENSE'
    exclude 'META-INF/DEPENDENCIES'
    exclude 'META-INF/notice.txt'
    exclude 'META-INF/license.txt'
    exclude 'META-INF/dependencies.txt'
    exclude 'META-INF/LGPL2.1'
    exclude 'META-INF/ASL2.0'
}

dependencies代码块
dependencies称作依赖配置,一般可以配置三种:依赖本地库文件,依赖远程库文件,依赖本地工程模块
分别示例如下:

compile fileTree(dir: 'libs', include: '*.jar')
provided fileTree(dir: '../honjane-demo-library/libs', include: '*.jar')//依赖本地jar
compile(name: 'liblivenessdetector2-release', ext: 'aar')
compile(name: 'lib-1.1', ext: 'aar')//依赖本地aar

compile 'com.jakewharton:butterknife:8.2.1'
compile 'com.squareup.okhttp3:okhttp:3.4.1'//依赖远程库

if (isModule.toBoolean()) {
    compile project(':mylibrary')
} else {
    compile project(':module2')
    compile project(':module3')
    compile project(':module4')
    compile project(':module5')
}//依赖本地工程模块

关于Gradle的介绍就到这里啦,欢迎大家一起讨论。

项目地址:github
项目地址:github
项目地址:github
重要的事情说三遍

谢谢大家。完结撒花

这里写图片描述
这里写图片描述

你可能感兴趣的:(Android 开发之 Gradle那些事儿(三))