囯产精品一品二区三区的使用体验_久久老子午夜精品无码怎么打_超碰免费个人观看_粉嫩人妻91精品蜜芽在线_无码成人aaaaa毛片

首頁(yè) > 快訊 > 正文

每日播報(bào)!Flutter熱更新技術(shù)探索

2023-05-26 12:22:34 來(lái)源:博客園
一,需求背景:

APP發(fā)布到市場(chǎng)后,難免會(huì)遇到嚴(yán)重的BUG阻礙用戶使用,因此有在不發(fā)布新版本APP的情況下使用熱更新技術(shù)立即修復(fù)BUG需求。原生APP(例如:Android & IOS)的熱更新需求已經(jīng)比較成熟,但Flutter技術(shù)棧目前還缺少類似的技術(shù)方案,因此Flutter研發(fā)團(tuán)隊(duì),也需要類似的熱更新技術(shù)。

二,F(xiàn)lutter熱更新技術(shù)方向分析:

經(jīng)過(guò)分析目前可能有三種可行的方案: 1)類似RN框架; 2)頁(yè)面動(dòng)態(tài)組件框架; 3)Dart虛擬機(jī)定制方案;


【資料圖】

方案名稱原理優(yōu)點(diǎn)缺點(diǎn)開源方案
類似RN的方案用JS以Flutter語(yǔ)法寫dart,然后用JavaScript把XML DSL轉(zhuǎn)為Flutter的原子widget組件,然后再讓Flutter來(lái)渲染由于ios系統(tǒng)內(nèi)置支持js,ios上完全可以實(shí)現(xiàn)更新1)由于跨語(yǔ)言執(zhí)行,對(duì)于性能有影響;學(xué)習(xí)成本高 2)Android 端需要額外引入JS庫(kù)手Q的MXFlutter,58同城的Fair
頁(yè)面動(dòng)態(tài)組件方案編譯期時(shí)插樁/預(yù)埋好DynamicWidget到代碼中,然后動(dòng)態(tài)下發(fā)Json 數(shù)據(jù),通過(guò)協(xié)定好的語(yǔ)義匹配到JSON內(nèi)的數(shù)據(jù),動(dòng)態(tài)替換Widget內(nèi)容來(lái)實(shí)現(xiàn)更新能支持Android/iOS 兩端的更新1)UI更新相對(duì)較容易,業(yè)務(wù)邏輯動(dòng)態(tài)化較麻煩; 2)語(yǔ)義解析器開發(fā)成本相對(duì)較大,且不易維護(hù) 3)需要一整套前后端服務(wù)和工具天貓的Tangram,淘寶的DinamicX等
Dart虛擬機(jī)定制方案通過(guò)分析Dart虛擬機(jī)的原理,修改Flutter Engine層Java/C++代碼實(shí)現(xiàn)熱更新的目標(biāo);性能影響小,動(dòng)態(tài)性很高,技術(shù)上可以替換所有Flutter頁(yè)面(包括UI,邏輯,資源文件)由于使用的是定制引擎,需要維護(hù)不同版本的Flutter引擎代碼;未開源

因?yàn)槠渌绞蕉加虚_源的示例,本案將重點(diǎn)以第三種“Dart虛擬機(jī)定制方案”為目標(biāo),做方案的研究講解。

三,預(yù)備知識(shí)

在開始了解技術(shù)方案之前,需要提前了解一些相應(yīng)的技術(shù)概念:

3.1 Flutter編譯模式

Flutter開發(fā)語(yǔ)言是Dart,它的編譯模式來(lái)自Dart的編譯模式,主要有JIT(Just In Time)和AOT(Ahead Of Time)。

