准备工作
创建一个新的工程,编译完成后新建一个Module工程:File>New>New Module,一路Next,记得给你的Module命名
最后结构目录如下:
总所周知,组件化因为需要引用各个不同的module组件,如果都引用了同一种第三方包,但是可能因为版本号不同会出现资源冲突问题,所以我们为了更好的管理各个module之间的版本关系,先创立一个统一的配置文件,供各个Module使用,顺便增加APP的SDK版本信息
ext {
/**
* 编译SDK版本
*/
compileSdkVersion = 28
/**
*最新支持版本
*/
minSdkVersion = 15
/**
* 目标SDK版本
*/
targetSdkVersion = 28
/**
* 版本号
*/
versionCode = 1
/**
* 版本信息
*/
versionName = "1.0"
}
然后在项目的build.gradle引入使用,然后Sync Now
引入后我们就可以在app下的build.gradle下使用了,配置如下
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion rootProject.ext.compileSdkVersion
defaultConfig {
applicationId "com.test.testmodule"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode rootProject.ext.versionCode
versionName rootProject.ext.versionName
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 "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
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'
}
到此我们前期工作就差不多完成了
BaseModule的畅想
如果你像我一样在新建Module的时候一直是Next的,那么这里的Module其实是可以直接运行的。我们将显示内容修改为APP的名称,以便于区别展示,然后选择myfistmodule,点击run,
等待编译结果,编译成功,结果展示正常
其实这就有点组件化的意思了,因为这也可以完全单独调试,修改增加需求也完全和其他模块区分,互不影响。但是缺点也同样明显,因为并未做Application和library区分处理,所以这里运行结果会在你的设备上出现两个APP文件,一个是正常的主APP,一个是ModuleAPP。这样就有点尴尬 了,如果有很多个Module集成,单独运行一个却将其他所有的APP也都编译安装,那么无疑是一种极坏的体验。所以我们就要要加以区分,在需要的时候编译,不需要的时候集成。
1.SDK配置修改
还记得刚才写的global_config.gradle文件吗?为了将版本保持一致,我们可以把Module的SDK版本也直接引用global_config中的配置
2.application和library切换操作
怎么区分application和library呢?其实很简单,就跟上面引用一样,我们只需要在global_config中增加一共字段,用来区分就好了,以isDebug为例
点击Sync Now会发现报错了,看一下错误信息是提示原来是Library是不能设置applicationid的
那么我们将module中的applicationid注释掉,然后重新编译,编译通过,如果你的isDebug写的是false,那么你会看到运行出myfirstmodule会出现红色的叉叉,这是正常现象,不必意外,你把isDebug改为true就会正常了,这就说明自主切换是完成了
3.调试状态下清单文件切换
既然上面说了每个组件都是可以单独运行的,那么在肯定会在AndroidManifest文件中有所冲突,所以我们需要修改下,我们在main文件下先创建一个debug文件夹,然后将清单文件复制进来,这样就将调试模式和编译模式区别开来,debug下文件主复杂调试模式,功能和正常清单文件一致,原清单文件要对其修改,报证其在编译时不会发出文件冲突及其他错误,结构如下图:
然后再bulid.gradle做判断处理
sourceSets {
main {
if (rootProject.ext.isDebug) {
manifest.srcFile 'src/main/debug/AndroidManifest.xml'
} else {
manifest.srcFile 'src/main/AndroidManifest.xml'
}
}
}
主APP引用
既然module都已经配置完毕了,那么接下来就看看该如何引用,其实引用内部Module和引用三方框架没什么太大的区别,唯一区别就是引用第三方框架是链接,而引用本地则是走文件路径
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
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'
if(!rootProject.ext.isDebug){
api project (":myfirstmodule")
}
}
到此我们的初始化配置算是差不多结束了,配置其他module原理跟当前配置也几乎一样,那我就就来看看效果如何
点击运行看看效果如果,正常显示只有一个APP了
进入app,点击按钮是否会跳转到指定组件页面
总结
Android 组件化实施方案原理并不是特别复杂,但是需要注意的地方还是挺多的,如文件冲突,资源冲突等,初用时肯定会有很多欠缺的地方,但是这是一个长而久的过程,需要我们一步步优化,一步步实现。
愿与君共勉