前言
组件化并非Google官方严格定义的术语,但在国内比较流行,会搭建能更好顺应潮流。组件化是一种将系统拆分为独立、可复用模块的设计方法,旨在提升开发效率、系统灵活性和维护性。 描述摘自AI,能找到这里的彦祖亦菲,多少都了解过组件化的优点,这里不再赘述。下面直奔主体,实现一些AI做不到的内容,文章结尾附上源码。
Tips
注意:本文需要1~2年的开发基础,对模块化和 Android 目录组成有一定了解,不然有可能看不懂(能看到是最好)。
基础薄弱的同学,可以参考别的组件化文章。
最终效果
一、搭建环境
1.1 Android Studio
1.2 Gradle 版本
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
1.3 开发语言:Kotlin
二、项目结构
2.1 目录
新建一个项目,项目名称如Example2025(根据项目实际命名):
目录解释(目录根据公司项目需求及个人习惯命名,这里示例仅供参考)
- app壳 仅发布app作为一个壳,集成所有业务包,不要在这里做业务。如果项目用到Hilt, 需要在这里定义Application。
- business业务目录,为最上层,各个业务在这里完成,平级业务不能依赖,向下可以依赖lib或core,可以单独调试每个业务。
- lib库目录,为中间层,向上提供服务,平级库可以依赖,向下可以依赖core,但不能依赖business。
- core核心目录,为最低层,向上提供服务,平级最好不要依赖,避免出现环型依赖。不要向上依赖lib库, 更不能依赖business业务。
- buildSrc脚本目录,等下会解释这个目录的作用。
- templates模板目录,配合脚本使用。
2.2 项目结构
2.3 关键代码
组件化关键代码是root/business/module_xxx/build.gradle.kts。 isDebug 开关决定是作为单独应用,还是作为库。
plugins {
if (libs.versions.isDebug.get().toBoolean()) {
alias(libs.plugins.android.application)
} else {
alias(libs.plugins.android.library)
}
}
为了应用统一版本号,需要在一个地方统一定义版本号。三个地方供参考:
- 在root/build.gradle.kts文件中定义(本文使用方式):
project.ext.apply {
set("compileSdk", 34)
set("minSdk", 23)
set("targetSdk", 34)
set("versionCode", 1)
set("versionName", "1.0.0")
}
- 在root/gradle/libs.versions.toml中定义:
[versions]
isDebug = "false"
compileSdk = "34"
minSdk = "23"
targetSdk = "34"
versionCode = "1"
versionName = "1.0.0"
- 在root/version_info.properties,version_info.properties文件需要手动创建:
compileSdk=34
minSdk=23
targetSdk34
versionCode1
versionName1.0.0
以上三个方案中,只需选其中一个即可。 然后在root/business/module_xxx/build.gradle.kts中作如下配置: (配置需要根据选用的方案获取版本值)
android {
namespace = "com.example.home_module"
compileSdk = rootProject.ext["compileSdk"] as Int
defaultConfig {
if (libs.versions.isDebug.get().toBoolean()) {
defaultConfig.applicationId = "com.example.home"
defaultConfig.versionCode = project.properties["versionCode"] as Int
defaultConfig.versionName = project.properties["versionName"].toString()
}
minSdk = rootProject.ext["minSdk"] as Int
targetSdk = rootProject.ext["targetSdk"] as Int
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
}
注意:isDebug 为 false 时,即作为库使用时,属性 applicationId、versionCode 、versionName 编译出错,AI给出的方案有误,出现AI幻觉。最后通过查看libs.plugins.android.library源码,这三属性都被移除了,查看源码后,在属性前加defaultConfig解决,编译顺利通过。 business间路由跳转,用的是货拉拉的TheRouter, 用法跟阿里的ARouter差不多,为什么不用ARouter呢? 因为ARouter不维护了,对kts支持不足, 货拉拉的TheRouter是更好的平替。
三.效果
通过 isDebug 不同赋值 (true / false), 效果如下: isDebug 定义在root/gradle/libs.versions.toml文件中。
至此组件的基本配置完成,可以开始组件化的开发了。
四. 提高效率
文中只有三个实例,开发者手动复制root/business/module_xxx还行。但是实际开发中, 项目中往往有十几个甚至几十个业务,手动复制就显得力不从心。如果改漏一些属性,导致出现一些难发现的bug,如同名资源覆盖, 最后问题排查起来费时费力。 这时需要用到脚本, 帮我们一键完成module_xxx的创建,开发者只需关心业务即可。 前面目录介绍留下了伏笔, buildSrc为脚本目录,本文选择Gradle 的Task作为脚本,配合templates里面的模板文件,自动生成文件、 目录,其中脚本已经配置好,用户可以直接输入命令使用。用户可根据自身需求如MVP、MVVM、MVI修改模板文件里面的代码,本文用的是MVI做示例。
4.1 如何使用脚本
在Terminal窗口中, 输入命令:
./gradlew gm -PmodName=hello -PpackName="com.example.hello"
命令解释:
gm:generate module (生成模块)
-PmodName:模块名
-PpackName:包名
模块名和包名根据需求输入
回车,可以看到:
大约等45秒左右,命令执行成功:
可以看到 root/business/ 目录下多了一个 module_hello 业务模块:
Android Studio 运行这里也由原来的2个模块变为3个:
自动生成 module_hello 目录及文件效果:
生成Activity内容:
至此,一键生成模块也完成了。
core、lib 目录也可以照葫芦画瓢,自定义脚本一键生成。
五. 源码
GitHub:源码
考虑到国内上 GitHub 有困难, 特意安排了国内的云盘。
百度网盘:网盘
阿里云盘:云盘
总结
以上就是今天要讲的内容,本文介绍了组件化的搭建,而脚本能使我们快速便捷生成模块。