編譯模式名稱特點(diǎn)優(yōu)點(diǎn)缺點(diǎn)
JIT即時(shí)編譯,典型例子V8,它可以即時(shí)編譯運(yùn)行JS,只需要輸入源代碼字符串,就可以編譯運(yùn)行代碼可以動(dòng)態(tài)下發(fā)和執(zhí)行代碼,不用管CPU架構(gòu),可以提供動(dòng)態(tài)化內(nèi)容1,大量字符串代碼讓JIT編譯器花費(fèi)時(shí)間和內(nèi)存; 2,性能不好;
AOT預(yù)先編譯,典型例子C/C++,通過(guò)GCC編譯成二進(jìn)制代碼,然后安裝取得權(quán)限后才可以加載執(zhí)行事先編譯好的,加載和執(zhí)行速度快1,編譯時(shí)區(qū)分CPU架構(gòu); 2,生成的二進(jìn)制代碼包比較大; 3,二進(jìn)制代碼需要取得權(quán)限才可以執(zhí)行,無(wú)法在ios系統(tǒng)上動(dòng)態(tài)更新

Flutter編譯模式有:Debug,Release,Profile;

Flutter編譯模式特點(diǎn)
Debug對(duì)應(yīng)JIT模式,支持設(shè)備和模擬器; 打開了斷言,支持快速開發(fā),支持HotReload; 并未對(duì)包大小,執(zhí)行速度做優(yōu)化;
Release對(duì)應(yīng)AOT模式,支持真機(jī),不支持模擬器; 禁止了所有斷言調(diào)試信息; 對(duì)包大小,啟動(dòng)和執(zhí)行速度進(jìn)行了優(yōu)化;
Profile類似Release模式,保留了一些調(diào)試功能,幫助性能分析;
3.2 Flutter編譯產(chǎn)物分析

Flutter下的iOS/Android工程本質(zhì)上是一個(gè)標(biāo)準(zhǔn)的iOS/Android的工程;IOS平臺(tái):Flutter通過(guò)在BuildPhase中添加shell(xcode_backend.sh)來(lái)生成和嵌入App.framework和Flutter.framework到ios; Android平臺(tái):Flutter通過(guò)gradle來(lái)添加flutter.jar和編譯完的二進(jìn)制文件添加到Android;

3.2.1 引擎層結(jié)構(gòu)分析:

3.2.2 Android編譯產(chǎn)物的分析

3.2.3 IOS編譯產(chǎn)物的分析

四,熱更新技術(shù)方案分析4.1 業(yè)務(wù)代碼分析

根據(jù)“3.3.1” ~“3.3.2”的分析可以確定無(wú)論是IOS還是Android APP業(yè)務(wù)代碼都是由四個(gè)段組成:kDartVmSnapshotData、kDartVmSnapshotInstructions、kDartIsolateSnapshotData、kDartIsolateSnapshotInstructions;理論上只要能動(dòng)態(tài)替換加載的代碼段&數(shù)據(jù)段代碼即可實(shí)現(xiàn)目標(biāo)。

名稱注釋作用注釋
kDartIsolateSnapshotDataDart isolate數(shù)據(jù)段類信息,全局變量,函數(shù)指針等允許動(dòng)態(tài)下發(fā)
kDartIsolateSnapshotInstructionsDart isolate指令段包含由Dart isolate執(zhí)行的AOT代碼IOS不允許動(dòng)態(tài)下發(fā)
kDartVmSnapshotDatavm isolate數(shù)據(jù)段isolate 之間共享的 Dart 堆 (heap) 的初始狀態(tài)允許動(dòng)態(tài)下發(fā)
kDartVmSnapshotInstructionsvm isolate指令段包含 VM 中所有 Dart isolate 之間共享的通用程序的 AOT 指令IOS不允許動(dòng)態(tài)下發(fā)

注釋: isolate, snapshot, vm isolate含義解釋如下:

名稱含義
isolateDart是單線程,isolate跟線程差不多,可以理解為 Dart 中的線程。 isolate 與線程的區(qū)別:線程與線程之間是共享內(nèi)存的,而 isolate 和 isolate 之間是內(nèi)存不共享的。 不存在鎖競(jìng)爭(zhēng)問題,兩個(gè)Isolate完全是兩條獨(dú)立的執(zhí)行線,且每個(gè)Isolate都有自己的事件循環(huán),它們之間只能通過(guò)發(fā)送消息通信,所以它的資源開銷低于線程。
snapshot將類信息、全局變量、函數(shù)指令直接以序列化的方式存在磁盤中,稱為 Snapshot(快照)。
vm isolate同一個(gè)進(jìn)程里可以有很多isolate,但兩個(gè) isolate 的堆區(qū)是不能共享的,所以官方設(shè)計(jì)了 VM isolate,也就是 kDartVmSnapshot,用來(lái)多個(gè) isolate 之間的交互。
4.2 業(yè)務(wù)代碼的加載分析(運(yùn)行時(shí))

