Android 快速搭建组件化项目

155 阅读5分钟

前言

组件化并非Google官方严格定义的术语,但在国内比较流行,会搭建能更好顺应潮流。组件化是一种将系统拆分为独立、可复用模块的设计方法,旨在提升开发效率、系统灵活性和维护性。 描述摘自AI,能找到这里的彦祖亦菲,多少都了解过组件化的优点,这里不再赘述。下面直奔主体,实现一些AI做不到的内容,文章结尾附上源码。

Tips

注意:本文需要1~2年的开发基础,对模块化和 Android 目录组成有一定了解,不然有可能看不懂(能看到是最好)。

基础薄弱的同学,可以参考别的组件化文章。

最终效果

image.png

一、搭建环境

1.‌1 Android Studio

image.png

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(根据项目实际命名):

目录解释(目录根据公司项目需求及个人习惯命名,这里示例仅供参考)

  1. app壳 仅发布app作为一个壳,集成所有业务包,不要在这里做业务。如果项目用到Hilt, 需要在这里定义Application。
  2. business业务目录,为最上层,各个业务在这里完成,平级业务不能依赖,向下可以依赖lib或core,可以单独调试每个业务。
  3. lib库目录,为中间层,向上提供服务,平级库可以依赖,向下可以依赖core,但不能依赖business。
  4. core核心目录,为最低层,向上提供服务,平级最好不要依赖,避免出现环型依赖。不要向上依赖lib库, 更不能依赖business业务。
  5. buildSrc脚本目录,等下会解释这个目录的作用。
  6. templates模板目录,配合脚本使用。

image.png

2.2 项目结构

image.png

image.png

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)
    }
}

为了应用统一版本号,需要在一个地方统一定义版本号。三个地方供参考:

  1. 在root/build.gradle.kts文件中定义(本文使用方式):
project.ext.apply {
    set("compileSdk", 34)
    set("minSdk", 23)
    set("targetSdk", 34)
    set("versionCode", 1)
    set("versionName", "1.0.0")
}
  1. 在root/gradle/libs.versions.toml中定义:
[versions]
isDebug = "false"
compileSdk = "34"
minSdk = "23"
targetSdk = "34"
versionCode = "1"
versionName = "1.0.0"
  1. 在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文件中。

image.png

image.png

至此组件的基本配置完成,可以开始组件化的开发了。

四. 提高效率

文中只有三个实例,开发者手动复制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:包名

模块名和包名根据需求输入

回车,可以看到:

image.png 大约等45秒左右,命令执行成功:

image.png 可以看到 root/business/ 目录下多了一个 module_hello 业务模块:

image.png

Android Studio 运行这里也由原来的2个模块变为3个:

image.png

自动生成 module_hello 目录及文件效果:

image.png

生成Activity内容:

image.png

至此,一键生成模块也完成了。

core、lib 目录也可以照葫芦画瓢,自定义脚本一键生成。

五. 源码

GitHub:源码

考虑到国内上 GitHub 有困难, 特意安排了国内的云盘。

百度网盘:网盘

阿里云盘:云盘

总结

以上就是今天要讲的内容,本文介绍了组件化的搭建,而脚本能使我们快速便捷生成模块。