【BYM】Android模块化实践复盘
blow your mind
bym系列意在除开技术分享,还分享下思路,不止是做一个代码的搬运工。
背景介绍
二线城市小公司,Android团队就两个人,但是刚入职时发现公司产品多达五个以上,在梳理了解熟悉过后,决定将现有产品的代码进行模块化管理,拆分通用部分,提炼业务模块,方便在新的项目到来时能更快的实现基础框架和雷同业务模块的搭建以及引入。这样咱们就不用加班或者机械式的复制代码了。
image.png正文开始
入职2年后的产品多达了18个了,翻了一番。刚入职预计到可能的情况就打算做模块化处理。
1.粗略计划制定
首先第一步是把现有产品线的业务模块进行拆分出来,那么在拆分的过程中势必会有重复引用到的工具类,方法以及第三方lib,那么这些重复的东西就放到base/common里,反正先往里丢。按照这样的节奏就可以制定出第一版的粗略计划。
image.pngWX20210331-142359@2x.png
整体花费了3个月的时间进行了v1.0版本的抽离,这里很感谢另一位Android同事的帮助。
如果各位读者公司的产品线也很繁多的话,也可以尝试进行模块化的拆分,能给后续的工作节约大量的时间。
本身模块化的工作还有个优点:让你更加熟悉公司的产品和业务线,毕竟大多数公司入职后做的都是二开工作,提前做重构/拆分的工作,让自己上手更快。
2.后续的细致计划
跟领导沟通过后,将公司的产品UI组件进行统一化处理,也就有了后续的UI组件化,mvp->mvvm,以及jetpack的引入,kt的转化。
WX20210331-142617@2x.png 1617172182269.jpg3.ARouter的引入
ARouter各位肯定不陌生,模块化拆分的项目中,ARouter可以方便解耦各个模块,例如:我们可以抽离出一个文件预览模块,其他模块如需要打开图片、文件等进行预览,我们只需要在base/common模块中编写一个RouterConfig。
WX20210331-143441@2x.png这里使用ARouter命令path时需要注意,module不要重名。如需了解更多ARouter使用,可以参考其他ARouter的文章。
4.Nexus发布
公司内部项目的lib一般存储在Nexus上,方便发布和引用。
// 引入maven工具
apply plugin: 'maven'
// 生成Javadoc文档
task androidJavadocs(type: Javadoc) {
source = android.sourceSets.main.java.srcDirs
classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
}
// 生成Javadoc文档jar包
task androidJavadocsJar(type: Jar, dependsOn: androidJavadocs) {
classifier = 'javadoc'
from androidJavadocs.destinationDir
}
// 防止编码问题
tasks.withType(Javadoc) {
options.addStringOption('Xdoclint:none', '-quiet')
options.addStringOption('encoding', 'UTF-8')
options.addStringOption('charSet', 'UTF-8')
}
// 生成源码文件jar包
task androidSourcesJar(type: Jar) {
classifier = 'sources'
from android.sourceSets.main.java.srcDirs
}
artifacts {
// 源码文件jar包执行命令
archives androidSourcesJar
// Javadoc文档jar包执行命令
archives androidJavadocsJar
}
tasks.getByPath(":base:androidJavadocs").enabled = false
// 上传命令
uploadArchives {
repositories {
mavenDeployer {
// url 私服仓库地址
repository(url: "仓库地址") {
// userName 私服仓库账号 password 私服仓库账号密码
authentication(userName: "仓库账号", password: "仓库密码")
}
pom.project {
name 'base'//base
version rootProject.ext.push.base//版本号
artifactId 'base'//最后下载的aar包名称就是这个
groupId '组id'// 建议使用包命
packaging 'aar'//打包类型
description '描述信息'// 描述信息
licenses {
license {
name 'The Apache Software License, Version 2.0'
url 'http://wiki.bidostar.com/pages/viewpage.action?pageId=3943695'
}
}
pom.withXml {
def dependenciesNode = asNode().appendNode('dependencies')
//Iterate over the compile dependencies (we don't want the test ones), adding a <dependency> node for each
configurations.api.allDependencies.each {
def dependencyNode = dependenciesNode.appendNode('dependency')
dependencyNode.appendNode('groupId', it.group)
dependencyNode.appendNode('artifactId', it.name)
dependencyNode.appendNode('version', it.version)
dependencyNode.appendNode('scope', 'api')
}
}
}
}
}
}
5.版本管理
既然模块化了,那么统一第三方lib的版本以及统一管理自有的lib就很重要,在根目录的build.gradle里进行统一管理即可。
WX20210331-144301@2x.png对于已有的模块项目进行版本统一管理
1617172968874.jpg//模块化引用时通过local参数判断是本地环境还是引用nexus版本
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
if (rootProject.ext.local) {
implementation project(':base')
} else {
implementation "xxx:base:$rootProject.ext.push.base"
}
复盘感想
回想刚入职自告奋勇的来实施这个模块化的计划,期间获得领导的支持,同事的帮助。尤其是另一位Android同事已经能自发的学习kt,自发的考虑重构代码,让我觉得点滴的努力都是值得。或许有人会觉得公司的项目没必要折腾搞这些,但是我认为有必要,节约出来的时间可以用来做更多,想更多。本期blow your mind的第一期就分享到这里。我知道我还有很多地方欠缺和不足,希望大佬看到能够指点一二,不胜感激。