按照4.1的分析思路,我們首先需要了解Flutter運(yùn)行時(shí)代碼加載的完整流程,經(jīng)過(guò)梳理分析流程如下:

1 )Android- APP業(yè)務(wù)代碼的加載流程:

2)IOS- APP業(yè)務(wù)代碼的加載流程:

4.3 業(yè)務(wù)代碼的編譯生成(編譯時(shí))

根據(jù)以上的分析,我們知道了Flutter業(yè)務(wù)代碼的數(shù)據(jù)結(jié)構(gòu),也知道了在運(yùn)行時(shí)如何加載,因此我們只需要在編譯時(shí)做更改,產(chǎn)生自己需要的代碼段,和數(shù)據(jù)段文件。在運(yùn)行時(shí)加載自己的構(gòu)建產(chǎn)物即可達(dá)到目標(biāo)。

1)在此以 IOS 構(gòu)建自己的業(yè)務(wù)代碼流程做詳細(xì)分析:

**有完成構(gòu)建流程可以分析,基本流程是“Dart Code(業(yè)務(wù)代碼)” -> (通過(guò)Dart編譯器gen_snapshot.cc) 生成 snapshot_assemble.S 的匯編文件 -> (通過(guò)xcrun工具)生成 snapshot_assemble.o的obj文件 -> (通過(guò)xcun clang工具鏈) 生成了 App.Framework。

2)Android的產(chǎn)物構(gòu)建流程和IOS類似。由于Android有其他更簡(jiǎn)單的方案, 因此省略詳細(xì)的構(gòu)建流程分析,大致如下:

4.4 實(shí)現(xiàn)熱更新的方案探索

根據(jù)上面的技術(shù)分析結(jié)果,已經(jīng)可以獨(dú)立生成自己的代碼段,數(shù)據(jù)段文件。通過(guò)需改虛擬機(jī)底層代碼的方式,也可以動(dòng)態(tài)的加載運(yùn)行。但由于IOS系統(tǒng)目前底層的系統(tǒng)還不能動(dòng)態(tài)加載可讀寫的代碼段數(shù)據(jù)到內(nèi)存中,所以還有技術(shù)難點(diǎn)需要突破。但Android端有更簡(jiǎn)單的路徑可以解決,因此下面以Android端為例重點(diǎn)分析思路,大致如下圖所示:

由上圖可以得知,Android端 熱修復(fù)核心步驟如下:

1, 修改Flutter Engine代碼,加載指定路徑的libapp.so和flutter_aasets,比如私有目錄(data/data/files);

2, 編譯APK時(shí),利用Gradle Transform插件,根據(jù)Flutter SDK的engine version動(dòng)態(tài)替換官方的Flutter engine,最終寫入修改后的engine到APK;

3, 生成補(bǔ)丁包:利用BSdiff算法比較新舊APK文件,生成patch補(bǔ)丁包

4, APP啟動(dòng)時(shí)訪問后端接口,根據(jù)參數(shù)(app的版本號(hào),補(bǔ)丁包版本號(hào),md5,flutter SDK版本號(hào),Engine版本號(hào))拉取補(bǔ)丁包;

5, 合成補(bǔ)丁包:校驗(yàn)md5,app版本號(hào),補(bǔ)丁版本號(hào),安裝時(shí)間;

6, 自定義Flutter Engine加載指定路徑的libapp.so和flutter_assets資源文件;

作者:京東科技 劉振中、周智

內(nèi)容來(lái)源:京東云開發(fā)者社區(qū)

關(guān)鍵詞:

本文來(lái)源: 博客園


上一篇: 環(huán)球時(shí)訊:理想汽車CEO李想深夜發(fā)文:我們不怕被黑,為大量使用中國(guó)本土供應(yīng)商感到自豪!
下一篇: 最后一頁(yè)

為您推薦
推薦閱讀

資訊

行業(yè)

服務(wù)

人才