前言
我们在写 flutter 项目时每次执行 pub clean 后.android 项目同样会重新创建,在我们项目中遇到minSdkVersion 默认(17)及 kotlin 默认 (1.3.50) 版本低,相信大家都遇到过,每次都需要手动设置,考虑这种手动操作繁琐让我团队成员不胜其扰。通过 py 脚本一键处理这个问题,大家也就能愉快开发了~😆
minSdkVersion 版本问题
kotlin 版本问题
思考
之前我们手动修改 flutter 自动生成的 build.gradle 的模板文件,具体可以看这里 传送门。但每次都需要自己去手动去修改模板文,文件路径打开比较麻烦,并且我们更新 flutter 版本后这里也会重置掉。既然如此我想通过 Python 脚本自动去生成对应的模板文件覆盖即可。
使用
方式一
- 配置好
ssh 工具shuttle 一键执行,其实shuttle的命令是用json来设置,可以结合[jsonnet](https://github.com/google/jsonnet)去动态生成,这样就可以复用给别人

- 当然我们也可以直接终端执行,不过需要自己写好对应的路径相对麻烦些如下, 所以我更推荐使用
ssh 工具shuttle 一键执行。cd /Users/zhengzeqin/Desktop/GitLab/TWHouseScript; python flutter_android_build_gradle_set.py -p '/Users/addcn/flutter/packages/flutter_tools/templates/module/android/gradle/build.gradle.tmpl' -a /Users/addcn/flutter/packages/flutter_tools/templates/module/android/host_app_common/app.tmpl/build.gradle.tmpl
方式二
路径我们也可以写在脚本里,定义好需要修改的 flutter sdk 的目标模板路径即可,具体如下
# 定义 flutter 目标 android project build_gradle 配置的路径_project_build_gradle_set_file = "/Users/zhengzeqin/flutter/packages/flutter_tools/templates/module/android/gradle/build.gradle.tmpl"# 定义 flutter 目标 android app build_gradle 配置的路径_app_build_gradle_set_file = "/Users/zhengzeqin/flutter/packages/flutter_tools/templates/module/android/host_app_common/app.tmpl/build.gradle.tmpl"# 定义需要写入的 android project 根目录的 build_gradle 配置_build_gradle_tmpl_for_project = "/build_gradle_tmpl_for_project.txt"# 定义需要写入的 android app 目录的 build_gradle 配置_build_gradle_tmpl_for_app = "/build_gradle_tmpl_for_app.txt"# ...if __name__ == "__main__":# 执行脚本路径修改 Android build gradle 的目标模板set_android_build_gradle_params_files()pass
完整脚本代码
自定义 Android Project 的 build gradle 模板
def flutterPluginVersion = 'managed'apply plugin: 'com.android.application'android {compileSdkVersion 31compileOptions {sourceCompatibility JavaVersion.VERSION_1_8targetCompatibility JavaVersion.VERSION_1_8}defaultConfig {applicationId "{{androidIdentifier}}.host"minSdkVersion 21targetSdkVersion 31versionCode 1versionName "1.0"}buildTypes {profile {initWith debug}release {// TODO: Add your own signing config for the release build.// Signing with the debug keys for now, so `flutter run --release` works.signingConfig signingConfigs.debug}}}buildDir = new File(rootProject.projectDir, "../build/host")dependencies {implementation project(':flutter')implementation fileTree(dir: 'libs', include: ['*.jar'])implementation 'androidx.appcompat:appcompat:1.0.2'implementation 'androidx.constraintlayout:constraintlayout:1.1.3'}
自定义 Android App 的 build gradle 模板
// Generated file. Do not edit.buildscript {ext.kotlin_version = '1.6.10'repositories {google()mavenCentral()}dependencies {classpath 'com.android.tools.build:gradle:{{agpVersion}}'classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"classpath "org.jetbrains.kotlin:kotlin-android-extensions:$kotlin_version"}}allprojects {repositories {google()mavenCentral()}}task clean(type: Delete) {delete rootProject.buildDir}
需要修改的 Flutter 目标模板

脚本代码
# -*- coding: utf-8 -*-# -*- author: zhengzeqin -*-# -*- date: 2022-03-07 -*-"""Flutter 修改默认生成的 minSdkVersion 问题flutter pub get 会自动生成 android 目录,但是如果要修改 build.gradle 文件里面的内容,需要每次都要手动改一下,很麻烦解决办法修改 flutter 自动生成的 build.gradle 的模板文件模板文件路径: flutter_sdk/packages/flutter_tools/templates/module/android/host_app_common/app.tmpl/build.gradle.tmplpy 解决思路: 通过脚本一键复制修改 flutter 配置模板"""import osimport sysimport getopt# 定义 flutter 目标 android project build_gradle 配置的路径_project_build_gradle_set_file = "/Users/zhengzeqin/flutter/packages/flutter_tools/templates/module/android/gradle/build.gradle.tmpl"# 定义 flutter 目标 android app build_gradle 配置的路径_app_build_gradle_set_file = "/Users/zhengzeqin/flutter/packages/flutter_tools/templates/module/android/host_app_common/app.tmpl/build.gradle.tmpl"# 定义需要写入的 android project 根目录的 build_gradle 配置_build_gradle_tmpl_for_project = "/build_gradle_tmpl_for_project.txt"# 定义需要写入的 android app 目录的 build_gradle 配置_build_gradle_tmpl_for_app = "/build_gradle_tmpl_for_app.txt"# 读取文件内容def readfile(file_name):file2 = open(file_name)str = file2.read()file2.close()return str# 设置 build_gradle 的内容def android_gradle_set():# 获取当前文件路径concurrent = os.path.abspath(os.path.dirname(__file__))read_file_path = concurrent + '/build_gradle_tmpl_for_project.txt'write_file_path = concurrent + '/build.gradle.tmpl'read_file = open(read_file_path, 'r')write_file = open(write_file_path, "w")s = read_file.read()w = write_file.write(s)read_file.close()write_file.close()# 从文件路径中写入到目标文件def set_build_gradle_file(read_file_path, write_file):read_file = open(read_file_path, 'r')write_file = open(write_file, "w")s = read_file.read()write_file.write(s)read_file.close()write_file.close()# 获取当前文件夹的路径def get_current_path():return os.path.abspath(os.path.dirname(__file__))# 设置 app 的 filedef set_app_build_gradle_file():read_file_path = get_build_gradle_file(_build_gradle_tmpl_for_app)set_build_gradle_file(read_file_path, _app_build_gradle_set_file)# 设置 project 根目录的 filedef set_pro_build_gradle_file():read_file_path = get_build_gradle_file(_build_gradle_tmpl_for_project)set_build_gradle_file(read_file_path, _project_build_gradle_set_file)# 读取本地配置文件def get_build_gradle_file(build_gradle_tmpl):concurrent = os.path.abspath(os.path.dirname(__file__))read_file_path = concurrent + build_gradle_tmplreturn read_file_path# 通过本地文件配置路径修改 Android 项目的 build_gradle 配置def set_android_build_gradle_params_files():set_pro_build_gradle_file()set_app_build_gradle_file()# 通过参数配置路径修改 Android 项目的 build_gradle 配置def set_android_build_gradle_argv_files():argv = sys.argv[1:]# android project build_gradle 配置的路径project_path = ""# android app build_gradle 配置的路径app_path = ""# 默认关闭is_close_bitcode = Truetry:opts, args = getopt.getopt(argv, "p:a:", ["project=", "app="])except getopt.GetoptError:print('flutter_android_gradle_set.py -p "项目路径"')sys.exit(2)print("opts ===>", opts)for opt, arg in opts:if opt in ["-p", "--project"]:project_path = argif opt in ["-a", "--app"]:app_path = arg# 设置 project build gradleread_pro_file_path = get_build_gradle_file(_build_gradle_tmpl_for_project)set_build_gradle_file(read_pro_file_path, project_path)# 设置 app build gradleread_app_file_path = get_build_gradle_file(_build_gradle_tmpl_for_app)set_build_gradle_file(read_app_file_path, app_path)if __name__ == "__main__":# set_android_build_gradle_params_files()set_android_build_gradle_argv_files()pass
