版权声明:
本公众号发布的所有文章,均属于原创,版权归本公众号所有。
允许有条件转载,转载请附带底部二维码。
一、前言
在实际的工作中,当接手的App项目逐渐做大的时候,总有一些原因需要根据需求对项目做一些定制化的维护,例如:三方合作定制、海外版本之类的。但是通常这种方式定制,其大体的框架都是一样的,只是根据不同的需求点,做部分定制,
本文就这种定制的需求,利用Gradle做一个解决方案。
二、上古时代的做法
曾经,通用的做法是为不同的专版需求,切出一个git branch出来,然后在这个分支上根据需求,对功能进行定制。每次打包的时候,从这个分支切换代码进行打包、测试、发版。
但是这样存在一个根本上的问题,如果这种专版需求比较多的时候,对于开发而言,一个小小的改动,将它们手工同步到所有的专版分支上,将是一个噩梦。尤其是互联网公司,可能需求天天在变,就会从一个技术活变成一个体力活,并且人工修改,次数多了,难免会有错漏的时候,为了保证质量,同时也加重了测试的难度。
所以,这种方式现在已经是不可取的了。那么,有什么新的方式吗?
三、分清需求,再选方案
所有的技术选型,都要依据实际的业务。当框架的复杂度越高,维护起来就越吃力,所以最好的方案就是在现有的需求之上实现,并且保有可扩展的功能,使之在之后的迭代中,也同样可以胜任。其实就是选个平衡。
那么,如果对于专版需求而言,只是修改一些文案,各个页面的图片等等,这样的小改动,完全可以通过定制不同的productFlavors,然后根据名称,去新建对应名称的文件夹,然后替换主项目内,同名的资源文件即可。
实际操作起来,网上已经有大量的例子,并且也不是本文的主题,这里不再细说。有兴趣的可以自行查阅文档。
那么这种方案的缺陷是什么呢?
它只能简单的适应,在不同的专版之间,只是替换一下各项资源。如果有更复杂的定制功能,它是没法满足的,例如:不同的版本依赖不同的SDK。遇上这样的情况,会将所有专版需要的jar包、so等打在一起,这样无形中增大的apk安装包的体积。
四、不同专版,不同SDK如何解决?
如果遇上不同专版,需要接入不同的SDK去实现,这样的情况下,同样可以通过Gradle来处理这样的情况。
简单的思路:
在主项目之外,通过新建Module(Android Library)的方式,把不同专版间需要改动的地方抽取出来。然后将它们与主项目连接的地方抽象出来,做成接口去做交互。
也就是说,除了主项目Module之外,其他的每个专版作为一个Module存在在项目中,这样可以分别维护自己的定制逻辑,并且所有资源分开来配置,引用的包也是分开的,同事不会增加Apk安装包的体积。
五、举个例子
首先,需要把现有的项目拆分,那些功能是可以允许专版定制的,那些功能是共有的部分。
举个例子,一个视频播放的App,需要用户登录,进入之后,可以购买视频进行播放,那么这样一个App,简单的进行功能上的拆分,可以拆出如下的流程。
![Uploading gradle_module_444571.png . . .]
](http://upload-images.jianshu.io/upload_images/1420036-d528d13de8bfd97f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
从上图可以看出,除了视频播放这个功能是通用的,其他的逻辑都是需要在不同的专版之间做定制,可能购买就需要使用不同合作方的SDK等等。
把功能拆分出来之后,就可以开始着手干了,下面以一个简单的例子说明一下。
新建一个项目,并且在项目内再新建多个Module。记在,这里需要选择Android Library。这种类型的Module,可以编译成arr的包,就可以携带布局文件和so等资源。
用Android Library的方式,新建两个Module,分别表示国内版本(inland)和海外版本(overseas)。
构建好之后,在不同的Module下,分别设定同样一个Activity,完成之后,项目结构如下。
已经到这一步基本上完成了编码的工作,后面就需要配置主Module的build.gradle文件了。
主要需要配置的地方,已经红线标注出来了。
需要制定productFlavors,设定两个版本需要配置的基本信息。然后在dependencies中为不同的版本,做不同的引用,格式就是xxxCompile即可。
因为是个demo,在MainActivity只有一个简单的按钮,点击跳转到LoginActivity。而这里用dependencies制定了不同版本跳转的LoginActivity页面。到这里就可以直接使用了。
在AS的Build Variant窗口,选择需要运行的版本。就可以在手机上运行不同的版本进行调试。
这里只是简单的提供思路,具体Gradle每个字段表示什么意思。这个还是需要查看一下文档,每个版本的格式可能略有不同。
技术之外
这里的技术难点在于,如何将现有项目拆分,如何把拆分后的模块,用接口的形式抽象出来。
那么,在技术之外,还有什么难点?
- 需要和产品协调,共有逻辑尽量不要对专版进行单独定制。如果必要定制,只是简单替换资源图片。
- 需要和设计协调,在出设图的时候,对共有部分UI,不要有对专版的定制UI即可。
用多Module的方式重构了项目之后,核心的问题就是在于如何和多方协调不要在共有的部分进行定制,要么都改,要么就保持原样。