4

企业级 Android 模块化平台建设

 2 years ago
source link: https://www.kymjs.com/pay/2018/01/22/01/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

企业级 Android 模块化平台建设

2018-01-22 By 张涛 | 本文已被访问 34 次

版权声明:本文是开源实验室原创文章,如您转载必须以链接形式注明原文地址:https://kymjs.com/pay/2018/01/22/01
这篇文章是应对各个公司所谓的:架构组,基础组,移动横向组,这样的部门在开发与日常工作时提升效率的一些建议(这些问题都是在我本人曾经的工作中遇到的),同时也适用于模块化开发的场景。

对本文有任何问题,可加我的个人微信询问:kymjs666

本文将以模块化开发的场景作为切入点(基础架构组请将每个组件理解为一个独立模块) 首先,模块化开发这个普通的技术点我不打算再讲了,而且随着移动端技术越来越成熟,也没必要再去讲一些过时的东西了。
如果你还不懂什么是模块化开发,可以查看我2016年写的博客:《Android业务组件化开发实践https://kymjs.com/code/2016/10/18/01/

首先,这是一篇有门槛的文章,如果你们是只有两三个人的团队,那建议还是别折腾了,太浪费时间。如果是比较大的团队而且项目模块化已经完成了的,那还是可以考虑一下的,毕竟可以节省出来不少模块间联调与跨模块沟通的时间。

模块间联调

事实上我们的模块独立性已经做的非常好了,可以做到每个模块的增删,代码零改动,一行都不需要改。原理请见这篇文章:《优雅移除模块间耦合
但不可避免的,还是有三四个强业务模块,必须依赖全局Service才能工作的。
还有就是某些模块虽然不依赖外部模块,但需要一些全局信息,例如id用户名这种。但是如果使用mock数据,又会增大工作量,开发不愿意做。
解决办法其实很简单,Android Studio是支持工程compile module的。如何做?来看张图:

开源实验室-kymjs张涛

setting.gradle文件中,可以指定一个project位置,这里就可以将一个外部工程中的模块导入到APP工程中了。
然后这个useFeature,通过在local.properties文件中配置,就可以达到每个人修改自己的模块不会影响到其他人了。

顺带一提,也有另一种实现方案是直接将工程中的module单独作为一个git仓库,然后在外层(工程级)仓库的.gitignore中配置忽略掉module。这样在本地看来就是一个工程级仓库中包含了多个module仓库。这种方式也可以达到目的,但我个人不推荐使用这种方式。

让模块引用与aar引用互斥

解决了前一个问题,在模块联调与源码修改的时候是非常方便了的。但是实际开发中,如果你直接这么做,一定会碰到有类冲突的情况。
举一个例子:
base模块是每个模块都会依赖的,此刻base被打为了一个aar包,在使用的时候直接compile
login模块依赖了base模块。
此时如果我想调试base模块,用上面的方法把base的源码导入,就会发生,项目中不仅依赖了base的源码,同时还引入了baseaar,就会造成类冲突。

解决办法也是有的,就是本节标题:让模块引用与aar引用互斥。

可以通过自定义插件的形式,定义一个特定的关键词,比如像atlas就定义叫bundleCompile。在编译的时候,让这个bundleCompile继承自compile,并检测到如果setting.gradle文件中引入了module的源码就排除掉module对应的aar

gradle插件代码太长了,又是得继承指定类,又是得按照编译流程来麻烦的要死,其实还有一种简单的办法,就是直接在gradle脚本代码里面自己定义一个方法,方法名叫bundleCompile,也可以达到同样的目的。

防偷懒,我就只贴截图了,自己动手敲一遍吧。

开源实验室-kymjs张涛

组件平台建设

组件平台建设,这其实是一个企业级开发很重要的点,也是很多人所很难想明白的点。
就像我前面说的,如果你们是只有两三个人的团队建议别折腾了,没必要,口头约束比什么事都写下来要快很多,而且很方便。但如果是比较大的团队可能有什么事你去跟每个人说一遍的时间,都得花一天时间了。

现在每个公司应该都会有所谓的:架构组、基础组、移动横向组,这样的部门。在开发与日常工作时他们通常是做一些面向开发者的事情,例如网络统计、WebView(web容器)、统一配置管理这种的功能。
放大后,我们从宏观去看,其实每个应用的一个模块,也就是前面提到的一个基础功能,那么这种基础功能是否可以对外提供呢,就像一个网页一样,我告诉一个路由scheme你就打开我指定页面就好了,我告诉你一个接口,你就调我给你的接口对象就好了。

想做到上面的点就很依赖基础设施平台。由于原本公司就有很完善的基础设施平台这是先天优势(感兴趣的可以看一下这个PPT),那么基于这个平台,再去建设基础组件平台就变得非常容易。下面详细说一下几个重要的点:

  1. 组件的构建很重要,应当是统一由后端构建并直接上传至内部maven仓库。这样避免了开发人员手动打包过程中,测试包通过的包和正式包不一致的情况。如果是后端打包,可以直接精确到某次git commit保证测试的包就是最终发布的包。
  2. 平台具有版本提示作用,每个版本做了什么,当前最新版本是多少,当前应用中接入的版本是多少,当前线上某个版本接入的某个模块是哪个版本的,这些信息都一应俱全。任何一个有权限的人都可以很清楚的了解到这些细节信息,保证出意外时拥有修复的能力(例如模块的热修复)。
  3. 模块的测试与发布。前面我也说了,我们几乎所有模块可以做到动态增删不用修改代码。那么测试人员就可以通过远端直接拉取某个线上版本,将那个应用中指定模块给update或者配合exclude,通过控制变量来测试这个已经release的包是否因为此次模块改动造成问题。
  4. 线上事故记录。难免有测不到的BUG被发布,那么这个问题是哪个版本的应用,哪个版本的模块,问题是否在新版本已经修复过,是否是因为某些特殊接入环境造成的。这些信息也是可以统计到平台内,作为快速自查手册,以避免开发人员多次被同样的事情给打断。

自动版本号

自动版本号的实现网上有很多种办法,这里我讲一下我的实现方法。在gradle执行上传aar的时候,可以去远端maven仓库读maven-metadata.xml这样的一个文件。他里面记录了当前aar的各个版本以及最新的release版本的version。通过xml解析,取到后对这个版本做+1,就得到了新版本的版本号。
具体代码就是一个URLConnection去访问那个xml文件,然后解析,这里就不贴代码了,相信如果你能看到这里,这种代码你也是能写出来的。

了解更多有深度技术的文章,与移动端、大前端未来方向的认知,前往订阅 开源实验室小专栏。


Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK