新聞中心
為什么flutter debug版本和release版本有差別?
為了利用debug工具,大多數(shù)程序猿開(kāi)發(fā)的時(shí)候使用AS的debug版本,最終發(fā)布版本是release版本,但是在這個(gè)轉(zhuǎn)變的過(guò)程中可能會(huì)出現(xiàn)一些意外。
專(zhuān)注于為中小企業(yè)提供成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作、外貿(mào)網(wǎng)站建設(shè)服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)同仁免費(fèi)做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動(dòng)了近千家企業(yè)的穩(wěn)健成長(zhǎng),幫助中小企業(yè)通過(guò)網(wǎng)站建設(shè)實(shí)現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。
1、releas版本與debug版本的applicationId不一樣
為了客戶端上兩個(gè)版本共存,通常debug設(shè)置不同applicationId,這會(huì)導(dǎo)致需要填寫(xiě)applicationId申請(qǐng)的第三方平臺(tái)使用不正常,比如小米推送和微信分享等。
2、混淆問(wèn)題: 一般情況下,debug版本的混淆是關(guān)閉的,release版本是打開(kāi)的
這個(gè)坑我是多次涉入。
(1)使用Gson或者FastGson 轉(zhuǎn)換Json字符后提供給某些類(lèi)使用,比如Adapter。Release版本發(fā)現(xiàn)列表不能正常顯示,結(jié)果是因?yàn)榛煜臅r(shí)候沒(méi)有keep相關(guān)的Entity類(lèi)。
(2) 使用反射,利用類(lèi)名調(diào)起類(lèi)時(shí),注意keep該類(lèi),防止混淆。
使用案例: Switch 分支很多,導(dǎo)致代碼很長(zhǎng),閱讀困難。因此把switch的String作為類(lèi)名, 使用反射調(diào)起。有新的情況時(shí),只需要增加新類(lèi),不需要看以前的分支,也不用放在一個(gè)類(lèi)里面。
Flutter 切換指定版本
查看所有分支和當(dāng)前分支
切換 到指定分支。 例如
查看所有版本
切換 到指定版本。 例如
更新到最新版本
cd到自己的flutter目錄下
執(zhí)行。git reset --hard id
這是1.20.4的id
git reset --hard fba99f6cf9a14512e461e3122c8ddfaa25394e89
這是2.5.1的id
git reset --hard ffb2ecea5223acdd139a5039be2f9c796962833d
這是1.22.4的id
git reset --hard 1aafb3a8b9b0c36241c5f5b34ee914770f015818
這是1.22.3的id
git reset --hard 8874f21e79d7ec66d0457c7ab338348e31b17f1d
flutter git地址
找commit id 的手順
Flutter設(shè)置APP版本與構(gòu)建版本
當(dāng)一個(gè)純Flutter APP開(kāi)發(fā)完成,我們要打包發(fā)布到App Store和各大安卓市場(chǎng),這時(shí)候我們需要設(shè)置APP的版本號(hào)。
如果我們?cè)谑褂迷鷌OS或者Android開(kāi)發(fā)的時(shí),我們會(huì)在info.plist中設(shè)置 version 和 build 或是在build.gradle中設(shè)置 versionName 和 versionCode ,他們分別表示APP的版本和構(gòu)建版本。
但是我們?cè)谑褂肍lutter管理APP版本時(shí),打開(kāi) pubspec.yaml 只看到一個(gè) version 字段。這時(shí)候我們應(yīng)該怎么設(shè)置APP的 version 和 build 呢?
我們?cè)趐ub上隨便找一個(gè)Flutter的組件,例如官方的 camera ,我們可以看到截止目前為止最新的版本為: camera: ^0.5.2+1 ??吹竭@里,我想大家都明白了,Dart采用的是加號(hào)式的版本描述方式, + 前面是版本號(hào), + 后面是當(dāng)前版本的build號(hào)。所以我們?cè)O(shè)置APP的版本號(hào)和build次數(shù),在這里設(shè)置即可,例如: version: 1.2.0+1 。
當(dāng)我們新建一個(gè)Flutter工程的時(shí)候,我們分別使用Xcode和Android Studio打開(kāi)iOS和Android的工程可以看到,iOS中的 version 和 build 的值分別為 FLUTTER_BUILD_NAME 和 FLUTTER_BUILD_NUMBER :
同樣我們打開(kāi)Android工程可以看到有如下定義:
事實(shí)上,F(xiàn)lutter在編譯的時(shí)候會(huì)生成 ios/Flutter/Generated.xcconfig 和 android/local.properties 文件。這兩個(gè)文件由Flutter編譯自動(dòng)生成,不可更改。記錄了包含SDK路徑或者文件路徑,版本信息,環(huán)境配置(release/debug)等信息。原生工程獲取版本信息的變量就定義在這兩個(gè)文件里面。
Flutter SDK回退指定版本
由于flutter到sdk是托管在github倉(cāng)庫(kù)里的,所以升級(jí)降級(jí)SDK版本完全可以基于git的形式操作,這也是 flutter version 廢棄后官方推薦的改變SDK版本的方式,
通過(guò)Git的方式回退版本一共需要四步:
macOS和Linux的用戶可以在 命令行 中使用 which 命令查看flutter SDK的路徑:
Windows用戶可以在 命令行 中使用 where 命令查看flutter SDK的路徑:
從執(zhí)行命令的結(jié)果中截取 /bin/flutter 前的路徑,就是flutter SDK的路徑,例如:
使用 cd 命令進(jìn)入flutter SDK的路徑:
點(diǎn)擊鏈接 flutter的版本列表 選擇版本號(hào),注意需要選擇和當(dāng)前Channel一致的版本(參考1.1節(jié)中的方法)
flutter 2.3版本之前,提供了 version 和 downgrade 兩個(gè)參數(shù)可以幫助用戶回退版本,這兩個(gè)參數(shù)都能回退到指定版本號(hào),區(qū)別是:
使用 verison或downgrade參數(shù)僅需以下三步 :
點(diǎn)擊鏈接 flutter的版本列表 選擇版本號(hào),注意需要選擇和當(dāng)前Channel一致的版本,查看Channle的方法如何:
Flutter 啟動(dòng)頁(yè)的前世今生適配歷程
APP 啟動(dòng)頁(yè)在國(guó)內(nèi)是最常見(jiàn)也是必備的場(chǎng)景,其中啟動(dòng)頁(yè)在 iOS 上算是強(qiáng)制性的要求,其實(shí)配置啟動(dòng)頁(yè)挺簡(jiǎn)單,因?yàn)樵?Flutter 里現(xiàn)在只需要:
一般只要配置無(wú)誤并且圖片尺寸匹配,基本上就不會(huì)有什么問(wèn)題, 那既然這樣,還有什么需要適配的呢?
事實(shí)上大部分時(shí)候 iOS 是不會(huì)有什么問(wèn)題, 因?yàn)? LaunchScreen.storyboard 的流程本就是 iOS 官方用來(lái)做應(yīng)用啟動(dòng)的過(guò)渡;而對(duì)于 Andorid 而言,直到 12 之前 windowBackground 這種其實(shí)只能算“民間”野路子 ,所以對(duì)于 Andorid 來(lái)說(shuō),這其中就涉及到一個(gè)點(diǎn):
所以下面主要介紹 Flutter 在 Android 上為了這個(gè)啟動(dòng)圖做了哪些騷操作~
在已經(jīng)忘記版本的“遠(yuǎn)古時(shí)期” , FlutterActivity 還在 io.flutter.app.FlutterActivity 路徑下的時(shí)候,那時(shí)啟動(dòng)頁(yè)的邏輯相對(duì)簡(jiǎn)單,主要是通過(guò) App 的 AndroidManifest 文件里是否配置了 SplashScreenUntilFirstFrame 來(lái)進(jìn)行判斷。
在 FlutterActivity 內(nèi)部 FlutterView 被創(chuàng)建的時(shí)候,會(huì)通過(guò)讀取 meta-data 來(lái)判斷是否需要使用 createLaunchView 邏輯 :
是不是很簡(jiǎn)單,那就會(huì)有人疑問(wèn)為什么要這樣做?我直接配置 Activity 的 android:windowBackground 不就完成了嗎?
這就是上面提到的時(shí)間差問(wèn)題, 因?yàn)閱?dòng)頁(yè)到 Flutter 渲染完第一幀畫(huà)面中間,會(huì)出現(xiàn)概率出現(xiàn)黑屏的情況,所以才需要這個(gè)行為來(lái)實(shí)現(xiàn)過(guò)渡 。
經(jīng)歷了“遠(yuǎn)古時(shí)代”之后, FlutterActivity 來(lái)到了 io.flutter.embedding.android.FlutterActivity , 在到 2.5 版本發(fā)布之前,F(xiàn)lutter 又針對(duì)這個(gè)啟動(dòng)過(guò)程做了不少調(diào)整和優(yōu)化,其中主要就是 SplashScreen 。
自從開(kāi)始進(jìn)入 embedding 階段后, FlutterActivity 主要用于實(shí)現(xiàn)了一個(gè)叫 Host 的 interface ,其中和我們有關(guān)系的就是 provideSplashScreen 。
默認(rèn)情況下它會(huì)從 AndroidManifest 文件里是否配置了 SplashScreenDrawable 來(lái)進(jìn)行判斷 。
默認(rèn)情況下當(dāng) AndroidManifest 文件里配置了 SplashScreenDrawable ,那么這個(gè) Drawable 就會(huì)在 FlutterActivity 創(chuàng)建 FlutterView 時(shí)被構(gòu)建成 DrawableSplashScreen 。
DrawableSplashScreen 其實(shí)就是一個(gè)實(shí)現(xiàn)了 io.flutter.embedding.android.SplashScreen 接口的類(lèi),它的作用就是:
之后 FlutterActivity 內(nèi)會(huì)創(chuàng)建出 FlutterSplashView ,它是個(gè) FrameLayout。
FlutterSplashView 將 FlutterView 和 ImageView 添加到一起, 然后通過(guò) transitionToFlutter 的方法來(lái)執(zhí)行動(dòng)畫(huà),最后動(dòng)畫(huà)結(jié)束時(shí)通過(guò) onTransitionComplete 移除 splashScreenView 。
所以整體邏輯就是:
當(dāng)然這里也是分狀態(tài):
當(dāng)然這個(gè)階段的 FlutterActivity 也可以通過(guò) override provideSplashScreen 方法來(lái)自定義 SplashScreen 。
看到?jīng)]有,做了這么多其實(shí)也就是為了彌補(bǔ)啟動(dòng)頁(yè)和 Flutter 渲染之間, 另外還有一個(gè)優(yōu)化,叫 NormalTheme 。
通過(guò)該配置 NormalTheme ,在 Activity 啟動(dòng)時(shí),就會(huì)首先執(zhí)行 switchLaunchThemeForNormalTheme(); 方法將主題從 LaunchTheme 切換到 NormalTheme 。
大概配置完就是如下樣子, 前面分析那么多其實(shí)就是為了告訴你,如果出現(xiàn)問(wèn)題了,你可以從哪個(gè)地方去找到對(duì)應(yīng)的點(diǎn) 。
講了那么多, Flutter 2.5 之后 provideSplashScreen 和 io.flutter.embedding.android.SplashScreenDrawable 就被棄用了,驚不喜驚喜,意不意外,開(kāi)不開(kāi)心 ?
通過(guò)源碼你會(huì)發(fā)現(xiàn),當(dāng)你設(shè)置了 splashScreen 的時(shí)候,會(huì)看到一個(gè) log 警告:
為什么會(huì)棄用?
其實(shí)這個(gè)提議是在 這個(gè) issue 上,然后通過(guò) 這個(gè) pr 完成調(diào)整。
大概意思就是: 原本的設(shè)計(jì)搞復(fù)雜了,用 OnPreDrawListener 更精準(zhǔn),而且不需要為了后面 Andorid12 的啟動(dòng)支持做其他兼容,只需要給 FlutterActivity 等類(lèi)增加接口開(kāi)關(guān)即可 。
也就是2.5之后 Flutter 使用 ViewTreeObserver.OnPreDrawListener 來(lái)實(shí)現(xiàn)延遲直到加載出 Flutter 的第一幀。
為什么說(shuō)默認(rèn)情況? 因?yàn)檫@個(gè)行為在 FlutterActivity 里,是在 getRenderMode() == RenderMode.surface 才會(huì)被調(diào)用,而 RenderMode 又和 BackgroundMode 有關(guān)心 。
所以在 2.5 版本后, FlutterActivity 內(nèi)部創(chuàng)建完 FlutterView 后就會(huì)執(zhí)行一個(gè) delayFirstAndroidViewDraw 的操作。
這里主要注意一個(gè)參數(shù): isFlutterUiDisplayed 。
當(dāng) Flutter 被完成展示的時(shí)候, isFlutterUiDisplayed 就會(huì)被設(shè)置為 true。
所以當(dāng) Flutter 沒(méi)有執(zhí)行完成之前, FlutterView 的 onPreDraw 就會(huì)一直返回 false ,這也是 Flutter 2.5 開(kāi)始之后適配啟動(dòng)頁(yè)的新調(diào)整。
看了這么多,大概可以看到其實(shí)開(kāi)源項(xiàng)目的推進(jìn)并不是一帆風(fēng)順的,沒(méi)有什么是一開(kāi)始就是最優(yōu)解,而是經(jīng)過(guò)多方嘗試和交流,才有了現(xiàn)在的版本,事實(shí)上開(kāi)源項(xiàng)目里,類(lèi)似這樣的經(jīng)歷數(shù)不勝數(shù):
Mac--Flutter更換指定版本
類(lèi)似錯(cuò)誤No named parameter with the name ‘XXXXXX‘問(wèn)題
原因:Flutter版本問(wèn)題
一、回退到指定版本
1、GitHub搜索flutter 點(diǎn)擊進(jìn)入后,選擇tags找到需要的版本點(diǎn)進(jìn)去,如圖:
2、復(fù)制版本號(hào)
cd ?/Users/apple/Documents/flutter ? ?根目錄,同bash_profile中PATH配置保持一致即可。
git reset --hard 3595343e20a61ff16d14e8ecc25f364276bb1b8b
執(zhí)行完成,檢測(cè) flutter --version
執(zhí)行 flutter doctor
????????了
分享題目:flutter每個(gè)版本,flutter20性能
網(wǎng)址分享:http://fisionsoft.com.cn/article/dsgphgo.html