一条电商 Android 工程化实践

版权声明:本文是开源实验室原创文章,如您转载必须以链接形式注明原文地址:https://kymjs.com/code/2019/1

大家好,今天跟大家分享的主题是:从小作坊到大工厂,一条电商的 Android 工程化开发实践

一条电商 Android 工程化实践

我是张涛,就职于一条生活馆,我们公司是一家电商新零售公司,目前移动端的一些开发管理工作都是由我在负责。对今天的分享有哪些值得探讨的也都欢迎与我交流

Android 作为一个诞生近十一年的移动操作系统,占据了近 80% 的市场份额。

一条电商 Android 工程化实践

这是我们曾经的 APP,携程、美团、京东、淘宝,这是我在网上找的四张图片,时间都是在2014年2015年的,主要是再久一点的也找不到了。

一条电商 Android 工程化实践

你们都知道,接下来我要放现在的了:这是我最近才从我手机上截的四张图,依然是携程、美团、京东、淘宝。

一条电商 Android 工程化实践

这张图,是我们一条生活馆的移动架构图,这张图应该可以覆盖如今百分之九十 APP 的架构模型。最上层是业务层,常见的 APP 各个业务模块,比如我们一条生活馆的最重要的几个业务,CMS首页、内容相关模块、电商的商品购物、还有拍卖等等。

一条电商 Android 工程化实践

回到我们今天的主题:如何完成作坊到工厂的转变?把上面那些技术全都用一遍吗?哪怕你说插件化 Kotlin 都不适合我们,我找出适合我们的技术都用上,就是大工厂了吗?

一条电商 Android 工程化实践

一套成体系的工程化平台

一条电商 Android 工程化实践

比如说我们前面介绍的一个应用有多个功能模块,包含基础模块和业务模块,这也是近几年被喊的很火的移动端模块化技术。

一条电商 Android 工程化实践

无论任何一个应用,想要做到模块化拆分,都必不可少要面临这三个问题:跨模块函数调用、跨模块界面跳转、跨模块消息传递。当然,如果这是一个业界常见问题,一定会有开源的解决方案,比如前面两个,我们可以通过阿里开源的ARouter解决,后一个我相信做Android的没有人不知道EventBus。但是这两个框架在我们真正用起来的时候,都会碰上一些问题。比如ARouter,他从一开始设计就是为了淘宝这样大型的APP去做的,他在应用首次启动的时候要把所有类遍历一遍而这个时间是非常长的,即便是通过分组懒加载也依然很慢。

一条电商 Android 工程化实践

YitBridge 使用了与后端 SOA 设计思路类似的方式:将模块之间的主动依赖倒置,变为功能的提供与使用。那什么是 SOA 的设计思路呢,我们看到一张我画的漫画图:SOA 它是一种面向服务的架构模型。

一条电商 Android 工程化实践

接下来我们来看具体到代码上是如何使用的:首先是作为服务使用方,也就是上一张图右半部分的Client。我们看到上面是传统的做法,首先声明一个借口类型,然后new出接口的实现类给他赋值。而使用了YitBridge的时候,你是不需要关心接口的实现类到底是谁的。这就是YitBridge唯一的用处,隐藏实现类,做到彻底的面相接口编程。

一条电商 Android 工程化实践

之前说过,YitBridge将模块之间依赖倒置,由之前的服务提供方被动的接受调用方调用变为,服务方主动提供服务给调用方。那作为服务提供方需要做些什么事呢,非常简单,你只需要给你的对象提供方法加上一个@Creator注解,告诉YitBridge这是一个创建器方法就可以了。

一条电商 Android 工程化实践

前面讲YitBridge实现完美实现了模块间的解耦,而YitBridge的内部实现就是通过这个APT来完成的。Annotation Processing Tool,相信大家都有听说过这个APT,即便是你没听说过,你也肯定早就用过了,只是你不知道。Android 上有一个注明的注解绑定框架叫 Butterknife,他的内部实现就是通过APT来做的,还有 Google 出品的 Dtabinding、Dagger2,这些也都是APT来做的。那这个注解处理器在 YitBridge 中做了些什么呢,我们来看这段代码。

一条电商 Android 工程化实践

这是 YitBridge 在编译以后生成的一段类:还是继续我们前面讲的那段示例来继续,在运行时,他会根据你传入的 get() 方法的参数,来判断你所需要的是哪个接口的实现,然后去调用对应的创建器方法。

一条电商 Android 工程化实践

那么除了这个问题,还有就是多版本协作开发时候的模块依赖问题。Android 使用的是 Gradle 构建,如果出现基础接口更新,上层所有依赖都跟着重新更改一下,再做一次兼容。这种事本来是无可避免的,但是如果我们有多个版本同时开发,这个问题就大大提升了版本管理的复杂度问题。所以我们引入了一个 baseVersion 的概念,也就是你当前模块构建的目标版本号。只要依赖的模块的目标版本号一致,就可以不用考虑兼容性问题直接更新,如果baseVersion 不一致,那说明这是一次不兼容升级,需要上层模块处理完兼容性问题后再发布。

一条电商 Android 工程化实践

这就是前面 moduleApi的实现,其实就是判断了一下baseVersion是否一致,如果一致,那么就直接引用最新版本,如果不一致,则抛异常退出编译。从而将运行时的错误在编译期就直接发现。

一条电商 Android 工程化实践

第二部分,数据驱动模块重组

一条电商 Android 工程化实践

数据这里,我能跟大家聊的不多。

第二个,商品曝光与转化统计。

一条电商 Android 工程化实践

第三部分,标准化持续集成与交付

一条电商 Android 工程化实践

这里是我们目前使用的模块依赖构建工具,大家可以从这张图中感受一下。构建工具,主要的功能是很明显的,就是用于构建模块,在这之上,还有隐含的功能,就是集中了构建模块的权限,可以更便于统一管理;当然还有最重要的优势就在于模块版本的管理,你可以很清晰的知道当前主应用所接入的模块的版本是哪个,当前最新构建的SNAPSHOT是哪个,以及每个版本的更新日志;这样做了以后,在跨团队协作上的沟通就大大降低了,如果你已经接入或者即将接入的模块是另一个团队开发的模块组件,那你可以直接关注它,它的所有版本变动日志,最新版本全都一目了然;并且可以通过平台简化模块的测试与模块发布的流程,比如提测的时候,如果是一次兼容版本的发布,你只需要告诉测试提测分支,测试可以自己根据现在线上应用的tag,同时引入当前提测的模块替换老版本的模块重新编译,很容易就能控制变量。

一条电商 Android 工程化实践

第二个就是,通过平台化的构建工具,可以很方便的动态选择模块依赖,比如我们在测试某个模块的时候,可以排除部分已经保证没有问题的模块,那么在测试的时候就可以更聚焦,让测试只看我们发生改动了的模块,最终集成测试只需要简单看一下就行了。

一条电商 Android 工程化实践

接下来我们再看看发布效率。最早我们的代码,是非常严格的 N 周一个迭代的发布。但是随着业务越来越多,团队也越来越大。很多时候不得不 delay 一两天来照顾到所有的业务团队。

一条电商 Android 工程化实践

在之后就是我前面提过的,工厂化发布一个APP。我们可以根据业务需要任意组装业务模块,最后拼成一个APP,快速发布到线上,查看这个应用的数据反馈,如果这个应用从数据层面看运行的非常好,那么就可以考虑引导流量到这个应用。如果数据不好,那么尽早放弃降低研发成本,准备其他的业务也更灵活。

                        喜欢 就关注吧,欢迎投稿!

一条电商 Android 工程化实践

1/02/01