code小生,一个专注 Android 领域的技术平台
公众号回复 Android 加入我的安卓技术群
作者:xxj_1e04
链接:https://www.jianshu.com/p/62e88f544d2f
声明:本文已获xxj_1e04
授权发表,转发等请联系原作者授权
本组件化方案已开源在github,欢迎转载和star。https://github.com/beyondxia/modules
上篇中我们对传统的组件化方案的实现原理进行了简单的介绍,以及对其优缺点进行了相应的分析。针对接口通信机制的方案,有如下缺点:
a、需要提供一个公共的目录或者公共模块用作为服务层,所有接口文件和中间共享的文件都需要手动拷贝至服务层。
b、组件若需要提供服务,除了本身的实现类,还需要提供一个或多个中间接口文件,增加了开发量和组件集成的复杂度以及维护成本。
c、由于服务实现类与服务接口存在依赖关系,所以业务方需要实现暴露的接口,并要实现具体需要暴露的业务功能。
d、所有的组件服务的注册都需要手动进行,增加了开发量与风险。
e、与接口相关的一些中间类(特别model)也需要同步下沉至公共目录。
针对不足点a和b,如果可以自动生成并拷贝接口文件,那为题就迎刃而解,那该如何做呢?
我们知道,APT(Annotation Processing Tool 的简称)可以在代码编译期解析注解,生成新的Java文件,可以减少手动的代码输入.
本框架就是利用APT进行接口文件的自动生成。用户要做的只是给需要暴露的服务以及服务中需要暴露的方法添加相应的注解(@ExportMethod),APT将根据注解自动生成接口。如下图所示,Message即为组件提供的服务类,IMessage为生成的接口。
image.pngAPT可以生成对外暴露接口,那接下来我们需要做的就是让业务方实现该接口,并完成真正功能的实现,那又改如何做呢?
其实从代码层面看,我们只需要Message类实现IMessage,由于Message在IMessage接口生成前就已经由模块内部实现,所以如果要修改Message,最好的方法还是编译阶段修改Message.class字节码。
Javassist 是一个执行字节码操作的库。它可以在一个已经编译好的类中添加新的方法,成员,或者实现某个接口、继承某个父类等。
针对不足点c:Javassist刚好可以满足我们的需求,编译阶段通过修改字节码,让Message实现接口IMessage。这样就实现了服务类Message与服务接口类IMessage的实现关系。
image.png这样还有一个好处:若服务类进行版本升级,框架会通过APT与gradle transform技术可以对服务接口做到静默自动同步,对组件开发者完全无感知,开发者只需专注于开发自己的组件业务即可。
针对不足点d:框架通过APT技术,对有ExportService注解标识的服务类进行收集,并在框架初始化的时候进行自动注册,开发者完全不需要参与注册工作。并且我们根据服务的使用场景以及频率提供了不同的实例化时机,可根据组件的使用场景在注解上进行相应的配置即可。
image.png针对不足点e:我们不提倡组件间以自定义的model传输数据,但传输复杂类型的数据类型又是不可避免的,当然可以选择现有的序列化方式传输,如json,但在序列化和反序列化时需要开发者做诸多繁琐的操作。为此,框架提供了一种简单易用的的传输复杂类型数据类型的方式,极大程度上简化了序列化与反序列化的操作。
如果组件间因为业务需要,需要共享复杂数据结构,如:
image.png需要暴露一个自定义view。 从原则上来讲,组件化设计不建议组件间共享复杂类型,即使有这类类型,更建议以通用数据下沉至base层的方式。 但是针对一个大型项目做组件化拆分的时候,有时必然要设计这类问题。针对这样的问题,是需要手动拷贝文件至服务层。
通过以上介绍的方案,框架基本上解决了接口通信方式存在的缺点。大部分工作已经由框架在编译阶段完成,极大的减少了业务接入的成本,对代码侵入性极小,使开发者可以专注于组件功能的开发。
Android 通用的组件自动注册、自动初始化解决方案
组件化框架简介
Android 彻底组件化—如何使用 Arouter
Android 彻底组件化 demo 发布
分享技术我是认真的