Flutter 解放双手-Shell自动化打包之APK
终于有时间,可以安安静静地写点东西了,把解放双手系列给续下去了.好了,废话少说,直接开始.
您能在这里看到啥
温故知新
往期文章
流程图如下所示
脚本目录如下所示
android 打包流程
经过我们分析完成后,总结出以上流程,这样更方便在编写代码的时候,减少出错率. 此时,我们再来看一下pack_apk.sh文件,看看里面的执行方法吧
# 执行打包命令
flutterBuild()
# 构建渠道包
apkBuild()
# 最终执行打包apk全部流程
buildApk()
这三个方法,就完成了完整的打包流程,具体里面的细节,我们慢慢展开来讲.
- buildApk()
- 展开代码我们来看一下里面具体的内容
buildApk() { # 1.执行打包 mycmd=apkBuild echo "$mycmd" # 2. 判断打包是否成功 if $mycmd; then if [ "$project_build_type" == 1 ]; then expord_path="$export_apk_release_path" else expord_path="$export_apk_debug_path" fi echomsg "$upload_type" # 3. 打包成功后,判断上传类型 if [ "$upload_type" == 2 ]; then # 开始上传蒲公英 for f in "$expord_path"*.apk; do [[ -e "$f" ]] || break echo "$f" uploadPgyer "$api_key" "$f" done else # 打开apk 路径 echomsg "apk 打包成功" open "$export_apk_release_path" fi else echomsg "apk 打包失败" fi }
- 展开代码我们来看一下里面具体的内容
从代码流程中,我们再来总结一下
- 执行打包
- 判断打包是否成功
- 打包成功后,判断上传类型
- 开始上传蒲公英
- 打开apk路径
- 完成apk打包
是的,没有一点问题,完全符合流程图.下面我们再打开剩下的两个方法吧
apkBuild()
flutterBuild()
这里我们直接跳到最终落地打包的方法里,因为apkBuild(),只是做了一个简单构建版本的逻辑处理,最终还是flutterBuild() 抗下了所有(all in)
- flutterBuild()
- 展开代码我们来看一下里面具体的内容
flutterBuild() { echo "$build_type" echomsg "$upload_type" # 最终执行打包命令,展现出来了. flutter build apk --no-shrink --dart-define=CHANNEL="$1" --dart-define=DEBUG="$build_type" --"$build_type" if [[ $project_build_type == 1 ]]; then cp -R "$flutter_release_apk_path"*.apk "$export_apk_release_path" else cp -R "$flutter_debug_apk_path"*.apk "$export_apk_debug_path" fi }
从上面的代码中,我们终于看到了最终的打包指令
flutter build apk --no-shrink --dart-define=CHANNEL="$1" --dart-define=DEBUG="$build_type" --"$build_type"
这个指令,总共分为三个部分
-
flutter build
构建app系统类型,分apk,ios等等类型. eg: flutter build apk --release(默认类型,可以不用写)
-
--no-shrink
不使用混淆 如果你想使用混淆,请手动删除即可.
-
--darf-define(重点要讲)
可以用于和项目传参数,这样就可以让我们,最起码实现多渠道分发的功能 eg: --darf-define=name=params eg: 多个参数就是--darf-define=name=params --darf-define=name=params 即可
下面我们来讲一下和 --darf-define 相互配合的就是android项目配置
android 项目配置
--dart-define=CHANNEL="1"−−dart−define=DEBUG="1" --dart-define=DEBUG="1"−−dart−define=DEBUG="build_type"
那我们怎么让安卓项目接收这些参数呢,下面我们先看一下,不配置后面参数的时候,我们来看下,打包成功后,显示的原始apk名字.
- flutter build apk
- 执行脚本如下
如图所示,默认情况下我们打包的环境的release,所以flutter自己导出的apk,默认就是app+budiltype.apk,即app-release.apk.那我们怎么修改打包出的apk名字呢.
- 执行脚本如下
- 修改android原生中gradle中的配置,添加修改apk名字的代码.如下所示
对应的代码如下所示
applicationVariants.all { variant ->
variant.outputs.all { output ->
// 设置新名称
println(dartEnvironmentVariables.DEBUG)
println(dartEnvironmentVariables)
println(variant.buildType.name)
def newApkName ="APP_${dartEnvironmentVariables.CHANNEL}_${dartEnvironmentVariables.DEBUG}_${flutterVersionName}_${flutterVersionCode.toInteger()}.apk"
outputFileName = new File(newApkName)
}
}
这样我们就可以去定义apk的名字了.细心的你会发现,上面的代码中有几个和dart有关的参数.
dartEnvironmentVariables
flutterVersionName
flutterVersionCode
-
dartEnvironmentVariables
这个是我在buidl.gradle中,定义的一个属性.来我们也看一下,它具体做了些什么呢
从代码中,我们终于找到了和 --dart--define有关的代码了.通过上面的方式,我们就可以获取到 --dart-define=CHANNEL="1"−−dart−define=DEBUG="1" --dart-define=DEBUG="1"−−dart−define=DEBUG="build_type" 中的CHANNEL和DEBUG,对应的参数了.
-
flutterVersionName
flutter项目pubspec.yaml中的name: 字段
-
flutterVersionCode
flutter项目pubspec.yaml中的version: 字段中 + 前面版本
此时我们设置的apk命名规范就变成如下所示:
APP_+ {app渠道}_ + {buildType}_ + {flutterVersionName}_ + {flutterVersionCode}.apk
到此.apk名字修改就配置完成了.剩下的就是打包APK时,代码的配置了.
android 最终打包
最终还是到了这一步,终于经过前面的配置.我们还是来到了这里.
经过前面的项目配置,以及pack_apk.sh,文件的编写.我们的APK打包终于完成. 并且我们的android项目也适配了,多渠道打包的功能.就是通过 --dart--define 参数的形式,去重新编写不同渠道的apk的名字.也可以根据业务需求,做不同渠道的事件处理,这里我就不一一讲解了.
那我们就再看一下,脚本是怎么实现多渠道打包.如下所示
# 构建渠道包
apkBuild() {
echomsg "开始打包"
if [[ $apk_chanhels_length == 0 || $upload_type == 2 ]]; then
flutterBuild "Normal"
elif [[ $pack_apk_channel == 0 && $apk_chanhels_length != 0 ]]; then
echomsg "开始构建: 全部渠道包"
for ((i = 0; i < "$apk_chanhels_length"; i++)); do
echomsg "正在构建: ${apk_channels[$i]}渠道包"
flutterBuild apk_channels["$i"]
done
else
flutterBuild apk_channels["$pack_apk_channe"]
fi
}
从代码上,我这边做了三个逻辑处理,分别如下:
- 构建默认渠道.
- 构建全渠道的
- 构建指定渠道的
这样基本上就满足了我们正常的打包需求.至此.APK自动化打包完成.
系列文章
转载自:https://juejin.cn/post/7155042848633520164