Flutter 升級(jí) 2.0 填坑指導(dǎo),帶你原地起飛

Flutter 2.0 的發(fā)布帶來(lái)了很多的 break change ,特別是新增加的空聲明安全,相信不少大哥嘗鮮之后立馬反思自己“手賤” ,事實(shí)上舊項(xiàng)目升級(jí) Flutter 2.0 確實(shí)有很多兼容的點(diǎn),但是“吃螃蟹”其實(shí)我們可以逐步拆解,比如“先蒸熟了再吃”?

image

其實(shí)正如《 Dart 2.12 發(fā)布,穩(wěn)定空安全聲明和FFI版本》 里所說(shuō),升級(jí)到 Flutter 2.0 并不會(huì)強(qiáng)制要求你馬上使用空聲明安全 ,所以我們可以把整個(gè)升級(jí)適配過(guò)程拆解幾步來(lái)完成,最終完成 2.0 的升級(jí)適配。

1、針對(duì) API 的調(diào)整

首先你需要先將本地的 Flutter SDK 升級(jí)到 2.0 以上的版本,升級(jí)完成之后首先確保 Dart SDK 的 environment 小于 2.12.0 , 可以選中 2.10.0 之類的版本,如下所示的配置是不需要針對(duì)空聲明安全進(jìn)行適配,接下來(lái)我們就可以針對(duì) SDK API 的 break change 先進(jìn)行適配調(diào)整。


environment:
  sdk: '>=2.10.0 <3.0.0'

首先你會(huì)應(yīng)該遇到最多的應(yīng)該是 List 對(duì)象的修改,因?yàn)?factory List 的函數(shù)已經(jīng)被 Deprecated ,所以你需要使用 [] 或者 List.filled 來(lái)替換你原有的實(shí)現(xiàn),從這開始就是“體力活”了。

image
image.png

常見的還有 runZonedonError 參數(shù)也被 Deprecated ,需要使用 runZonedGuarded 來(lái)替代。

一般使用 runZoned 的都是用于對(duì) Dart 層做錯(cuò)誤信息收集。

image

Stack 控件的 overflow 參數(shù)也被 Deprecated ,需要替換為 clipBehavior,比如以前的 Overflow.visible 可以修改為 Clip.none ,默認(rèn)情況下是 Clip.hardEdge

image.png

FlatButton 也被標(biāo)志為棄用,需要替換成 TextButton;類似的 RaisedButton 需要替換為 ElevatedButton

這里主要需要注意的是: FlatButtonRaisedButton 上的 padding、color 等方法現(xiàn)在需要使用 ButtonStyle 來(lái)設(shè)置。

image.png

類似的還有 Scaffold.of(builderContext).showSnackBar 方法需要替換為 ScaffoldMessenger.of(builderContext).showSnackBar 使用。

image.png

最后還有:

  • ScaffoldresizeToAvoidBottomPadding 參數(shù)正式取消,需要使用 resizeToAvoidBottomInset 參數(shù)替代。

  • Theme.of(context, shadowThemeOnly: true)shadowThemeOnly 參數(shù)正式取消。

  • 官方新增了 DateUtils'package:flutter/material.dart' 里,可能會(huì)與你的項(xiàng)目里的 DateUtils 命名沖突。

  • Localizations.localeOf(context, nullOk: true)MediaQuery.of(context, nullOk: true)nullOk 參數(shù)正式取消。

大致上我遇到的 break change 或者棄用警告就是上面這些,調(diào)整完后在沒有打開空安全配置的情況下,是可以正常運(yùn)行的。

當(dāng)然你也可能遇到:修改完后依舊無(wú)法運(yùn)行的情況,因?yàn)檫€有第三方插件包依賴需要調(diào)整。

2、針對(duì)依賴倉(cāng)庫(kù)的調(diào)整

雖然 Flutter 2.0 沒有要求主項(xiàng)目一定使用空聲明安全,但是對(duì)于插件的適配要求卻比價(jià)嚴(yán)格,所以你仍可能需要升級(jí)一些 pub 倉(cāng)庫(kù)的依賴來(lái)完成適配。

前提是祈禱你使用插件包有適配 null-safety

如圖所示,正常支持 null-safety 的包在 pub 官網(wǎng)上是有 Null safety 的標(biāo)簽或者 nullsafety 的預(yù)覽版本,這時(shí)候只要修改你的依賴版本,使用支持空聲明安全的插件版本就可以了。

image.png

完了嗎?明顯沒有!

因?yàn)榇罅康牟寮?jí)就可能帶來(lái)版本沖突,比如 analyzer 版本沖突,在 json_serializablebuilt_value_generator 中他們分別依賴了不同的 analyzer 版本,所以會(huì)有版本沖突問(wèn)題。

image.png

另外比如 build_runnergraphql 的版本之間存在 web_socket_channel 的沖突。

image.png

這些沖突要怎么解決呢?這里給大家展示使用 dependency_overrides 臨時(shí)解決這些沖突。

如下圖所示,可以看到在 dependency_overrides 下我強(qiáng)行使用了 analyzer: 1.1.0web_socket_channel ,這樣運(yùn)行之后 analyzerweb_socket_channel 的版本會(huì)被強(qiáng)制指定,從而忽略沖突來(lái)解決無(wú)法運(yùn)行的問(wèn)題。

