很多时候,会有以下需求:
同一个项目生成不同的APK,比如说一个正式版、一个测试版,他们会拥有不同的包名,打包出来后两个APK都能同时安装到同一个Android设备。
甚至有更复杂的需求:比如说,为每一个省/城市打包为具有不同包名的APK,每个APK的桌面图标、应用名称均不相同。
不一定每个开发者都会遇到这种奇葩需求,但是我的确是遇到了。
以下演示,同一个项目打包为两个APK,一个正式版,一个测试版,
正式版包名: com.example.www
测试版包名: com.example.www.test
从环境变量入手
在cli生成的项目, package.json
中的 scripts
中,可以看到一堆的环境变量配置,比如:
{
"dev:h5": "cross-env NODE_ENV=development UNI_PLATFORM=h5 vue-cli-service uni-serve",
}
使用 cross-env
配置环境变量,这里,传入了:
- NODE_ENV
- UNI_PLATFORM
通过 process.env
取出环境变量,我们可以做很多事情,比如根据不同的环境变量设置不同的接口地址:
// #ifdef H5
let baseApi = ""
switch (process.env.NODE_ENV) {
case 'development':
baseApi = "https://api.example.com/"
break
case 'production':
baseApi = "https://api.example.com/"
break
case 'test':
baseApi = "https://testapi.example.com/"
break
}
// #endif
那么,我们是不是可以通过环境变量,编写一个自动化打包脚本,分别用于不同环境、不同渠道?答案肯定是可以的。
手动配置Android原生工程
在进行自动化打包之前,我们需要知道手动如何进行多环境、多渠道打包。以便我们后续编写自动化打包脚本,模拟开发者手动执行打包操作。
我们知道,包名配置于build.gradle
:
defaultConfig {
applicationId "com.example.www"
minSdkVersion 19
targetSdkVersion 28
versionCode 300
versionName "1.0.0"
}
如果我们想要快速地添加一个打包环境 debug
,在默认包名的基础上生成一个新的包名,比如在默认包名后添加一个后缀 .test
,也就是:com.example.www.test
。直接修改 build.gradle
,配置两个打包环境:
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
resValue "string", "app_name", "My APP"
}
debug {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
applicationIdSuffix ".test"
resValue "string", "app_name", "My APP 测试"
}
}
其中:
applicationIdSuffix
应用包名后缀,测试包名在正常包名后添加后缀resValue
配置的string
资源,相当于在strings.xml
中添加资源:<string name="app_name">My APP</string>
不过需要注意,在build.gradle
中添加过 resValue
后,对应的资源应该删掉,否则编译会报错,提示有重复的资源。
自动化打包脚本
当然,不可能每次打包的时候都去开一个Android Studio,然后手动去点击签名打包。一两次还好,每次都去搞就会很烦。于是,我们可以将打包过程做成一个脚本,自动匹配环境,自动使用命令打包,无需可视化。
具体做法是: