
我們團(tuán)隊(duì)一直用 Flutter 做跨端應(yīng)用但最近半年越來(lái)越多項(xiàng)目開始要求適配國(guó)內(nèi)幾款自研操作系統(tǒng)。Flutter 官方雖然支持多平臺(tái)但對(duì)這些新系統(tǒng)的支持往往滯后。所以當(dāng)我一看到 Flutter-OH 3.35.7-ohos-0.0.2 這個(gè)版本號(hào)就知道 Flutter 在 OHOS 方向的適配又往前推了一步。這篇文章我不打算做一個(gè)簡(jiǎn)單的發(fā)布公告復(fù)述而是結(jié)合我自己研究這個(gè)版本、上手跑通 demo 的經(jīng)驗(yàn)聊清楚三個(gè)問題這個(gè)版本到底解決了什么、OHOS 上跑 Flutter 的適配難點(diǎn)究竟在哪、以及你拿到工程后應(yīng)該怎么排查問題。不管你是剛接觸 Flutter 的新手還是已經(jīng)在做跨端容器適配的老手這篇內(nèi)容應(yīng)該都能讓你少走幾天彎路。1. 版本號(hào)里的信號(hào)Flutter 3.35.7 與 ohos-0.0.2 分別意味著什么1.1 上游 Flutter 版本決定的是地基版本號(hào)拆開來(lái)看Flutter-OH 3.35.7-ohos-0.0.2 里前半段是上游 Flutter SDK 的版本號(hào)后半段是 OHOS 適配殼層的版本號(hào)。第一部分 3.35.7 決定了整個(gè)容器的基礎(chǔ)能力比如 Dart 運(yùn)行時(shí)版本、Flutter 引擎的渲染后端、框架層的組件特性都跟著它走。對(duì)用過(guò) Flutter 的人來(lái)說(shuō)3.x 這個(gè)主線已經(jīng)非常成熟。尤其是 3.35 這個(gè)版本系從框架層角度看Impeller 渲染引擎已經(jīng)逐步覆蓋更多平臺(tái)動(dòng)畫和渲染的流暢度比早期的 Skia 后端有明顯提升從工具鏈角度看Flutter Build 的緩存機(jī)制、熱重載穩(wěn)定性也都有改進(jìn)。所以當(dāng)你看到適配版基于 3.35.7可以理解為上游地基選擇了一個(gè)相對(duì)穩(wěn)健的版本而不是某個(gè)激進(jìn)的新特性分支。我實(shí)際跑下來(lái)這個(gè)上游版本最讓我舒服的是 Dart 側(cè)的 async 調(diào)度和 Isolate 通信在 OHOS 這種非標(biāo)準(zhǔn)平臺(tái)上的穩(wěn)定性。早期 Flutter 移植到其他平臺(tái)經(jīng)常會(huì)出現(xiàn)異步任務(wù)不觸發(fā)、UI 線程卡頓等問題那是因?yàn)?Flutter 的 Task Runner 和新系統(tǒng)原生線程池的對(duì)接不夠順。3.35.7 這一檔位的 Flutter 引擎對(duì)自定義 Task Runner 的兼容性已經(jīng)比較友好很多潛在調(diào)度坑被上游提前處理了。1.2 適配殼的版本號(hào)告訴我們成熟度再看后半段 ohos-0.0.2這個(gè) 0.0.x 號(hào)很誠(chéng)實(shí)它說(shuō)明適配層還處于非常早期的階段。通常一個(gè)跨平臺(tái)框架的移植會(huì)經(jīng)歷三個(gè)階段第一階段0.0.x跑通最小鏈路火焰測(cè)試能起來(lái)基礎(chǔ) Widget 能顯示但深度功能缺失 第二階段0.1.x ~ 0.9.x補(bǔ)齊引擎能力和平臺(tái)通道對(duì)接插件生態(tài)批量移植穩(wěn)定性逐漸提升 第三階段1.0API 對(duì)齊官方、構(gòu)建產(chǎn)物完善、可作為生產(chǎn)依賴使用。Flutter-OH 3.35.7-ohos-0.0.2 正處在第一階段向第二階段過(guò)渡的位置。這意味著它能做基礎(chǔ)渲染、能跑業(yè)務(wù)頁(yè)面但如果你想直接在里面用大量第三方插件大概率會(huì)碰壁。不過(guò) 0.0.2 這個(gè)版本能放出來(lái)至少說(shuō)明這套適配方案已經(jīng)有人維護(hù)、有人測(cè)試而不是某個(gè)同學(xué)畢設(shè)做完就丟在那兒了。我在評(píng)估要不要接入的時(shí)候會(huì)看三個(gè)信號(hào)項(xiàng)目是否持續(xù)更新、適配側(cè)的構(gòu)建 ID 是否存在、以及社區(qū)有沒有基礎(chǔ) issue 反饋。0.0.2 的發(fā)布說(shuō)明指向的正是持續(xù)更新這個(gè)信號(hào)所以我認(rèn)為值得投入時(shí)間研究它。1.3 版本匹配里最容易被忽略的細(xì)節(jié)使用這套適配版本時(shí)最容易踩的坑是 Flutter SDK 版本和適配殼版本不匹配。有些人會(huì)單獨(dú)下載 Flutter-OH 適配殼的工程文件然后把它丟進(jìn)一個(gè)官方 3.35.7 的 Flutter SDK 環(huán)境里編譯結(jié)果發(fā)現(xiàn)平臺(tái)補(bǔ)丁覆蓋不上。正確做法是使用適配項(xiàng)目提供的完整 SDK 包或統(tǒng)一管理腳本確保上游 Flutter 和 OHOS 平臺(tái)補(bǔ)丁在同一套目錄下。另外OHOS 側(cè)的編譯鏈要求也要留意。適配版本通常會(huì)綁定某一代 DevEco Studio 的 API 版本。比如某些版本適配的是 API 9 或 API 12你如果拿 API 11 的工程去跑編譯雖然能過(guò)但運(yùn)行時(shí) NAPI 調(diào)用會(huì)出現(xiàn)符號(hào)找不到的問題。因此我建議拿到版本后第一步先記錄所有環(huán)境指紋Flutter SDK commit、適配補(bǔ)丁工程版本、OHOS SDK API 等級(jí)有時(shí)候還要加上 Node 和 Java 的版本。環(huán)境不對(duì)的情況下任何抱怨都可能是誤判。2. 移植適配的硬骨頭從 Flutter 引擎到 OHOS 側(cè)的四層對(duì)接2.1 第一層引擎與渲染后端的平臺(tái)適配Flutter 在 OHOS 上跑最先面對(duì)的問題就是 Flutter 引擎如何在一個(gè)沒有官方參考實(shí)現(xiàn)的操作系統(tǒng)上被翻譯成可以運(yùn)行的代碼。這個(gè)翻譯不是源代碼層面的直譯而是引擎內(nèi)部各種抽象接口要重新實(shí)現(xiàn)一套后端。具體來(lái)說(shuō)Flutter 引擎依賴底層平臺(tái)做四類基礎(chǔ)服務(wù)線程調(diào)度、內(nèi)存分配、渲染 API、事件輸入。在 Android 上這些都有現(xiàn)成的映射比如線程調(diào)度對(duì)應(yīng) Android 的 Looper渲染對(duì)應(yīng) Vulkan API。在 OHOS 上線程調(diào)度有自己的一套機(jī)制渲染則圍繞其渲染引擎和圖形接口體系展開。所以適配殼要做的事情是把 Flutter 引擎的 Platform 抽象層重新指向一套新實(shí)現(xiàn)。這個(gè)版本能跑通火焰測(cè)試即例子工程里的計(jì)時(shí)器旋轉(zhuǎn)動(dòng)畫說(shuō)明渲染對(duì)接已經(jīng)基本可用但我提醒大家別盲目樂觀動(dòng)畫渲染和紋理合成這兩條路徑通常不是同一套代碼?;鹧鏈y(cè)試用的是普通 Widget 繪制而攝像頭預(yù)覽、視頻播放這類場(chǎng)景要走 Texture 路徑Texture 路徑如果沒適配哪怕最簡(jiǎn)單的視頻播放也會(huì)黑屏。0.0.2 版本大概率還沒覆蓋到 Texture 的完整校驗(yàn)這是后續(xù)版本要看重的觀察點(diǎn)。2.2 第二層Dart 運(yùn)行時(shí)與原生側(cè)的雙向調(diào)用橋Flutter 業(yè)務(wù)代碼跑在 Dart VM 里但打開相冊(cè)、讀取定位、調(diào)起掃碼等能力必須借由原生代碼完成。這個(gè)橋在 Android 上是 MethodChannel內(nèi)部走二進(jìn)制消息在 OHOS 上則需要適配到其 Native API 體系上。我在閱讀這套適配工程的源碼時(shí)注意到一個(gè)特點(diǎn)OHOS 殼層里面大量用到了 NAPI 的 napi_create_function 和 napi_call_function 這類接口來(lái)做橋接相當(dāng)于把 Ohos 的異步回調(diào)轉(zhuǎn)換成 Flutter 側(cè)的 Future。這里面有兩個(gè)典型的坑一個(gè)是參數(shù)類型映射。Dart 側(cè)傳過(guò)來(lái)的 Map在 NAPI 側(cè)會(huì)被轉(zhuǎn)成 napi_value 對(duì)象如果你拿它去做基礎(chǔ)類型轉(zhuǎn)換稍不注意就會(huì)出現(xiàn) int 變成 double 的情況不會(huì)報(bào)錯(cuò)但結(jié)果不對(duì)。建議這種做法通道里盡量用字符串或者用 JSON 序列化傳遞結(jié)構(gòu)化數(shù)據(jù)減少隱式類型轉(zhuǎn)換。另一個(gè)是線程切換問題。MethodChannel 的回調(diào)默認(rèn)是跑在平臺(tái)主線程上的但 OHOS 的 NAPI 異步接口很多回調(diào)在 IO 線程如果你不手動(dòng)切回。 在這個(gè)問題上報(bào)錯(cuò)不算嚴(yán)重卡頓也就是時(shí)間的問題嚴(yán)重的是崩潰。2.3 第三層事件輸入與感知能力對(duì)齊Flutter 渲染的頁(yè)面能夠響應(yīng)觸摸事件依賴的是引擎層從平臺(tái)接收 PointerEvent。從 OHOS 側(cè)把觸摸手勢(shì)和鍵鼠事件轉(zhuǎn)換成 Flutter 內(nèi)部的 PointerDataPacket也是適配工程必須完成的任務(wù)。這個(gè)版本已經(jīng)實(shí)現(xiàn)了基礎(chǔ)觸摸事件轉(zhuǎn)發(fā)但是有兩個(gè)細(xì)節(jié)我得提一下多點(diǎn)觸控的 id 映射Flutter 要求每個(gè)觸摸點(diǎn)有唯一 idOHOS 的事件參數(shù)如果不做歸一化切換手勢(shì)時(shí)就會(huì)出現(xiàn)指針丟失頁(yè)面表現(xiàn)為偶爾點(diǎn)擊沒反應(yīng)。文本輸入框拉起輸入法這個(gè)比觸摸更麻煩。OHOS 某版本輸入法soc這種域是嵌入式進(jìn)化的Flutter View 里的 EditText 實(shí)際上并不存在而是用引擎自繪方式在畫布上渲染輸入法聯(lián)通需要自己實(shí)現(xiàn)連接綁定這部分在 0.0.2 版本里我實(shí)測(cè)下來(lái)文本輸入能彈鍵盤因?yàn)槲覀冊(cè)谕獠空{(diào)試時(shí)開啟了輔助連接但連續(xù)輸入時(shí)偶爾會(huì)丟失首字母。這個(gè)體驗(yàn)只能算可接受不能算完整。所以如果你是拿這個(gè)版本來(lái)做表單類生產(chǎn)應(yīng)用我個(gè)人建議暫時(shí)打住。2.4 第四層插件生態(tài)與原生 SDK 的隔離普通 Flutter 項(xiàng)目里插件的豐富程度是最大賣點(diǎn)。但在 OHOS 適配版里第三方的插件基本處于薛定諤的可用狀態(tài)。因?yàn)椴寮?Android 下依賴的是 AndroidX 和 Activity/Fragment 生命周期在 OHOS 下需要依賴的是對(duì)應(yīng)的生命周期模型這兩者完全不一樣。適配社區(qū)現(xiàn)在通常做的是建一個(gè)映射層把常用插件用 OHOS 的 SDK 重新實(shí)現(xiàn)一遍。比如權(quán)限申請(qǐng)、網(wǎng)絡(luò)狀態(tài)、路徑獲取這類基礎(chǔ)插件先補(bǔ)而需要綁定廠商 SDK 的插件如地圖、推送則優(yōu)先級(jí)很低。Flutter-OH 3.35.7-ohos-0.0.2 的發(fā)布說(shuō)明里若是提到了幾個(gè)內(nèi)置插件可用那么你最好只動(dòng)這幾個(gè)其他的還是用 Native 視圖 自有通道自己封裝。我后來(lái)習(xí)慣的做法是在 OHOS 適配階段不依賴任何第三方插件把需要的能力全部下沉到 OHOS 原生代碼里實(shí)現(xiàn)然后統(tǒng)一以 MethodChannel 暴露給 Flutter 層。聽起來(lái)工作量更大但實(shí)際上是避開插件匹配混亂最省錢的方式。3. 實(shí)操接入在 OHOS 工程里跑起 Flutter 首個(gè)頁(yè)面的完整鏈路3.1 環(huán)境準(zhǔn)備哪些工具必須精確匹配動(dòng)手之前先確認(rèn)一套工具鏈版本。以下是我在 0.0.2 版本環(huán)境下驗(yàn)證可用的版本組合供參考操作系統(tǒng)標(biāo)準(zhǔn) PC 環(huán)境Windows / macOS 都行Flutter SDK上游 3.35.7 OHOS 補(bǔ)丁包OHOS 開發(fā)套件某版本 DevEco StudioAPI 12 及其配套 SDKNode.js不低于 16主要用于構(gòu)建腳本JavaOpenJDK 17不同機(jī)器上出現(xiàn)構(gòu)建錯(cuò)誤時(shí)優(yōu)先檢查的不是代碼而是這些工具的版本組合。OHOS 的 NAPI 頭文件對(duì)編譯器版本有要求DevEco 自帶的編譯器如果和本機(jī) Java 的 class 版本沖突直接表現(xiàn)為構(gòu)建時(shí)必現(xiàn)的異常報(bào)錯(cuò)。3.2 創(chuàng)建工程的正確姿勢(shì)用 Flutter-OH 適配版創(chuàng)建工程時(shí)建議不要直接執(zhí)行 flutter create 生成標(biāo)準(zhǔn) Flutter 模板因?yàn)槟0謇锏?android 和 ios 目錄對(duì)這個(gè)場(chǎng)景沒意義。更可靠的方式是先創(chuàng)建標(biāo)準(zhǔn)的 Flutter 模塊flutter create --templateapp刪除工程里的 android、ios、web 等平臺(tái)目錄只保留 lib、pubspec.yaml 和 assets在工程根目錄接入 ohos 平臺(tái)目錄這個(gè)目錄通常由適配殼的工具腳本生成或者手動(dòng)從模板拷貝打開 DevEco Studio以 ohos 目錄下的工程作為獨(dú)立工程打開配置好簽名在 ohos 目錄里關(guān)聯(lián) Flutter 模塊的構(gòu)建產(chǎn)物通常是通過(guò) gradle 或 hvigor 的構(gòu)建腳本引用 libs 下的 Flutter 引擎包。這樣做的原因是Flutter-OH 的適配版收斂了上游 SDK 的構(gòu)建邏輯它會(huì)把 Dart 代碼編譯成標(biāo)準(zhǔn)的 Flutter 引擎可執(zhí)行產(chǎn)物然后再由 OHOS 側(cè)打包成 HarmonyAbility 可以加載的模塊。如果你跳過(guò)這個(gè)轉(zhuǎn)化過(guò)程想直接用 DevEco 打開 Flutter 根目錄通常會(huì)抱錯(cuò)或者不識(shí)別 DART 語(yǔ)言。3.3 跑通第一個(gè) Hello World 的完整鏈路從命令角度來(lái)說(shuō)這套鏈路可以分成五步# 第一步進(jìn)入適配版 SDK 根目錄拉取依賴 flutter pub get # 第二步觸發(fā) Flutter 引擎產(chǎn)物生成 flutter build ohos --debug # 第三步確認(rèn)生成 .so 和 .abc 等關(guān)鍵產(chǎn)物 ls build/ohos/debug/ # 第四步用 DevEco Studio 打開 ohos 宿主目錄 # 同步倉(cāng)庫(kù)并等待構(gòu)建完成 # 第五步配置簽名后運(yùn)行到真機(jī)/模擬器每一步都可能出問題我把自己實(shí)際操作中遇到的兩個(gè)問題列出來(lái)第一個(gè)是 flutter pub get 之后pubspec.lock 里如果包含官方 pub 倉(cāng)庫(kù)的緩存路徑后續(xù)構(gòu)建時(shí)會(huì)把非 OHOS 平臺(tái)的緩存也拉進(jìn)去導(dǎo)致編譯時(shí)出現(xiàn)平臺(tái)無(wú)關(guān)的依賴報(bào)錯(cuò)。這種問題不好定位我直接鎖定 pubspec.yaml 里的依賴全部為本地路徑或者確定可用版本避免混用。第二個(gè)是 hvigor 構(gòu)建腳本偶爾會(huì)因?yàn)?OHOS SDK 的環(huán)境路徑變量沒設(shè)置好而找不到 NAPI 頭文件。盡管 devEco 自帶檢測(cè)但命令行構(gòu)建時(shí)我們需要顯式設(shè)置環(huán)境變量比如 SDK 路徑否則構(gòu)建日志里會(huì)直接出現(xiàn) include file not found 的錯(cuò)誤。一旦你過(guò)了這一步不出意外的話模擬器上就能看到 Flutter 的計(jì)時(shí)器那個(gè)啟動(dòng)頁(yè)面了。這一步跑通了接下來(lái)的開發(fā)迭代就在這個(gè)框架上做。3.4 驗(yàn)證版本的邊界別急著上業(yè)務(wù)既然版本號(hào)還是 0.0.2我的建議是第一次跑通后立即做一個(gè)簡(jiǎn)單評(píng)估清單確認(rèn)當(dāng)前適配版本的能力邊界基礎(chǔ)渲染列表滑動(dòng)是否流暢文字是否能正常顯示字體與國(guó)際化中文顯示是否正常是否有多字體缺字問題輸入框鍵盤彈出、輸入、收起是否正常路由與動(dòng)畫頁(yè)面跳轉(zhuǎn)、Hero 動(dòng)畫、顯隱動(dòng)畫是否出現(xiàn)閃白網(wǎng)絡(luò)請(qǐng)求HttpClient 和 WebSocket 是否能跑通生命周期前后臺(tái)切換、應(yīng)用銷毀時(shí) Flutter Engine 是否會(huì)泄漏。這一套清單我在 0.0.2 版本上實(shí)際測(cè)下來(lái)列表滑動(dòng)和文字顯示是 OK 的網(wǎng)絡(luò)請(qǐng)求和頁(yè)面跳轉(zhuǎn)也有較好水平但輸入框和部分渲染特效如模糊效果有明顯短板。所以從我的判斷來(lái)看當(dāng)前版本適合做 Pilot 項(xiàng)目和原型的搭建調(diào)優(yōu)不適合直接引進(jìn)重交互項(xiàng)目。明確邊界之后你后續(xù)的排錯(cuò)也會(huì)更容易。4. 跑起來(lái)只是開始適配中真正廢時(shí)間的問題排查清單4.1 崩潰類問題引擎初始化與 NAPI 符號(hào)缺失適配版本最常出現(xiàn)的一類崩潰是引擎啟動(dòng)時(shí)崩潰日志往往只給出一句 terminated 或其他泛化提示。這個(gè)時(shí)候我先做三件事第一檢查 .so 是否放到正確目錄。OHOS 應(yīng)用啟動(dòng)加載 Flutter 引擎的動(dòng)態(tài)庫(kù)一旦路徑不對(duì)直接段錯(cuò)誤 第二確認(rèn) NAPI 符號(hào)是否齊全。用 nm 命令查看 .so 導(dǎo)出符號(hào)確認(rèn) napi_reference_ref 這類關(guān)鍵符號(hào)存在且版本匹配 第三清理緩存后重建。NAPI 接口在設(shè)計(jì)上有不少版本差異老的符號(hào)和新的鏈接路徑串了就會(huì)在運(yùn)行時(shí)找不到符號(hào)。這一步單靠報(bào)錯(cuò)信息很難定位到底發(fā)生在哪一層我通常用日志切分法先最小化場(chǎng)景不加載任何業(yè)務(wù) Dart 代碼只看引擎能否啟動(dòng)。如果最小場(chǎng)景通過(guò)再逐層添加業(yè)務(wù)問題就暴露在哪里。4.2 渲染類問題白屏、黑屏、閃爍Flutter 頁(yè)面在 0.0.2 上出現(xiàn)白屏或黑屏大概率不是業(yè)務(wù)代碼的問題而是 Flutter 渲染 Surface 和 OHOS 側(cè)容器視圖的尺寸或紋理格式不一致。這可能發(fā)生在橫豎屏切換時(shí)因?yàn)槿萜饕晥D沒有實(shí)時(shí)把尺寸變化同步給 Flutter Engine 的 Surface 坐標(biāo)畫了一個(gè)錯(cuò)位畫布看起來(lái)就像白屏或黑邊。還有在部分真機(jī)上默認(rèn)的 Buffer 格式對(duì) 10bit 色深支持不完整畫面會(huì)整體偏淡或者閃爍。臨時(shí)的應(yīng)對(duì)方式是把容器 View 強(qiáng)制設(shè)置為不透明并鎖定 RGB888 格式這樣雖然犧牲一點(diǎn)色彩表現(xiàn)但至少穩(wěn)定。4.3 內(nèi)存類問題Flutter Engine 雙重泄漏我發(fā)現(xiàn)適配版本最容易出現(xiàn)的隱性問題是 Flutter Engine 的重復(fù)初始化。在 OHOS 的 page 生命周期切換里如果開發(fā)者在 onPageShow 里重復(fù)初始化 Engine 對(duì)象而此前沒有正確釋放就會(huì)出現(xiàn)多個(gè)引擎實(shí)例。在 Android 上 Flutter 官方已經(jīng)做了大量處理來(lái)防止這種情況但 OHOS 適配版對(duì)生命周期事件的監(jiān)聽可能沒有完全對(duì)齊。規(guī)避這個(gè)問題的做法是在啟動(dòng)層和銷毀層都加上路由鎖。我見過(guò)一個(gè)項(xiàng)目反復(fù)進(jìn)入頁(yè)面后內(nèi)存趨勢(shì)直線上漲后來(lái)又用 leak 插件看自然是泄漏其實(shí)就是因?yàn)?onPageHide 回調(diào)沒有真正觸發(fā) Flutter Engine 的 detach 過(guò)程。所以在你寫業(yè)務(wù)之前先確認(rèn)宿主框架是否在頁(yè)面 onHide/onDestroy 的階段做了顯式 engine.destroy 調(diào)用。如果沒做那就是定時(shí)炸彈。4.4 網(wǎng)絡(luò)與異步類問題粘包、丟回調(diào)OHOS 的網(wǎng)絡(luò)接口本身和 Android 的差異就很大適配版 Flutter 引擎里的 HttpClient 走的是 dart:io 的原生實(shí)現(xiàn)理論上不依賴系統(tǒng)網(wǎng)絡(luò)庫(kù)。但 flutter 側(cè)平臺(tái)通道里如果混用了 OHOS 原生網(wǎng)絡(luò)能力就比較容易出現(xiàn)丟回調(diào)的現(xiàn)象。這個(gè)問題的根源通常是異步 id 錯(cuò)位。NAPI 同時(shí)支持同步返回和異步回調(diào)如果你的原生函數(shù)立刻返回一個(gè) Result而后又調(diào)用一個(gè)回調(diào)Flutter 側(cè)可能只接到了其中一份數(shù)據(jù)。我的經(jīng)驗(yàn)是在寫這類通道時(shí)加一層統(tǒng)一的消息序列號(hào)包裝類似 RPC 的消息 id。每次調(diào)用都帶一個(gè)序號(hào)回調(diào)帶上同一個(gè)序號(hào)在 Dart 側(cè)創(chuàng)建 Completer 時(shí)把序號(hào)注冊(cè)到 Map 里這樣即便順序亂掉也能找回來(lái)。這種設(shè)計(jì)寫起來(lái)會(huì)多一些代碼但對(duì)于底層跨語(yǔ)言橋來(lái)說(shuō)它是穩(wěn)定性的關(guān)鍵。4.5 取舍建議哪些坑不值得你花時(shí)間用 0.0.2 版本時(shí)有幾個(gè)方向我認(rèn)為不值得投入人力深挖插件兼容性改造如果不影響核心業(yè)務(wù)路徑全部繞過(guò)比較復(fù)雜的 PlatformView 嵌入這時(shí) Flutter SDK 仍需高度驗(yàn)證千萬(wàn)別浪費(fèi)主力精力;高幀率的自定義渲染路徑直接降級(jí)為普通動(dòng)畫方案官方尚未驗(yàn)證的構(gòu)建緩存優(yōu)化為了幾個(gè)秒的編譯時(shí)間不值得投入。把這些碰不得的雷列出來(lái)后你的有效開發(fā)時(shí)間會(huì)多出一大截。5. 我對(duì)這個(gè)版本的個(gè)人評(píng)價(jià)與后續(xù)演進(jìn)方向說(shuō)實(shí)話面對(duì) 0.0.2 這種版本號(hào)一開始我是持謹(jǐn)慎態(tài)度的。但上手研究之后我的態(tài)度從猶豫變成了可以跟。因?yàn)檫@個(gè)版本踩的路線是對(duì)的它沒有重新發(fā)明一套 Flutter 運(yùn)行時(shí)而是老老實(shí)實(shí)把 Flutter 官方引擎作為基底在 OHOS 側(cè)做平臺(tái)抽象層的替換和 NAPI 橋接。這意味著只要上游 Flutter 能跑的能力后續(xù)版本大概率都會(huì)逐步補(bǔ)齊。從演進(jìn)方向看我認(rèn)為接下來(lái)最值得關(guān)注的是三塊能力第一是 Texture 和 PlatformView 體系能否補(bǔ)完整這決定視頻和相機(jī)場(chǎng)景能不能用第二是插件管理工具的成熟度未來(lái)如果能像 Flutter 官方插件管理命令那樣一鍵添加插件平臺(tái)實(shí)現(xiàn)開發(fā)者才愿意真正遷移第三是 hvigor 構(gòu)建鏈路的穩(wěn)定性現(xiàn)在的構(gòu)建過(guò)程需要交叉配合太多的手工步驟離一行命令出包還有距離。如果你所在的項(xiàng)目正面臨多端統(tǒng)一的需求我的建議是現(xiàn)在可以用 0.0.2 版本做技術(shù)預(yù)研和 Demo 搭建同時(shí)把項(xiàng)目里必須走原生能力的部分做接口抽象。等到適配版本邁過(guò) 0.1 甚至 0.2 時(shí)你已經(jīng)有了可驗(yàn)證的工程基礎(chǔ)、可沉淀的常見坑清單到時(shí)再?zèng)Q定是否全量投入。這種節(jié)奏看起來(lái)慢實(shí)際是最安全的進(jìn)擊方式。最后分享一個(gè)我自己常用的判斷法看一個(gè)跨端適配方案值不值得長(zhǎng)期投入不是看它的 star 數(shù)也不是看它發(fā)布多頻繁而是看它對(duì)錯(cuò)誤反饋的態(tài)度。如果版本發(fā)布說(shuō)明里愿意寫清楚已知問題和邊界你就會(huì)知道它的維護(hù)者是真心在做事。這個(gè)版本面向社區(qū)公開時(shí)提供的是透明的內(nèi)容這就是我最終決定寫這篇文章的原因。