文章的运行环境为:
AndroidStudio版本:3.1.4
Gradle版本:3.1.4
在日常开发中,不同平台,不同客户,我们需要打包不同的版本,有可能还要进行一些显示上的改动。
如果多达几十个版本,我们一个个替换更改,是很让人抓狂的。
因此我们可以通过build.gradle配置,实现多渠道打包,一劳永逸。
仅通过build.gradle配置,不能在代码中用if-else、swith等实现如下四个问题:
1、在同一台手机上能够同时安装debug版本和release版本;
2、在同一台手机上的debug版本和release版本能够在首页上显示自己是debug版本还是release版本;
3、在同一台手机上能够同时安装公司debug版本、公司release版本、医院debug版本、医院release版本;
4、在同一台手机上的公司debug版本、公司release版本、医院debug版本、医院release版本能够在首页上显示自己是什么版本;
由于不能使用if-else,所以就无法使用BuildConfig.DEBUG来判断debug还是release。
GitHub: https://github.com/MyAndroidDemo/MultiChannelPackaging
如上效果图,主界面只有两个TextView。
第一个显示当前版本,通过资源文件的string值来控制不同版本显示。
第二个显示当前包名,使用getPackageName()获取。
public class MainActivity extends AppCompatActivity {
TextView tvPackage;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvPackage = findViewById(R.id.tv_package);
tvPackage.setText("当前包名:" + getPackageName());
}
}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/home_text"
android:textColor="#000000"
android:textSize="18sp" />
<TextView
android:id="@+id/tv_package"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:textColor="#000000"
android:textSize="18sp" />
LinearLayout>
为了达到不同版本显示不同的内容,我们可以对资源文件进行适配。
配置资源文件路径,可动态指定不同版本资源文件。
如上目录所示,我们可以创建格式如:res-版本 来控制不同版本使用不同的资源文件。
版本问题解决了,那么怎么来判断debug还是release?
在build.gradle定义资源文件值,可以在程序中像其他string值一样被引用。
如果不明白的可以查看这两篇文章:
Gradle实现多渠道打包(不同资源文件打不同的包)
Android 同时安装debug release版, 并且显示不同名字
<resources>
<string name="app_name">Demo(C)string>
<string name="text_release">Company_releasestring>
<string name="text_debug">Company_debugstring>
resources>
<resources>
<string name="app_name">Demo(H)string>
<string name="text_release">Hospital_releasestring>
<string name="text_debug">Hospital_debugstring>
resources>
android {
...
//配置资源文件路径,可动态指定不同版本资源文件
sourceSets {
//用各自对应的资源文件路径
company.res.srcDirs = ['src/main/res-company']
hospital.res.srcDirs = ['src/main/res-hospital']
...
}
buildTypes {
//在build.gradle定义资源文件值,可以在程序中像其他string值一样被引用
//格式resValue 类型, key(不能与strings.xml文件中的相同), value(可以直接使用strings.xml文件中的值)
debug {
...
resValue "string", "home_text", "@string/text_debug"
...
}
release {
...
resValue "string", "home_text", "@string/text_release"
...
}
}
....
}
flavor维度,3.0以上,必须每个渠道版本必须增加,此处以版本号作为维度值
详情见:https://blog.csdn.net/syif88/article/details/75009663/
android {
...
//多渠道配置,可以配置多个,此处只配置两个
productFlavors {
company {
//修改包名,能够同时安装多个渠道版本
applicationId "com.demon.multichannelpackaging.company"
versionCode 1
versionName "0.1"
//flavor维度,3.0以上,必须每个渠道版本必须增加,此处以版本号作为维度值
//详情见:https://blog.csdn.net/syif88/article/details/75009663/
flavorDimensions "versionCode"
}
hospital {
//修改包名,能够同时安装多个渠道版本
applicationId "com.demon.multichannelpackaging.hospital"
versionCode 1
versionName "0.1"
flavorDimensions "versionCode"
}
}
...
}
android {
...
//版本比较多时,自定义导出的APK名称,不同的渠道编出的APK的文件名应该是不一样的
//Android插件3.0迁移指南所示:
//用all()而不是each()
//如果您只更改文件名(这是您的情况),请使用outputFileName而不是output.outputFile
applicationVariants.all { variant ->
variant.outputs.all() { output ->
def flavor = variant.productFlavors[0]
def fileName = "${variant.flavorName}_${flavor.versionCode}.${variant.versionName}.apk"
/*//默认打包方式,打包到app的子目录下
outputFileName = fileName*/
//修改打包路径,工程apkpackage文件夹下
//也可以在打包时手动选择对应目录
def des = output.packageApplication.outputDirectory.toPath().relativize(rootDir.toPath()).toFile()
outputFileName = new File("$des/apkpackage", fileName)
}
}
...
}
代码注释些的很多,请自行查看。
apply plugin: 'com.android.application'
android {
compileSdkVersion 28
dexOptions {
javaMaxHeapSize "2g"
preDexLibraries = false
}
defaultConfig {
applicationId "com.demon.multichannelpackaging"
minSdkVersion 16
targetSdkVersion 28
versionCode 1
versionName "1.0"
multiDexEnabled true
}
//配置资源文件路径,可动态指定不同版本资源文件
sourceSets {
//用各自对应的资源文件路径
company.res.srcDirs = ['src/main/res-company']
hospital.res.srcDirs = ['src/main/res-hospital']
//多渠道打包目录配置
debug.setRoot('build-types/debug')
release.setRoot('build-types/release')
}
//版本比较多时,自定义导出的APK名称,不同的渠道编出的APK的文件名应该是不一样的
//Android插件3.0迁移指南所示:
//用all()而不是each()
//如果您只更改文件名(这是您的情况),请使用outputFileName而不是output.outputFile
applicationVariants.all { variant ->
variant.outputs.all() { output ->
def flavor = variant.productFlavors[0]
def fileName = "${variant.flavorName}_${flavor.versionCode}.${variant.versionName}.apk"
/*//默认打包方式,打包到app的子目录下
outputFileName = fileName*/
//修改打包路径,工程apkpackage文件夹下
//也可以在打包时手动选择对应目录
def des = output.packageApplication.outputDirectory.toPath().relativize(rootDir.toPath()).toFile()
outputFileName = new File("$des/apkpackage", fileName)
}
}
//debug和release版本的签名配置
signingConfigs {
debug {
storeFile file("DeMon.jks")
keyAlias = 'key'
keyPassword = '123456'
storePassword = '123456'
}
release {
storeFile file("DeMon.jks")
keyAlias = 'key'
keyPassword = '123456'
storePassword = '123456'
}
}
buildTypes {
//指定打包时的签名,如果有不同的签名可放在productFlavors不同项目下执行,不过一般都会相同
debug {
//显示Log
buildConfigField "boolean", "LOG_DEBUG", "true"
//apk包名称后缀,用来区分release和debug
versionNameSuffix "-debug"
//修改包名,能够同时安装debug和release
applicationIdSuffix ".debug"
//在build.gradle定义资源文件值,可以在程序中像其他string值一样被引用
//格式resValue 类型, key(不能与strings.xml文件中的相同), value(可以直接使用strings.xml文件中的值)
resValue "string", "home_text", "@string/text_debug"
minifyEnabled false
signingConfig signingConfigs.debug
}
release {
//不显示Log
buildConfigField "boolean", "LOG_DEBUG", "false"
versionNameSuffix "-release"
//修改包名,能够同时安装debug和release
applicationIdSuffix ".release"
resValue "string", "home_text", "@string/text_release"
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
}
//多渠道配置,可以配置多个,此处只配置两个
productFlavors {
company {
//修改包名,能够同时安装多个渠道版本
applicationId "com.demon.multichannelpackaging.company"
versionCode 1
versionName "0.1"
//flavor维度,3.0以上,必须每个渠道版本必须增加,此处以版本号作为维度值
//详情见:https://blog.csdn.net/syif88/article/details/75009663/
flavorDimensions "versionCode"
}
hospital {
//修改包名,能够同时安装多个渠道版本
applicationId "com.demon.multichannelpackaging.hospital"
versionCode 1
versionName "0.1"
flavorDimensions "versionCode"
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0-rc02'
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
}
Gradle实现多渠道打包(不同资源文件打不同的包)
Android 同时安装debug release版, 并且显示不同名字
https://blog.csdn.net/syif88/article/details/75009663/