当前位置: 首页 > news >正文

flutter:捕捉异常:

一,代码:

1,main

import 'dart:async';import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'services/AuthService.dart';
import 'routes/routes.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';void main() {runZonedGuarded(() {// 第二层:Flutter框架自身的错误回调FlutterError.onError = (FlutterErrorDetails details) {print("捕捉到了异常");FlutterError.presentError(details); // 开发时显示红屏print('详情打印开始:');String detail = details.toString();print(detail);print('详情打印结束:');};// 第三层:Widget构建时的错误边界ErrorWidget.builder = (FlutterErrorDetails details) {// 当Widget构建失败时,展示我们自定义的错误界面,而不是崩溃print('Widget错误时详情打印开始:');String detail = details.toString();print(detail);print('Widget错误时详情打印结束:');return ErrorRecoveryWidget(details);};runApp(MyApp());}, (error, stackTrace) {// 处理所有未被前面捕获的异常//_handleZoneError(error, stackTrace);//print("处理所有未被前面捕获的异常");//print(error);print('未被前面捕获的异常: $error');print('未被前面捕获的异常的堆栈: $stackTrace');});
}class ErrorRecoveryWidget extends StatelessWidget {final FlutterErrorDetails errorDetails;final VoidCallback? onRetry;const ErrorRecoveryWidget(this.errorDetails, {this.onRetry,Key? key,}) : super(key: key);@overrideWidget build(BuildContext context) {return Material(child: Container(color: Colors.grey[100],padding: const EdgeInsets.all(20),child: Column(mainAxisAlignment: MainAxisAlignment.center,children: [Icon(Icons.error_outline,size: 64,color: Colors.red[400],),const SizedBox(height: 20),Text('页面加载失败',style: Theme.of(context).textTheme.headlineMedium?.copyWith(color: Colors.red[700],),),const SizedBox(height: 12),Text(errorDetails.exceptionAsString(),textAlign: TextAlign.center,style: const TextStyle(color: Colors.grey),maxLines: 3,overflow: TextOverflow.ellipsis,),const SizedBox(height: 24),if (onRetry != null)ElevatedButton.icon(onPressed: onRetry,icon: const Icon(Icons.refresh),label: const Text('重试'),style: ElevatedButton.styleFrom(backgroundColor: Colors.blue,foregroundColor: Colors.white,),),const SizedBox(height: 16),TextButton(onPressed: () {showErrorDetailsDialog(context, errorDetails);},child: const Text('查看错误详情'),),],),),);}// 提供一个对话框展示详细的错误信息,方便调试void showErrorDetailsDialog(BuildContext context, FlutterErrorDetails details) {showDialog(context: context,builder: (context) => AlertDialog(title: const Text('错误详情'),content: SingleChildScrollView(child: Column(crossAxisAlignment: CrossAxisAlignment.start,children: [const Text('异常类型:', style: TextStyle(fontWeight: FontWeight.bold)),SelectableText(details.exception.runtimeType.toString()),const SizedBox(height: 12),const Text('异常信息:', style: TextStyle(fontWeight: FontWeight.bold)),SelectableText(details.exception.toString()),const SizedBox(height: 12),const Text('堆栈跟踪:', style: TextStyle(fontWeight: FontWeight.bold)),SizedBox(height: 200,child: SingleChildScrollView(child: SelectableText(details.stack.toString()),),),],),),actions: [TextButton(onPressed: () => Navigator.pop(context),child: const Text('关闭'),),TextButton(onPressed: () {Clipboard.setData(ClipboardData(text: '${details.exception}\n\n${details.stack}'));ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('已复制到剪贴板')),);},child: const Text('复制'),),],),);}
}class MyApp extends StatelessWidget {const MyApp({super.key});@overrideWidget build(BuildContext context) {return ScreenUtilInit(designSize: const Size(750, 1334),minTextAdapt: true,splitScreenMode: true,// Use builder only if you need to use library outside ScreenUtilInit contextbuilder: (_ , child) {return GetMaterialApp(debugShowCheckedModeBanner: false, //去除debug图标defaultTransition: Transition.rightToLeft,   //指定动画theme: ThemeData(primarySwatch: Colors.red),initialRoute: "/",    //初始化页面getPages: APPage.routes,   //路由);},);}}

homepage.dart

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:mylist2/utils/functions.dart';
import 'package:mylist2/views/MyButton.dart';import '../services/AuthService.dart';class HomePage extends StatefulWidget {@overrideState<HomePage> createState() => _HomePageState();
}class _HomePageState extends State<HomePage>  {//按钮被点击后抛出异常void myclick() {print('按钮被点击过了');throw new Exception("自定义异常aaa");}@overrideWidget build(BuildContext context) {const widget = null;return Scaffold(appBar: AppBar(backgroundColor: Theme.of(context).colorScheme.inversePrimary,title: const Text("home页面"),),body: Center(child:Column(children:[MyButton(onPressed: myclick),],),),);}}

二,测试效果:

image

点击后:

I/flutter (10164): 按钮被点击过了
I/flutter (10164): 捕捉到了异常
I/flutter (10164): 详情打印开始:
I/flutter (10164): ══╡ EXCEPTION CAUGHT BY GESTURE ╞════════════════════════════════
I/flutter (10164): The following _Exception was thrown while handling a gesture:
I/flutter (10164): Exception: 自定义异常aaa
I/flutter (10164): 
I/flutter (10164): When the exception was thrown, this was the stack:
I/flutter (10164): #0      _HomePageState.myclick (package:mylist2/pages/HomePage.dart:18:5)
I/flutter (10164): #1      _InkResponseState.handleTap (package:flutter/src/material/ink_well.dart:1224:21)
I/flutter (10164): #2      GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:345:24)
I/flutter (10164): #3      TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:758:11)
I/flutter (10164): #4      BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:383:5)
I/flutter (10164): #5      BaseTapGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/tap.dart:314:7)
I/flutter (10164): #6      PrimaryPointerGestureRecognizer.handleEvent (package:flutter/src/gestures/recognizer.dart:721:9)
I/flutter (10164): #7      PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:97:12)
I/flutter (10164): #8      Point
I/flutter (10164): 详情打印结束:======== Exception caught by gesture ===============================================================
The following _Exception was thrown while handling a gesture:
Exception: 自定义异常aaaWhen the exception was thrown, this was the stack: 
#0      _HomePageState.myclick (package:mylist2/pages/HomePage.dart:18:5)
#1      _InkResponseState.handleTap (package:flutter/src/material/ink_well.dart:1224:21)
#2      GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:345:24)
#3      TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:758:11)
#4      BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:383:5)
#5      BaseTapGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/tap.dart:314:7)
#6      PrimaryPointerGestureRecognizer.handleEvent (package:flutter/src/gestures/recognizer.dart:721:9)
#7      PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:97:12)
#8      PointerRouter._dispatchEventToRoutes.<anonymous closure> (package:flutter/src/gestures/pointer_router.dart:140:9)
#9      _LinkedHashMapMixin.forEach (dart:_compact_hash:765:13)
#10     PointerRouter._dispatchEventToRoutes (package:flutter/src/gestures/pointer_router.dart:138:18)
#11     PointerRouter.route (package:flutter/src/gestures/pointer_router.dart:128:7)
#12     GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:528:19)
#13     GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:498:22)
#14     RendererBinding.dispatchEvent (package:flutter/src/rendering/binding.dart:473:11)
#15     GestureBinding._handlePointerEventImmediately (package:flutter/src/gestures/binding.dart:437:7)
#16     GestureBinding.handlePointerEvent (package:flutter/src/gestures/binding.dart:394:5)
#17     GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:341:7)
#18     GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:308:9)
#22     _invoke1 (dart:ui/hooks.dart:374:10)
#23     PlatformDispatcher._dispatchPointerDataPacket (dart:ui/platform_dispatcher.dart:467:7)
#24     _dispatchPointerDataPacket (dart:ui/hooks.dart:307:31)
(elided 3 frames from dart:async)
Handler: "onTap"
Recognizer: TapGestureRecognizer#609c1debugOwner: GestureDetectorstate: possiblewon arenafinalPosition: Offset(200.0, 105.1)finalLocalPosition: Offset(59.8, 19.1)button: 1sent tap down
====================================================================================================

 

http://www.jsqmd.com/news/447231/

相关文章:

  • CompactGUI终极路线图:Windows压缩技术的未来演进指南
  • JustPy未来路线图:探索即将推出的令人兴奋的新功能
  • 终极指南:如何在TypeScript项目中完美集成NumberFlow数字动画组件
  • 揭秘Input Leap发布流程:从代码提交到正式发布的完整周期指南
  • 看戒戒有感
  • 终极指南:Input Leap拖拽功能深度解析及Linux支持现状
  • Windows透明压缩黑科技:CompactGUI如何用WOF技术释放60%存储空间
  • 基于PaddleOCR的营业执照识别与数据分析系统
  • PackNet-SfM部署指南:将单目深度估计模型集成到实际应用中
  • 如何利用CompactGUI的Compactor组件实现Windows文件透明压缩:完整指南
  • Nano Stores终极指南:5个生命周期管理技巧助你构建高效应用
  • 基于深度学习的电信号分类识别与混淆矩阵分析
  • 终极指南:如何用Nano Stores实现高性能状态管理
  • NumberFlow自定义主题终极指南:打造独特的数字动画风格
  • 文件服务器部署(samba集成ldap认证)
  • C++ 之类的构造、析构、初始化列表使用注意事项经典易错案例详细分析总结
  • 【AI平台】n8n入门7:本地n8n更新(保留配置)
  • Yari架构揭秘:如何高效渲染MDN Web Docs海量技术文档
  • 【HEVC视频流可视化分析工具】画出视频中每帧的CTU块的形状与深度——v1.0
  • 力扣2615. 等值距离和
  • 使用python编程贪吃蛇单机小游戏(超详细讲解)
  • 倒立摆系统控制器设计报告
  • FTP服务器部署(vsftpd)
  • 贝叶斯分类
  • uniapp token过期的几种常见处理方案
  • ubuntu+windows双系统恢复
  • 7.28 进制交换|迭代器模式|map|子集按位或|带参递归
  • Elasticsearch-SQL终极指南:如何用SQL轻松查询Elasticsearch日志数据
  • 扫码枪写入案例。关于js原生聚焦以及扫码枪原理
  • 中医药方剂大模型开发方案