另外在我的 dependency_overrides 里可以看到很多帶有 # 的注解版本,這些版本都是在遇到?jīng)_突之后,為了成功運(yùn)行一個(gè)個(gè)添加上去,之后在對(duì)應(yīng)插件更新支持兼容后才注釋掉。

image.png
image.png

添加了 dependency_overrides 之后運(yùn)行會(huì)有 Warning 提示,這部分忽略就行了。

image.png

3、針對(duì)空聲明安全的調(diào)整

在完成上面兩個(gè)步驟,項(xiàng)目應(yīng)該就可以在 Flutter 2.0 上運(yùn)行,那接下來(lái)就是把版本升級(jí)到空安全聲明的支持,當(dāng)然前提是你想要使用 null safety 。

升級(jí)到空安全聲明,推薦使用官方的 dart migrate 命令,命令會(huì)生成一個(gè)可視化的界面,引導(dǎo)你將項(xiàng)目遷移到空安全聲明,并且自動(dòng)幫你覆蓋代碼。

如果你還有插件沒有完全支持空安全聲明,那么可以使用 dart migrate --skip-import-check 來(lái)完成遷移。

image.png

運(yùn)行后可以看到一個(gè)鏈接,點(diǎn)擊如圖所示鏈接就可以打開引導(dǎo)界面,引導(dǎo)界面上可以看到每個(gè)文件會(huì)被修改位置和數(shù)量,你可以自己重新調(diào)整內(nèi)容后點(diǎn)擊刷新,或者直接點(diǎn)擊 APPLY MIGRATION 按鍵,之后再到項(xiàng)目里進(jìn)行修改。

image.png

相信我,修改后肯定會(huì)有一堆報(bào)錯(cuò)和警告,不要擔(dān)心,這是正常的,接下來(lái)就是“體力活”了。

首先某些地方可能會(huì)被修改為如下圖所示代碼,你只需要對(duì)應(yīng)修改回來(lái)就好,自動(dòng)覆蓋的腳本確實(shí)有些傻。

image.png

有時(shí)候某些 await 語(yǔ)法會(huì)被強(qiáng)行增加 as FutureOr ,如果你不需要改為原來(lái)的聲明就可以。

image.png

還有比如 compute 方法中的 Function(_) 錯(cuò)誤提示,只需要改為對(duì)應(yīng)分參數(shù)傳入,比如 Function(String? data) 就可以了。

image.png

有時(shí)候一些方法定義也會(huì)被強(qiáng)行修改,比如 redux 相關(guān)的這些修改可能也會(huì)影響運(yùn)行問(wèn)題,所以只需要把 as 部分去除就可以了。

image.png

而比如這類方法報(bào)錯(cuò),一般就是提供的參數(shù)和使用參數(shù)對(duì)應(yīng)不上,只需要添加上 ? 即可修復(fù)。

image.png

最后有時(shí)也會(huì)使用 ! 來(lái)暫時(shí)完成適配,比如某個(gè)參數(shù)你確定不會(huì)為 null,你可以在使用時(shí)通過(guò) ! 表示強(qiáng)行使用(就是任性不判空),比如下圖就是對(duì) _dragOffsetnotification.scrollDelta 的強(qiáng)行修改對(duì)比。

image.png

可以看到這部分內(nèi)容也是純粹體力活,雖然自動(dòng)覆蓋的靠譜程度肯定不高,還是需要一定的人工修改,但是這個(gè)自動(dòng)化過(guò)程大大提高了遷移的效率,而在代碼覆蓋之后,environmentsdk 也會(huì)自動(dòng)修改為 >=2.12.0 。

空安全聲明遷移完成!

4、針對(duì)遷移中運(yùn)行的調(diào)整

最后,到這里你可能會(huì)發(fā)現(xiàn),升級(jí)到 dart 1.12之后,適配完 null safety 點(diǎn) IDE 上的運(yùn)行發(fā)現(xiàn)還是運(yùn)行不起來(lái),比如下圖所示:

image.png

這是因?yàn)槟氵€有沒有遷移完成的依賴包,但是有時(shí)候依賴包不是一時(shí)半會(huì)就能兼容完成,這時(shí)候應(yīng)該如何適配運(yùn)行呢?

這時(shí)候就可以通過(guò) flutter run --no-sound-null-safety 命令來(lái)運(yùn)行調(diào)試項(xiàng)目,通過(guò)此命令運(yùn)行的項(xiàng)目并不會(huì)使用空安全聲明校驗(yàn),然后通過(guò)輸入 r 或者 R 等就可以完成 hotload 等調(diào)試操作。

image

如果需要 debug 代碼或者性能調(diào)試,還可以通過(guò) chrome 瀏覽器打開 http://localhost:9100 地址,然后把運(yùn)行得到的 Observatory 地址如: http://127.0.0.1:62145/H1PrDXLbA3w=/ 輸入到 Connect 輸入框,這樣就可以打開 DartTools 進(jìn)行調(diào)試。

image.png

最后不得不說(shuō), Flutter 2.0 算是 Flutter 新的起點(diǎn),希望新的版本能給你們帶來(lái)更穩(wěn)定和更便捷的開發(fā)體驗(yàn)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容