Flutter Analysis and Practice: Hybrid Projects and Continuous Integration

Image for post
Image for post

1.3.1 Background

Image for post
Image for post
Figure 1–16

1.3.2 Implementation Methods

1.3.2.1 Analyze Flutter Projects That Native Projects Depend On

Image for post
Image for post
Figure 1–17

1.3.2.2 Extract the Flutter Library Android Depends On

echo "Clean old build"
find . -d -name "build" | xargs rm -rf
./flutter/bin/flutter clean
echo "Get packages"
./flutter/bin/flutter packages get
echo "Build release AOT"
./flutter/bin/flutter build aot --release --preview-dart-2 --output-dir= build/flutteroutput/aot
echo "Build release Bundle"
./flutter/bin/flutter build bundle --precompiled --preview-dart-2 --asset-dir=build/flutteroutput/flutter_assets
project.android.buildTypes.each {
addFlutterJarImplementationDependency(project, releaseFlutterJar)
}
project.android.buildTypes.whenObjectAdded {
addFlutterJarImplementationDependency(project, releaseFlutterJar)
}
private static void addFlutterJarImplementationDependency(Project project, releaseFlutterJar) {
project.dependencies {
String configuration
if (project.getConfigurations().findByName("api")) {
configuration = "api"
} else {
configuration = "compile"
}
add(configuration, project.files {
releaseFlutterJar
})
}
}
// 合并 flutter assets
def allertAsset ="${project.projectDir.getAbsolutePath()}/flutter/assets/ release"
Task mergeFlutterAssets = project.tasks.create(name: "mergeFlutterAssets${variant.name.capitalize()}", type: Copy) {
dependsOn mergeFlutterMD5Assets
from (allertAsset){
include "flutter_assets/**"
include "vm_snapshot_data"
include "vm_snapshot_instr"
include "isolate_snapshot_data"
include "isolate_snapshot_instr"
}
into variant.mergeAssets.outputDir
}
variant.outputs[0].processResources.dependsOn(mergeFlutterAssets)
echo 'Clean packflutter input(flutter build)'
rm -f -r android/packflutter/flutter/
# 拷贝flutter.jar
echo 'Copy flutter jar'
mkdir -p android/packflutter/flutter/flutter/android-arm-release && cp flutter/bin/cache/artifacts/engine/android-arm-release/flutter.jar "$_"
# 拷贝asset
echo 'Copy flutter asset'
mkdir -p android/packflutter/flutter/assets/release && cp -r build/ flutteroutput/aot/* "$_"
mkdir -p android/packflutter/flutter/assets/release/flutter_assets && cp -r build/flutteroutput/flutter_assets/* "$_"
# 将Flutter库和flutter_app打成AAR文件,同时发布到Ali-maven
echo 'Build and publish idlefish flutter to aar'
cd android
if [ -n "$1" ]
then
./gradlew :packflutter:clean :packflutter:publish -PAAR_VERSION=$1
else
./gradlew :packflutter:clean :packflutter:publish
fi
cd ../
# 将Plugin发布到Ali-maven
echo "Start publish flutter-plugins"
for line in $(cat .flutter-plugins)
do
plugin_name=${line%%=*}
echo 'Build and publish plugin:' ${plugin_name}

cd android
if [ -n "$1" ]
then
./gradlew :${plugin_name}:clean :${plugin_name}:publish -PAAR_VERSION =$1
else
./gradlew :${plugin_name}:clean :${plugin_name}:publish
fi
cd ../
done
configurations.all {
resolutionStrategy.cacheChangingModulesFor 0, 'seconds'
}
ext {
flutter_aar_version = '6.0.2-SNAPSHOT'
}
dependencies {
//Flutter主工程依赖:包含基于Flutter开发的功能、Flutter引擎lib
compile("com.taobao.fleamarket:IdleFishFlutter:${getFlutterAarVersion(project)}") {
changing = true
}
//其他依赖
}
static def getFlutterAarVersion(project) {
def resultVersion = project.flutter_aar_version
if (project.hasProperty('FLUTTER_AAR_VERSION')) {
resultVersion = project.FLUTTER_AAR_VERSION
}
return resultVersion
}

1.3.3 Extract the Flutter Library That iOS Depends On

1.3.3.1 Generate Flutter Dependency Files on iOS

1.3.3.2 Implement Flutter Dependency Extraction on iOS

echo "===清理flutter历史编译==="
./flutter/bin/flutter clean
echo "===重新生成plugin索引==="
./flutter/bin/flutter packages get
echo "===生成App.framework和flutter_assets==="
./flutter/bin/flutter build ios --release
echo "===生成各个插件的二进制库文件==="
cd ios/Pods
#/usr/bin/env xcrun xcodebuild clean
#/usr/bin/env xcrun xcodebuild build -configuration Release ARCHS='arm64 armv7' BUILD_AOT_ONLY=YES VERBOSE_SCRIPT_LOGGING=YES -workspace Runner.xcworkspace -scheme Runner BUILD_DIR=../build/ios -sdk iphoneos
for plugin_name in ${plugin_arr}
do
echo "生成lib${plugin_name}.a..."
/usr/bin/env xcrun xcodebuild build -configuration Release ARCHS='arm64 armv7' -target ${plugin_name} BUILD_DIR=../../build/ios -sdk iphoneos -quiet
/usr/bin/env xcrun xcodebuild build -configuration Debug ARCHS='x86_64' -target ${plugin_name} BUILD_DIR=../../build/ios -sdk iphonesimulator -quiet
echo "合并lib${plugin_name}.a..."
lipo -create "../../build/ios/Debug-iphonesimulator/${plugin_name}/lib${plugin_name}.a" "../../build/ios/Release-iphoneos/${plugin_name}/lib${plugin_name}.a" -o "../../build/ios/Release-iphoneos/${plugin_name}/lib${plugin_name}.a"
done
echo "===生成注册入口的二进制库文件==="
for reg_enter_name in "flutter_plugin_entrance" "flutter_service_register"
do
echo "生成lib${reg_enter_name}.a..."
/usr/bin/env xcrun xcodebuild build -configuration Release ARCHS='arm64 armv7' -target ${reg_enter_name} BUILD_DIR=../../build/ios -sdk iphoneos
/usr/bin/env xcrun xcodebuild build -configuration Debug ARCHS='x86_64' -target ${reg_enter_name} BUILD_DIR=../../build/ios -sdk iphonesimulator
echo "合并lib${reg_enter_name}.a..."
lipo -create "../../build/ios/Debug-iphonesimulator/${reg_enter_name}/lib${reg_enter_name}.a" "../../build/ios/Release-iphoneos/${reg_enter_name}/lib${reg_enter_name}.a" -o "../../build/ios/Release-iphoneos/${reg_enter_name}/lib${reg_enter_name}.a"
done

1.3.4 Continuous Integration Process of the Flutter Hybrid Project

Image for post
Image for post
Figure 1–18

Original Source:

Follow me to keep abreast with the latest technology news, industry insights, and developer trends.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store