Android笔记:Android 组件化方案探索与思考
组件化项目,通过gradle脚本,实现module在编译期隔离,运行期按需加载,实现组件间解耦,高效单独调试。
先来一张效果图
组件化初衷
- APP版本不断的迭代,新功能的不断增加,业务也会变的越来越复杂,维护成本高。
- 业务耦合度高,代码越来越臃肿,团队内部多人协作开发困难。
- Android项目在编译代码的时候电脑会非常卡,又因为单一工程下代码耦合严重,每修改一处代码后都要重新编译打包测试,导致非常耗时。
- 方便单元测试,改动单独一个业务模块,不需要着重于关注其他模块被影响。
什么是组件化
组件化就是将一个app分成多个Module,如下图,每个Module都是一个组件(也可以是一个基础库供组件依赖),开发的过程中我们可以单独调试部分组件,组件间不需要互相依赖,但可以相互调用,最终发布的时候所有组件以lib的形式被主app工程依赖并打包成一个apk。
组件化优势
- 组件化就是将通用模块独立出来,统一管理,以提高复用,将页面拆分为粒度更小的组件,组件内部除了包含UI实现,还包含数据层和逻辑层。
- 每个工程都可以独立编译、加快编译速度,独立打包。
- 每个工程内部的修改,不会影响其他工程。
- 业务库工程可以快速拆分出来,集成到其他App中。
- 迭代频繁的业务模块采用组件方式,业务线研发可以互不干扰、提升协作效率,并控制产品质量,加强稳定性。
- 并行开发,团队成员只关注自己的开发的小模块,降低耦合性,后期维护方便等。
指导思想
- 组件拆分:将一个project划分成业务组件、基础组件、路由组件。其中业务组件是相互隔离的,可以单独调试,基础组件提供业务组件所公用的功能,路由组件为业务组件之间通信提供支持。
- 组件隔离:业务组件之间的隔离,可以单独调试。
- 核心法则:编译期隔离,运行期按需依赖。
依赖关系
组件化需要考虑的问题
- 模式切换:如何使得APP在单独调试跟整体调试自由切换
- 资源冲突:当我们创建了多个Module的时候,如何解决相同资源文件名合并的冲突
- 依赖关系:多个Module之间如何引用一些共同的library以及工具类
- 组件通信:组件化之后,Module之间是相互隔离的,如何进行UI跳转以及方法调用
- 入口参数:我们知道组件之间是有联系的,所以在单独调试的时候如何拿到其它的Module传递过来的参数
组件化后项目结构如下图
理论说了那么多,下面开始撸代码
实现步骤
1、全局设置Gradle,每一个业务Module需要的版本都定义在这里方便后期维护多个Module版本号
ext {// Sdk and toolsminSdkVersion = 16targetSdkVersion = 26compileSdkVersion = 26buildToolsVersion = '26.0.2'supportLibraryVersion = '26.1.0'// App dependenciesaRouter = '1.2.2'leakcanaryVersion = '1.3'glideVersion = '3.7.0'
}####每个业务Module编译依赖版本compileSdkVersion rootProject.ext.compileSdkVersionbuildToolsVersion rootProject.ext.buildToolsVersionminSdkVersion rootProject.ext.minSdkVersiontargetSdkVersion rootProject.ext.targetSdkVersion
2、模式切换
组件化后的每一个业务的module都可以是一个单独的APP(isModuleRun=false)
, release 包的时候各个业务module作为lib依赖,这里完全由一个变量控制,在根项目 gradle.properties
里面的 isModuleRun=true
。
isModuleRun状态不同,加载application和AndroidManifest都不一样,以此来区分是独立的APK还是lib, 实现方式如下 在build.grade
里面配置
if (isModuleRun.toBoolean()) {apply plugin: 'com.android.application'
} else {apply plugin: 'com.android.library'
}##单Module运行需要配置
sourceSets {main {if (isModuleRun.toBoolean()) {manifest.srcFile 'src/main/debug/AndroidManifest.xml'} else {manifest.srcFile 'src/main/AndroidManifest.xml'java {//全部Module一起编译的时候剔除debug目录exclude '**/debug/**'}}}}
3、资源冲突
业务Module和BaseModule资源文件名称重复会产生冲突,解决方案在 每个 module 都有 app_name,为了不让资源名重名,在每个组件的 build.gradle 中增加 resourcePrefix “xxx_
强行检查资源名称前缀。 固定每个组件的资源前缀。但是 resourcePrefix 这个值只能限定 xml 里面的资源,并不能限定图片资源。 个人认为约定大于配置,团队内协定好规范,可以避免冲突。
4、组件通讯 组件通讯框架在github上有star最多的有ARouter和ActivityArouter,前者是个人项目,后者是阿里巴巴开源,权衡之下选择阿里的ARouter, 各业务Module之前不需要任何依赖可以通过路由跳转,完美解决业务之间耦合 使用方式如下。
if (BuildConfig.DEBUG) { // 这两行必须写在init之前,否则这些配置在init过程中将无效ARouter.openLog(); // 打印日志ARouter.openDebug(); // 开启调试模式(如果在InstantRun模式下运行,必须开启调试模式!线上版本需要关闭,否则有安全风险)}
ARouter.init(this); // 尽可能早,推荐在Application中初始化
compile "com.alibaba:arouter-api:$rootProject.aRouter"
每个业务Module都需要添加注解
annotationProcessor 'com.alibaba:arouter-compiler:1.1.3'
跳转方法 在目标Activity上添加path
@Route(path = ARouterManager.BModuleActivity)
public class BModuleActivity extends BaseActivity {@Autowiredpublic String name;@Autowired(name = "age")int age;TextView txt;@Overrideprotected int getLayoutId() {return R.layout.b_module_layout;}@Overrideprotected void initView() {txt = findViewById(R.id.txt);//String name = getIntent().getStringExtra("name"); 也可以这样接受参数ARouter.getInstance().inject(this);txt.setText("name:" + name + ",age:" + age);#开始跳转btn2.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {// 2\. 跳转并携带参数ARouter.getInstance().build(ARouterManager.BModuleActivity).withString("name", "888").withInt("age", 11).navigation();}});
/*** 路由管理类*/public final class ARouterManager {public static final String AFragment = "/amodule/AFragment";public static final String BFragment = "/bmodule/BFragment";public static final String CFragment = "/cmodule/CFragment";public static final String AModuleActivity = "/amodule/AAModuleActivity";public static final String BModuleActivity = "/bmodule/BModuleActivity";public static final String CModuleActivity = "/cmodule/CModuleActivity";}
上述只使用了ARouter的简单用法,更多进阶用法请参考ARouter文档, ARouter
5、Application
当组件单独运行的时候,每个Module自成一个APK,那么就意味着会有多个Application,很显然我们不愿意重复写这么多代码,所以我们只需要定义一个BaseApplication即可,其它的Application直接继承此BaseApplication就OK了,BaseApplication里面还可定义公用的参数。
更多Android进阶指南 可以扫码 解锁 《Android十大板块文档》
1.Android车载应用开发系统学习指南(附项目实战)
2.Android Framework学习指南,助力成为系统级开发高手
3.2023最新Android中高级面试题汇总+解析,告别零offer
4.企业级Android音视频开发学习路线+项目实战(附源码)
5.Android Jetpack从入门到精通,构建高质量UI界面
6.Flutter技术解析与实战,跨平台首要之选
7.Kotlin从入门到实战,全方面提升架构基础
8.高级Android插件化与组件化(含实战教程和源码)
9.Android 性能优化实战+360°全方面性能调优
10.Android零基础入门到精通,高手进阶之路
敲代码不易,关注一下吧。ღ( ´・ᴗ・` ) 🤔
相关文章:
Android笔记:Android 组件化方案探索与思考
组件化项目,通过gradle脚本,实现module在编译期隔离,运行期按需加载,实现组件间解耦,高效单独调试。 先来一张效果图 组件化初衷 APP版本不断的迭代,新功能的不断增加,业务也会变的越来越复杂…...
MeterSphere v2.10.X-lts 双节点HA部署方案
一、MeterSphere高可用部署架构及服务器配置 1.1 服务器信息 序号应用名称操作系统要求配置要求描述1负载均衡器CentOS 7.X /RedHat 7.X2C,4G,200GB部署Nginx,实现负载路由。 部署NFS服务器。2MeterSphere应用节点1CentOS 7.X /RedHat 7.X8C,16GB,200G…...
Java进阶篇--网络编程
目录 计算机网络体系结构 什么是网络协议? 为什么要对网络协议分层? 网络通信协议 TCP/IP 协议族 应用层 运输层 网络层 数据链路层 物理层 TCP/IP 协议族 TCP的三次握手四次挥手 TCP报文的头部结构 三次握手 四次挥手 …...
PyTorch入门之【CNN】
参考:https://www.bilibili.com/video/BV1114y1d79e/?spm_id_from333.999.0.0&vd_source98d31d5c9db8c0021988f2c2c25a9620 书接上回的MLP故本章就不详细解释了 目录 traintest train import torch from torchvision.transforms import ToTensor from torchvi…...
马斯洛需求层次模型之安全需求之云安全浅谈
在互联网云服务领域,安全需求是用户首要考虑的因素之一。用户希望在将数据和信息托付给云服务提供商时,这些数据和信息能够得到充分的保护,避免遭受未经授权的访问、泄露或破坏。这种安全需求的满足,对于用户来说是至关重要的&…...
Pikachu靶场——远程命令执行漏洞(RCE)
文章目录 1. RCE1.1 exec "ping"1.1.1 源代码分析1.1.2 漏洞防御 1.2 exec "eval"1.2.1 源代码分析1.2.2 漏洞防御 1.3 RCE 漏洞防御 1. RCE RCE(remote command/code execute)概述: RCE漏洞,可以让攻击者直接向后台服务器远程注入…...
【WSN】无线传感器网络 X-Y 坐标到图形视图和位字符串前缀嵌入方法研究(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
Linux定时任务
文章目录 前言设置定时任务流程定时规则例子 终止定时任务列出当前的定时任务重启任务调度 前言 在Linux系统中有时侯需要周期性的自动执行一些命令,这时候Linux定时任务就派上用场了 设置定时任务流程 进入定时任务的编辑模式 crontab -e编辑定时任务ÿ…...
【Overload游戏引擎分析】画场景网格的Shader
Overload引擎地址: GitHub - adriengivry/Overload: 3D Game engine with editor 一、栅格绘制基本原理 Overload Editor启动之后,场景视图中有栅格线,这个在很多软件中都有。刚开始我猜测它应该是通过绘制线实现的。阅读代码发现࿰…...
【JavaEE】多线程进阶(一)饿汉模式和懒汉模式
多线程进阶(一) 文章目录 多线程进阶(一)单例模式饿汉模式懒汉模式 本篇主要引入多线程进阶的单例模式,为后面的大冰山做铺垫 代码案例介绍 单例模式 非常经典的设计模式 啥是设计模式 设计模式好比象棋中的 “棋谱”…...
C++树详解
树 树的定义 树(Tree)是n(n≥0)个结点的有限集。n0时称为空树。在任意一颗非空树中:①有且仅有一个特定的称为根(Root)的结点;②当n>1时,其余结点可分为m(…...
支付环境安全漏洞介绍
1、平台支付逻辑全流程分析 2、平台支付漏洞如何利用?买东西还送钱? 3、BURP抓包分析修改支付金额,伪造交易状态? 4、修改购物车参数实现底价购买商品 5、SRC、CTF、HW项目月入10W副业之路 6、如何构建最适合自己的网安学习路线 1…...
抄写Linux源码(Day16:内存管理)
回忆我们需要做的事情: 为了支持 shell 程序的执行,我们需要提供: 1.缺页中断(不理解为什么要这个东西,只是闪客说需要,后边再说) 2.硬盘驱动、文件系统 (shell程序一开始是存放在磁盘里的,所以需要这两个东…...
Cookie和Session详解以及结合生成登录效果
目录 引言 1.Cookie中的数据从哪来数据长啥样? 2.Cookie有什么作用? 3.cookie与session的工作关联? 4.Cookie到哪去? 5.Cookie如何存? 6.Session 7.Cookie与Session的关联与区别 8.通过代码理解 8.1 相关代码 8.2…...
Spring基础以及核心概念(IoC和DIQ)
1.Spring是什么 Spring是包含了众多工具方法的IoC容器 2.loC(Inversion of Control )是什么 IoC:控制反转,Spring是一个控制反转容器(控制反转对象的生命周期) Spring是一个loC容器,我们之前学过的List/Map就是数据存储的容器,to…...
《C和指针》笔记32:多维数组初始化
文章目录 使用括号进行初始化初始化省略维度 使用括号进行初始化 我们可以给数组赋值一个长长的列表: int matrix[2][3] { 100, 101, 102, 110, 111, 112 };它等价于 matrix[0][0]100; matrix[0][1]101; matrix[0][2]102; matrix[1][0]110; matrix[1][1]111; ma…...
零食食品经营小程序商城的作用是什么
零食几乎可以涵盖每个年龄阶段,同时又是市场中常见的零售批发商品,在多个场景中都有销售/购买属性,对消费者来说,购买零食的渠道多种多样,无论线下还是线上,都可随心而购。 庞大市场升级促进下,…...
Java泛型--什么是泛型?
https://www.bilibili.com/video/BV1xJ411n77R?p5&vd_sourcebb1fced25254581cf052adea5e87a1ff 1.泛型类、接口 1.1.泛型类 泛型类的定义 class 类名称 <泛型标识, 泛型标识, ...> {private 泛型标识 变量名;...... }常用的泛型标识:T、E、K、V jav…...
LabVIEW工业虚拟仪器的标准化实施
LabVIEW工业虚拟仪器的标准化实施 创建计算机化的测试和测量系统,从计算机桌面控制外部测量硬件设备,以及在计算机屏幕上显示的类似仪器的面板上查看来自外部设备的测试或测量数据,所有这些都需要虚拟仪器系统软件。该软件允许用户执行所有这…...
JavaScript系列从入门到精通系列第十七篇:JavaScript中的全局作用域
文章目录 前言 1:什么叫作用域 一:全局作用域 1:全局变量的声明 2:变量声明和使用的顺序 3:方法声明和使用的顺序 前言 1:什么叫作用域 可以起作用的范围 function fun(){var a 1; } fun();consol…...
汇编指令集合
...
TinyWebServer整体流程
从main主函数开始: 一、定义MySQL数据库的账号、密码和用到的数据库名称。 二、调用Config获得服务器初始化属性 在这一步确定触发模式端口等信息。 三、创建服务器实例对象 设置根目录、开辟存放http连接对象的空间,开辟定时器空间。 四、利用Confi…...
【Java项目推荐之黑马头条】自媒体文章实现异步上下架(使用Kafka中间件实现)
自媒体文章上下架功能完成 需求分析 流程说明 接口定义 说明接口路径/api/v1/news/down_or_up请求方式POST参数DTO响应结果ResponseResult DTO Data public class WmNewsDto {private Integer id;/*** 是否上架 0 下架 1 上架*/private Short enable;}ResponseResult 自媒…...
自学(黑客)技术方法————网络安全
如果你想自学网络安全,首先你必须了解什么是网络安全!,什么是黑客!! 1.无论网络、Web、移动、桌面、云等哪个领域,都有攻与防两面性,例如 Web 安全技术,既有 Web 渗透2.也有 Web 防…...
python+playwright 学习-84 Response 接口返回对象
Response 是获取接口响应对象,根据Response 对象可以获取响应的状态码,响应头部,响应正文等内容。 Response 相关操作方法 all_headers 所有响应HTTP标头, 返回Dict 类型 response.all_headers()body 获取 bytes 类型body内容 response.body()json 返回响应主体的 JS…...
GCN详解
a ⃗ \vec{a} a 向量 a ‾ \overline{a} a 平均值 a ‾ \underline{a} a下横线 a ^ \widehat{a} a (线性回归,直线方程) y尖 a ~ \widetilde{a} a a ˙ \dot{a} a˙ 一阶导数 a \ddot{a} a 二阶导数 H(l)表示l层的节点的特征 W(l)表示l层的参数 D ~ \widet…...
总结二:linux面经
文章目录 1、 Linux中查看进程运行状态的指令、查看内存使用情况的指令、tar解压文件的参数。2、文件权限怎么修改?3、说说常用的Linux命令?4、说说如何以root权限运行某个程序?5、 说说软链接和硬链接的区别?6、说说静态库和动态…...
12、【Qlib】【主要组件】Qlib Recorder:实验管理
11、【Qlib】【主要组件】Qlib Recorder:实验管理 简介Qlib RecorderExperiment ManagerExperimentRecorderRecord Template简介 Qlib包含一个名为QlibRecorder的实验管理系统,旨在帮助用户以高效的方式处理实验并分析结果。 该系统有三个组件: 实验管理器(ExperimentMan…...
三一充填泵:煤矿矸石无害化充填,煤炭绿色高效开采的破局利器
富煤贫油少气是我国的能源禀赋特征,决定了我国以煤炭为主的能源结构,煤炭为国民经济发展提供了重要的基础。煤炭开采过程会对土地、地下水、空气等环境造成较大的污染,但大宗固废煤矸石无害化充填的技术手段可以有效改善这样的情况࿰…...
医疗器械标准目录汇编2022版共178页(文中附下载链接!)
为便于更好地应用医疗器械标准,国家药监局医疗器械标准管理中心组织对现行1851项医疗器械国家和行业标准按技术领域,编排形成《医疗器械标准目录汇编(2022版)》 该目录汇编分为通用技术领域和专业技术领域两大类,通用…...
爱站网 关键词挖掘工具站长工具/网站优化排名技巧
既然知道自己是个不自觉的人,自制力很差,那么就在做事情的时候不要给自己任何借口来推脱和延后完成,这是自己唯一能提高效率的办法!!转载于:https://www.cnblogs.com/zhangxiangning/p/10214439.html...
重庆电力公司网站/快手流量推广网站
自增()和自减(--)运算符在JAVA语言中存在着很多运算符,但是在实际开发中我们或许很少用到它们,在初次学习中却时常出现它们的身影,对于这些运算符的含义和用法,是否还记得呢?1. 概述自增操作符()和自减操作符(--)是对变…...
电子网站建设/大数据分析网站
java面试基础知识大全java基础知识在面试中是常考知识点,那么java面试必备基础知识点有哪些?下面跟yjbys小编一起来学习一下吧!1、JVM、JRE和JDK的区别:JVM(Java Virtual Machine):java虚拟机,用于保证java的跨平台的特性。java语言是跨平台…...
wordpress上传视频限制/免费网络推广平台有哪些
全网最全大数据面试提升手册!如果这个文章对你有帮助,不要忘记 「在看」 「点赞」 「收藏」 三连啊喂!2022年全网首发|大数据专家级技能模型与学习指南(胜天半子篇)互联网最坏的时代可能真的来了我在B站读大学,大数据专业我们在学…...
wordpress做商品筛选/网站优化排名推荐
Linux-C Http请求 一、简述 在C语言中使用http请求公开的API接口,接口返回数据。如请求快递数据、天气数据。 链接: https://pan.baidu.com/s/1Tr4HZJPmLEY4yoTSwtltVA 提取码: hpsv 例子1 :查询快递信息。 例子2:查询当前时间,…...
私人免费网站怎么下载/江北seo页面优化公司
使用默认的参数生成的java类会报错。在类中的注解中说required 未定义。搜索半天终于发现问题解决了。方法:wsdl2java 命令行时添加一个参数 -frontend jaxws21...