业务背景
最近接到了一个任务,在flutter项目中实现类似web应用的配置scripts可以进行使用不同配置构建应用产物,刚入坑flutter不久,以为也可以使用不同配置构建不一样的安卓生产产物从而在一台设备上安装不同版本的包(确实可以,不过不太一样,例如test版本、release版本等)。
开干
配置文件
先打开Android目录下的app目录,打开build.gradle文件,找到关键的地方
初始想法
signingConfigs是用来配置签名文件的,那么能不能实现release版本使用正式签名,trial(原来叫test,但是构建后报错不能使用这个名字)版本使用测试签名呢,得,那么开干试试。
生成测试版本keystore
一句代码在cmd敲上即可
bash
keytool -genkey -alias testalias -keyalg RSA -keysize 2048 -validity 36500 -keystore test.keystore
- testalias是证书别名,可修改为自己想设置的字符
- test.keystore是证书文件名称,可修改为自己想设置的文件名称,也可以指定完整文件路径
- 36500是证书的有效期,表示100年有效期,单位天,建议时间设置长一点,避免证书过期
设置新的构建模式
首先老样子,先配置.properties文件存放keystore信息
storePassword=store密码
keyPassword=key密码
keyAlias=别名
storeFile=../release.keystore文件存放地址(这里他的/目录是Android/app,我是存放在Android下所以使用../)
接下来改build.gradle
scss
// 在android前加(读取文件用)
def keystoreProperties = new Properties()
def keystorePropertiesFile = rootProject.file('key.properties')
if (keystorePropertiesFile.exists()) {
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}
android {
// ...你的代码
signingConfigs {
//...原先的release配置
trial {
keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword']
storeFile file(keystoreProperties['storeFile'])
storePassword keystoreProperties['storePassword']
}
}
buildTypes {
// ...原先代码
trial {
signingConfig signingConfigs.trial
}
}
}
原来以为到这里可以了,然后执行flutter build apk --trial,结果:
g,问了代码小助手回答的全是牛头不对马嘴,行吧这时候查安卓文档,结果发现:
也捣鼓了半天试着能不能自定义buildType然后指定这个模式构建(就像web一样pnpm build、pnpm dev这样,若有帅哥美女有解决方案可以踢我一下),几个h之后,哎,遂放弃。。。
Flavor大法
又查了一遍安卓文档,总算找到一些有用的(感谢flutter群友黄金矿工提供方向,头像是我就这么叫了):
原来安卓里叫变体,配置在productFlavors(直译生产口味,听起来有点怪怪的),既然查到了解决方案,那么就开始把,写配置文件。
arduino
android {
// ...原代码
flavorDimensions "version"
productFlavors {
trial {
dimension "version"
applicationIdSuffix ".trial"
versionNameSuffix "-trial"
}
}
}
applicationIdSuffix可以指定在applicationId后面加后缀,versionNameSuffix打出来的包加后缀,也可以直接指定新的applicationId覆盖defaultConfig中的applicationId,至此问题解决了(本来是打算用两个签名打两个包,其实想装在一台机子上不同版本签名可以一样,只需要applicationId不一样就行)。
对了还有一个问题还没解决,打包的时候偶发
注释掉flavor相关代码再打包一次又解决了,要打包flavor中的变体版本再解开注释即可,有知道的帅哥美女们可以告诉我一下怎么解决)
配置不同环境api接口
其一方法是:分两个不一样的入口打包(这里感谢李小轰大佬提供的思路)
scss
flutter build apk --verbose --target = lib/main.dart // 正式环境
flutter build apk --verbose --target = lib/main_test.dart //测试环境
其二方法:在初始化的时候读取包名结尾,比如打了两个包 一个是以.demo结尾 一个以.release结尾,这时候读取到应用的包名,在初始化的时候就可以区分当前环境作接口区分。
两个方法总结:方法1适用于版本差异不是很大的,比如测试和生产版本只差了个api地址,如果还牵扯到主题等还是方法2更好一点
总结
一个在web上比较容易实现的问题搞了一天,写flutter还是要有些移动端的知识储备好,写了几个月flutter了,这些ai工具不知道是因为知识库的问题还是什么问题,回答的flutter解决方案要么就是编的指令,要么就是n久以前的版本解决方案(编译器经常提示废弃了请用新的api代替),试过gpt、智谱清言都不好用,最后祝大家都0warning、0error。