Flutter异常上报及性能监控实现

        1. 页面异常监测
         在Flutter中,通常用FlutterError监测Flutter框架抛出的异常,用runZonedGuarded监测应用中用户代码异常。
            
class AppGuarded {
  run(Widget app) {
    //1. 用FlutterError监测flutter框架抛出的异常
    FlutterError.onError = (FlutterErrorDetails details) async {
      //线上环境,将异常交给zone统一处理
      if (kReleaseMode) {
        Zone.current.handleUncaughtError(details.exception, details.stack!);
      } else {
        //开发期间,走Console抛出
        FlutterError.dumpErrorToConsole(details);
      }
    };
    
    //2. runZonedGuarded监测整个用应用代码异常 不使用FlutterError默认只能捕捉业务代码异常
    runZonedGuarded(() {
      runApp(app);
    }, (e, s) => _reportError(e, s));
  }

  ///通过接口上报异常
  _reportError(Object error, StackTrace s) {
    print('kReleaseMode:$kReleaseMode');
    print('catch error:$error');
  }
}

        2. 监测页面流畅性(帧率)

        帧率监测在Flutter中通常通过在SchedulerBinding中注册fps相关回调来实现。通常需要保留最近若干个FrameTiming的总耗时,计算其平均值,以消除不必要数据波动。

void start() {
  SchedulerBinding.instance.addTimingsCallback(_onReportTimings);
}
// 不需监听时移除
void stop() {
  SchedulerBinding.instance.removeTimingsCallback(_onReportTimings);
}
void _onReportTimings(List<FrameTiming> timings) {
  // TODO
}

         3. 页面显示耗时(FCP)

         记录页面初始化和首次上屏时间,然后计算其时间差即可。

@override
  initState() {
    super.initState();
    //1. 记录页面创建时间
    double startTime = time(0);
    
    //2.注册首帧显示时间回调
    WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
      double endTime = time(0);
      print('WidgetsBinding Test-${(context as Element).size}');
    });

        4. 页面PV监测

        页面PV监测核心是检测到页面栈的变化,以便统计出页面曝光次数。如果应用采用自定义导航框架,只需在导航框架正确位置添加埋点即可。若采用的是系统默认的导航框架,则可通过继承NavigatorObserver,捕获Navigator的didPush和didPop回调。

//导航栈的变化监听
class MyNavigator extends NavigatorObserver{
  @override
  void didPop(Route<dynamic> route, Route<dynamic> previousRoute) {
    super.didPop(route, previousRoute);
    var previousName = '';
    if (previousRoute == null) {
      previousName = 'null';
    }else {
      previousName = previousRoute.settings.name;
    }
    print('YM----->NavObserverDidPop--Current:' + route.settings.name + '  Previous:' + previousName);
  }

  @override
  void didPush(Route<dynamic> route, Route<dynamic> previousRoute) {
    super.didPush(route, previousRoute);

    var previousName = '';
    if (previousRoute == null) {
      previousName = 'null';
    }else {
      previousName = previousRoute.settings.name;
    }
    print('YM-------NavObserverDidPush-Current:' + route.settings.name + '  Previous:' + previousName);

  }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值