Android组件化架构实践(2)

在实践过程中,现有的方案都需要维护3个HashMap,分别是路由表、服务表以及组件表,当服务多到一定的程度,手动维护3个哈希表是一场灾难。以小赢理财现有的Scheme路由库为例,初代版本中是在内存中维护一个静态的HashMap路由表,key表示路径,value代表calss。虽然这样方便省事但是可维护性较差,一旦跳转规则变化或者忘记及时更新则会失效。秉承着“能让机器完成绝不自己动手”的原则,在迭代中改成了通过反射去扫描AndroidManifest,自动生成维护HashMap,这样可以做到map的自动注册。但是由于扫描是在Application的onCreare()方法中完成,用AOP测试发现扫描过程比较耗时,这种自动化的方式是以牺牲启动时间为代价的。联想到注解,可以通过编译时注解插入代码动态生成HashMap,但尝试过后发现部分场景下行不通,因为编译时注解的特性只在源码编译时生效,无法扫描到aar包里的注解,这种情况不适合远程预埋aar,动态下发的场景。运行时注解也会不可避免的会造成性能的缺失。幸运的是,Android官方提供了Transform API,可以用来在.class转换为.dex前操作class文件。这样配合ASM(如果觉得javap命令生成字节码太麻烦,可以使用IntelliJ IDEA插件‘Bytecode outline’,可方便快捷根据java类生成字节码)或javassist就可以动态的修改字节码,从而动态生成HashMap而不需要损耗性能。这种方式配合后台下发的方式,就能保住灵活性。

大致步骤如下:

  1. 新建buildSrc工程,或者独立工程;

  2. 接入Transform依赖:implementation ‘com.android.tools.build:gradle:3.2.1’,值得注意的是这个包里面包含了ASM库;

  3. 新建一个class实现Transform类,将扫描范围设置为:TransformManager.SCOPEFULLPROJECT,并在tranform(TransformInvocation transformInvocation)中遍历目录输入和jar输入,并使用ClassVisitor操作字节码;

  4. 最后在自定义Plugin中注册这个自定义Transform。

具体的操作细节可以参考官方文档。

3. 组件生命周期管理

一个进程对应着一个虚拟机,虚拟机需要管理APk的生命周期。同理,如果把APP看作一个虚拟机,把各个业务组件看成是小型的APP,那么APP是需要妥善管理各个业务组件的生命周期的。也就是说我们需要同步资源初始化、使用、销毁的时机。可以模拟虚拟机的工作流程:加载-验证-准备-解析-初始化-使用-卸载,同时使用ApplicationDelegate代理,hook住Application的各个生命周期,这样就可以实现组件的同步加载,需要主动销毁时,则可以将module手动卸载。

4. 依赖和主包管理

随着拆分出来的Module和aar越来越多,每次都需要重复配置依赖和项目基本参数。由于每层(主Module层、业务组件层、功能组件层、基础组件层)之间的依赖都大同小异的,因此抽出一层gradle_component,专门用来配置通用gradle,这样就可以统一依赖,比如:

然后把这些gradle分别apply到对应的层级,当然为了方便管理减少.gradle文件,可以将具体的依赖通过自定Plugin的形式注入。由于module和aar比较多,当真正进行build的时候,需要检查settings.gradle并对每个Module进行初始化配置,再运行具体的task进行打包。这个操作随着Module个数的增多,执行的耗时会直线上升。实际情况是,假设只修改了某个module,并只想运行这一部分增量代码,这个时候可以通过切换主APP完成。由于Android项目是通过plugin来识别的:

apply plugin:‘com.android.application’ // 主module
apply plugin: ‘com.android.library’ // module

这样我们可以在本地自定义一个’isMainAPP’参数来控制主Module和Module的切换。

if(isMainAPP) { // 切换
apply plugin:‘com.android.application’ // 主module
} else {
apply plugin: ‘com.android.library’ // module
}

5. 多进程通信

进程是最小的资源分配管理单位,当业务组件多大一定的程度时,会需要考虑使用多进程通信。如果只是简单的跳转不涉及到数据的获取,那么路由组件是可以胜任的,因为Android内置的Intent机制本来就是跨进程的。如果需要同步数据,则需要考虑进程通信中出现的脏数据,比如同时操作sharepreferences是比较棘手的,因为sharepreferences在文件和内存中各有一份数据,且有时候不相同。Android系统提供了基于mmap的Binder通信机制,落实到工程代码就是实现AIDL,生成远程Binder类和当前进程的Proxy类,并定义相关的Service和BinderPool。但是这样稍微有点重,可以考虑使用现有的ContentProvider + SQLite(ContentProvider本身也是AIDL通信机制,只是系统对其进行了一层封装),在路由库中增加对多进程通信拦截链的支持。

已有的解决方案

当前的一些大公司都先后开源了自己的组件化架构框架,比较知名的有美团的modular-event,阿里的ARouter以及得到(逻辑思维主打APP)的DDComponentForAndroid。其设计思想大同小异,基本也是机遇以上的设计要点,辅助一些同步和异步功能。美团舍弃了之前开发的“WMRouter”路由,转而使用了modular-event,阿里和得到则是使用路由+接口下沉的方式去构建整个架构。“组件化架构”能够清晰的划分项目结构,严格的将代码根据“业务组件”、“模块组件”、“基础组件”进行划分,各个项目组成员可以并行开发module而互不干扰,而且其可扩展性也比较强,对业务不断扩大的项目是一个不错的选择。

最后相关架构及资料

组件化框架设计.png

Android高级技术大纲

#####领取方式:

点赞+加群免费获取 Android IOC架构设计

加群 Android IOC架构设计领取获取往期Android高级架构资料、源码、笔记、视频。高级UI、性能优化、架构师课程、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter全方面的Android进阶实践技术,群内还有技术大牛一起讨论交流解决问题。

最后

对于很多初中级Android工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。整理的这些架构技术希望对Android开发的朋友们有所参考以及少走弯路,本文的重点是你有没有收获与成长,其余的都不重要,希望读者们能谨记这一点。

同时我经过多年的收藏目前也算收集到了一套完整的学习资料以及高清详细的Android架构进阶学习导图及笔记分享给大家,希望对想成为架构师的朋友有一定的参考和帮助。

下面是部分资料截图,诚意满满:特别适合有开发经验的Android程序员们学习。

不论遇到什么困难,都不应该成为我们放弃的理由!

如果你看到了这里,觉得文章写得不错就给个赞呗?如果你觉得那里值得改进的,请给我留言,一定会认真查询,修正不足,谢谢。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值