文档当前状态:**beta0.4**
* [x] 选题收集:2017/11/21
* [x] 初稿整理:
* [ ] 补充校对:
* [ ] 入库存档:
---
之前已经整体的对组件化框架进行了概述,这篇文章只针对组件化的编译脚本的配置进行详述。
在概览的时候,我们提出了几个目标:可复用、热插拔、灵活发布。
那么,如何才能算是可灵活发布呢?
1、组件可以独立运行
2、组件可以独立发布
3、组件有独立的版本
### 组件可以独立运行
组件可以独立运行,就是说在有时候 Module 可以以libary运行,有时候可以以application运行,为了实现这些目标,以下的这些使我们需要改动的。
* 自动选择android plugin——application或libary
* 自动引入ApplicationId
* 自动匹配不同环境时的AndroidMenifest文件
* 代码隔离:组件在单独运行时的测试代码以及资源等应该与核心发布代码进行隔离
* 自动匹配依赖项
首先,为了区分不同运行环境:Application或Libary,我们需要在build.gradle 引入一个布尔值 **isApp**。
最开始,我们添加了两个配置文件 config.gradle和configpersonal.gradle:
* **config.gradle**:主要对各个模块的依赖版本号进行 统一管理,团队的全体成员应该同一份该文件;
* **configpersonal.gradle**:主要是对不同模块 进行 模式切换的统一配置文件,方便管理。初始化后,不应再commit该文件的改动,以避免不必要的冲突;
此外,因为settings.gradle 是gradle run最先运行的几个文件之一,暂时没有发现可以通过在其他文件中 配置一个布尔值,来自动 include对应的module,只能手动开关注释来处理。
好啦现在我们通过一份具体的build.gradle 里了解我们所需要的解决的问题。完整版本的build.gradle 可以查看最下面的build.gradle.
为了获取configpersonal.gradle中 指定module的运行模式,这里定义了 isApp的全局变量,用于获取configpersonal中的值。后续moudle的build.gradle都会依赖这个布尔值。
~~~
def isApp = rootProject.isApplication_ModuleD
~~~
首先,我们通过isApp 来选择对应的 android plugin:
~~~
if (isApp) {
apply plugin: 'com.android.application'
} else {
apply plugin: 'com.android.library'
}
~~~
接着处理 在libary中不能使用applicationId的问题:
~~~
...
android {
compileSdkVersion rootProject.ext.android.compileSdkVersion
buildToolsVersion rootProject.ext.android.buildToolsVersion
defaultConfig {
if (isApp) applicationId "com.example.app.moduled"
...
}
}
~~~
再来处理 不同状态时,AndroidMenifest.xml和java、res的配置:
~~~
//***************************不同build下,Module代码文件
sourceSets {
main {
if (isApp) {
manifest.srcFile 'src/main/debug/AndroidManifest.xml'
java.srcDirs = ['src/main/java', 'src/main/java-debug']
res.srcDirs = ['src/main/res', 'src/main/res-debug']
} else {
manifest.srcFile 'src/main/release/AndroidManifest.xml'
}
}
}
~~~
相关说明:
* java文件夹存放Module的正常源代码文件
* java-debug存放Module单独运行时的额外源代码文件
* res存放Module的正常资源文件
* res-debug存放Module单独运行时的额外资源文件
* release/AndroidManifest.xml存放Module的正常配置信息
* debug/AndroidManifest.xml存放Module单独运行的配置信息,要包括AndroidManifest.xml的所有内容。
需要特别注意的地方:
1. java文件夹中的类不能调用java-debug中的类,因为java-debug中的类在作为library发布的时候是非源码文件夹,不参与编译,编译时会报错。而java-debug文件夹的类可以随意引用java中的类。java文件夹与java-debug文件夹不能出现重复的类。
2. res文件夹中的资源不能引用res-debug文件夹中的资源,原因同上,并且不能出现重复的资源。
3. debug/AndroidManifest.xml中必须包含所有release/AndroidManifest.xml中的配置信息,并且可以随意添加其他信息。原因同上。
最后我们在java-debug中添加我们的测试入口类TestActivity.java,在res-debug中添加测试layout文件activity_test.xml,在debug/AndroidManifest.xml中设置TestActivity为Main入口。
最后,不用状态时,依赖关系也需要分别处理 ,比如Arouter插件的问题:
~~~
if(isApp) compile 'com.alibaba:arouter-api:x.x.x'
annotationProcessor 'com.alibaba:arouter-compiler:x.x.x'
~~~
## 参考:
* [组件化开发:build.gradle配置](http://www.jianshu.com/p/9620a40c203f)
* [android模块化简单教程](http://www.wxdroid.com/index.php/4048.html)
和java、res的配置:
~~~
~~~
---
## 附件:
settings.gradle
~~~
//根据自己的需要打开/关闭对应的module
//used for team release
//include ':app', ':ModuleA', ':ModuleB', ':ModuleC', ':ModuleD'
// only for ModuleD debug used
include ':ModuleD'
~~~
---
config.gradle
~~~
//公共配置信息,依赖版本,统一管理
ext {
//通用build 版本
android = [
compileSdkVersion: 26,
buildToolsVersion: "26.0.2",
minSdkVersion : 21,
targetSdkVersion : 22,
versionCode : 10,
versionName : "6.0"
]
//公共依赖
supportV4_Ver = "25.2.0"
supportV7_Ver = "25.2.0"
supportV13_Ver = "25.2.0"
constraint_layout_Ver = "1.0.2"
leakcanary_Ver = "1.5"
okhttp3_Ver = "3.8.0"
gson_Ver = "2.3.1"
glide_Ver = "3.7.0"
eventbus_Ver = "3.0.0"
rxjava_Ver = "2.0.8"
rxandroid_Ver = "2.0.1"
retrofit_Ver = "2.2.0"
alibaba_arouter_Ver ="1.2.1.1"
alibaba_arouter_compiler_Ver ="1.1.2.1"
}
~~~
---
configpersonal.gradle
~~~
//个人配置项,用于个人定制项目
ext {
/**
* 移除不必要的gradle task ,加快build速度
*/
isRemoveSomeTask = true
/**
* 本地编译 配置项目
* isApplication_Main = true 表示 将 main Module 编译为application
* 1.main 为false时,需要注释applicationid(调试自己module时,最后setting注释掉)
* 2.main 为ture时,其依赖的子module 不能为true, 如libary、baseModule(缘由-application 不能依赖 application)
* 3.子module为Application时,最后在setting中把 不必要的给注释掉
*/
modulesBuildMode = [
isApplication_app = true,
isApplication_ModuleA = false,
isApplication_ModuleB = false,
isApplication_ModuleC = false,
isApplication_ModuleD = false,
]
}
~~~
项目的root build.gradle
~~~
// Top-level build file where you can add configuration options common to all sub-projects/modules.
apply from: "config.gradle"
apply from: "configpersonal.gradle"
buildscript {
repositories {
//maven 私服地址,如不能使用,尝试切换到maven.aliyun
maven { url 'http://10.10.4.43:8083/repository/maven-public/' }
// maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
}
dependencies {
classpath 'com.android.tools.build:gradle:3.0.1'
}
}
allprojects {
repositories {
//maven 私服地址,如不能使用,尝试切换到maven.aliyun
maven { url 'http://10.10.4.43:8083/repository/maven-public/' }
// maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
flatDir {
dirs '../Library/libs'
dirs '../FingerPrintModule/libs'
dirs '../UpdateLib/libs'
}
}
//全局配置,移除不必要的gradle task,加快编译
if (rootProject.ext.isRemoveSomeTask) gradle.taskGraph.whenReady {
tasks.each { task ->
if (task.name.contains("lint")
//如果instant run不生效,把clean这行干掉
//||task.name.equals("clean")
//如果项目中有用到aidl则不可以舍弃这个任务
|| task.name.contains("Aidl")
//用不到测试的时候就可以先关闭
|| task.name.contains("mockableAndroidJar")
|| task.name.contains("UnitTest")
|| task.name.contains("AndroidTest")
//用不到NDK和JNI的也关闭掉
|| task.name.contains("Ndk")
//|| task.name.contains("Jni")
) {
task.enabled = false
}
}
}
}
~~~
ModuleD的build.gradle
~~~
def isApp = rootProject.isApplication_ModuleD
if (isApp) {
apply plugin: 'com.android.application'
} else {
apply plugin: 'com.android.library'
}
android {
compileSdkVersion rootProject.ext.android.compileSdkVersion
buildToolsVersion rootProject.ext.android.buildToolsVersion
defaultConfig {
if (isApp) applicationId "com.example.app.moduled"
minSdkVersion rootProject.ext.android.minSdkVersion
targetSdkVersion rootProject.ext.android.targetSdkVersion
versionCode rootProject.ext.android.versionCode
versionName rootProject.ext.android.versionName
//项目只是使用armeabi情况下,为避免产生不必要的.so文件夹
//在gradle.properties中添加 android.useDeprecatedNdk=true,并在defaultConfig中添加以下代码
// 如支持更多平台,abiFilters "armeabi", "armeabi-v7a", "x86"
ndk {
abiFilters "armeabi-v7a"
}
javaCompileOptions {
annotationProcessorOptions {
arguments = [ moduleName : project.getName() ]
}
}
}
//自定义BuildConfig,添加一个 字段 IS_DEBUG
//主要是为了处理gradle插件2.x module中的BuildConfig.DEBUG 值异常的bug,3.0修复了这个问题
//gradle插件 2.x使用以下进行依赖
//debugCompile project(path: ':GlxssModule', configuration: 'debug')
//releaseCompile project(path: ':GlxssModule', configuration: 'release')
//gradle插件 3.0 后,仅使用一行即可,implementation或api
//api project(':GlxssModule')
publishNonDefault true
buildTypes {
debug {
minifyEnabled false
buildConfigField "boolean", "IS_DEBUG", "true"
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
release {
minifyEnabled false
buildConfigField "boolean", "IS_DEBUG", "false"
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
//***************************不同build下,Module代码文件
sourceSets {
main {
if (isApp) {
manifest.srcFile 'src/main/debug/AndroidManifest.xml'
java.srcDirs = ['src/main/java', 'src/main/java-debug']
res.srcDirs = ['src/main/res', 'src/main/res-debug']
} else {
manifest.srcFile 'src/main/release/AndroidManifest.xml'
}
}
}
//资源文件名前缀约束,避免发布release时可能重名的问题
resourcePrefix "glxss_"
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile "com.android.support:appcompat-v7:$rootProject.ext.supportV7_Ver"
compile "com.android.support.constraint:constraint-layout:$rootProject.ext.constraint_layout_Ver"
compile "org.greenrobot:eventbus:$rootProject.ext.eventbus_Ver"
if(isApp) compile 'com.alibaba:arouter-api:x.x.x'
annotationProcessor 'com.alibaba:arouter-compiler:x.x.x'
}
~~~
- 0-发现
- AndroidInterview-Q-A
- Android能让你少走弯路的干货整理
- LearningNotes
- temp
- temp11
- 部分地址
- 0-待办任务
- 待补充列表
- 0-未分类
- AndroidView事件分发与滑动冲突处理
- Spannable
- 事件分发机制详解
- 1-Java
- 1-Java-01基础
- 未归档
- 你应该知道的JDK知识
- 集合框架
- 1-Java-04合集
- Java之旅0
- Java之旅
- JAVA之旅01
- JAVA之旅02
- JAVA之旅03
- JAVA之旅04
- JAVA之旅05
- JAVA之旅06
- JAVA之旅07
- JAVA之旅08
- JAVA之旅09
- java之旅1
- JAVA之旅10
- JAVA之旅11
- JAVA之旅12
- JAVA之旅13
- JAVA之旅14
- JAVA之旅15
- JAVA之旅16
- JAVA之旅17
- JAVA之旅18
- JAVA之旅19
- java之旅2
- JAVA之旅20
- JAVA之旅21
- JAVA之旅22
- JAVA之旅23
- JAVA之旅24
- JAVA之旅25
- JAVA之旅26
- JAVA之旅27
- JAVA之旅28
- JAVA之旅29
- java之旅3
- JAVA之旅30
- JAVA之旅31
- JAVA之旅32
- JAVA之旅33
- JAVA之旅34
- JAVA之旅35
- 1-Java-05辨析
- HashMapArrayMap
- Java8新特性
- Java8接口默认方法
- 图解HashMap(1)
- 图解HashMap(2)
- 2-Android
- 2-Android-1-基础
- View绘制流程
- 事件分发
- AndroidView的事件分发机制和滑动冲突解决
- 自定义View基础
- 1-安卓自定义View基础-坐标系
- 2-安卓自定义View基础-角度弧度
- 3-安卓自定义View基础-颜色
- 自定义View进阶
- 1-安卓自定义View进阶-分类和流程
- 10-安卓自定义View进阶-Matrix详解
- 11-安卓自定义View进阶-MatrixCamera
- 12-安卓自定义View进阶-事件分发机制原理
- 13-安卓自定义View进阶-事件分发机制详解
- 14-安卓自定义View进阶-MotionEvent详解
- 15-安卓自定义View进阶-特殊形状控件事件处理方案
- 16-安卓自定义View进阶-多点触控详解
- 17-安卓自定义View进阶-手势检测GestureDetector
- 2-安卓自定义View进阶-绘制基本图形
- 3-安卓自定义View进阶-画布操作
- 4-安卓自定义View进阶-图片文字
- 5-安卓自定义View进阶-Path基本操作
- 6-安卓自定义View进阶-贝塞尔曲线
- 7-安卓自定义View进阶-Path完结篇伪
- 8-安卓自定义View进阶-Path玩出花样PathMeasure
- 9-安卓自定义View进阶-Matrix原理
- 通用类介绍
- Application
- 2-Android-2-使用
- 2-Android-02控件
- ViewGroup
- ConstraintLayout
- CoordinatorLayout
- 2-Android-03三方使用
- Dagger2
- Dagger2图文完全教程
- Dagger2最清晰的使用教程
- Dagger2让你爱不释手-终结篇
- Dagger2让你爱不释手-重点概念讲解、融合篇
- dagger2让你爱不释手:基础依赖注入框架篇
- 阅读笔记
- Glide
- Google推荐的图片加载库Glide:最新版使用指南(含新特性)
- rxjava
- 这可能是最好的RxJava2.x入门教程完结版
- 这可能是最好的RxJava2.x入门教程(一)
- 这可能是最好的RxJava2.x入门教程(三)
- 这可能是最好的RxJava2.x入门教程(二)
- 这可能是最好的RxJava2.x入门教程(五)
- 这可能是最好的RxJava2.x入门教程(四)
- 2-Android-3-优化
- 优化概况
- 各种优化
- Android端秒开优化
- apk大小优化
- 内存分析
- 混淆
- 2-Android-4-工具
- adb命令
- 一键分析Android的BugReport
- 版本控制
- git
- git章节简述
- 2-Android-5-源码
- HandlerThread 源码分析
- IntentService的使用和源码分析
- 2-Android-9-辨析
- LRU算法
- 什么是Bitmap
- 常见图片压缩方式
- 3-Kotlin
- Kotlin使用笔记1-草稿
- Kotlin使用笔记2
- kotlin特性草稿
- Kotlin草稿-Delegation
- Kotlin草稿-Field
- Kotlin草稿-object
- 4-JavaScript
- 5-Python
- 6-Other
- Git
- Gradle
- Android中ProGuard配置和总结
- gradle使用笔记
- Nexus私服搭建
- 编译提速最佳实践
- 7-设计模式与架构
- 组件化
- 组件化探索(OKR)
- 1-参考列表
- 2-1-组件化概述
- 2-2-gradle配置
- 2-3-代码编写
- 2-4-常见问题
- 2-9-值得一读
- 8-数据结构与算法
- 0临时文件
- 汉诺塔
- 8-数据-1数据结构
- HashMap
- HashMap、Hashtable、HashSet 和 ConcurrentHashMap 的比较
- 迟到一年HashMap解读
- 8-数据-2算法
- 1个就够了
- Java常用排序算法(必须掌握的8大排序算法)
- 常用排序算法总结(性能+代码)
- 必须知道的八大种排序算法(java实现)
- 9-职业
- 阅读
- 书单
- 面试
- 面试-01-java
- Java面试题全集骆昊(上)
- Java面试题全集骆昊(下)
- Java面试题全集骆昊(中)
- 面试-02-android
- 40道Android面试题
- 面试-03-开源源码
- Android图片加载框架最全解析(二),从源码的角度理解Glide的执行流程
- 面试-07-设计模式
- 面试-08-算法
- 面试-09-其他
- SUMMARY
- 版权说明
- temp111