关于组件化的理解大同小异,本文就从个人角度来简单讨论一下组件化,并且将自己学到的信息做以记录。
一、什么是组件化,为什么学习组件化
1、单一分包模式:
描述:此模式是早期开发应用一般采用的模式,所有的代码都写在app模块的不同包里面;
特点:低内聚问题、高耦合、无重用、层次混乱;
2、组件化模式:
描述:如下图所示:
正如上图所示,对于用户来讲,入口为app壳,而下层实现将由product、order、personal三个模块组成,而此三个模块则组成了所谓的组件化,他们可以单独运行,也可以依附于app壳,纵向依赖于公共基础库,横向则不能直接通信,如果横向要通信,则可以通过接口下沉到公共基础库层(类似于后面我们要讲的ARoute)来实现;
特点:不相互依赖、可以相互交互、任意组合、高度解耦、自由拆卸、自由组装、重复利用、分层独立化;
二、集成化/组件化环境部署
在项目开发中,经常会遇到类似于这些场景:在项目上线之前必须测试业务功能,那就必须有测试环境与正式环境之分;随着业务的扩展,全覆盖测试成为痛点,那就必须有模块化单独测试的要求;对于以上要求,我们可以考虑采用Gradle来控制或者实现以上需求;
1、Gradle的简单了解:
众所周知Gradle它的实现语言是Groovy,Groovy是JAVA的一个分支,在一个Android APP工程项目中,gradle文件也是分层级的,比如settings.grade->build.gradle->app.gradle等;具体关于Gradle及Groovy语法等相关知识,我们将在后续文章中体现;
2、公共配置gradle的抽离:
一个APP中会涵盖多个module,比如上图说的product、order、personal每个模块都有自己的gradle文件,这些文件中都含有一些公共部分的设置比如:
android {
compileSdkVersion 29
buildToolsVersion "29.0.0"
defaultConfig {
applicationId "com.zero.materialdesign"
minSdkVersion 27
targetSdkVersion 29
versionCode 1
versionName "1.0"
这部分,可以通过自定义test.gradle来设置:
ext {
androidID = [
compileSdkVersion : 30,
buildToolsVersion : "30.0.1",
applicationId : "com.derry.derry",
minSdkVersion : 16,
targetSdkVersion : 30,
versionCode : 1,
versionName : "1.0",
testInstrumentationRunner: "androidx.test.runner.AndroidJUnitRunner"
]
}
然后在build.gradle中引入自定义的test.gradle:
apply from : 'test.gradle'
在app.gralde中的应用:
//先定义(此方式为正确打开方式,有性能方面的优化)
def androidID = rootProject.ext.androidID
//自定义后的应用
android {
compileSdkVersion androidID.compileSdkVersion
buildToolsVersion androidID.buildToolsVersion
defaultConfig {
applicationId appID.app
minSdkVersion androidID.minSdkVersion
targetSdkVersion androidID.targetSdkVersion
versionCode androidID.versionCode
versionName androidID.versionName
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
3、测试环境与正式环境的配置:
在test.gradle中的ext扩展块中可添加:
// 扩展快
ext {
// 正式环境 和 测试环境
isRelease = false
// 正式环境 和 测试环境 服务器 URL 配置
url = [
"debug" : "http://192.168.12.229/debug",
"release": "http://192.168.12.229/release"
]
在app.gradle中的应用:
defaultConfig {
applicationId appID.app
minSdkVersion androidID.minSdkVersion
targetSdkVersion androidID.targetSdkVersion
versionCode androidID.versionCode
versionName androidID.versionName
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
// 让我的Java代码也可以用
// 给Java代码暴漏,标记,正式环境 和 测试环境 的标记
// 组件化 和 集成化 的时候需要
buildConfigField("boolean", "isRelease", String.valueOf(isRelease))
}
buildTypes {
debug {
buildConfigField("String", "debug", "\"${url.debug}\"")
}
release {
buildConfigField("String", "release", "\"${url.release}\"")
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
注意在调用buildConfigField会自动生成BuildConifg.java文件,并且将此时对应值写入到BuildConfig.java中:
public final class BuildConfig {
省略...
// Fields from build type: debug
public static final String debug = "https://192.188.22.99/debug";
// Fields from default config.
public static final boolean isRelease = true;
}
此时即可以在Java代码中直接调用:
String url = BuildConfig.debug;
4、模块单独运行与集成化运行:
在测试中,如果要测试某个模块,那必须要求此module能够单独运行,那可以在对应module的gradle文件中通过以下方式设置:
if (isRelease) { // 如果是发布版本时,各个模块都不能独立运行
apply plugin: 'com.android.library' // 正式环境 library不能独立运行
} else {
apply plugin: 'com.android.application' // 测试环境 application独立运行
}
如图所示可查看可运行状态:
模块可单独运行状态.png
另外,也可以通过类似于一下的设置来指定AndroidManifest的加载及集成环境中文件的集成等:
sourceSets {
main {
if (!isRelease) {
// 如果是组件化模式,需要单独运行时 Debug
manifest.srcFile 'src/main/debug/AndroidManifest.xml' // 生效
} else { // 正式环境下
// 集成化模式,整个项目打包apk
manifest.srcFile 'src/main/AndroidManifest.xml' // 让我们之前 默认的路径下的清单文件再次生效
java {
// release 时 debug 目录下文件不需要合并到主工程
exclude "**/debug/**"
}
}
}
}
总结一下:简单介绍了一下组件化的意义,同时简单了解了一下通过Gradle来对组件化的一些简单配置,进一步的组件化学习,持续更新中。。。
网友评论