Android打包Flutter模块上传到maven仓库的最佳实现
在混合开发中,把Flutter模块打包成aar提供给宿主工程依赖可以很大成都降低团队Flutter的学习成本,也是很多混合开发团队的首选,但是如何把build出来的aar包上传到maven仓库,却是一个值得探讨的话题,以为上传到远端maven仓库会存在以下问题:
1、如何自动化上传所有的aar和pom文件?
在对Flutter模块进行打包时,很少只会打出一个aar模块,因为许多依赖的三方库在打包时也会生成aar和pom文件,通过手动的方式上传到maven仓库显然是不合适的,因此需要一个自动化脚本来帮我们遍历build/host/outputs/repo
下面的所有aar和pom文件并上传。
2、如何隔离不同项目flutter模块里相同三方依赖冲突的风险?
如果有5个不同项目里都有flutter模块,这些模块都依赖的webview_flutter
,但是版本有可能不同,webview_flutter
生成的pom文件里组织名是相同的,如果直接上传到maven,可能会影响到其他的项目。需要隔离不同flutter中引用的相同框架生成的aar来规避不确定风险,因为一旦出现这样的风险,将会很难排查。
以下就是针对上诉问题,我给你的答案:
首先在flutter项目根目录定义一个package.properties
的文件,其内容如下:
projectName=demo
packageName=com.example.upload
buildVersion=1.0.5
mavenRepository=http://admin:admin123@localhost:8081/repository/flutter_modules/
mavenSnapshots=http://admin:admin123@localhost:8081/repository/maven-snapshots/
复制代码
projectName
:flutter项目的名称,该名称会作为maven仓库中的artifactId
来起隔离作用。
packageName
:即yaml文件中定义的androidPackage
,这个也是生成flutter aar的groupId
buildVersion
:要打包的aar版本号,每次升级在这里修改版本号,也是maven中的version
,通过在文件里显示定义,也能更好的起到记录作用。
mavenRepository
:发布Release版本要上传的仓库地址
mavenSnapshots
:发布Debug版本要上传的仓库地址,因为debug版本的发布频繁,因此使用snapshots来管理。
配置文件做好后,创建一个名为packageHelper.sh
的文件,文件内容如下,我把关键节点用注解的方式标注在了脚本中:
#!/bin/bash
# shellcheck disable=SC2086
# shellcheck disable=SC2001
# shellcheck disable=SC2005
# shellcheck disable=SC2016
#引入配置文件
PROPERTIES="package.properties"
#maven依赖三要素
packageNameV=""
projectNameV=""
buildVersionV=""
#maven仓库地址
mavenRepositoryV=""
mavenSnapshotsV=""
#是否为release版本
isRelease=$1
#当前使用的仓库,根据isRelease的不同而不同
usedMavenRepo=""
#读取配置文件信息并做容错处理
if [ -f "$PROPERTIES" ]
then
. $PROPERTIES
packageNameV=$packageName
projectNameV=$projectName
buildVersionV=$buildVersion
if [ -z "$packageNameV" ]; then
echo ERROR:"package.properties文件中没有配置packageName!"
exit 1
fi
if [ -z "$projectNameV" ]; then
echo ERROR:"package.properties文件中没有配置projectName!"
exit 1
fi
if [ -z "$buildVersionV" ]; then
echo ERROR:"package.properties文件中没有配置buildVersion!"
exit 1
fi
mavenRepositoryV=$mavenRepository
mavenSnapshotsV=$mavenSnapshots
if [[ -z "$mavenRepositoryV" ]] && [[ -z "$mavenSnapshotsV" ]]
then
echo ERROR:"请检查是否在package.properties中正确配置了maven仓库信息!"
exit 1
fi
else
echo ERROR:"请先根据要求配置package.properties文件然后执行该脚本!"
exit 1
fi
#根据是否为release版来确定使用的仓库地址
if [ $isRelease = "true" ]
then
usedMavenRepo=$mavenRepositoryV
echo "当前打包Release版本,版本号:$buildVersion,running..."
else
usedMavenRepo=$mavenSnapshotsV
echo "当前打包Debug版本,版本号固定为1.0-SNAPSHOT,running..."
fi
#如果不是release版本,则版本号强行指定为1.0-SNAPSHOT
showBuildVersion=1.0-SNAPSHOT
#打包前清理
echo "flutter clear..."
flutter clean
#打包前获取依赖
echo "flutter pub get..."
flutter pub get
echo "flutter pub get..."
#根据isRelease执行不同的打包逻辑
if [ $isRelease = "true" ]
then
showBuildVersion=$buildVersionV
#打包release版本,避免生成多余的包导致资源浪费
flutter build aar --target-platform android-arm --no-profile --no-debug --build-number "$showBuildVersion"
else
#打包debug版本,避免生成多余的包导致资源浪费
flutter build aar --target-platform android-arm --no-profile --no-release --build-number "$showBuildVersion"
fi
echo "aar打包完成,开始上传maven..."
#方法 修改所有pom文件的名称
function renameAllPomArtifactId() {
find build/host/outputs/repo -name "*.pom" | while read -r file
do
sed -i -e "s/>$1</>$2</g" $file
done
}
#第一次遍历repo文件夹下所有后缀名为.aar的文件
find build/host/outputs/repo -name "*.aar" | while read -r file
do
#当前aar文件所在的目录
currDirName=$(dirname $file)
aarName=$file
#当前aar文件对应的pom文件(aar和pom一一对应)
pomName="$currDirName/$(basename $file .aar).pom"
#从pom文件中读取出groupId信息
groupId=$(awk '/<groupId>[^<] </groupId>/{gsub(/<groupId>|</groupId>/,"",$1);print $1;exit;}' $pomName)
#从pom文件中读取出artifactId信息,但是此时的artifactId并不是我们在properties中配置的,而是编译器自动生成的
artifactId=$(awk '/<artifactId>[^<] </artifactId>/{gsub(/<artifactId>|</artifactId>/,"",$1);print $1;exit;}' $pomName)
#修改artifactId为在properties中配置的
renameAllPomArtifactId $artifactId $projectName
done
#第二次遍历repo文件夹下所有后缀名为.aar的文件,为什么要二次遍历?
#为了防止pom中的artifactId还没有全部修改完便被上传到maven引起的问题
find build/host/outputs/repo -name "*.aar" | while read -r file
do
#当前aar文件所在的目录
currDirName=$(dirname $file)
aarName=$file
#当前aar文件对应的pom文件(aar和pom一一对应)
pomName="$currDirName/$(basename $file .aar).pom"
#从pom文件中读取出groupId信息
groupId=$(awk '/<groupId>[^<] </groupId>/{gsub(/<groupId>|</groupId>/,"",$1);print $1;exit;}' $pomName)
#从pom文件中读取出artifactId信息,此时已经修改为properties中配置的
artifactId=$(awk '/<artifactId>[^<] </artifactId>/{gsub(/<artifactId>|</artifactId>/,"",$1);print $1;exit;}' $pomName)
echo "正在上传 = $aarName ..."
#执行上传maven仓库命令
mvn deploy:deploy-file
-DgroupId=$groupId
-DartifactId=$projectName
-Dpackaging=aar
-Dversion=$showBuildVersion
-Dfile=$aarName
-DpomFile=$pomName
-Durl=$usedMavenRepo
done
#所有操作完成后给一个友善的提示
function finishEcho() {
echo "
上传完毕!请通过如下方式引入Flutter模块到宿主项目中:
1. 打开宿主项目根目录build.gradle文件并添加如下引用:
String storageUrl = System.env.FLUTTER_STORAGE_BASE_URL ?: "https://storage.googleapis.com"
repositories {
repositories {
//TODO 删除maven仓库url中配置的账号密码信息
maven { url "$1" }
}
maven {
url "$storageUrl/download.flutter.io"
}
}
2. 在使用到Flutter的模中添加如下依赖:
dependencies {
debugImplementation '$2:$3:$4'
//or
releaseImplementation '$2:$3:$4'
}
3. 同步项目,完成Flutter模块的依赖。
"
}
finishEcho $usedMavenRepo $packageNameV $projectName $showBuildVersion
复制代码
引入后项目结构如下:
在根目录下运行命令:
代码语言:javascript复制//打包debug版本 不传参数默认为debug版本
./packageHelper.sh false
//打包release版本
./packageHelper.sh true
复制代码
Tips:注意packageHelper.sh文件是否有运行权限
最后结果如下:
最后,就可以在宿主工程中愉快的引入flutter模块的依赖了~
Demo地址:flutter_aar_upload,赶快试试吧~