资讯动态

Day9_开源鸿蒙_Flutter_for_OpenHarmony_logger实战_本地日志与异常捕获

发布时间:2026/8/15 22:25:33 来源:尧图企业网站定制
开源鸿蒙 Flutter for OpenHarmonylogger 实战本地日志 全局异常捕获欢迎加入开源鸿蒙跨平台社区https://openharmonycrossplatform.csdn.net离线笔记做到 Day8功能看起来已经很“像样”了但只要开始真机跑就会遇到一个很现实的问题用户说“闪退/点不了/没反应”你没有任何线索。尤其是 OpenHarmony 场景下有些问题只在真机/模拟器出现没接入远程日志平台我们这个项目是纯离线靠print很难统一格式也不方便在手机上复制出来发给你排查Day9 的目标把日志做成“可用工具”。统一日志格式带时间、级别在应用内保存一份“最近 300 行日志”加一个“应用日志”页面复制/清空/手动写日志/模拟异常全局捕获未处理异常FlutterError / PlatformDispatcher / runZonedGuarded1. 今天用到的第三方库logger为什么不用 printprint的问题不在于它不能用而在于没级别info/warn/error没统一格式时间、tag、堆栈打出来之后手机上很难“拿到一份完整日志”logger就是做这件事的把日志当成一个正式能力来用。添加依赖flutter pubaddlogger2. 实现一个 AppLogger既写控制台也写“内存日志” 文件lib/shared/app_logger.dart我们做一个单例AppLogger有两个输出方向用logger输出到控制台调试时看自己维护一个lines最多 300 行用于 App 内展示/复制classAppLogger{AppLogger._();staticfinalAppLoggerinstanceAppLogger._();final_loggerLogger(printer:PrettyPrinter(methodCount:0,errorMethodCount:20,colors:false,printEmojis:false,dateTimeFormat:DateTimeFormat.onlyTimeAndSinceStart,),);finallinesString[].obs;}然后封装 3 个最常用的方法i/w/evoidi(Stringmessage){_logger.i(message);_add(I,message);}voidw(Stringmessage,{Object?error,StackTrace?stackTrace}){_logger.w(message,error:error,stackTrace:stackTrace);_add(W,_format(message,error,stackTrace));}voide(Stringmessage,{Object?error,StackTrace?stackTrace}){_logger.e(message,error:error,stackTrace:stackTrace);_add(E,_format(message,error,stackTrace));}_add里做两件事拼一个本地时间戳更适合读超过 300 行就裁掉最旧的void_add(Stringlevel,Stringtext){finalnowDateTime.now();finalts${now.year}-${_two(now.month)}-${_two(now.day)}${_two(now.hour)}:${_two(now.minute)}:${_two(now.second)};lines.add([$ts][$level]$text);if(lines.length300){lines.removeRange(0,lines.length-300);}}3. 全局异常捕获把“没抓住的异常”也写进日志很多异常不是你主动 try/catch 的它会直接冒到框架层。这一步就是把三条常用的“兜底入口”接上。 文件lib/main.dart3.1 FlutterError.onErrorFlutter 框架错误FlutterError.onError(details){FlutterError.presentError(details);AppLogger.instance.e(FlutterError,error:details.exception,stackTrace:details.stack,);};3.2 PlatformDispatcher.instance.onError更底层的 uncaughtPlatformDispatcher.instance.onError(error,stack){AppLogger.instance.e(PlatformDispatcher,error:error,stackTrace:stack);returntrue;};3.3 runZonedGuarded兜底一层runZonedGuarded(()runApp(constNotesApp()),(error,stack)AppLogger.instance.e(Zone,error:error,stackTrace:stack),);到这里哪怕你忘了 try/catch至少也能在“应用日志”页看到异常堆栈。4. 做一个“应用日志”页复制/清空/模拟异常 文件lib/features/debug/ui/app_logs_page.dart4.1 日志列表用 Obx 实时刷新lines是RxListString所以用Obx渲染Expanded(child:Obx((){finallineslogger.lines;if(lines.isEmpty)returnconstCenter(child:Text(暂无日志));returnListView.builder(itemCount:lines.length,itemBuilder:(_,i)SelectableText(lines[i]),);}),)4.2 顶部按钮复制/清空复制时直接把整份dump()放到剪贴板awaitClipboard.setData(ClipboardData(text:logger.dump()));清空就一句logger.clear();4.3 “模拟异常”按钮方便自测这一步不是给用户用的是开发时确认“全局兜底有没有生效”Timer.run(()throwStateError(Day9 模拟异常));点一下日志页应该能看到一条 error 级别的堆栈信息。 截图位建议 2~3 张![Day9-日志入口按钮](图_day9_log_entry.png) ![Day9-日志页列表与复制](图_day9_log_page.png) ![Day9-模拟异常日志出现](图_day9_throw_log.png)5. 给日志页加入口放在列表页右上角 文件lib/features/note/ui/notes_list_page.dartIconButton(onPressed:(){Navigator.of(context).push(MaterialPageRoute(builder:(_)constAppLogsPage()),);},icon:constIcon(Icons.bug_report),tooltip:日志,),这样真机遇到问题时让对方打开日志页点“复制”直接把文本发过来排查成本会小很多。6. 自测清单Day9打开日志页点“写日志” → 列表出现一条 info 记录点“模拟异常” → 列表出现 error 堆栈点“复制” → 能把日志完整复制到剪贴板随便粘贴到备忘录验证点“清空” → 列表清空

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价