Flutter崩溃报告与错误追踪插件bugsee_flutter的使用
Flutter崩溃报告与错误追踪插件bugsee_flutter的使用
Bugsee for Flutter
Bugsee 是一个移动SDK,可以为您的错误和崩溃报告添加关键信息。Bugsee 报告包括用户操作的视频、网络流量、控制台日志和其他重要跟踪信息。现在您可以确切地知道是什么导致了意外行为。
注册服务请访问 Bugsee 官网。
安装
在 pubspec.yaml
文件中添加 Bugsee 插件依赖:
dependencies:
bugsee_flutter: ^8.4.2
启动
在主函数中启动 Bugsee,并配置应用运行回调:
import 'package:bugsee_flutter/bugsee_flutter.dart';
import 'dart:io';
import 'package:flutter/material.dart';
Future<void> launchBugsee(void Function(bool isBugseeLaunched) appRunner) async {
var launchOptions;
var bugseeToken = "";
if (Platform.isAndroid) {
bugseeToken = "<android app token>";
launchOptions = AndroidLaunchOptions();
} else if (Platform.isIOS) {
bugseeToken = "<ios app token>";
launchOptions = IOSLaunchOptions();
}
await Bugsee.launch(bugseeToken,
appRunCallback: appRunner, launchOptions: launchOptions);
}
Future<void> main() async {
// 这是为了让 Bugsee 拦截网络请求
HttpOverrides.global = Bugsee.defaultHttpOverrides;
await launchBugsee((bool isBugseeLaunched) async {
runApp(const MyApp());
});
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatelessWidget {
final String title;
MyHomePage({required this.title});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ElevatedButton(
child: Text('Dart exception'),
onPressed: () {
throw StateError('This is a Dart exception.');
},
),
ElevatedButton(
child: Text('async Dart exception'),
onPressed: () async {
foo() async {
throw StateError('This is an async Dart exception.');
}
bar() async {
await foo();
}
await bar();
},
),
ElevatedButton(
child: Text('Java exception'),
onPressed: () async {
Bugsee.testExceptionCrash();
},
),
ElevatedButton(
child: Text('Handled exception'),
onPressed: () async {
try {
throw FormatException('Expected at least 1 section');
} catch (ex, st) {
Bugsee.logException(ex, st);
}
},
),
ElevatedButton(
child: Text('Handled empty exception'),
onPressed: () {
Bugsee.logException(
StateError('This is a Dart exception with empty stack trace.'),
'');
},
),
ElevatedButton(
child: Text('Exception in another isolate'),
onPressed: () async {
Isolate isolate = await Isolate.spawn((dynamic arg) {
throw StateError('This is an exception in another isolate.');
}, "", paused: true, errorsAreFatal: false);
isolate.addBugseeErrorListener();
if (isolate.pauseCapability != null) {
isolate.resume(isolate.pauseCapability!);
}
},
),
ElevatedButton(
child: Text('Log messages'),
onPressed: () {
print("This is a message posted with print() call");
Bugsee.log("This is a test console message");
Bugsee.log("This is a test console ERROR message", BugseeLogLevel.error);
Bugsee.log("This is a test console DEBUG message", BugseeLogLevel.debug);
Bugsee.log("This is a test console INFO message", BugseeLogLevel.info);
Bugsee.log("This is a test console WARNING message", BugseeLogLevel.warning);
},
),
ElevatedButton(
child: Text('Network request'),
onPressed: () async {
var response = await http.post(
Uri.parse('https://reqres.in/api/users'),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
body: jsonEncode(<String, String>{
'title': 'Some fancy title',
}),
);
var responseBody = response.body;
print('Received network response. Length: ${responseBody.length}');
},
),
ElevatedButton(
child: Text('Custom events'),
onPressed: () async {
Map<String, dynamic> params = <String, dynamic>{};
params['string'] = 'test';
params['int'] = 5;
params['float'] = 0.55;
params['bool'] = true;
Bugsee.event('event', params);
Bugsee.trace('number', 5);
Bugsee.trace('float', 0.55);
Bugsee.trace('string', 'test');
Bugsee.trace('bool', true);
Bugsee.trace('map', params);
Bugsee.setAttribute('age', 36);
Bugsee.setAttribute('name', 'John Doe');
Bugsee.setAttribute('married', false);
},
),
ElevatedButton(
child: Text('Show report dialog'),
onPressed: () {
Bugsee.showReportDialog('Test summary', 'Test description');
},
),
ElevatedButton(
child: Text('Upload report'),
onPressed: () {
Bugsee.upload('Test summary', 'Test description');
},
),
ElevatedButton(
child: Text('Show Feedback'),
onPressed: () {
Bugsee.showFeedbackUI();
},
),
ElevatedButton(
child: Text('Add secure rect'),
onPressed: () {
Bugsee.addSecureRect(Rectangle(20, 20, 100, 100));
},
),
ElevatedButton(
child: Text('Get all secure rects'),
onPressed: () async {
dynamic rects = await Bugsee.getAllSecureRects();
print(rects);
},
),
ElevatedButton(
child: Text('Capture view hierarchy'),
onPressed: () async {
await Bugsee.captureViewHierarchy();
},
),
ElevatedButton(
child: Text('Show video'),
onPressed: () async {
showDialog(
context: context,
builder: (BuildContext context) => _buildVideoPopupDialog(context));
},
),
ElevatedButton(
child: Text('Dummy button'),
onPressed: () async {},
),
],
),
),
);
}
Widget _buildVideoPopupDialog(BuildContext context) {
return Dialog(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(children: [
VideoWidget(),
const SizedBox(height: 10),
TextButton(
onPressed: () {
Navigator.pop(context);
},
child: const Text('Close'),
),
])));
}
}
class VideoWidget extends StatefulWidget {
const VideoWidget({Key? key}) : super(key: key);
@override
_VideoWidgetState createState() => _VideoWidgetState();
}
class _VideoWidgetState extends State<VideoWidget> {
late VideoPlayerController _controller;
@override
void initState() {
super.initState();
_controller = VideoPlayerController.networkUrl(
Uri.parse('https://flutter.github.io/assets-for-api-docs/assets/videos/bee.mp4'))
..initialize().then((_) {
// 确保视频初始化后显示第一帧
setState(() {});
});
_controller.play();
}
@override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
_controller.value.isInitialized
? AspectRatio(
aspectRatio: _controller.value.aspectRatio,
child: VideoPlayer(_controller),
)
: Container(),
]);
}
@override
void dispose() {
super.dispose();
_controller.dispose();
}
}
自定义数据
事件
事件通过字符串标识,可以包含可选的参数字典,这些参数将存储并随报告一起传递。
// 不带任何附加参数
Bugsee.event(name: 'payment_processed');
// 带附加自定义参数
Bugsee.event(name: 'payment_processed', parameters: <String, dynamic>{
'amount': 125,
'currency': 'USD'
});
跟踪
跟踪可以在问题发生前跟踪特定变量或状态的变化。
// 手动设置名为 "credit_balance" 的属性值为 15
Bugsee.trace(name: 'credit_balance', value: 15);
手动报告
您可以使用以下方法注册非致命异常:
try {
some_code_that_throws();
} catch (ex, st) {
await Bugsee.logException(exception: ex, handled: true, stackTrace: st);
}
Bugsee 可以进一步定制。有关更多选项和API的完整SDK文档,请访问 Bugsee Flutter 文档。
更多关于Flutter崩溃报告与错误追踪插件bugsee_flutter的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter崩溃报告与错误追踪插件bugsee_flutter的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter项目中集成并使用bugsee_flutter
插件来进行崩溃报告与错误追踪的详细步骤和代码示例。
1. 添加依赖
首先,你需要在pubspec.yaml
文件中添加bugsee_flutter
依赖:
dependencies:
flutter:
sdk: flutter
bugsee_flutter: ^最新版本号 # 请替换为实际可用的最新版本号
然后运行以下命令以获取依赖:
flutter pub get
2. 初始化Bugsee
在你的Flutter应用的入口文件(通常是main.dart
)中,初始化Bugsee并配置相关参数。
import 'package:flutter/material.dart';
import 'package:bugsee_flutter/bugsee_flutter.dart';
void main() {
// 初始化Bugsee
Bugsee.init(
apiKey: "你的Bugsee API密钥", // 请替换为你的Bugsee API密钥
enableInDebugMode: true, // 是否在debug模式下启用Bugsee(生产环境中应设为false)
enableLogs: true, // 是否启用日志记录
enableNetwork: true, // 是否启用网络请求的捕获
enableCrashReporting: true // 是否启用崩溃报告
);
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
// 示例:手动发送一个错误报告
try {
throw Exception("这是一个手动触发的错误");
} catch (e) {
Bugsee.logError(e);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'你点击了按钮 $_counter 次',
),
ElevatedButton(
onPressed: _incrementCounter,
child: Text('点击我'),
),
],
),
),
);
}
}
3. 捕获和处理错误
你可以使用Bugsee.logError
方法来手动捕获并发送错误报告。在上面的代码中,我们在按钮点击事件中演示了如何捕获一个异常并发送错误报告。
4. 捕获网络请求(可选)
如果你启用了网络请求的捕获(enableNetwork: true
),Bugsee将自动捕获所有发出的HTTP请求和响应。
5. 其他功能
bugsee_flutter
插件还提供了其他功能,如自定义日志、用户反馈等,你可以根据文档进一步探索和使用这些功能。
注意事项
- 隐私保护:确保你遵守相关的隐私政策和法规,不要在未经用户同意的情况下捕获敏感信息。
- 生产环境:在生产环境中,应将
enableInDebugMode
设为false
,以避免不必要的日志输出和性能影响。
通过以上步骤,你就可以在Flutter项目中集成并使用bugsee_flutter
插件来进行崩溃报告与错误追踪了。