在原生App中,我们用来监听异常和崩溃的工具有很多,主流的有Bugly,友盟等等。而在flutter中,异常的监听就没那么容易了,好在官方提供了一个插件供我们使用,这就是sentry,关于sentry的用法,官方没有解释太详细,网上资料也不多,但也能找到,不过有些写的比较简单,没有详细解释原因,所以在使用过程中难免要走不少的弯路。
今天博主就把sentry的使用方法略加详细的介绍一下,还有一些扩展的用法;
1.首先sentry的使用需要先搭建自己的私服,这个可能需要后端的小伙伴来帮忙部署;
2.搭建成功后可以在平台上创建对应项目,拿到一个DSN,这个DSN包含了你要上传的地址信息;
3.sentry平台不仅仅flutter能使用,前端也是可以使用的哦;
本文只针对flutter做介绍。sentry一般要写在main.dart的入口函数中,看下代码:
const dsn='xxxxxxx';
final SentryClient _sentry = new SentryClient(
dsn: dsn,
);
Future<Null> main() async {
///用于捕获framework在某一时刻的错误
FlutterError.onError = (FlutterErrorDetails details) async {
if (isInDebugMode) {
///debug模式下,将错误转到控制台输出,可以通过detail的bool值控制
FlutterError.dumpErrorToConsole(details);
} else {
///捕获的异步错误,转到应用的root zone处理,就是main方法中runZoned的异常处理中
Zone.current.handleUncaughtError(details.exception, details.stack);
}
};
///开一个长开端口监听异常
Isolate.current.addSentryErrorListener(_sentry);
///在应用的root zone中捕获异常,可以认为是,可捕获整个应用运行周期内的所有异常
runZoned<Future<Null>>(() async {
runApp(MyApp());
}, onError: (error, stackTrace) async {
await _reportError(error, stackTrace);
});
}
Future<Null> _reportError(dynamic error, dynamic stackTrace) async {
//用于判断是否是debug模式
if (isInDebugMode) {
print(stackTrace);
return;
}
final SentryResponse response = await _sentry.capture(
event: Event(
exception: error,
stackTrace: stackTrace,
),
);
// 上报结果处理
if (response.isSuccessful) {
print('Success! Event ID: ${response.eventId}');
} else {
print('Failed to report to Sentry.io: ${response.error}');
}
}
//获取运行的模式
bool get isInDebugMode {
bool inDebugMode = false;
assert(inDebugMode = true);
return inDebugMode;
}
// Candidate API for the SDK
extension IsolateExtensions on Isolate {
void addSentryErrorListener(SentryClient sentry) {
///打开一个用于接收消息的长期端口,然后来监听异常,关于Isolate,是有自己的内存和单线程控制的运行实体,isolate之间的内存在逻辑上是隔离的,相当于监听的端口是隔离的,不会受其他影响而打断
final receivePort = RawReceivePort(
(dynamic values) async {
await sentry.captureIsolateError(values);
},
);
Isolate.current.addErrorListener(receivePort.sendPort);
}
}
// Candidate API for the SDK
extension SentryExtensions on SentryClient {
Future<void> captureIsolateError(dynamic error) {
print('Capture from IsolateError $error');
///这里是一个堆栈跟踪的字符串转化
if (error is List<dynamic> && error.length != 2) {
dynamic stackTrace = error[1];
if (stackTrace != null) {
stackTrace = StackTrace.fromString(stackTrace as String);
}
return captureException(exception: error[0], stackTrace: stackTrace);
} else {
return Future.value();
}
}
}
注释已经写了,有啥不明白的可以提问,这篇博客讲解了sentry的基本使用,关于sentry的扩展:
1.增加版本号的上传;
2.在异常上报的过程中对app进行截图,然后上传到sentry;
以上两个扩展将在后续博客中发布,欢迎持续关注。