1、组件化项目的意义
开发需求:不相互依赖、可以相互交互、任意组合、高度解耦
团队效率:分模块打包、测试、统一版本管理>
2、Phone Module和Android Library区别、切换
3、新建common公共库、order订单库、personal个人信息库
模块中有小绿点的是可以单独运行的,模块中有柱状图的是不可以单独运行的。在做组件化模式的时候需要子模块可以独立运行,在做集成化模式的时候需要打包整个项目apk,子模块不可独立运行。
4、gradle搭建组件化项目环境
环境:Android Studio3.4.1+Gradle5.1.1
思考:我们在修改版本号的时候,需要修改各个子模块中的版本号,万一漏了有一个怎么办?这个时候就需要把版本号与引入的第三方库统一管理起来。
//如果要添加多个自定义的属性,需要在ext代码块中引入
ext {
// 定义一个项目全局变量isRelease,用于动态切换:组件化模式 / 集成化模式
// false: 组件化模式(子模块可以独立运行),true :集成化模式(打包整个项目apk,子模块不可独立运行)
isRelease = false
// 建立Map存储,对象名、key可以自定义
androidId = [
compileSdkVersion: 28,
buildToolsVersion: "29.0.0",
minSdkVersion : 24,
targetSdkVersion : 28,
versionCode : 1,
versionName : "1.0"
]
appId = ["app" : "com.migill.modular",
"order" : "com.migill.modular.order",
"personal": "com.migill.modular.personal"]
url = [
"debug" : "https://11.22.33.44/debug",
"release": "https://55.66.77.88/release"
]
supportLibrary = "28.0.0"
dependencies = [
// ${supportLibrary}表示引用一个变量
"appcompat" : "com.android.support:appcompat-v7:${supportLibrary}",
"recyclerview": "com.android.support:recyclerview-v7:${supportLibrary}",
"constraint" : "com.android.support.constraint:constraint-layout:1.1.3",
"okhttp3" : "com.squareup.okhttp3:okhttp:3.10.0",
"retrofit" : "com.squareup.retrofit2:retrofit:2.5.0",
"fastjson" : "com.alibaba:fastjson:1.2.58",
]
}
apply from: "config.gradle"
1、buildConfigField("boolean", "isRelease", String.valueOf(isRelease))这句是什么意思?
是在BuildConfig文件中新增一个isRelease属性。
2、为什么是在isRelease为true的时候引入order和personal 模块?
是因为isRelease为false的时候是组件化模式,order与personal模块都是application模块,application模块是不能引用application模块的。
apply plugin: 'com.android.application'
def rootAndroidId = rootProject.ext.androidId
def appId = rootProject.ext.appId
def support = rootProject.ext.dependencies
android {
compileSdkVersion rootAndroidId.compileSdkVersion
buildToolsVersion rootAndroidId.buildToolsVersion
defaultConfig {
// app子模块在组件化开发中,默认为application
applicationId appId.app
minSdkVersion rootAndroidId.minSdkVersion
targetSdkVersion rootAndroidId.targetSdkVersion
versionCode rootAndroidId.versionCode
versionName rootAndroidId.versionName
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
// 切记:不能在android根节点,只能在defaultConfig或buildTypes节点下
buildConfigField("boolean", "isRelease", String.valueOf(isRelease))
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
// 循环引入第三方库
support.each { k, v -> implementation v }
implementation project(':common') // 公共基础库
// 如果是集成化模式,做发布版本时。各个模块都不能独立运行了
if (isRelease) {
implementation project(':order')
implementation project(':personal')
}
}
isRelease=true:集成化模式(打包整个项目apk,子模块不可独立运行)需要配置成Android Library
isRelease=false:组件化模式(子模块可以独立运行)需要配置成Phone Module
if (isRelease) { // 如果是发布版本时,各个模块都不能独立运行
apply plugin: 'com.android.library'
} else {
apply plugin: 'com.android.application'
}
def rootAndroidId = rootProject.ext.androidId
def appId = rootProject.ext.appId
def support = rootProject.ext.dependencies
android {
compileSdkVersion rootAndroidId.compileSdkVersion
buildToolsVersion rootAndroidId.buildToolsVersion
defaultConfig {
if (!isRelease) { // 如果是集成化模式,不能有applicationId
applicationId appId.order // 组件化模式能独立运行才能有applicationId
}
minSdkVersion rootAndroidId.minSdkVersion
targetSdkVersion rootAndroidId.targetSdkVersion
versionCode rootAndroidId.versionCode
versionName rootAndroidId.versionName
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
buildConfigField("boolean", "isRelease", String.valueOf(isRelease))
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
// 循环引入第三方库
support.each { k, v -> implementation v }
implementation project(':common') // 公共基础库
}
if (isRelease) { // 如果是发布版本时,各个模块都不能独立运行
apply plugin: 'com.android.library'
} else {
apply plugin: 'com.android.application'
}
def rootAndroidId = rootProject.ext.androidId
def appId = rootProject.ext.appId
def support = rootProject.ext.dependencies
android {
compileSdkVersion rootAndroidId.compileSdkVersion
buildToolsVersion rootAndroidId.buildToolsVersion
defaultConfig {
if (!isRelease) { // 如果是集成化模式,不能有applicationId
applicationId appId.personal // 组件化模式能独立运行才能有applicationId
}
minSdkVersion rootAndroidId.minSdkVersion
targetSdkVersion rootAndroidId.targetSdkVersion
versionCode rootAndroidId.versionCode
versionName rootAndroidId.versionName
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
buildConfigField("boolean", "isRelease", String.valueOf(isRelease))
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
// 循环引入第三方库
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
support.each { k, v -> implementation v }
implementation project(':common') // 公共基础库
}
总结:app、order、personal模块的build.gradle的修改都是围绕如下两点:
- 第一点,配置成统一管理的版本号等等。
- 第二点,根据isRelease配置成是组件化模式还是继承化模式
5、集成化模式开发、组件化模式开发
6、组件化开发的临时代码,集成化打包时动态隔离
思考:比如我们在order中创建了A、B、C三个测试类,在集成环境打包的时候,我不希望打包到APK中去,这个怎么办呢?
这个时候就可以用到资源配置,方便测试环境,打包不继承到正式环境
如下图,在main下创建debug目录放AndroidManifest.xml文件,在com.migill.modular.order.debug下放测试的文件
修改isRelease = true,编译正式的APK,可以发现A、B、C、Order_DebugActivity都没有打包到正式环境中。
修改isRelease = false,单独运行order模块。首页就变成了Order_DebugActivity的页面了。
android {
...
// 配置资源路径,方便测试环境,打包不集成到正式环境
sourceSets {
main {
if (!isRelease) {
// 如果是组件化模式,需要单独运行时
manifest.srcFile 'src/main/debug/AndroidManifest.xml'
} else {
// 集成化模式,整个项目打包apk
manifest.srcFile 'src/main/AndroidManifest.xml'
java {
// release 时 debug 目录下文件不需要合并到主工程
exclude '**/debug/**'
}
}
}
}
...
}
网友评论