尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Android 架构 - 组件化 Modularzation(Kotlin版)
Groovy 语法迁移到 Kotlin DSLlibs.versions.toml 用法一、概念组件化是基于可重用目的对单个功能进行开发提升复用性降低耦合度。多个功能组件起来就是一个业务组件多个业务组件组合起来就是一个应用因此去除了模块间的耦合使得按业务划分的模块成了可单独运行的业务组件。组件化只是一定程度上的独立还是依附于整个项目中想完全独立详见插件化功能复用每个组件都是一个单独的功能可被不同的模块甚至不同的应用所使用。提高效率每个组件都是一个可单独编译运行的APP由于拆分使得代码量少调试起来快。协同开发组件之间相互独立使得不同的开发人员能专注于各自的功能开发互不影响。1.1 组件划分依赖关系是上层依赖下层修改频率是上层高于下层。对于业务组件由于存在页面跳转、方法调用、事件通信等问题需要使用路由通信其它层组件不存在耦合问题封装成 Library 即可。app壳应用的入口只依赖各业务组件不包含具体业务代码。将业务组件打包成一个APP做一些配置工作打包环境、签名、混淆等。业务组件module_XXX某个页面根据业务拆分的独立模块如主页模块、登录模块、商城模块。业务组件之间无直接关系通过路由进行通信。既可以作为 Application 单独编译运行调试又可作为 Library 集成到项目中。功能组件feature_XXX公共功能是对公用的功能进行封装与实现如网络请求、日志打印、地图、支付、广告。非必须层业务组件可以直接依赖基础组件去实现功能。基础组件lib_XXX最底层修改频率极低统一依赖配置和资源文件如引入第三方框架Retrofit、Glide、存放公用资源文件strings、drawable、自定义View、工具类Utils、实现路由ARouter。1.2 组件模式在 Module 的 build.gradle 中指定插件类型指定为集成模式Library可以被其它组件调用指定为独立模式Application可以单独运行调试。com.android.application项目构建后输出 apk 包在调试时是一个应用能单独编译运行。com.android.library项目构建后输出 aar 包在打包时是一个库文件集成到项目中。plugins { alias(libs.plugins.android.library) }1.3 创建组件File或在Project上右键→New→New Module。独立模式业务组件选择【Phone Tablet】集成模式功能组件、基础组件需要用到资源文件选【Android Library】纯代码选【Java or kotlin Library】。使用目录来聚合同类型组件使层次结构更清晰。语法是模块取名的时候使用“:library:lib_base”这样 lib_base 就在根目录的 library 下了。二、统一配置2.1 动态模式切换在 TOML 的节点 [versions] 中定义属性 isDebug false 用于后续在业务组件中读取来动态切换组件模式true为组件模式会编译成Applicationfalse为集成模式会编译成Library同步一下后就可以在每个组件的 build.gradle 中读取并做相应的动态处理。见下方5.5[versions] isDebug false2.2 抽取 build.gradle 中相同的配置组件中有很多相同的配置分别抽成【commonMoudle.gradle】【commonLib.gradle】 文件并在对应组件中引入就可以删除重复的配置了。2.2.1 抽取在项目上右键→New→File→命名为“commonModule.gradle.kts”。commonMoudle提供组件模式的切换剔除各个 module 组件专有的 namespace、applicationId 属性。commonLib剔除各个 lib 组件专有的 namespace 属性。12.2.2 引入在每个组件的 build.gradle 中引入写在顶部。apply(from $rootDir/commonModule.gradle)三、基础组件将一直作为 Library 存在app壳和所有的业务组件都依赖它主要封装公共功能网络请求、数据存储、自定义控件、工具类、版本管理和统一第三方依赖。3.1 创建 lib_base 组件3.2 提供 BaseApplication其它组件都依赖于 lib_base因此在其中提供一个全局的 BaseApplication 供其它组件在代码中使用需要获取全局上下文的时候就使用这个BaseApplication所有资源的初始化也在这里。在集成模式Library中使用不需要注册在App壳和组件模式Application中需要自定义一个类继承 BaseApplication 后注册到 AndroidManifest 中使得从 BaseApplication 中获取的全局上下文生效还有初始化数据之用。组件所处的模式引入后如何使用集成模式Library直接使用 BaseApplication不是应用不需要注册。独立模式Application在 debug 文件夹中创建一个子类继承自 BaseApplication 然后注册到 debug 文件夹中的 AndroidManifest 中不需要使用自己定义的就注册为 BaseApplication。app壳创建一个子类继承自 BaseApplication 然后在 AndroidManifest 中注册不需要使用自己定义的就注册为 BaseApplication 。open class App : Application() { companion object { SuppressLint(StaticFieldLeak) //注解忽略警告 lateinit var context: Context private set } override fun onCreate() { super.onCreate() context applicationContext //在APP创建的时候就赋值 } }3.3 提供权限声明 AndroidManifest声明了项目中用到的所有权限这样其它组件就无需在自己的 AndroidManifest.xm 声明自己要用到的权限了。?xml version1.0 encodingutf-8? manifest xmlns:androidhttp://schemas.android.com/apk/res/android uses-permission android:nameandroid.permission.ACCESS_NETWORK_STATE / uses-permission android:nameandroid.permission.INTERNET/ /manifest3.4 提供依赖 build.gradle统一所有组件中用到的第三方库和jar包。使用 imlemntation 添加的依赖只对当前组件有效使用 api 添加的依赖对其上层组件同样有效这样依赖于基础组件的组件就不用再添加相同的依赖了。项目中某个组件会被其它组件重复依赖在集成构建应用时 Gradle 会自动剔除重复的 arr 包这样就不会存在好几份重复的代码了。而第三方库和我们的项目可能都依赖了相同的库例如 Glide 中也依赖了 OkHttp就会导致重复加载解决办法是找出相同的库根据组件名或包名排除。仅用于当前组件可向上传递引入这个组件的上层组件不用重复添加依赖项implementationapitestImplementationtestApiandroidTestImplementationandroidTestApidebugImplementationdebugApi[versions] agp 8.13.1 kotlin 2.3.0 coreKtx 1.16.0 junit 4.13.2 junitVersion 1.1.5 espressoCore 3.5.1 lifecycleRuntimeKtx 2.10.0 composeActivity 1.12.0 composeBom 2025.12.00 [libraries] #Compose compose-bom { module androidx.compose:compose-bom, version.ref composeBom } compose-material3 { module androidx.compose.material3:material3 } #预览 compose-ui-tooling { module androidx.compose.ui:ui-tooling } compose-ui-tooling-preview { module androidx.compose.ui:ui-tooling-preview } #测试 compose-ui-test-junit4 { module androidx.compose.ui:ui-test-junit4 } compose-ui-test-manifest { module androidx.compose.ui:ui-test-manifest } #可选 compose-activity { module androidx.activity:activity-compose, version.ref composeActivity } #其它 androidx-core-ktx { module androidx.core:core-ktx, version.ref coreKtx } androidx-lifecycle-runtime-ktx { module androidx.lifecycle:lifecycle-runtime-ktx, version.ref lifecycleRuntimeKtx } androidx-junit { module androidx.test.ext:junit, version.ref junitVersion } androidx-espresso-core { module androidx.test.espresso:espresso-core, version.ref espressoCore } junit { module junit:junit, version.ref junit } [plugins] android-application { id com.android.application, version.ref agp } android-library { id com.android.library, version.ref agp } kotlin-android { id org.jetbrains.kotlin.android, version.ref kotlin } kotlin-compose { id org.jetbrains.kotlin.plugin.compose, version.ref kotlin }dependencies { //Compose //物料清单 api(platform(libs.compose.bom)) androidTestApi(platform(libs.compose.bom)) //主题 api(libs.compose.material3) //预览 api(libs.compose.ui.tooling.preview) debugImplementation(libs.compose.ui.tooling) //UI测试 androidTestImplementation(libs.compose.ui.test.junit4) debugImplementation(libs.compose.ui.test.manifest) //可选 api(libs.compose.activity) //默认 api(libs.androidx.core.ktx) api(libs.androidx.lifecycle.runtime.ktx) testApi(libs.junit) androidTestApi(libs.androidx.junit) androidTestApi(libs.androidx.espresso.core) }3.4.1 处理 jar 包 aar 包依赖一般依赖的都是 Maven 仓库如果提供的是 aar、jar 文件第一行添加如下代码引入。dependencies { api(fileTree(mapOf(dir to libs, include to listOf(*.jar, *.aar)))) }3.5 提供公共资源自定义的类Utils、Base、Constants、Ext、Widgets、res资源目录drawable、strings、通用业务Retrofit、通用配置等都应该放在这里。四、功能组件3.1 创建 feature_common 组件3.2 引入基础组件 lib_basedependencies { api(project(:library:lib_base)) }五、业务组件5.1 创建 module_main 组件现在都是单 Activity 的应用开发创建的时候选 NoActivity。5.2 创建 debug 包在业务组件根目录中创建 debug 包用于存放只在独立模式下使用的文件在集成模式下会被剔除不参与打包。在业务组件的 src/main/java 目录上右键→New→Package。不推荐在组件的其它层级上创建目录存放切换到Android视图不会显示5.2.1 自定义 Application有的业务组件需要被传入数据或是用到的资源需要初始化自定义一个 TestApplication 继承 lib_base 中提供的 BaseApplication。如果用不到就直接把 BaseApplication 注册。class MyApp : App() {}5.2.2 自定义入口 LauncherActivity现在都是单 Activity 的应用开发业务模块在独立模式下需要有 Activity 承载显示因此 debug 包下创建一个 LauncherActivity。class LauncherActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) enableEdgeToEdge() setContent { MsgScreen() } } }5.2.3 两份 AndroidManifest处于独立模式时需要为了application标签配置、自定义Application 、启动入口 Activity 而在 AndroidManifest 中进行注册但在集成模式下打包到一起时存在重复和冲突如桌面上好几个启动图标、只能注册一个自定义的Application、同一个权限无须多次申请。将自动创建的 AndroidManifest 复制一份到 debug 包下对 manifest 标签添加 package 属性指定为组件的包名将 .MainActivity 改成自定义的启动Activity。然后像单工程那样用就行。再修改自动创建的 AndroidManifest也对 manifest 标签添加 package 属性指定为组件的包名。若该业务组件不是程序入口将 application 的属性和子标签都删除只存放四大组件的注册。5.3 修改 build.gradle根据在 TOML 中定义的 isDebug 来动态切换插件模式、设置applicationId、加载AndroidManifest。引入需要功能组件。5.3.1 动态切换组件模式plugins { if (libs.versions.isDebug.get().toBoolean()) { alias(libs.plugins.android.application) } else { alias(libs.plugins.android.library) } }5.3.2 动态设置 applicationId这里会提示找不到 applicationId、versionCode、versionName注释掉能正常执行。20260112android { defaultConfig { if (libs.versions.isDebug.get().toBoolean()) { applicationId com.example.module_main } } }5.3.3 动态加载 AndroidManifest这里剔除 debug 包下文件有问题用了AI也找不到相应语法报错方法不正确。20260112sourceSets { named(main) { if (isDebug) { manifest.srcFile(src/main/java/debug/AndroidManifest.xml) } else { manifest.srcFile(src/main/AndroidManifest.xml) } } }5.3.4 引入需要的功能模块dependencies { implementation(project(:library:lib_base)) }六、搬空 app 壳6.1 搬运程序入口 MainActivity将 app 中的 MainActivity.class 和 activity_main.xmlCompose没有这个 剪切至 module_main 中。将 AndroidManifest 中的 MainActivity 注册包含程序入口也剪切至 module_core 中只保留 application 标签。6.2 搬运资源目录 res将 app 中的整个 res 目录剪切至 lib_base 中。6.3 自定义 Application需要用到就自定义一个 MyApp 继承 lib_base 中提供的 BaseApplication用不到就直接把 BaseApplication 注册。6.4 修改 AndroidManifestapplication标签的属性都是在app壳配置的而其它组件也会有自己的清单在集成模式下最终会打包合并成一个文件需要解决属性重复在上面5.4中用于集成模式的AndroidManifest的application标签并不会进行配置但还是会配置theme分别对 app 的 manifest 和 application 添加如下代码。manifestxmlns:toolshttp://schemas.android.com/toolsapplicationtools:replaceandroid:name,android:label,android:icon,android:theme,android:allowBackup?xml version1.0 encodingutf-8? manifest xmlns:androidhttp://schemas.android.com/apk/res/android xmlns:toolshttp://schemas.android.com/tools application android:namecom.example.lib_base.App android:allowBackuptrue android:dataExtractionRulesxml/data_extraction_rules android:fullBackupContentxml/backup_rules android:iconmipmap/ic_launcher android:labelstring/app_name android:roundIconmipmap/ic_launcher_round android:supportsRtltrue android:themestyle/Theme.WAModularization tools:replaceandroid:name,android:label,android:icon,android:theme,android:allowBackup /application /manifest6.5 修改 build.gradle应用的打包签名、buildTypes、defaultConfig 都需要在这里配置而它的 dependencies 则需要根据 isDebug 的值分别依赖不同的组件在独立模式下app壳只需要依赖 lib_common 组件在集成模式下必须依赖所有声明的业务组件。当需要同时引入好几个组件时可以像“分组”一样一次性引入避免每次新建组件引入多个其他组件的时候出错。像多渠道打包、测试某几个固定组件协同时使用。dependencies { implementation(project(:library:lib_base)) if (!libs.versions.isDebug.get().toBoolean()) { implementation(project(:module:module_main)) } }
RELATED

相关推荐

腾讯混元A13B:800亿参数模型如何用130亿算力实现行业突破?

腾讯混元A13B:800亿参数模型如何用130亿算力实现行业突破?

腾讯混元A13B:800亿参数模型如何用130亿算力实现行业突破? 导语 腾讯开源大语言模型Hunyuan-A13B-Instruct-GGUF以创新MoE架构实现效率革命,800亿总参数仅激活130亿即可媲美全量模型性能,为企业级AI部署提供资源友好型解决方案。 …

📅 2026/10/30 1:44:47
高校生鲜配送系统:轻量级SpringBoot+Vue冷链接闭环方案

高校生鲜配送系统:轻量级SpringBoot+Vue冷链接闭环方案

简介:高校社区生鲜配送系统是一套面向大学生及周边居民的轻量级在线生鲜电商解决方案,适用于Java Web课程设计、毕业设计或中小型校园O2O项目实践,聚焦用户管理、商品调度、订单履约与本地化配送等核心业务闭环。资源包共909个文件&#xff0…

📅 2026/10/30 1:44:47
小体量项目为什么能稳住增长:从单路信号到社区讨论的传导链

小体量项目为什么能稳住增长:从单路信号到社区讨论的传导链

小体量项目为什么能稳住增长:从单路信号到社区讨论的传导链 【免费下载链接】bama BAMA: Build Any Mac App. Agent skills to research, clone, design, build, optimize, and test native macOS apps with Swift and SwiftUI. 项目地址: https://gitcode.com/gh…

📅 2026/10/30 1:44:47
MORE NEWS

更多资讯

📰

滑动窗口的使用(一)

一、长度最小的子数组 209. 长度最小的子数组 - 力扣&#xff08;LeetCode&#xff09; class Solution { public:int minSubArrayLen(int target, vector<int>& nums) {int n nums.size();int sum 0;int len INT_MAX;int t 0;for(int left 0, right 0;right …

📰

FileLocator Pro v9.3.3566:免索引全文搜索+压缩包内容扫描+正则布尔,安装包下载

电脑里文件越来越多&#xff0c;记不清文件名的情况我遇到过不少。只记得文档里的一句话&#xff0c;却翻不到在哪&#xff0c;很烦。FileLocator Pro 就是解决这个问题的。它不用提前建索引&#xff0c;直结对文件内容做全文搜索。Word、PDF 甚至压缩包里的文字都能扫出来&…

📰

STM32MP2 Developer Package(stm32mp-openstlinux-6.6-yocto-scarthgap-mpu-v26.06.10) - (2)

更新证书 阿里云 python3 scripts/signaling_server.py --host 0.0.0.0 --port 9000 cat /etc/nginx/ssl/cam.crtmkdir -p /usr/local/share/ca-certificates/ cp /home/root/cam.crt /usr/local/share/ca-certificates/update-ca-certificatesdeveloper developer#!mkdir Dist…

📰

我的Token根本用不完

Magpie&#xff1a;让多个 AI 编程助手共用一套模型管理入口 文章目录Magpie&#xff1a;让多个 AI 编程助手共用一套模型管理入口项目链接演示在这里插入图片描述Magpie&#xff1a;让多个 AI 编程助手共用一套模型管理入口一、它能解决什么问题&#xff1f;二、本地网关&…

📰

【Quectel Pi M2 实战】Day1 开箱:双开发板对比,硬件初识与上电准备

【Quectel Pi M2 实战】Day1 开箱&#xff1a;双开发板对比&#xff0c;硬件初识与上电准备 目录 【Quectel Pi M2 实战】Day1 开箱&#xff1a;双开发板对比&#xff0c;硬件初识与上电准备 前言 一、开发板简介 1.1 Quectel Pi M2介绍 1.2 与UniKnect Gen1 Pro对比 二…

📰

小白程序员必看:收藏这份AI大模型学习指南,轻松掌握核心概念与实战技巧

本文深入浅出地解释了Agent、Skill、MCP、CLI、Model这五个AI核心概念之间的关系及调用逻辑&#xff0c;并针对企业老系统提出了AI应用的三大改造路径&#xff1a;API封装、CLI包装、RPA兜底。文章还详细介绍了MCP的实现形式及其分类&#xff0c;并辅以BS和CS架构的实战案例&am…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