在MAUI最初發布的時候就曾建立過幾個範本專案進行體驗過,沒遇到什麼坑。由於最近需要開發針對餐飲行業的收銀機(Android 系統)開發一款應用,這種收銀機一般配置不怎麼樣,系統版本和效能也肯定比不上我們自己使用的手機。在做技術選型時首先想到了MAUI,備選Flutter,React Native。都是大廠維護的跨平台應用框架,在使用MAUI框架時遇到新建的範本應用居然啟動時直接閃退,最終也是解決了這個閃退問題,遂分享下這一經歷。
建立專案
示範建立專案過程,所有流程都是 IDE 預設,不做任何修改。
新增 MAUI 範本專案
用 VS 新增MAUI範本專案,如下

專案名也預設為MauiApp1

連接裝置
- 透過 USB 連接目標 Android 裝置
- 目標裝置開啟開發者模式,然後開啟 USB 偵錯(自行
百度Bing/Google) - 手機上切換 USB 偵錯的模式,一般會出現 僅充電,檔案傳輸。。。,簡單粗暴的切換各種選項,當 VS 列出了你的裝置就可以了。

偵錯專案
完成上一步的裝置連接,直接的 debug 模式下啟動專案

等待一會,可以在裝置上看到應用已經安裝了,按說應該會被自動打開,等了好久也沒動靜,VS 的輸出視窗也不再有新的內容輸出了

手動點擊裝置上的安裝好的MauiApp1應用,然後剛看到啟動頁面一個大大的.NET 標誌,隨後來了個 Maui1已停止運行

