我們在調試flutter時,通常看到的并不是我們熟悉的logcat,而是Run里的Consale,也就是控制臺窗口,那么當我們需要在flutter和原生互相調用時,看原生的打印該怎么辦呢?答案當然是讓logcat重新出來了,在flutter項目中出來,而不用重新跑一個原生項目,或者說用原生項目和flutter來回切,這樣太浪費時間了,想要調出logcat一共需要三步:
10年積累的成都網站制作、網站設計經驗,可以快速應對客戶對網站的新想法和需求。提供各種問題對應的解決方案。讓選擇我們的客戶得到更好、更有力的網絡服務。我雖然不認識你,你也不認識我。但先網站策劃后付款的網站建設流程,更有固始免費網站建設讓你可以放心的選擇與我們合作。
第一步:
配置SDK
都配置完后記得點確定。
感謝這篇文章的作者
Flutter項目沒有Logcat界面時打開Logcat的方法
Flutter 里的 BuildContext 相信大家都不會陌生,雖然它叫 Context,但是它實際是 Element 的抽象對象,而在 Flutter 里,它主要來自于 ComponentElement 。
關于 ComponentElement 可以簡單介紹一下,在 Flutter 里根據 Element 可以簡單地被歸納為兩類:
所以一般情況下,我們在 build 方法或者 State 里獲取到的 BuildContext 其實就是 ComponentElement 。
那使用 BuildContext 有什么需要注意的問題 ?
首先如下代碼所示,在該例子里當用戶點擊 FloatingActionButton 的時候,代碼里做了一個 2秒的延遲,然后才調用 pop 退出當前頁面。
正常情況下是不會有什么問題,但是當用戶在點擊了 FloatingActionButton 之后,又馬上點擊了 AppBar 返回退出應用,這時候就會出現以下的錯誤提示。
可以看到此時 log 說,Widget 對應的 Element 已經不在了,因為在 Navigator.of(context) 被調用時, context 對應的 Element 已經隨著我們的退出銷毀。
一般情況下處理這個問題也很簡單, 那就是增加 mounted 判斷,通過 mounted 判斷就可以避免上述的錯誤 。
上面代碼里的 mounted 標識位來自于 State , 因為 State 是依附于 Element 創建,所以它可以感知 Element 的生命周期 ,例如 mounted 就是判斷 _element != null; 。
那么到這里我們收獲了一個小技巧: 使用 BuildContext 時,在必須時我們需要通過 mounted 來保證它的有效性 。
那么單純使用 mounted 就可以滿足 context 優化的要求了嗎 ?
如下代碼所示,在這個例子里:
由于在 5 秒之內,Item 被劃出了屏幕,所以對應的 Elment 其實是被釋放了,從而由于 mounted 判斷, SnackBar 不會被彈出。
那如果假設需要在開發時展示點擊數據上報的結果,也就是 Item 被釋放了還需要彈出,這時候需要如何處理 ?
我們知道不管是 ScaffoldMessenger.of(context) 還是 Navigator.of(context) ,它本質還是通過 context 去往上查找對應的 InheritedWidget 泛型,所以其實我們可以提前獲取。
所以,如下代碼所示,在 Future.delayed 之前我們就通過 ScaffoldMessenger.of(context); 獲取到 sm 對象,之后就算你直接退出當前的列表頁面,5秒過后 SnackBar 也能正常彈出。
為什么頁面銷毀了,但是 SnackBar 還能正常彈出 ?
因為此時通過 of(context); 獲取到的 ScaffoldMessenger 是存在 MaterialApp 里,所以就算頁面銷毀了也不影響 SnackBar 的執行。
但是如果我們修改例子,如下代碼所示,在 Scaffold 上面多嵌套一個 ScaffoldMessenger ,這時候在 Item 里通過 ScaffoldMessenger.of(context) 獲取到的就會是當前頁面下的 ScaffoldMessenger 。
這種情況下我們只能保證Item 不可見的時候 SnackBar 還能正常彈出, 而如果這時候我們直接退出頁面,還是會出現以下的錯誤提示,因為 ScaffoldMessenger 也被銷毀了 。
所以到這里我們收獲第二個小技巧: 在異步操作里使用 of(context) ,可以提前獲取,之后再做異步操作,這樣可以盡量保證流程可以完整執行 。
既然我們說到通過 of(context) 去獲取上層共享往下共享的 InheritedWidget ,那在哪里獲取就比較好 ?
還記得前面的 log 嗎?在第一個例子出錯時,log 里就提示了一個方法,也就是 State 的 didChangeDependencies 方法。
為什么是官方會建議在這個方法里去調用 of(context) ?
首先前面我們一直說,通過 of(context) 獲取到的是 InheritedWidget ,而 當 InheritedWidget 發生改變時,就是通過觸發綁定過的 Element 里 State 的 didChangeDependencies 來觸發更新, 所以在 didChangeDependencies 里調用 of(context) 有較好的因果關系 。
那我能在 initState 里提前調用嗎 ?
當然不行,首先如果在 initState 直接調用如 ScaffoldMessenger.of(context).showSnackBar 方法,就會看到以下的錯誤提示。
這是因為 Element 里會判斷此時的 _StateLifecycle 狀態,如果此時是 _StateLifecycle.created 或者 _StateLifecycle.defunct ,也就是在 initState 和 dispose ,是不允許執行 of(context) 操作。
當然,如果你硬是想在 initState 下調用也行,增加一個 Future 執行就可以成功執行
那我在 build 里直接調用不行嗎 ?
直接在 build 里調用肯定可以,雖然 build 會被比較頻繁執行,但是 of(context) 操作其實就是在一個 map 里通過 key - value 獲取泛型對象,所以對性能不會有太大的影響。
真正對性能有影響的是 of(context) 的綁定數量和獲取到對象之后的自定義邏輯 ,例如你通過 MediaQuery.of(context).size 獲取到屏幕大小之后,通過一系列復雜計算來定位你的控件。
例如上面這段代碼,可能會導致鍵盤在彈出的時候,雖然當前頁面并沒有完全展示,但是也會導致你的控件不斷重新計算從而出現卡頓。
所以到這里我們又收獲了一個小技巧: 對于 of(context) 的相關操作邏輯,可以盡量放到 didChangeDependencies 里去處理 。
APP 啟動頁在國內是最常見也是必備的場景,其中啟動頁在 iOS 上算是強制性的要求,其實配置啟動頁挺簡單,因為在 Flutter 里現在只需要:
一般只要配置無誤并且圖片尺寸匹配,基本上就不會有什么問題, 那既然這樣,還有什么需要適配的呢?
事實上大部分時候 iOS 是不會有什么問題, 因為 LaunchScreen.storyboard 的流程本就是 iOS 官方用來做應用啟動的過渡;而對于 Andorid 而言,直到 12 之前 windowBackground 這種其實只能算“民間”野路子 ,所以對于 Andorid 來說,這其中就涉及到一個點:
所以下面主要介紹 Flutter 在 Android 上為了這個啟動圖做了哪些騷操作~
在已經忘記版本的“遠古時期” , FlutterActivity 還在 io.flutter.app.FlutterActivity 路徑下的時候,那時啟動頁的邏輯相對簡單,主要是通過 App 的 AndroidManifest 文件里是否配置了 SplashScreenUntilFirstFrame 來進行判斷。
在 FlutterActivity 內部 FlutterView 被創建的時候,會通過讀取 meta-data 來判斷是否需要使用 createLaunchView 邏輯 :
是不是很簡單,那就會有人疑問為什么要這樣做?我直接配置 Activity 的 android:windowBackground 不就完成了嗎?
這就是上面提到的時間差問題, 因為啟動頁到 Flutter 渲染完第一幀畫面中間,會出現概率出現黑屏的情況,所以才需要這個行為來實現過渡 。
經歷了“遠古時代”之后, FlutterActivity 來到了 io.flutter.embedding.android.FlutterActivity , 在到 2.5 版本發布之前,Flutter 又針對這個啟動過程做了不少調整和優化,其中主要就是 SplashScreen 。
自從開始進入 embedding 階段后, FlutterActivity 主要用于實現了一個叫 Host 的 interface ,其中和我們有關系的就是 provideSplashScreen 。
默認情況下它會從 AndroidManifest 文件里是否配置了 SplashScreenDrawable 來進行判斷 。
默認情況下當 AndroidManifest 文件里配置了 SplashScreenDrawable ,那么這個 Drawable 就會在 FlutterActivity 創建 FlutterView 時被構建成 DrawableSplashScreen 。
DrawableSplashScreen 其實就是一個實現了 io.flutter.embedding.android.SplashScreen 接口的類,它的作用就是:
之后 FlutterActivity 內會創建出 FlutterSplashView ,它是個 FrameLayout。
FlutterSplashView 將 FlutterView 和 ImageView 添加到一起, 然后通過 transitionToFlutter 的方法來執行動畫,最后動畫結束時通過 onTransitionComplete 移除 splashScreenView 。
所以整體邏輯就是:
當然這里也是分狀態:
當然這個階段的 FlutterActivity 也可以通過 override provideSplashScreen 方法來自定義 SplashScreen 。
看到沒有,做了這么多其實也就是為了彌補啟動頁和 Flutter 渲染之間, 另外還有一個優化,叫 NormalTheme 。
通過該配置 NormalTheme ,在 Activity 啟動時,就會首先執行 switchLaunchThemeForNormalTheme(); 方法將主題從 LaunchTheme 切換到 NormalTheme 。
大概配置完就是如下樣子, 前面分析那么多其實就是為了告訴你,如果出現問題了,你可以從哪個地方去找到對應的點 。
講了那么多, Flutter 2.5 之后 provideSplashScreen 和 io.flutter.embedding.android.SplashScreenDrawable 就被棄用了,驚不喜驚喜,意不意外,開不開心 ?
通過源碼你會發現,當你設置了 splashScreen 的時候,會看到一個 log 警告:
為什么會棄用?
其實這個提議是在 這個 issue 上,然后通過 這個 pr 完成調整。
大概意思就是: 原本的設計搞復雜了,用 OnPreDrawListener 更精準,而且不需要為了后面 Andorid12 的啟動支持做其他兼容,只需要給 FlutterActivity 等類增加接口開關即可 。
也就是2.5之后 Flutter 使用 ViewTreeObserver.OnPreDrawListener 來實現延遲直到加載出 Flutter 的第一幀。
為什么說默認情況? 因為這個行為在 FlutterActivity 里,是在 getRenderMode() == RenderMode.surface 才會被調用,而 RenderMode 又和 BackgroundMode 有關心 。
所以在 2.5 版本后, FlutterActivity 內部創建完 FlutterView 后就會執行一個 delayFirstAndroidViewDraw 的操作。
這里主要注意一個參數: isFlutterUiDisplayed 。
當 Flutter 被完成展示的時候, isFlutterUiDisplayed 就會被設置為 true。
所以當 Flutter 沒有執行完成之前, FlutterView 的 onPreDraw 就會一直返回 false ,這也是 Flutter 2.5 開始之后適配啟動頁的新調整。
看了這么多,大概可以看到其實開源項目的推進并不是一帆風順的,沒有什么是一開始就是最優解,而是經過多方嘗試和交流,才有了現在的版本,事實上開源項目里,類似這樣的經歷數不勝數:
You are building a fat APK that includes binaries for android-arm, android-arm64.
If you are deploying the app to the Play Store, it's recommended to use app bundles or split the APK to reduce the APK size.
To generate an app bundle, run:
? ? flutter build appbundle --target-platform android-arm,android-arm64
? ? Learn more on:
To split the APKs per ABI, run:
? ? flutter build apk --target-platform android-arm,android-arm64 --split-per-abi
? ? Learn more on:?
Initializing gradle...? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 2.3s
Resolving dependencies...? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 14.2s
Running Gradle task 'assembleRelease'...? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?: E:\work_tool\flutter\.pub-cache\hosted\pub.flutter-io.cn\connectivity-0.4.4\android\src\main\java\io\flutter\plugins\connectivity\ConnectivityPlugin.java???????????????? API??
?: ?й???????, ????? -Xlint:deprecation ???±???
?: E:\work_tool\flutter\.pub-cache\hosted\pub.flutter-io.cn\url_launcher-5.1.3\android\src\main\java\io\flutter\plugins\urllauncher\WebViewActivity.java?
??????????????? API??
?: ?й???????, ????? -Xlint:deprecation ???±???
Calling mockable JAR artifact transform to create file: C:\Users\Administrator\.gradle\caches\transforms-1\files-1.1\android.jar\baf414ed95f14e507d85c560886dfbe2\android.jar with input E:\work_tool\sdk\android-sdk-windows\platforms\android-28\android.jar
Calling mockable JAR artifact transform to create file: C:\Users\Administrator\.gradle\caches\transforms-1\files-1.1\android.jar\ab096bb3fb172ccb785acdb1058c10a9\android.jar with input E:\work_tool\sdk\android-sdk-windows\platforms\android-27\android.jar
Request to incrementing alive workforce from 0. Current workforce (dead or alive) 0
thread-pool size=4
ProGuard, version 6.0.3
Reading input...
Reading program jar [C:\Users\Administrator\.gradle\caches\transforms-1\files-1.1\flutter.jar\ab2691c929f4d2aa57a17fa551e662a6\jetified-flutter.jar] (filtered)
Reading program jar [F:\dartSpace\flutter\jiddspace\nfc\build\app\intermediates\flutter\release\libs.jar] (filtered)
Reading program jar [C:\Users\Administrator\.gradle\caches\transforms-1\files-1.1\localbroadcastmanager-1.0.0.aar\7a407f962902eada026a8e241a760bac\jars\classes.jar] (filtered)
Reading program jar [C:\Users\Administrator\.gradle\caches\transforms-1\files-1.1\work-runtime-2.1.0.aar\8e3a1e8a8ff79006a94df6c01ceeb4f5\jars\classes.jar] (filtered)
Reading program jar [C:\Users\Administrator\.gradle\caches\transforms-1\files-1.1\fragment-1.1.0.aar\4fa7d1b49e3514cb08c8a696f9b59436\jars\classes.jar] (filtered)
Reading program jar [C:\Users\Administrator\.gradle\caches\transforms-1\files-1.1\room-runtime-2.1.0.aar\1b8774fa39759f08defb930275652eac\jars\classes.jar] (filtered)
Reading program jar [C:\Users\Administrator\.gradle\caches\transforms-1\files-1.1\room-runtime-2.1.0.aar\1b8774fa39759f08defb930275652eac\jars\libs\room-common-java8-2.1.0.jar] (filtered)
Reading program jar [C:\Users\Administrator\.gradle\caches\transforms-1\files-1.1\viewpager-1.0.0.aar\885186e7f6f969363bc93cd607d741a5\jars\classes.jar] (filtered)
Reading program jar [C:\Users\Administrator\.gradle\caches\transforms-1\files-1.1\loader-1.0.0.aar\f84f22ad0a97d2c689850b912fc04277\jars\classes.jar] (filtered)
Reading program jar [C:\Users\Administrator\.gradle\caches\transforms-1\files-1.1\activity-1.0.0.aar\a46db1490fae1b9001fc672a24eb288f\jars\classes.jar] (filtered)
Reading program jar [C:\Users\Administrator\.gradle\caches\transforms-1\files-1.1\customview-1.0.0.aar\fe8bf4a709414e884086911d2168b715\jars\classes.jar] (filtered)
Reading program jar [C:\Users\Administrator\.gradle\caches\transforms-1\files-1.1\core-1.1.0.aar\87febb54759dd5a2c7be8e971d745644\jars\classes.jar] (filtered)
Reading program jar [C:\Users\Administrator\.gradle\caches\transforms-1\files-1.1\versionedparcelable-1.1.0.aar\754157c6f50ca4e4cf3ac8d7cb5ced26\jars\classes.jar] (filtered)
Reading program jar [C:\Users\Administrator\.gradle\caches\modules-2\files-2.1\androidx.collection\collection\1.1.0\1f27220b47669781457de0d600849a5de0e89909\collection-1.1.0.jar] (filtered)
Reading program jar [C:\Users\Administrator\.gradle\caches\transforms-1\files-1.1\lifecycle-livedata-2.0.0.aar\de6944801d37d99b1dd0b877649fde1f\jars\classes.jar] (filtered)
Reading program jar [C:\Users\Administrator\.gradle\caches\transforms-1\files-1.1\lifecycle-livedata-core-2.0.0.aar\e21d6663beb6faa41a30fd5a582cb4d9\jars\classes.jar] (filtered)
Reading program jar [C:\Users\Administrator\.gradle\caches\transforms-1\files-1.1\core-runtime-2.0.1.aar\724bb0cc2ce99eaf0a23a99bb1cc5c23\jars\classes.jar] (filtered)
Reading program jar [C:\Users\Administrator\.gradle\caches\modules-2\files-2.1\androidx.room\room-common\2.1.0\b87765704590bd992ea0d92ac50253a9df7818a0\room-common-2.1.0.jar] (filtered)
Reading program jar [C:\Users\Administrator\.gradle\caches\transforms-1\files-1.1\sqlite-framework-2.0.1.aar\9cbdf82e938f7e565620a3682d2406e9\jars\classes.jar] (filtered)
Reading program jar [C:\Users\Administrator\.gradle\caches\transforms-1\files-1.1\sqlite-2.0.1.aar\1215aa5476f752bd431fb2d8059a1a39\jars\classes.jar] (filtered)
Reading program jar [C:\Users\Administrator\.gradle\caches\transforms-1\files-1.1\lifecycle-service-2.0.0.aar\9d24ebd4d6766d7b2cd515369a737934\jars\classes.jar] (filtered)
Reading program jar [C:\Users\Administrator\.gradle\caches\transforms-1\files-1.1\lifecycle-runtime-2.1.0.aar\ca02c0867547ae607130bcc54a4a9ba5\jars\classes.jar] (filtered)
Reading program jar [C:\Users\Administrator\.gradle\caches\transforms-1\files-1.1\lifecycle-viewmodel-2.1.0.aar\594e1ff6298a01d8933530bb534fa472\jars\classes.jar] (filtered)
Reading program jar [C:\Users\Administrator\.gradle\caches\transforms-1\files-1.1\savedstate-1.0.0.aar\8a2c3791a34fc80e5d9d268bf2886f95\jars\classes.jar] (filtered)
Reading program jar [C:\Users\Administrator\.gradle\caches\modules-2\files-2.1\androidx.lifecycle\lifecycle-common\2.1.0\c67e7807d9cd6c329b9d0218b2ec4e505dd340b7\lifecycle-common-2.1.0.jar] (filtered)
Reading program jar [C:\Users\Administrator\.gradle\caches\modules-2\files-2.1\androidx.arch.core\core-common\2.1.0\b3152fc64428c9354344bd89848ecddc09b6f07e\core-common-2.1.0.jar] (filtered)
Reading program jar [C:\Users\Administrator\.gradle\caches\modules-2\files-2.1\androidx.annotation\annotation\1.1.0\e3a6fb2f40e3a3842e6b7472628ba4ce416ea4c8\annotation-1.1.0.jar] (filtered)
Reading program jar [C:\Users\Administrator\.gradle\caches\modules-2\files-2.1\com.google.guava\listenablefuture\1.0\c949a840a6acbc5268d088e47b04177bf90b3cad\listenablefuture-1.0.jar] (filtered)
Reading program jar [F:\dartSpace\flutter\jiddspace\nfc\build\flutter_downloader\intermediates\intermediate-jars\release\classes.jar] (filtered)
Reading program jar [F:\dartSpace\flutter\jiddspace\nfc\build\shared_preferences\intermediates\intermediate-jars\release\classes.jar] (filtered)
Reading program jar [F:\dartSpace\flutter\jiddspace\nfc\build\url_launcher\intermediates\intermediate-jars\release\classes.jar] (filtered)
Reading program jar [F:\dartSpace\flutter\jiddspace\nfc\build\sqflite\intermediates\intermediate-jars\release\classes.jar] (filtered)
Reading program jar [F:\dartSpace\flutter\jiddspace\nfc\build\connectivity\intermediates\intermediate-jars\release\classes.jar] (filtered)
Reading program jar [F:\dartSpace\flutter\jiddspace\nfc\build\path_provider\intermediates\intermediate-jars\release\classes.jar] (filtered)
Reading program jar [F:\dartSpace\flutter\jiddspace\nfc\build\package_info\intermediates\intermediate-jars\release\classes.jar] (filtered)
Reading program directory [F:\dartSpace\flutter\jiddspace\nfc\build\app\intermediates\javac\release\compileReleaseJavaWithJavac\classes] (filtered)
Reading program jar [F:\dartSpace\flutter\jiddspace\nfc\build\app\intermediates\transforms\mergeJavaRes\release\0.jar] (filtered)
Reading library jar [C:\Users\Administrator\.gradle\caches\modules-2\files-2.1\androidx.annotation\annotation\1.0.0\45599f2cd5965ac05a1488fa2a5c0cdd7c499ead\annotation-1.0.0.jar] (filtered)
Reading library jar [E:\work_tool\sdk\android-sdk-windows\platforms\android-28\android.jar]
Reading library jar [E:\work_tool\sdk\android-sdk-windows\build-tools\28.0.3\core-lambda-stubs.jar]
Reading library jar [E:\work_tool\sdk\android-sdk-windows\platforms\android-28\optional\org.apache.http.legacy.jar]
Reading library jar [E:\work_tool\sdk\android-sdk-windows\platforms\android-28\optional\android.test.mock.jar]
Reading library jar [E:\work_tool\sdk\android-sdk-windows\platforms\android-28\optional\android.test.base.jar]
Reading library jar [E:\work_tool\sdk\android-sdk-windows\platforms\android-28\optional\android.test.runner.jar]
Initializing...
Warning: io.flutter.embedding.android.FlutterView: can't find referenced method 'android.graphics.Insets getSystemGestureInsets()' in library class android.view.WindowInsets
Warning: io.flutter.embedding.android.FlutterView: can't find referenced class android.graphics.Insets
Warning: io.flutter.embedding.android.FlutterView: can't find referenced class android.graphics.Insets
Warning: io.flutter.embedding.android.FlutterView: can't find referenced class android.graphics.Insets
Warning: io.flutter.embedding.android.FlutterView: can't find referenced class android.graphics.Insets
Warning: io.flutter.embedding.android.FlutterView: can't find referenced class android.graphics.Insets
Warning: io.flutter.embedding.android.FlutterView: can't find referenced class android.graphics.Insets
Warning: io.flutter.view.FlutterView: can't find referenced method 'android.graphics.Insets getSystemGestureInsets()' in library class android.view.WindowInsets
Warning: io.flutter.view.FlutterView: can't find referenced class android.graphics.Insets
Warning: io.flutter.view.FlutterView: can't find referenced class android.graphics.Insets
Note: io.flutter.view.AccessibilityViewEmbedder$ReflectionAccessors: can't find dynamically referenced class android.util.LongArray
Warning: io.flutter.view.FlutterView: can't find referenced class android.graphics.Insets
Warning: io.flutter.view.FlutterView: can't find referenced class android.graphics.Insets
Warning: io.flutter.view.FlutterView: can't find referenced class android.graphics.Insets
Warning: io.flutter.view.FlutterView: can't find referenced class android.graphics.Insets
Note: there were 1 unresolved dynamic references to classes or interfaces.
? You should check if you need to specify additional program jars.
? ()
Warning: Exception while processing task java.io.IOException: Please correct the above warnings first.
Thread(Tasks limiter_1): destruction
Warning: there were 12 unresolved references to classes or interfaces.
? ? You may need to add missing library jars or update their versions.
? ? If your code works fine without the missing classes, you can suppress
? ? the warnings with '-dontwarn' options.
? ? ()
Warning: there were 2 unresolved references to library class members.
? ? You probably need to update the library versions.
? ? ()
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app:transformClassesAndResourcesWithProguardForRelease'.
Job failed, see logs for details
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
* Get more help at
BUILD FAILED in 4m 23s
Running Gradle task 'assembleRelease'...
Running Gradle task 'assembleRelease'... Done? ? ? ? ? ? ? ? ? ? 264.4s (!)
*******************************************************************************************
The Gradle failure may have been because of AndroidX incompatibilities in this Flutter app.
See for more information on the problem and how to fix it.
*******************************************************************************************
Gradle task assembleRelease failed with exit code 1
APP集成百度地圖后,開發者模式直接連接真機可以打開地圖,打包成apk后安裝,應用直接閃退
驗證了3個環境
a、Android 6.0
b、Android 9.0
c、Android 8.1
真機USB線連接
選擇Logcat,將日志級別選擇未error,日志太多,或者用自定義的過濾規則
先清除日志,后迅速點擊手機上的APP,觀察日志
發現需要監控的APP報出異常信息,這個很關鍵,有異常就是有線索,couldn't find "libflutter.so"
這個時候問度娘就可以了
未明白具體的原因,臨時先解決了問題,馬克一下
在原生開發中, Android 使用 Gradle 來管理依賴, iOS 用 Cocoapods 來管理依賴,Node 中通過 npm來管理依賴。 Flutter 使用配置文件 pubspec.yaml (位于項目根目錄)來管理第三方依賴包。
Pub 是Google官方的Dart Packages倉庫,類似于node中的npm倉庫,android中的jcenter,我們可以在上面查找我們需要的包和插件,也可以向pub發布我們的包和插件。
Pub工具 包含管理Package、部署Package和部署命令行應用的命令。
如果使用的是Flutter SDK,不要直接使用pub命令。而是使用flutter pub命令,如下:
命令pub get/upgrade/outdated 屬于管理Package的依賴關系
用于檢索當前 Package 所依賴的其它 Package。如果 pubspec.lock 文件已經存在,則根據該文件中保存的依賴項版本獲取對應的依賴項。如有必要,將會創建或更新該文件。
更新 package 依賴
當你添加一個 package 后首次運行 flutter pub get, Flutter 將會保存在 pubspec.lock lockfile 中找到的具體 package 版本。這將確保當你或者團隊中其他開發者運行 flutter pub get 后能得到相同版本的 package。
如果你想升級到 package 的最新版本,比如使用 package 的最新特性,請運行 flutter pub upgrade 。這將檢索你在 pubspec.yaml 文件中指定的版本約束所允許的最高可用版本。
案例
在flutter項目中導入hive包,在pubspec.yaml文件中添加配置:
執行flutter pub get,可以在 pubspec.lock 中看到 hive 版本是2.1.0,這是因為目前hive的最新版本是2.1.0,配置“^”表示向最新版本兼容,具體可查看Package版本管理( ),所以再執行flutter pub upgrade 可以看到版本還是2.1.0,這個時候會發現pub get和 pub upgrade 效果一樣。
但是未來如果 hive 發布了2.2.0版本,這個時候使用flutter pub get在pubspec.lock中看到hive版本依舊是2.1.0,而執行flutter pub upgrade 后在pubspec.lock中看到hive版本就是2.2.0。
現在先在flutter 項目的pubspec.yaml文件添加配置,指定hive版本是2.0.5,如下:
這個時候執行flutter pub get后,可以在pubspec.lock的文件中看到hive版本是2.0.5,如果這個時候更改配置為 hive: ^2.0.5,再執行flutter pub get就會發現在pubspec.lock的文件中看到hive版本還是2.0.5,這個時候可以執行flutter pub outdated查看依賴的每個 package,如下圖,
可以看到,Upgrable項hive版本號為2.1.0,執行flutter pub upgrade 后可以看到在pubspec.lock的文件中看到hive版本是2.1.0
在pubspec.yaml文件添加配置:
lxx_package_demo信息如下圖:
執行flutter pub get后在pubspec.lock中看到flutter_log版本是0.0.1
現在修改lxx_package_demo版本號為0.0.2,再執行flutter pub get
會發現版本會及時更新為0.0.2,這個時候執行flutter pub get/upgrade效果一樣
參考文檔:
本文名稱:flutterlog,flutterlogo
分享地址:http://vcdvsql.cn/article44/dsdgdee.html
成都網站建設公司_創新互聯,為您提供網站設計、做網站、自適應網站、企業建站、網站收錄、
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