生產中的 flutter 應用程序中的灰屏是一種通用占位符,當框架遇到問題無法渲染預期用戶界面時就會顯示。是的,所以基本上是出現問題時的后備指示器。
有趣的是,這只出現在發布模式下。在任何其他模式下運行都會顯示紅色錯誤屏幕,并說明導致錯誤的原因。(檢查此處以了解各種類型的構建模式。)此類錯誤的常見原因是:
以下是可能導致灰屏的代碼示例:
class HomeView extends HookWidget { const HomeView({super.key}); @override Widget build(BuildContext context) { const widget = null; return Scaffold( appBar: AppBar( title: Text( 'Gallery', style: Theme.of(context).textTheme.headlineLarge, ), ), body: widget!, ); }}
在這里,我們犯了一個明顯的錯誤,在我們知道的 null 小部件上使用了 bang 運算符(!),這導致在非發布模式下出現紅屏,在發布模式下出現灰屏。
需要注意的是,我們不建議在不更新的情況下將部件明確設置為空值,空值錯誤是一個常見錯誤,而上述操作是重現該錯誤的簡單方法。
圖片
調試模式下的紅色錯誤屏幕(左)和發布模式下的灰色屏幕(右)的圖像
為了顯示更用戶友好的消息而不是灰屏,我們將策略性地在 main 函數中放置一行代碼。該行充當預防措施,確保每當發生未處理的異常時都會顯示自定義錯誤屏幕。
void main() { ErrorWidget.builder = (_) => const AppErrorWidget(); // This line does the magic! runApp(MyApp());}
也許您希望在開發過程中看到默認的紅色錯誤屏幕以進行調試。您可以通過將 ErrorWidget.builder 賦值包裝在檢查當前構建模式的 if 語句中來實現此目的:
void main() { if (kReleaseMode) ErrorWidget.builder = (_) => const AppErrorWidget(); runApp(MyApp());}
下一步涉及創建 AppErrorWidget 本身的內容。該小部件將確定發生未處理的異常時用戶看到的內容。
class AppErrorWidget extends StatelessWidget { const AppErrorWidget({super.key}); @override Widget build(BuildContext context) { return const Material( color: Colors.white, child: Padding( padding: EdgeInsets.all(24), child: Column( mainAxisAlignment: MainAxisAlignment.center, mainAxisSize: MainAxisSize.min, children: [ Icon( Icons.warning, size: 200, color: Colors.amber, ), SizedBox(height: 48), Text( 'So... something funny happened', textAlign: TextAlign.center, style: TextStyle( fontSize: 24, fontWeight: FontWeight.bold, ), ), SizedBox(height: 16), Text( 'This error is crazy large it covers your whole screen. But no worries' ' though, we/'re working to fix it.', textAlign: TextAlign.center, style: TextStyle( fontSize: 16, ), ), ], ), ), ); }}
AppErrorWidget 小部件的結果顯示
雖然鼓勵自定義應用程序的體驗,但 ErrorWidget.builder 上的 Flutter 文檔提醒我們,調用錯誤小部件時視圖處于不穩定狀態。構建(可能還有布局)期間的異常會使系統處于脆弱狀態。為了最大限度地減少進一步的問題,返回的小部件應該做最少的工作。LeafRenderObjectWidget (如默認的 RenderErrorBox )非常適合處理意外約束。
現在我們知道,當渲染預期 UI 的過程中發生錯誤時, ErrorWidget.builder 就會被調用,但是這到底是如何實現的呢?
如果我們深入研究 Flutter 的框架,我們會在構建或重建小部件時看到一個名為 _updateChild() 的方法。
void _updateChild() { try { final Widget child = (widget as _RawView).builder(this, _effectivePipelineOwner); _child = updateChild(_child, child, null); } catch (e, stack) { final FlutterErrorDetails details = FlutterErrorDetails( exception: e, stack: stack, library: 'widgets library', context: ErrorDescription('building $this'), informationCollector: !kDebugMode ? null : () => <DiagnosticsNode>[ DiagnosticsDebugCreator(DebugCreator(this)), ], ); FlutterError.reportError(details); final Widget error = ErrorWidget.builder(details); _child = updateChild(null, error, slot); }}
我們可以看到 ErrorWidget.builder 屬性用于根據提供的 FlutterErrorDetails 檢索自定義錯誤小部件;然后更新 _child 變量以顯示自定義錯誤小部件而不是原始子小部件。
定制向用戶呈現錯誤的方式是改善用戶體驗的關鍵一步。雖然 ErrorWidget.builder 幫助我們在出現錯誤時管理用戶體驗,但它并沒有為生產環境中的開發人員提供有價值的見解。本地調試不再是一種選擇,那么我們如何及時了解用戶設備上發生的錯誤呢?
這就是我們利用 FlutterError.onError 回調的力量的地方。讓我們看看這是如何完成的:
void main() { if (kReleaseMode) ErrorWidget.builder = (_) => const AppErrorWidget(); FlutterError.onError = (details) { FlutterError.dumpErrorToConsole(details); if (!kReleaseMode) return; // 發送到您的 crashlytics 服務... }; runApp(MyApp());}
我們添加了一行新代碼,它將新的回調函數分配給 FlutterError.onError 屬性。每當使用 FlutterError.reportError 報告錯誤時都會調用此回調。
在回調內部, FlutterError.dumpErrorToConsole(details) 通過將錯誤詳細信息轉儲到控制臺來幫助我們了解幕后情況。這對于在部署或分階段部署期間可能存在對用戶設備的訪問受限的調試目的非常有用。
最后的注釋行 ( // 發送到您的 crashlytics 服務... ) 強調了這種方法的真正威力。在這里,您可以集成您選擇的錯誤報告服務(例如 Crashlytics)以發送詳細的錯誤報告以供分析。
注意:此行包含在 if 語句中,以確保它僅在調試或分析模式下執行 ( !kReleaseMode )。
我們已經了解了導致灰屏的原因以及出現灰屏時如何更好地處理它;我們還應該介紹的一件事是,作為開發人員可以采取哪些措施來避免出現灰屏。其中一些是:
錯誤處理是任何編寫良好的 Flutter 應用程序的重要組成部分。當您努力編寫干凈的代碼并預測潛在問題時,異常情況必然會發生。通過實施 ErrorWidget.builder ,您可以確保即使發生意外情況,您的用戶也會看到清晰且內容豐富的消息,而不是令人困惑的灰屏,并且通過 FlutterError.onError 您可以確保您記錄這些意外錯誤,并且可以更輕松地調試和修復這些錯誤。
請記住,即使面對不可預見的障礙,一點準備對于保持積極的用戶和開發人員體驗也大有幫助。
原文:https://medium.com/@LordChris/understanding-and-addressing-the-grey-screen-in-flutter-5e72c31f408f
本文鏈接:http://www.tebozhan.com/showinfo-26-93688-0.html了解并解決 Flutter 中的灰屏問題
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com