解決閃退問題
以前也做過使用Android Studio開發過原生 Android 應用,一般這種問題都能在 IDE 有錯誤輸出,可以透過錯誤資訊找到閃退原因。
回顧剛才這個問題,不知道去哪裡查看日誌,這該怎麼去看閃退的原因呢,要是VS能像Android Studio那樣可以查看詳細的日誌就好了,目前我還不知道是否有地方能看詳細的 debug 日誌。我選擇了一種比較通用的排查錯誤的方式:adb工具。
有關adb不做介紹,讀者如有疑問自行百度Bing/Google,你只需要知道他是用來偵錯 Android 應用的一個強大工具即可。
下面的流程需要你將adb目錄新增到環境變數 PATH 中,方可全域使用adb命令。
常用命令
adb 命令檢視列出手機裝的所有 app 的包名:
adb shell pm list packages
列出系統應用的所有包名:
adb shell pm list packages -s
列出除了系統應用的第三方應用包名:
adb shell pm list packages -3
推測一個包中可能帶有的關鍵字:
adb shell dumpsys activity | findstr mFocusedActivity
清除應用資料與快取
adb shell pm clear 應用包名
檢視日誌
adb logcat
- V:詳細(最低優先順序)
- D:偵錯
- I:資訊
- W:警告
- E:錯誤
- F:嚴重
- S:靜默(最高優先順序,未曾輸出過任何內容)
找到我們要看的日誌
確認 adb 能識別到你的裝置
$ adb devices
List of devices attached
1234567890ABCDEF device
找出我們的包名
$ adb shell pm list packages -3
....
package:com.landi.print.service
package:com.companyname.mauiapp1
....
包名為:com.companyname.mauiapp1
- 使用
logcat
直接執行adb logcat能看到裝置的所有日誌,會對我們的排查造成干擾,我們只需要檢視package:com.companyname.mauiapp1的日誌,可以使用grep進行過濾,這個在windows的命令列工具都不支援,我使用的是GitBash的shell命令列工具,可以使用這一功能。
adb logcat | grep com.companyname.mauiapp1
這樣就只會輸出mauiapp1的日誌了。
執行上面的命令後,點選mauiapp1應用圖示啟動應用,得到我們應用啟動到崩潰的所有日誌如下:
06-16 10:21:11.953 1424 1424 D Launcher2.2.10: flow not clicked com.companyname.mauiapp1crc64e632a077a20c694c.MainActivity
06-16 10:21:11.953 1424 1424 D Launcher2.2.10: flow click desktop com.companyname.mauiapp1crc64e632a077a20c694c.MainActivity
06-16 10:21:11.953 424 466 I ActivityManager: START u0 {act=android.intent.action.MAIN flg=0x10200000 cmp=com.companyname.mauiapp1/crc64e632a077a20c694c.MainActivity} from uid 10072
06-16 10:21:11.958 424 466 E ActivityManager: getPackageFerformanceMode--ComponentInfo{com.companyname.mauiapp1/crc64e632a077a20c694c.MainActivity}----com.companyname.mauiapp1
06-16 10:21:11.967 424 1456 E ActivityManager: getPackageFerformanceMode--ComponentInfo{com.companyname.mauiapp1/crc64e632a077a20c694c.MainActivity}----com.companyname.mauiapp1
06-16 10:21:11.987 424 1456 I ActivityManager: Start proc 19415:com.companyname.mauiapp1/u0a97 for activity com.companyname.mauiapp1/crc64e632a077a20c694c.MainActivity
06-16 10:21:12.173 19415 19415 D debug-app-helper: Checking if libmonodroid was unpacked to /data/app/com.companyname.mauiapp1-Wpq5srmqUiNM5498jRmH8Q==/lib/arm/libmonodroid.so
06-16 10:21:12.173 19415 19415 D debug-app-helper: Native libs extracted to /data/app/com.companyname.mauiapp1-Wpq5srmqUiNM5498jRmH8Q==/lib/arm, assuming application/android:extractNativeLibs == true
06-16 10:21:12.173 19415 19415 D debug-app-helper: Added filesystem DSO lookup location: /data/app/com.companyname.mauiapp1-Wpq5srmqUiNM5498jRmH8Q==/lib/arm
06-16 10:21:12.173 19415 19415 W debug-app-helper: Using runtime path: /data/app/com.companyname.mauiapp1-Wpq5srmqUiNM5498jRmH8Q==/lib/arm
06-16 10:21:12.173 19415 19415 W debug-app-helper: checking directory: `/data/user/0/com.companyname.mauiapp1/files/.__override__/lib`
06-16 10:21:12.173 19415 19415 W debug-app-helper: directory does not exist: `/data/user/0/com.companyname.mauiapp1/files/.__override__/lib`
06-16 10:21:12.173 19415 19415 W debug-app-helper: Checking whether Mono runtime exists at: /data/user/0/com.companyname.mauiapp1/files/.__override__/libmonosgen-2.0.so
06-16 10:21:12.173 19415 19415 W debug-app-helper: Checking whether Mono runtime exists at: /data/app/com.companyname.mauiapp1-Wpq5srmqUiNM5498jRmH8Q==/lib/arm/libmonosgen-2.0.so
06-16 10:21:12.173 19415 19415 I debug-app-helper: Mono runtime found at: /data/app/com.companyname.mauiapp1-Wpq5srmqUiNM5498jRmH8Q==/lib/arm/libmonosgen-2.0.so
06-16 10:21:12.192 19415 19415 W monodroid: Creating public update directory: `/data/user/0/com.companyname.mauiapp1/files/.__override__`
06-16 10:21:12.198 19415 19415 F monodroid: No assemblies found in '/data/user/0/com.companyname.mauiapp1/files/.__override__' or '<unavailable>'. Assuming this is part of Fast Deployment. Exiting...
06-16 10:21:12.275 19433 19433 F DEBUG : pid: 19415, tid: 19415, name: nyname.mauiapp1 >>> com.companyname.mauiapp1 <<<
06-16 10:21:12.284 19433 19433 F DEBUG : Abort message: 'No assemblies found in '/data/user/0/com.companyname.mauiapp1/files/.__override__' or '<unavailable>'. Assuming this is part of Fast Deployment. Exiting...'
06-16 10:21:12.288 19433 19433 F DEBUG : #01 pc 0001b08b /data/app/com.companyname.mauiapp1-Wpq5srmqUiNM5498jRmH8Q==/lib/arm/libmonodroid.so (xamarin::android::internal::MonodroidRuntime::create_domain(_JNIEnv*, xamarin::android::jstring_array_wrapper&, bool, bool)+282)
06-16 10:21:12.288 19433 19433 F DEBUG : #02 pc 0001c08f /data/app/com.companyname.mauiapp1-Wpq5srmqUiNM5498jRmH8Q==/lib/arm/libmonodroid.so (xamarin::android::internal::MonodroidRuntime::create_and_initialize_domain(_JNIEnv*, _jclass*, xamarin::android::jstring_array_wrapper&, xamarin::android::jstring_array_wrapper&, _jobjectArray*, xamarin::android::jstring_array_wrapper&, _jobject*, bool, bool, bool)+26)
06-16 10:21:12.288 19433 19433 F DEBUG : #03 pc 0001d2c5 /data/app/com.companyname.mauiapp1-Wpq5srmqUiNM5498jRmH8Q==/lib/arm/libmonodroid.so (xamarin::android::internal::MonodroidRuntime::Java_mono_android_Runtime_initInternal(_JNIEnv*, _jclass*, _jstring*, _jobjectArray*, _jstring*, _jobjectArray*, _jobject*, _jobjectArray*, int, unsigned char, unsigned char)+4020)
06-16 10:21:12.288 19433 19433 F DEBUG : #04 pc 0001d55f /data/app/com.companyname.mauiapp1-Wpq5srmqUiNM5498jRmH8Q==/lib/arm/libmonodroid.so (Java_mono_android_Runtime_initInternal+50)
06-16 10:21:12.288 19433 19433 F DEBUG : #05 pc 0005282f /data/app/com.companyname.mauiapp1-Wpq5srmqUiNM5498jRmH8Q==/oat/arm/base.odex (offset 0x2e000)
06-16 10:21:12.905 424 19434 W ActivityManager: Force finishing activity com.companyname.mauiapp1/crc64e632a077a20c694c.MainActivity
06-16 10:21:12.916 424 451 I ActivityManager: Showing crash dialog for package com.companyname.mauiapp1 u0
06-16 10:21:12.976 424 877 I ActivityManager: Process com.companyname.mauiapp1 (pid 19415) has died: fore TOP
我們只關注日誌級別為F,E的即可:
下面錯誤資訊說明了程式掛掉的原因
06-16 10:21:12.198 19415 19415 F monodroid: No assemblies found in '/data/user/0/com.companyname.mauiapp1/files/.__override__' or '<unavailable>'. Assuming this is part of Fast Deployment. Exiting...
06-16 10:21:12.275 19433 19433 F DEBUG : pid: 19415, tid: 19415, name: nyname.mauiapp1 >>> com.companyname.mauiapp1 <<<
06-16 10:21:12.284 19433 19433 F DEBUG : Abort message: 'No assemblies found in '/data/user/0/com.companyname.mauiapp1/files/.__override__' or '<unavailable>'. Assuming this is part of Fast Deployment. Exiting...'
接下來就可以發揮我們程式設計師的重要技能之一:百度Google,能不能搜尋正確的答案就看造化了。
看來筆者有點東西,Google 到了一個類似的案例:https://stackoverflow.com/questions/42336546/xamarin-android-application-crashed-after-clear-data-in-settings
有興趣的去深究下,這裡xamarin的解決辦法是關閉 Use Fast Deployment
修改專案配置

經過仔細檢視屬性設定檔,找到這個設定與stackoverflow上說的關閉 Use Fast Deployment極其相似,應該就是它了,關閉它再次使用VS以 debug 模式啟動專案。
這次經過稍微漫長的過程,也執行到Found device: 1234567890ABCDEF不動了

手動開啟 App,沒任何效果。
解除安裝Mauiapp1重試
雖然上一步改了沒效果,但我堅信應該就是這樣,所以解除安裝 app 再試試,排除干擾因素。

Found device: 1234567890ABCDEF之後不在卡住不動了,隨後我的裝置上也安裝並自動打開了Mauiapp1,並且沒有閃退!