照片是 2020.05.01 花了半个小时用小米9专业模式拍出的效果,有点月色朦胧的味道。感觉到极客时间的摄影课没有白买,至少了解了一点摄影的基础知识。
开端
日常Android开发会有打出不同用途包的要求,最基本的就是给开发环境、测试环境和生产环境打出不同地址的包。以前都是在Java代码里写多个地址,打包时去注释切换不同的地址。例如:
String url = "";
url = "http://192.168.1.1/"; // 开发环境
// url = "http://192.168.1.2/"; // 测试环境
// url = "http://192.168.1.3/"; // 生产环境
这样的方式有个问题,如果忘记改了那就打错包了,而且一次只能打出一个包。如果多个人开发,并且切换过不同的地址提交到git,还得解决冲突问题,特别的麻烦。
以上就是我这个强迫症的动力源泉,就去万能的google搜索解决方案去了。说到这,还是要批评下自己,很多东西知道它的存在,但是没有亲自动手用过,影响就是需要用的时候不能直接上手,领导也不会让你直接用,还需要花时间学习使用。这也就是日常学习与练手的目的,知其然,知其所以然,还要能熟练运用。
单维度
上面的那个需求,只需要添加下面的配置,就可以将配置提到 gradle 内,在开发与打包时都可以通过选择版本来控制打包地址,甚至可以将三个包一同打出来。
flavorDimensions "default"
productFlavors {
dev {
buildConfigField "String", "BASE_URL", '"http://192.168.20.100/flavors/"'
}
ftest {
buildConfigField "String", "BASE_URL", '"http://172.16.20.100/flavors/"'
}
pro {
buildConfigField "String", "BASE_URL", '"http://www.pro.flavors.conan/"'
}
}
可以看到定义了三个地址,那么怎么在代码中运用呢?留意一下这个 BASE_URL 变量的名字,还有这个单引号嵌套双引号的写法。
public static Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BuildConfig.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(httpClient)
.build();
日常我们使用 Retrofit 作为网络库,在公共代码部分会使用 BuildConfig.BASE_URL 作为网络库地址。可以看到 BASE_URL 这个变量的名字,与我们上面在 gradle 中定义的变量是一样的。其实这个 BuildConfig 类就是由 gradle 编译时生成的类,它的内容大概是:
/**
* Automatically generated file. DO NOT MODIFY
*/
package com.example.xue.myapplication;
public final class BuildConfig {
public static final boolean DEBUG = Boolean.parseBoolean("true");
public static final String APPLICATION_ID = "com.example.xue.myapplication";
public static final String BUILD_TYPE = "debug";
public static final String FLAVOR = "dev";
public static final int VERSION_CODE = 1;
public static final String VERSION_NAME = "1.0";
// Fields from product flavor: dev
public static final String BASE_URL = "http://192.168.20.100/flavors/";
}
可以看到这个类的最后一行和它的注释这个就是我们配置的变量,这就说明了,刚才为什么要用单引号嵌套双引号。因为它是个String类型的变量,如果是 int 或者 boolean 类型就不需要写双引号了。
默认是 dev 地址的包,如果开发过程中想要使用 ftest 的包怎么办(ps:ftest不是打错了,是不让用test作为开头,所以可以使用for test -> test 或者 te5t 之类的作为名字)?可以使用 Build Variants 来切换环境包。
切换后 BuildConfig 会重新生成,也就能使用相应的地址了,这也就是切换地址的原理。打包时就更方便了:
可以选择需要的地址甚至是运行release包,来测试应用。这个方式可以还可以替换应用ID、应用名、应用图标等,计划在另外的教程内讲解。
双维度
如果公司要求不止三个地址,还需要区分手机和平板的应用,这时应该怎么办,难道是写六个配置吗?no,只需要写五个(ps:好像没有节省太多吖。。。)
先上配置:
// 维度定义
flavorDimensions "path", "type"
productFlavors {
dev {
dimension "path"
buildConfigField "String", "BASE_URL", '"http://192.168.20.100/flavors/"'
}
ftest {
dimension "path"
buildConfigField "String", "BASE_URL", '"http://172.16.20.100/flavors/"'
}
pro {
dimension "path"
buildConfigField "String", "BASE_URL", '"http://www.pro.flavors.conan/"'
}
mobile {
dimension "type"
applicationId "com.conan.multiflavors.mobile"
}
hd {
dimension "type"
applicationId "com.conan.multiflavors.hd"
}
}
可以看到 flavorDimensions 有了变化,上面我们没有讲,如果只有一个默认的值,基本可以忽略它的存在。这个单词的翻译,我没有找到确切的答案,有人称之为维度,我自己叫它调味盘。一份料理可以分成多个工序,手法,调料,食材,烹饪时间,改变一样料理就会有不同的味道,它们之间的组合就是笛卡尔积的关系。而 flavorDimensions 就是用来有多少个维度的。
然后每个配置会发现都多了一个 dimension ,这是用来指定当前配置属于哪个维度,这样 gradle 就会为我们生成多个维度的组合关系。
可以看到这里生成之前两倍的类型,值都是笛卡尔积的关系。打包的位置也是同理的,为了偷懒就不放图了。
三维度
这时如果需求找你,我们需要定义友盟渠道包,用来统计不用应用市场的运营情况。友盟需要在注册位置传入不用的渠道名作为区分,聪明的你应该想到了,这里还需要定义一个维度。
// 维度定义
flavorDimensions "path", "type", "channel"
productFlavors {
dev {
dimension "path"
buildConfigField "String", "BASE_URL", '"http://192.168.20.100/flavors/"'
}
ftest {
dimension "path"
buildConfigField "String", "BASE_URL", '"http://172.16.20.100/flavors/"'
}
pro {
dimension "path"
buildConfigField "String", "BASE_URL", '"http://www.pro.flavors.conan/"'
}
mobile {
dimension "type"
applicationId "com.conan.multiflavors.mobile"
}
hd {
dimension "type"
applicationId "com.conan.multiflavors.hd"
}
xiaomi {
dimension "channel"
manifestPlaceholders = [channel: "xiaomi"]
}
huawei {
dimension "channel"
manifestPlaceholders = [channel: "huawei"]
}
smartision {
dimension "channel"
manifestPlaceholders = [channel: "smartision"]
}
}
新增了一个 channel 的维度,用来区分不用的渠道商的类别,这里定义了三种,真实的可能需要十几种吧。
口算一下我们这次定义了 3 + 2 + 3 = 8 个配置,如果全都写在一起 3 * 2 * 3 = 18 个配置,可以节省很多配置呦。
打包时就可以选择相应渠道包,可以单选可以多选,一次性打出所有的包。这里要夸下 google,以前在这列出了所有的 release 和 debug 很不方便,现在有了改进,将 release 和 debug 改进成了下拉框,也是本来打包功能大部分需求也是 release 很少需要 debug 包的。
给大家看个产物,基本跟正常打包时差不多,也就是花打一个包的时间打出了所有需要的包。
因为不同的渠道产生的文件夹不一样,所以对 git 的 ignore 文件有影响,我是这样配置的忽略规则。
release
debug
by 费城的二鹏 2020.5.2 白山