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


            1. 页面异常监测
             在Flutter中,通常用FlutterError监测Flutter框架抛出的异常,用runZonedGuarded监测应用中用户代码异常。
                
    1. class AppGuarded {
    2. run(Widget app) {
    3. //1. 用FlutterError监测flutter框架抛出的异常
    4. FlutterError.onError = (FlutterErrorDetails details) async {
    5. //线上环境,将异常交给zone统一处理
    6. if (kReleaseMode) {
    7. Zone.current.handleUncaughtError(details.exception, details.stack!);
    8. } else {
    9. //开发期间,走Console抛出
    10. FlutterError.dumpErrorToConsole(details);
    11. }
    12. };
    13. //2. runZonedGuarded监测整个用应用代码异常 不使用FlutterError默认只能捕捉业务代码异常
    14. runZonedGuarded(() {
    15. runApp(app);
    16. }, (e, s) => _reportError(e, s));
    17. }
    18. ///通过接口上报异常
    19. _reportError(Object error, StackTrace s) {
    20. print('kReleaseMode:$kReleaseMode');
    21. print('catch error:$error');
    22. }
    23. }

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

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

    1. void start() {
    2. SchedulerBinding.instance.addTimingsCallback(_onReportTimings);
    3. }
    4. // 不需监听时移除
    5. void stop() {
    6. SchedulerBinding.instance.removeTimingsCallback(_onReportTimings);
    7. }
    8. void _onReportTimings(List timings) {
    9. // TODO
    10. }

             3. 页面显示耗时(FCP)

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

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

            4. 页面PV监测

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

    1. //导航栈的变化监听
    2. class MyNavigator extends NavigatorObserver{
    3. @override
    4. void didPop(Route<dynamic> route, Route<dynamic> previousRoute) {
    5. super.didPop(route, previousRoute);
    6. var previousName = '';
    7. if (previousRoute == null) {
    8. previousName = 'null';
    9. }else {
    10. previousName = previousRoute.settings.name;
    11. }
    12. print('YM----->NavObserverDidPop--Current:' + route.settings.name + ' Previous:' + previousName);
    13. }
    14. @override
    15. void didPush(Route<dynamic> route, Route<dynamic> previousRoute) {
    16. super.didPush(route, previousRoute);
    17. var previousName = '';
    18. if (previousRoute == null) {
    19. previousName = 'null';
    20. }else {
    21. previousName = previousRoute.settings.name;
    22. }
    23. print('YM-------NavObserverDidPush-Current:' + route.settings.name + ' Previous:' + previousName);
    24. }

  • 相关阅读:
    【计算机组成原理】指令系统&考研真题详解之拓展操作码!
    Sumo中Traci.trafficlight详解(上)
    躲避小行星游戏
    18 统计网站每日的访问次数
    java合成多个pdf为一个pdf
    大数据面试总结三
    一次不完整的渗透
    学过的汇编指令整合
    老卫带你学---leetcode刷题(76. 最小覆盖子串)
    R语言ggplot2可视化:使用ggpubr包的ggviolin函数可视化小提琴图、使用ggadd函数在可视化图像中添加均值数据点、标准差线、抖动数据点
  • 原文地址:https://blog.csdn.net/holyli1134516796/article/details/136409991