新的组件的设计只要保证对外提供的接口,完全符合,旧组件对外提供的接口
5、组件的热插拔,成为可能(如果构建正确)
我们想象下,在APP运行时,business中的组件可以动态加载,也可动态卸载。
那么我们可以轻松实现组件的懒加载:用户用到的组件,那么就加载进来。用完之后便可以卸载。
6、组件的独立编译、测试,成为可能(如果构建正确)
大的android工程项目,build一次要到5分钟左右,太浪费时间了。
拆成多个组件之后,如果每个组件都能单独build,单独测试,那么将大大提升开发效率。
上面讨论的这些优势,并不是将简单将 单工程 拆分成 分层的多module工程结构 就能获得这些优势。
想要获得这些优势,还任重道远,我们还需要解决很多问题,才能让我们的项目具备上面的说的优势。
二、组件化后,将面临哪些问题?如何解决?
1、module之间如何优雅的通信
通过ARouter通信。
ARouter是阿里开源的一个项目。github.com/alibaba/ARo…
通过ARouter跨module跳转Activity
@Route(path = “/test/activity”)//申明路由
public class YourActivity extend Activity {
…
}
//通过路由启动Activity
ARouter.getInstance().build(“/test/activity”).withLong(“key1”, 666L).navigation();
通过ARouter在module间共享对象,实现module间通信。
比如:我们有一个账号模块 business:account ,提供了登录、登出、用户信息查询等业务。
同级的其他模块,如何跟账号模块通信?获取用户的登录状态以及用户相关信息?
public class AccountBean {
private String name;
private int age;
//…
}
public interface IAccountService extends IProvider {
void login(Context context);//登录
void logout(Context context);//登出
AccountBean getAccountBean();//获取账号信息
}
对外的数据结构和接口定义。
@Route(path = BusinessRoutePath.ModuleAccount.ACCOUNT)
public class AccountServiceImpl implements IAccountService {
//…
}
bussiness:account模块中的实现。
IAccountService accountService = ARouter.getInstance().navigation(IAccountService.class);
accountService.login(activity);
AccountBean bean = accountService.getAccountBean();
但是问题来了:
同层的其他模块,如何,能拿到ARouter的path?
同层的其他模块编译时,如何,共享AccountBean类、IAccountService接口?
这就是模块之间的编译隔离,带来的问题。
我们很自然的想到了framework模块,或者base层的其他模块。
我们只要将这些path定义、AccountBean类、IAccountService接口,下沉到base层,就可以实现编译上的代码共享。
如此一来,就带来了,另一个问题:代码的中心化问题。
2、代码的中心化
简单的path字符串定义,放在framework倒是还好。
如果所有business模块对外提供的接口和数据结构,都定义到framework的话,问题就有点严峻。
将会破坏:组件的 可替代性、可重用性、组件间耦合度
因为framework是基础模块嘛,所有business模块都依赖的模块,如此,不管你的business1模块是否依赖business2模块的对外接口,都会存在这一层依赖。
模块间的代码边界出现一些劣化。缺少了编译上的隔离。许多模块将会变得不够“独立”了。
可替代性、可重用性 越来越弱,想要替换或者复用某个business组件将变得越来越难。
将会导致,我们很难知道,哪些business对哪些business 接口有依赖。
同时,framework模块随着功能迭代,会不断膨胀。
这就是,中心化的问题。
于是我们很自然的想到了一个解决方案:
实现了另一种接口暴露的形式——“.api化”。
将 business模块 对外提供的接口单独抽到 business-api 模块中。其他依赖他的模块只需要依赖他的business-api即可。
这个方案如何实践下去呢?
微信的api化方案
微信团队出了一个很巧妙的方案,这个方案对android的组件化开发,产生了非常深远的影响。
后面很多做组件化开发的团队,在解决中心化问题基本都会用到类似的方案。
以下为,微信官方博客的原文引用:
使用方式和思路都很简单。对于java文件,将工程里想要暴露出去的接口类后缀名从“.java”改成“.api”,就可以了。
而且并不只是java文件,其他文件如果也想暴露,在文件名后增加".api”,也一样可以。
当然,要让工程支持这样的方式,gradle文件肯定会有一点改变。
它的实现原理也相当简单:自动生成一个“SDK”工程,拷贝.api后缀文件到工程中就行了,后面其他工程依赖编译的只是这个生成的工程。简单好用。
api方案有点类似于android的AIDL的思路。
微信API方案的变种
gradle 根据src/api文件来,自动生成{moduleName}-api模块。
如果,src/api文件不存在,将不会自动生成 {moduleName}-api 模块。
通过API模块来解决代码中心化问题带来的好处:
-
让各个business的之间的依赖明确
-
让business对外提供的接口明确。
从而加强了模块的:可替代性。
只要两个business对外提供的API一致,就可以相互替换。
3、单独编译、测试 business的单个模块
模块变多了,项目变大了,整个项目的编译速度变慢了。
业内有两种常用做法。
- 方案一:动态配置 build.gradle。
只要让单个的组建能编译成APP就能单独测试。
- 方案二:多壳APP
方案来自,在聚美优品。
这里需要注意:假如,Demo1是business1的壳APP。那么Demo1还需要依赖哪些businessXXX呢?
刚好,前面做的api化,能排上用场。
business1依赖的businessXXX-api模块对应的businessXXX模块,Demo1也需要依赖。
为甚?因为,business1依赖的businessXXX-api模块,意味着,business1需要依赖 businessXXX提供的功能,比如要跳转到businessXXX的activity?或者,要获取businessXXX的对象。
4、模块变多了,gradle代码同比增长,gradle 代码复用
在项目跟目录的build.gradle文件中配置Extra属性
如此可以实现统一管理版本号,和依赖。
但是,但是,但是,这个方案存在明显的缺陷。
-
不支持,自动补全
-
不支持Find Usages,查找所有应用的地方
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
写在最后
在技术领域内,没有任何一门课程可以让你学完后一劳永逸,再好的课程也只能是“师傅领进门,修行靠个人”。“学无止境”这句话,在任何技术领域,都不只是良好的习惯,更是程序员和工程师们不被时代淘汰、获得更好机会和发展的必要前提。
如果你觉得自己学习效率低,缺乏正确的指导,可以加入资源丰富,学习氛围浓厚的技术圈一起学习交流吧!
加入我们吧!群内有许多来自一线的技术大牛,也有在小厂或外包公司奋斗的码农,我们致力打造一个平等,高质量的Android交流圈子,不一定能短期就让每个人的技术突飞猛进,但从长远来说,眼光,格局,长远发展的方向才是最重要的。
35岁中年危机大多是因为被短期的利益牵着走,过早压榨掉了价值,如果能一开始就树立一个正确的长远的职业规划。35岁后的你只会比周围的人更值钱。
id)**
[外链图片转存中…(img-Ue6p2VJ1-1710768522870)]
写在最后
在技术领域内,没有任何一门课程可以让你学完后一劳永逸,再好的课程也只能是“师傅领进门,修行靠个人”。“学无止境”这句话,在任何技术领域,都不只是良好的习惯,更是程序员和工程师们不被时代淘汰、获得更好机会和发展的必要前提。
如果你觉得自己学习效率低,缺乏正确的指导,可以加入资源丰富,学习氛围浓厚的技术圈一起学习交流吧!
加入我们吧!群内有许多来自一线的技术大牛,也有在小厂或外包公司奋斗的码农,我们致力打造一个平等,高质量的Android交流圈子,不一定能短期就让每个人的技术突飞猛进,但从长远来说,眼光,格局,长远发展的方向才是最重要的。
35岁中年危机大多是因为被短期的利益牵着走,过早压榨掉了价值,如果能一开始就树立一个正确的长远的职业规划。35岁后的你只会比周围的人更值钱。