一、概述
在Android开发中,我们需要构建不同的版本类型(Relase、Debug、Alpha),或者是不同渠道(豌豆荚、小米、三星等),这些都可以配置编译变体来实现,本文就是希望通过简短且概括性的文字来进行解释。
以下内容均可在Google官方文档中找到,详看:配置编译变体。
二、使用buildTypes构建不同版本类型
什么叫不同版本类型?根据我的理解就是,Google提供了一系列属性(参考:版本类型 DSL参考),然后我们可以根据需要为不同版本配置不同的属性,从而实现打出来差异化的包。
如果你没接触过,你应该会觉得很抽象,举个例子:
比如说,我要给当前项目构建两种包(Debug和Release),Debug版本可以支持adb debug,Release版本则不行,同时Debug版本的包名后缀需要在原有基础上增加“.debug”,那么我们就可以通过配置buildTypes来实现,代码如下:
1.修改app目录下的build.gradle文件
⚠️注意:release版本里面一定要加上签名,不然打出来的包安装不了,会提示没有签名信息!!签名过程这里不赘述了,不懂的同学也是自行搜索。
android {
//...
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
// release版本签名
signingConfig signingConfigs.release
}
debug {
applicationIdSuffix ".debug"
debuggable true
}
}
//...
}
2.同步代码
一般修改build.gradle后,都会要求你Sync Now,不懂怎么同步代码的同学自行搜索。
3.编包
在Teminal执行命令gradlew assemble
,编译成功会提示如下:
然后打开你的目录app下的build/apk/目录,下面多了两个文件夹,分别是debug和release,里面分别有两个apk,如下图所示。
4.验证
分别安装两个app,我们就可以验证它们是否满足我们的要求。
首先安装debug目录下的apk,打开调试工具可以看到,包名确实变成了“.debug”结尾,并且是可以调试的。
再来看relase包,安装后在调试工具看不到对应的可调试app,因为我们没有设置它是debuggable,通过pm list packages
命令查看已安装app,确实有一个com.ryan.testbuildtype
的app,跟debug包的包名是不一样的。
由此验证得知,确实可以通过buildTypes来构建不同类型的包,当然,在版本类型 DSL参考里面提供了很多不同的属性,如是否可以调试JNI代码的属性jniDebuggable
、是否打开Proguard的属性useProguard
、是否压缩资源文件的属性shrinkResources
等,你都可以根据自己的需求来进行构建不同属性类型的包。
三、使用productFlavors实现多渠道打包
在Google官方的解释是productFlavors是用以构建不同产品特性使用的,但是国内的开发者都喜欢用以实现多渠道打包,所以本文暂且这么来写。
我们都知道通过buildTypes可以实现构建不同属性的包,但是针对不同类型维度的打包,确实有心无力,怎么说?
比如,我们需要构建不同区域的包,实现内容是一样的,但是所有网络请求的域名随区域的变化而变化,假如我们在代码中通过if-else来实现,会显得非常冗余,下面就以这个例子来讲解productFlavors的使用。
1.首先在app目录下的build.gradle文件增加productFlavors属性
首先需要定义一个flavorDimensions,例如我定义的是location作为区分维度。假如你有多个维度,那么最终就会构建出来几个维度多种组合的包。
android {
// ...
// 特性维度
flavorDimensions "location"
productFlavors {
guangzhou{
dimension "location"
}
chengdu {
dimension "location"
}
}
// ...
}
2.同步代码
3.在src目录创建对应flavor的目录
如我们要根据地区,构建不同的ip地址,那么我们就可以把ip定义到java文件里面,在app目录下的src目录,右键new->Folder->Java Folder,然后选择对应的flavors,如本例中的guangzhou,就会生成一个guangzhou的目录,然后在java目录下新建一个包名(这个是必须要的),然后创建一个文件,如下图所示:
然后在里面定义广州的域名:
public class MyConstants {
public static final String DOMAIN = "http://www.guangzhou.com";
}
同样地,创建成都的目录,并创建同样的包名和类名,并创建同样的变量:
public class MyConstants {
public static final String DOMAIN = "http://www.chengdu.com";
}
也许你的java文件变成了红色,如下图所示:
不用担心,只是你当前的flavor是广州而已,选择as左下角的Build Variants,切换到成都的flavor,你的文件就是正常的类了。
4.在main目录下的文件引用不同flavor的属性
为了测试方便,我们就在MainActivity中打印MyConstants的值即可,代码如下所示:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textView = findViewById(R.id.tv_text);
textView.setText(MyConstants.DOMAIN);
}
}
使用teminal打包,构建出两个flavor的debug包:
分别安装,可以看到最终打印的域名是不一样的,从而实现了不同渠道打包:
当然,这只是非常简单的应用,当你需要进行更大代码差异化的时候,也可以利用productFlavors来划分特性,从而可以同时构建出不同渠道的apk,避免在代码中进行冗杂的if-else判断。