前言
工作中我们遇见过很多项目,或许每个项目的优点你都想借鉴,每个项目的缺点你总想优化。但很多时候,牵一发而动全身,于是继续采用了不变应万变的策略。
怎样才是现代Android最佳实践的方式,每个人都有自己的标准和答案。
本次环境为Android Studio Giraffe2022.3.1
考虑的一些方面
组件化,模块化,降低代码耦合,业务耦合
组件化的层级与模块划分每个公司可能需求不一样,见过的好的模块层级可以是以下几个层级,参照下面的部分描述:
yangchong211/YCAppTool: 组件化综合案例,组件分层为:基础公共组件,功能组件,业务组件,主工程。 (github.com)
-
主工程(壳工程代码,多favor,debug助手等):
- 除了一些全局配置和主 Activity 之外,不要包含太多的业务代码。有的也叫做空壳app,主要是依赖业务组件进行运行。
-
业务组件(主要是业务层拆分的组件):
- 最上层的业务,每个组件表示一条完整的业务线,彼此之间互相独立。原则上来说:各个业务组件之间不能有直接依赖!对于测试的时候,需要依赖多个业务组件的功能进行集成测试的时候。可以使用app壳进行多组件依赖管理运行。
-
功能组件(分为服务组件和中台组件):
- 该案例中分为,登录注册组件,分享组件,支付组件,Hybrid组件等等。同时注意,可能会涉及多个业务组件对某个功能组件进行依赖!
-
基础组件(分为工具组件和视图组件,这部分完全和业务无关):
- 支撑上层业务组件运行的基础业务服务。此部分组件为上层业务组件提供基本的功能支持。基础组件库中主要有,网络请求,图片加载,通信机制,工具类,自定义控件等等。
本工程中的预计设计为:
为了层级清晰,将对应模块放在了对应层级的子目录,后面模块多的时候也便于区分。
gradle版本管理TOML文件
项目采用koltin
版本的gradle
脚本, 常见的方式之一在settings.gradle.kts
中使用versionCatalogs
,libs
可以换成你喜欢的名字,甚至同级别你可以创建多个,只要名字不一样就行。
gradle
include(":app")
include(":hideapi")
pluginManagement {
repositories {
mavenLocal()
mavenCentral()
gradlePluginPortal()
}
}
dependencyResolutionManagement {
versionCatalogs {
create("libs") {
val agp = "7.2.0"
val appcompat = "1.4.1"
library("build-android", "com.android.tools.build:gradle:$agp")
library("androidx-appcompat", "androidx.appcompat:appcompat:$appcompat")
}
}
}
另外一种是使用toml文件,在gradle目录下libs.version.toml
文件管理依赖
文件内容可以包含version,libraries,plugins,bundles 更详细的说明,使用规则参照 Sharing dependency versions between projects (gradle.org)官方文档
使用自定义plugin减少模块内容
由于我们拆分的层级和模块,数量可能很多,每个模块的gradle脚本很大概率出现大量相同的模板内容,一不小心还可能不统一。比如:
gradle
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
android {
// lots of boilerplate
}
tasks.withType(KotlinCompile).configureEach {
kotlinOptions {
jvmTarget = JavaVersion.VERSION_11
}
}
现在可以考虑一种新的方式
gradle
plugins {
id("newandroid.android.application")
}
为了实现这个目标,新建一个build-logic
文件夹,里面定义了特定于本项目的约定插件,用于为通用模块配置保留单一的事实来源。大致结构如下:
核心是在build.gradle.kts中注册自定义插件的实现类;
使用根目录下的build.gradle.kts减少配置的一种方式
除了上面使用自定义的plugin方式减少配置,另一种方式是可以在根目录下的build.gradle.kts
添加如下内容。
子模块作为app调试的能力
如果是groovy脚本,过去我通常使用gradle properties属性控制,如果为true,就 apply buildAsApp.gradle
文件方式,但是使用kts格式,apply文件后会出现找不到一些引用值。所以解决方案可能在同一个kts文件下判断。然后设置对应的Manifest和源码目录。
最后
- 技术永远在进步,没有最好的方案。不断吸取优点改进加以运用就是好的。
- 代码仓库/new-android (github.com),还没想好主要工程内容,后面会慢慢增加模块代码。