Flutter 项目中集成腾讯 Bugly(flutter_bugly)异常上报
本文基于本工程已有的接入方式,介绍如何在 Flutter 端通过 flutter_bugly 完成异常与崩溃相关的上报,并把“同步异常、异步异常、平台未捕获异常”统一纳入 Bugly。
工程里做了什么
- 在
pubspec.yaml中引入依赖flutter_bugly: ^1.1.1 - 在
lib/main.dart中:- 仅 Android 平台初始化 Bugly
- 使用
runZonedGuarded+FlutterError.onError+PlatformDispatcher.instance.onError三层兜底捕获异常 - 把异常上传到 Bugly
1) 添加依赖(pubspec.yaml)
在本工程 pubspec.yaml 已有如下依赖:
# 腾讯 Bugly(Flutter 异常 + 原生崩溃,仅 Android 时在 main 中按平台初始化)
flutter_bugly: ^1.1.1
这一步的核心意义是:后续在 main.dart 里可以直接调用 FlutterBugly.init / uploadException / setUserId 等能力。
2) 在 main.dart 初始化 Bugly(仅 Android)
工程在 main() 的 runZonedGuarded 里完成初始化,关键点如下:
- 先确保 Flutter binding:
WidgetsFlutterBinding.ensureInitialized();
- 仅在非 Web 且 Android 平台初始化(iOS 不在这里初始化):
if (!kIsWeb && Platform.isAndroid) {
await FlutterBugly.init(
androidAppId: 'YOUR_APP_ID',
channel: 'default',
debugMode: debugmode,
);
await FlutterBugly.setUserId(await const AndroidId().getId() ?? '');
}
说明:
androidAppId:Bugly 控制台申请的 AppId。channel:发布渠道(这里固定为default)。debugMode: debugmode:Debug 下也会开上传模式(适合联调,但上线后是否要关闭取决于你们的噪音策略)。userId使用android_id获取设备标识,便于 Bugly 回溯到具体终端。
工程中注释明确提到:flutter_bugly 与原生 Application init 已移除相配合,因此初始化放在 Flutter 的 main 入口集中管理更直观。
3) 统一捕获并上报异常链路(FlutterError + Zone + PlatformDispatcher)
这部分是接入 Bugly 的“主价值”:让异常不只打印在控制台,而是被结构化采集、同时上传 Bugly。
3.1 同步 Flutter 异常:FlutterError.onError
工程通过重写 FlutterError.onError 来接住同步异常,并同时做:
- 组装
logData(包含异常类型、系统信息、BaseConstants.keyVersion版本号、locale 等) - 调用
FlutterBugly.uploadException上传到 Bugly
上传时使用了:
FlutterBugly.uploadException(
message: details.exceptionAsString(),
detail: details.stack?.toString() ?? StackTrace.current.toString(),
type: details.exception.runtimeType.toString(),
);
3.2 异步未捕获异常:runZonedGuarded 的 error 回调
runZonedGuarded 除了包裹初始化与 runApp,还提供了异步异常兜底:
- 在 error 回调里同样组装结构化日志
- 同样在 Android 调用
FlutterBugly.uploadException
这样能覆盖很多“Future/Stream 回调里抛出的异常”场景。
3.3 平台层未捕获异常:PlatformDispatcher.instance.onError
工程还补了一层“兜底”:
PlatformDispatcher.instance.onError = (error, stack) {
if (!kIsWeb && Platform.isAndroid) {
FlutterBugly.uploadException(
message: "PlatformDispatcher:$error",
detail: stack.toString() ?? StackTrace.current.toString(),
type: error.runtimeType.toString(),
);
}
return true;
};
该返回 true 的含义是:通知 Flutter 这类 onError 已处理,避免重复报错。
4) 用户标识与回溯策略(setUserId)
工程在初始化时通过:
await FlutterBugly.setUserId(await const AndroidId().getId() ?? '');
把每次上报绑定到 AndroidId。这对定位“某一批设备/某个用户群”的异常非常关键。
建议你们在后续演进时统一策略:
- 如果上线后希望按账号维度追踪,把
setUserId改成“登录账号 userId” - 如果还未有账号体系,则保留设备维度即可
5) 如何验证是否真的上报成功
你可以按下面顺序验证(建议只在 Android 上做):
- Debug 环境启动 App,触发一个可控异常(例如在某个按钮点击处直接抛出异常)
- 确认 Bugly 控制台是否能收到对应上传事件
- 再测一个异步异常(比如
Future.delayed(...).then((_) => throw ...)),看 Zone 兜底是否也能上传