中文字幕理论片,69视频免费在线观看,亚洲成人app,国产1级毛片,刘涛最大尺度戏视频,欧美亚洲美女视频,2021韩国美女仙女屋vip视频

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
閑魚flutter混合工程持續(xù)集成最佳實(shí)踐 · 語(yǔ)雀
作者:閑魚技術(shù)-然道

1. 引言

在之前的文章《Flutter混作者:閑魚技術(shù)-言合工程改造實(shí)踐》中,有些同學(xué)留言想了解抽取Flutter依賴到遠(yuǎn)程的一些實(shí)現(xiàn)細(xì)節(jié),所以本文重點(diǎn)來(lái)講一講Flutter混合工程中的Flutter直接依賴解除的一些具體實(shí)現(xiàn)。

2. 思考

因?yàn)槟壳拔覀冮e魚是Flutter和Native混合開發(fā)的模式,所以存在一部分同學(xué)只做Native開發(fā),并不熟悉Flutter技術(shù)。(1)如果直接采用Flutter工程結(jié)構(gòu)來(lái)作為日常開發(fā),那這部分Native開發(fā)同學(xué)也需要配置Flutter環(huán)境,了解Flutter一些技術(shù),成本比較大。(2)阿里集團(tuán)的構(gòu)建系統(tǒng)目前并不支持直接構(gòu)建Flutter項(xiàng)目,這個(gè)也要求我們解除Native工程對(duì)Flutter的直接依賴。鑒于這兩點(diǎn)原因,我們希望可以設(shè)計(jì)一個(gè)Flutter依賴抽取模塊,可以將Flutter的依賴抽取為一個(gè)Flutter依賴庫(kù)發(fā)布到遠(yuǎn)程,供純Native工程引用。如下圖所示:
>Flutter直接依賴解除

3. 實(shí)現(xiàn)

3.1 Native工程依賴的Flutter分析

我們分析Flutter工程,會(huì)發(fā)現(xiàn)Native工程對(duì)Flutter工程的依賴主要有三部分:1. Flutter庫(kù)和引擎: Flutter的Framework庫(kù)和引擎庫(kù)。2. Flutter工程: 我們自己實(shí)現(xiàn)的Flutter模塊功能,主要為Flutter工程下lib目錄下的dart代碼實(shí)現(xiàn)的這部分功能。3. 自己實(shí)現(xiàn)的Flutter Plugin: 我們自己實(shí)現(xiàn)的Flutter Plugin。
我們解開Android和iOS的APP文件,發(fā)現(xiàn)Flutter依賴的主要文件如下圖所示:
Flutter依賴的文件(Flutter產(chǎn)物)
其中,Android的Flutter依賴的文件:1. Flutter庫(kù)和引擎:icudtl.dat、libflutter.so、還有一些class文件。這些都封裝在flutter.jar中,這個(gè)jar文件位于Flutter庫(kù)目錄下的[flutter/bin/cache/artifacts/engine]下。2. Flutter工程產(chǎn)物:isolate_snapshot_data、isolate_snapshot_instr、vm_snapshot_data、vm_snapshot_instr、flutter_assets。3. Flutter Plugin:各個(gè)plugin編譯出來(lái)的aar文件。其中:
  • isolate_snapshot_data 應(yīng)用程序數(shù)據(jù)段
  • isolate_snapshot_instr 應(yīng)用程序指令段
  • vm_snapshot_data VM虛擬機(jī)數(shù)據(jù)段
  • vm_snapshot_instr VM虛擬機(jī)指令段
iOS的Flutter依賴的文件:**1. Flutter庫(kù)和引擎:**Flutter.framework**2. Flutter工程的產(chǎn)物:**App.framework**3. Flutter Plugin:**編譯出來(lái)的各種plugin的framework,圖中的其他framework
那我們只需要將這三部分的編譯結(jié)果抽取出來(lái),打包成一個(gè)SDK依賴的形式提供給Native工程,就可以解除Native工程對(duì)Flutter工程的直接依賴。

3.2 Android依賴的Flutter庫(kù)抽取

3.2.1 Android中Flutter編譯任務(wù)分析

