移动开发从iPhone手机问世之后,也快有十个年头了,随着App功能的不断的变多,代码规模越来越大,也为了适应多项目组协同开发的工程需要,各种移动端的模块化方案应运而生。
这两年来,各大公司以及各路大神,都或多或少放出部分模块化的方案或者思路。这段时间,看了挺多方案,想通过一个系列的文章,总结下心得体会。这些体会还是建立对模块化有些了解的基础上的,可能也不是很适合初学者阅读。
这里总结的大多是一些轻量级的方案。类似手淘Atlas
和蚂蚁金服支付宝MPass
这样大型的容器化方案,只适合超大型App,以及大规模团队开发的需要,可以借鉴下思路。
模块化的精髓,个人觉得应该就是解耦,所有才有了路由的出现。回想到几年前刚接触Android开发的时候,怎么也想不到,有一天,一个简单的Intent跳转,能被设计的这么复杂。
在Android领域的模块化方案,基本都逃不开路由的设计,基本原理,都是用到了intent-filter
中的data
的host
和scheme
,借鉴了网络中概念,通过类似url地址的信息和Activity建立路由映射关系,然后通过,url地址来请求,经过建立的路由映射关系,根据host
,scheme
进行处理,跳转对应模块。 所以在Android模块化方案中,大部分设计套路都集中在了 怎么建立这种路由表了。
当然可以本地建一个文件去记录这种映射关系,但是这种方案实在是过于简陋而且漏洞无穷。所以在当前的模块化方案中,路由表基本是靠代码动态建立,于是,注解来了。
注解分为三类,Source,Class,Runtime,第一类用处不大,后面两类的运用代表了两类不同模块化方案,路由表生成,以及加载的思路。
方案一:
利用 Class 类型的注解来动态生成路由关系。
代表方案: ActivityRouter,AndRouter,ARouter(阿里2017年初开源)
这些方案的大致思路如下:
- 定义部分路由相关信息的注解,可能还有一些拦截信息的注解,为了路由功能更加强大。
- 将注解声明在需要的代码中,一般为Activity,或者拦截器等路由框架支持功能的类中。
- 在代码编译过程中,通过注解处理器生成代码,动态生成路由表等信息。并一同打包。
- App运行阶段,通过反射,从之前动态信息的类中,拿到路由信息(可能还有其他信息),预加载到路由规则的缓存中。
- 发生模块间跳转,或者请求别的模块的功能时候,指定url路径,通过缓存中的路由规则进行跳转,而不是显式通过指定Activity的名称进行跳转。
- 跳转过程中,也会增加一些套路,可以对参数处理,使用了依赖注入的方式。大部分框架还支持拦截器,类似很多网络请求框架中拦截器的设计,可以在跳转中统一处理一些事件,这里用到了AOP的编程思想。
方案二
利用 Runtime 注解来动态生成路由关系。
代表方案:LiteRouter
应该还有其他类似方案,没有仔细寻找,不过思路应该大致差不多。
方案二的思路,既然使用了Runtime 注解,那么必然是代码在运行时,通过路由关系进行跳转。基本思想借鉴了Square
公司的网络请求库Retrofit
通过动态代理来实现。Retrofit
是将接口中的方法转成了网络请求,发起了对后端的请求,拿到数据。同样方案二的路由框架,是讲接口中的方法转换成Intent的数据,然后发起了模块跳转。从设计上说,这种思路无论优劣如何,个人从新意上说都是很巧妙的。
至于两种方案的源码,后续也会简单分析下,总结梳理自己的理解。