一个App可能有免费版和付费版之分,还可能有Phone何Tablet之分,但是不论什么版本,它们之间都有很大的
相同点,只是很少的地方有差异,它们称为build variants,Android Studio能否同时构建这些variants呢?
另外,任何一个版本都可能有debug何release之分,这叫做build type,不同的type能否共存呢?
Android Studio可以同时构建多种variants,每种variant有可以有自己的debug和release之分,而且,
最重要的是,这么多不同的版本可以同时安装到一台设备上,debug和release共存,pro和free同在,完美。
build types
build type只有两种:debug和release。在build.gradle中配置如下,
1 | android { |
build variants
build variants可以自己随便定义,如
1 | android { |
这样配置之后,在build variants
tool window就会出现四个不同的版本:
- flavor1Debug
- flavor1Release
- flavor2Debug
- flavor2Release
各种variants可以定义自己的applicationId,versionCode等参数,如果不设置的话就使用defaultConfig中的值。
上面说了参数设置,下面说说代码的目录结构,默认不同的variant(flavor)有各自的代码目录,如此时src目录下
就可以是这样的了:androidTest/
, main/
, flavor1/
, flavor2/
。当然默认各种flavor没有自己的代码,
而是与main
共享代码,也就是说编译flavor1时从flavor1/
和main/
目录下取代码,编译flavor2时从flavor2/
和main/
下取代码,资源文件可以同名,如同时存在res/values/string.xml
,编译时自动合并,但是Java类
不能一样,会报重复定义的编译错误。所以,如果同一个类有多个不同的版本时,就需要在不同的flavor中各自
定义,而且main中还不能存在同名类,这点儿要注意。
既然如此,我们也可以单独制定各个flavor的source set,只是多个flavor不要出现同一个文件夹的情况,重复
的部分都放到main
里面去,没有指定的部分使用默认值,如src/flavor1/res
是flavor1的默认resource目录,
1 | sourceSets { |
这里有一个例子。
注意,因为多个apk共存的本质其实就是在编译时把package name修改为applicationId而已,所以涉及到package name
的地方不要硬编码,如自定义View时如果用到自定义属性,那么xmlns不要硬编码package name,而应该使用res-auto
,xmlns:myapp="http://schemas.android.com/apk/res-auto"
,使用content provider的时候涉及到authority
也要灵活处理之。