Flutter工程的Android打包,其實(shí)只是在Android的Gradle任務(wù)中插入了一個(gè)flutter.gradle的任務(wù),而這個(gè)flutter.gradle主要做了三件事:(這個(gè)文件可以在Flutter庫(kù)中的[flutter/packages/flutter_tools/gradle]目錄下能找到。)1. 增加flutter.jar的依賴。2. 插入Flutter Plugin的編譯依賴。3. 插入Flutter工程的編譯任務(wù),最終將產(chǎn)物(兩個(gè)isolaate_snapshot文件、兩個(gè)vm_snapshot文件和flutter_assets文件夾)拷貝到mergeAssets.outputDir,最終merge到APK的assets目錄下。

3.2.2 Android的Flutter依賴抽取實(shí)現(xiàn)

弄明白Flutter工程的Android編譯產(chǎn)物之后,因此我們對(duì)Android的Flutter依賴抽取步驟如下1. 編譯Flutter工程。這部分主要工作是編譯Flutter的dart和資源部分,可以用AOT和Bundle命令編譯。
echo 'Clean old build'find . -d -name 'build' | xargs rm -rf./flutter/bin/flutter cleanecho 'Get packages'./flutter/bin/flutter packages getecho 'Build release AOT'./flutter/bin/flutter build aot --release --preview-dart-2 --output-dir=build/flutteroutput/aotecho 'Build release Bundle'./flutter/bin/flutter build bundle --precompiled --preview-dart-2 --asset-dir=build/flutteroutput/flutter_assets
2. 將flutter.jar和Flutter工程的產(chǎn)物打包成一個(gè)aar。這邊部分的主要工作是將flutter.jar和第1步編譯的產(chǎn)物封裝成一個(gè)aar。(1)添加flutter.jar依賴
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('implementation')) {            configuration = 'implementation'        } else {            configuration = 'compile'        }        add(configuration, project.files {            releaseFlutterJar        })    }}
(2)Merge Flutter的產(chǎn)物到assets
// merge flutter assetsdef 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/**' // the working dir and its files 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)
2. 同時(shí)將這個(gè)aar和Flutter Plugin編譯出來(lái)的aar一起發(fā)布到maven倉(cāng)庫(kù)。(1)發(fā)布Flutter工程產(chǎn)物打包的aar
echo 'Clean packflutter input(flutter build)'rm -f -r android/packflutter/flutter/# 拷貝flutter.jarecho 'Copy flutter jar'mkdir -p android/packflutter/flutter/flutter/android-arm-release && cp flutter/bin/cache/artifacts/engine/android-arm-release/flutter.jar '$_'# 拷貝assetecho '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庫(kù)和flutter_app打成aar 同時(shí)publish到Ali-mavenecho 'Build and publish idlefish flutter to aar'cd androidif [ -n '$1' ]then	./gradlew :packflutter:clean :packflutter:publish -PAAR_VERSION=$1else	./gradlew :packflutter:clean :packflutter:publishficd ../
(2)發(fā)布Flutter Plugin的aar
# 將plugin發(fā)布到Ali-mavenecho '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
3. 純粹的Native項(xiàng)目只需要compile我們發(fā)布到maven的aar即可。平時(shí)開發(fā)階段,我們需要實(shí)時(shí)能依賴最新的aar,所以我們采用SNAPSHOT版本。
configurations.all {    resolutionStrategy.cacheChangingModulesFor 0, 'seconds'}ext {    flutter_aar_version = '6.0.2-SNAPSHOT'}dependencies {    //flutter主工程依賴:包含基于flutter開發(fā)的功能、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}

3.3 iOS依賴的Flutter庫(kù)的抽取

3.3.1 iOS中Flutter依賴文件如何產(chǎn)生

執(zhí)行編譯命令“flutter build ios”,最終會(huì)執(zhí)行Flutter的編譯腳本[xcode_backend.sh],而這個(gè)腳本主要做了下面幾件事:1. 獲取各種參數(shù)(如project_path,target_path,build_mode等),主要來(lái)自于Generated.xcconfig的各種定義。2. 刪除Flutter目錄下的App.framework和app.flx。3. 對(duì)比Flutter/Flutter.framework與${FLUTTER_ROOT}/bin/cache/artifacts/engine/${artifact_variant}目錄下的Flutter.framework,若不相等,則用后者覆蓋前者。4. 獲取生成App.framework命令所需參數(shù)(build_dir,local_engine_flag,preview_dart_2_flag,aot_flags)。5. 生成App.framework,并將生成的App.framework和AppFrameworkInfo.plist拷貝到XCode工程的Flutter目錄下。

3.3.2 iOS的Flutter依賴抽取實(shí)現(xiàn)

iOS的Flutter依賴的抽取步驟如下:1. 編譯Flutter工程生成App.framework。
echo '===清理flutter歷史編譯==='./flutter/bin/flutter cleanecho '===重新生成plugin索引==='./flutter/bin/flutter packages getecho '===生成App.framework和flutter_assets==='./flutter/bin/flutter build ios --release
2. 打包各插件為靜態(tài)庫(kù)。這里主要有兩步:一是將plugin打成二進(jìn)制文件,二是將plugin的注冊(cè)入口打成二進(jìn)制文件。
echo '===生成各個(gè)plugin的二進(jìn)制庫(kù)文件==='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 iphoneosfor 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'doneecho '===生成注冊(cè)入口的二進(jìn)制庫(kù)文件==='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
3. 將這些上傳到遠(yuǎn)程倉(cāng)庫(kù),并生成新的Tag。4. 純Native項(xiàng)目只需要更新pod依賴即可。

4. Flutter混合工程的持續(xù)集成流程

按上述方式,我們就可以解除Native工程對(duì)Flutter工程的直接依賴了,但是在日常開發(fā)中還是存在一些問(wèn)題:1. Flutter工程更新,遠(yuǎn)程依賴庫(kù)更新不及時(shí)。2. 版本集成時(shí),容易忘記更新遠(yuǎn)程依賴庫(kù),導(dǎo)致版本沒(méi)有集成最新Flutter功能。3. 同時(shí)多條線并行開發(fā)Flutter時(shí),版本管理混亂,容易出現(xiàn)遠(yuǎn)程庫(kù)被覆蓋的問(wèn)題。4. 需要最少一名同學(xué)持續(xù)跟進(jìn)發(fā)布,人工成本較高。鑒于這些問(wèn)題,我們引入了我們團(tuán)隊(duì)的CI自動(dòng)化框架,從兩方面來(lái)解決:(關(guān)于CI自動(dòng)化框架,我們后續(xù)會(huì)撰文分享)一方面是自動(dòng)化,通過(guò)自動(dòng)化減少人工成本,也減少人為失誤。另一方面是做好版本控制, 自動(dòng)化的形式來(lái)做版本控制。具體操作:**首先,**每次需要構(gòu)建純粹Native工程前自動(dòng)完成Flutter工程對(duì)應(yīng)的遠(yuǎn)程庫(kù)的編譯發(fā)布工作,整個(gè)過(guò)程不需要人工干預(yù)。**其次,**在開發(fā)測(cè)試階段,采用五段式的版本號(hào),最后一位自動(dòng)遞增產(chǎn)生,這樣就可以保證測(cè)試階段的所有并行開發(fā)的Flutter庫(kù)的版本號(hào)不會(huì)產(chǎn)生沖突。**最后,**在發(fā)布階段,采用三段式或四段式的版本號(hào),可以和APP版本號(hào)保持一致,便于后續(xù)問(wèn)題追溯。
整個(gè)流程如下圖所示:
Standalone模式下構(gòu)建流程

5. 最后

閑魚技術(shù)團(tuán)隊(duì)是一只短小精悍的工程技術(shù)團(tuán)隊(duì)。我們不僅關(guān)注于業(yè)務(wù)問(wèn)題的有效解決,同時(shí)我們?cè)谕苿?dòng)打破技術(shù)棧分工限制(android/iOS/Html5/Server 編程模型和語(yǔ)言的統(tǒng)一)、計(jì)算機(jī)視覺(jué)技術(shù)在移動(dòng)終端上的前沿實(shí)踐工作。作為閑魚技術(shù)團(tuán)隊(duì)的軟件工程師,您有機(jī)會(huì)去展示您所有的才能和勇氣,在整個(gè)產(chǎn)品的演進(jìn)和用戶問(wèn)題解決中證明技術(shù)發(fā)展是改變生活方式的動(dòng)力。
簡(jiǎn)歷投遞:guicai.gxy@alibaba-inc.com
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
使用Flutter之后,我們的CPU占用率降了50%
Flutter Weekly Issue 60
Flutter完整開發(fā)實(shí)戰(zhàn)詳解(十四、混合開發(fā)打包 Android 篇)
Flutter Plugin開發(fā)流程
Flutter Weekly Issue 54
Android 開發(fā):由模塊化到組件化(一)
更多類似文章 >>
生活服務(wù)
熱點(diǎn)新聞
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服