Kahn's blogs

用Android productFlavors 构建你的多面应用

2018/05/03

前言

论天下大势,分久必合合久必分。前些年app的开发趋势是分解app。某些app从一个app,把其中的模块拆出来,分成多个app。现在又掀起了合并app的浪潮,一个app又开始集合多模块。最近公司让本公司的app融合。融合分为两步,1. 一个壳(就是我们的app module),多个app共享。2. 从原先的app中拆分出模块包,一个模块包对多个app提供服务。什么意思呢?打个比方:原先公司有两个app,两个app工程,两份代码。现在要使用一套工程,一个app,打包出两个apk。其中,原先的app A和app B又有一些通用的功能模块,把这个模块抽取出来,模块A一套代码,分别集成在两个app上。(- -!越说越绕)

模块化开发

之前对于两个app相同的功能,我们都是采用模块化开发的流程。把功能单独抽出一个module,单独对module打包成aar。然后两个app坐标依赖这个aar。如果碰上两个app的需求不一致,或者发版时间不同。这个独立module就需要拉出独立分支,并且独立打包。例如:module会有to_app_A的分支和to_app_B的分支。后来的后来,两个分支就会越走越远。有人会说,每次发版后不能合并吗。不能啊哥,你所在的项目组(以app区分项目组)上了一个功能,代码稳定,但是别的项目组还在处于开发阶段,随便合并代码,会被测试打死。

组件化开发

我理解的组件化开发就是能为不同的app提供组件。而开发过程中该组件又能单独的运行调试

正文

productFlavors

android的gradle插件提供了productFlavors配置谷歌官方问题如下
https://developer.android.com/studio/build/build-variants

该配置主要解决多方式打包的问题。例如:一个app,想打出两个apk,一个用于演示,一个用于正式发布。又比如,一个apk用于免费版本,一个用于付费版本。这些apk有共同的代码,也有差异化代码。使用productFlavors,就可以在编译期隔离这些代码差异。不用在代码中写if(是否为付费版==true)这样的代码。

现在项目其实已经使用了productFlavors

现在的项目中其实是有配置productFlavors的。我们配置了三个flavors,分别为:线上,预发和测试。线上,预发和测试的基本区别就是访问接口的不同。这三个flavor只是gradle配置不同,在三个flavor里分别加入了不同的变量,在meta-data中取出变量。然后在代码中又取出meta-data中设置的值。这种方式其实并没有进行代码隔离。只剩是在打包时,放入不同的值,然后代码中判断值,并走不同的分支。

productFlavors的代码隔离

真正想一个app module 多个应用共用,还是要用到productFlavors的代码隔离功能。

直接上配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
flavorDimensions "env", "app"
productFlavors {
//线上环境
product {
dimension "env"
// ... manifestPlaceholders = xxx
}
//测试环境
zroTest {
dimension "env"
// ... manifestPlaceholders = xxx
}
//测试环境
yfTest {
dimension "env"
// ... manifestPlaceholders = xxx
}
xxx1 {
dimension "app"
applicationId "kahn.com.app1"
}
xxx2 {
dimension "app"
applicationId "kahn.com.app2"
}
}

模块打包上传maven

在各自模块中

  1. 声明全局变量 publishConfigValue
  2. 在android{}中配置defaultPublishConfig的值为变量publishConfigValue
  3. 执行./gradlew -PpublishConfigValue=xxx1Release :xxx1:uploadArchives。如果想打xxx2,就把PpublishConfigValue的值换成xxx2Release

原理

命令行中的-PpublishConfigValue=xxxRelease可以在命令行中动态的把publishConfigValue改为xxxRelease。
android{}中配置defaultPublishConfig的含义:在执行uploadArchives任务时,上传本地哪个环境的aar。该值默认为release,平常不需要配置,因为如果没有配置多productFlavors,系统自带的环境就是release,所以不用配置。但是因为配置了两个productFlavors(xxx1和xxx2),本地就自动生成了两个环境,xxx1Release和xxx2Release。自带的release环境就不存在了。这时候defaultPublishConfig的值还为默认的release值的话,执行uploadArchives无法找到正确的aar。所以!要修改defaultPublishConfig。