跳转到主要内容
PRODUCT DOCUMENTS

快速找到所需文档,高效完成接入与排障

浏览产品文档与友盟 Skill,展开目录并阅读正文。

APM 支持 Flutter Boost插件

一、背景

Flutter Boost提供了一种简单且易于使用的方式,用于在现有的原生应用中嵌入Flutter页面。这意味着开发者可以在不重写整个应用的情况下,快速地将Flutter页面集成到已有的原生应用中,从而提供更好的用户体验。

Flutter Boost还解决了Flutter在与原生平台集成时的路由问题。在传统的Flutter中,页面之间的切换和传递参数需要使用Flutter自带的Navigator进行管理。但是在与原生平台集成时,需要与原生的路由进行对接,这可能会带来一些麻烦。而Flutter Boost提供了一种统一的路由管理机制,可以方便地进行页面之间的切换和参数传递,简化了开发流程。

二、问题

Flutter Boost 重新提供了一个全局页面路由状态监听器,导致了我们SDK原先基于Material和Cupertino风格的组件库提供的路由监听将全部失效,这会导致采集PV、页面性能、页面FPS的采集,计算、日志上报受到影响。

三、支持版本

APM Flutter SDK v.2.2.0 + (Flutter Boost 4.x +)

四、集成适配方案

4.1 SDK 初始化

// 执行入口
import 'package:umeng_apm_sdk/umeng_apm_sdk.dart';
import 'package:umeng_common_sdk/umeng_common_sdk.dart';

void main (List<String> args) {
  // 全局范围内添加一个页面可见性的观察者。这个观察者会在应用的页面可见性有变化时接收到通知
  // 参考说明 3.2
  PageVisibilityBinding.instance.addGlobalObserver(AppGlobalPageVisibilityObserver());

  // APM SDK初始化
  final UmengApmSdk umengApmSdk = UmengApmSdk(
    name: '',
    bver: '1.0.0+9',
    flutterVersion: '3.10.0',
    engineVersion: 'd44b5a94c9',
    enableLog: true,
    enableTrackingPageFps: true,
    enableTrackingPagePerf: true,
    errorFilter: {
      "mode": "ignore",
      // "rules": [RegExp('RangeError')],
      "rules": [],
    },
    // 参考 3.3 确保框架初始化
    initFlutterBinding: MyApmWidgetsFlutterBinding.ensureInitialized,
    // onError: (exception, stack) {},
  );
  umengApmSdk.init(appRunner: (observer) async {
    // 确保去掉原有的WidgetsFlutterBinding.ensureInitialized() ,以免出现重复初始化绑定的异常造成无法正常初始化,
    // SDK内部已通过initFlutterBinding入参带入继承的WidgetsFlutterBinding实现初始化操作
    // 依赖ensureInitialized()初始化的代码可在此调用
    // 需要异步获取设置应用名称和版本号可在此回调中操作
    // SDK实例化的设置可先将name和bver 为 "",然后通过以下方式进行设置
    // 如:umengApmSdk.name = 'app_demo';
    // 如:umengApmSdk.bver = '1.2.0+1';
    umengApmSdk.name = 'app_demo';
    return MyApp();
  });
  

}

4.2 混入SDK监听类

通过SDK 提供的ApmFlutterBoostPageObserver类混入自定义的AppGlobalPageVisibilityObserver类用于Boost插件页面状态全局观察

// 确保自定义页面状态观察类的定义
class AppGlobalPageVisibilityObserver extends GlobalPageVisibilityObserver
    with ApmFlutterBoostPageObserver {
  @override
  void onPagePush(Route<dynamic> route) {
    // 混入监听类执行的确保父类的super.onPagePush方法被调用之行
    super.onPagePush(route);
    Logger.log(
        'boost_lifecycle: AppGlobalPageVisibilityObserver.onPageCreate route:${route.settings.name}');
  }

  @override
  void onPageShow(Route<dynamic> route) {
    // 混入监听类执行的确保父类的super.onPageShow方法被调用之行
    super.onPageShow(route);
    Logger.log(
        'boost_lifecycle: AppGlobalPageVisibilityObserver.onPageShow route:${route.settings.name}');
  }

  @override
  void onPageHide(Route<dynamic> route) {
    // 混入监听类执行的确保父类的super.onPageHide方法被调用之行
    super.onPageHide(route);
    Logger.log(
        'boost_lifecycle: AppGlobalPageVisibilityObserver.onPageHide route:${route.settings.name}');
  }

  @override
  void onPagePop(Route<dynamic> route) {
    // 混入监听类执行的确保父类的super.onPagePop方法被调用之行
    super.onPagePop(route);
    Logger.log(
        'boost_lifecycle: AppGlobalPageVisibilityObserver.onPageDestroy route:${route.settings.name}');
  }

  @override
  void onForeground(Route route) {
    // 混入监听类执行的确保父类的super.onForeground方法被调用之行
    super.onForeground(route);
    Logger.log(
        'boost_lifecycle: AppGlobalPageVisibilityObserver.onForeground route:${route.settings.name}');
  }

  @override
  void onBackground(Route<dynamic> route) {
    // 混入监听类执行的确保父类的super.onBackground方法被调用之行
    super.onBackground(route);
    Logger.log(
        'boost_lifecycle: AppGlobalPageVisibilityObserver.onBackground route:${route.settings.name}');
  }
}

4.3 确保Flutter框架初始化

定义自定义MyApmWidgetsFlutterBinding类 继承 SDK 提供的ApmWidgetsFlutterBinding 类,并通过 with 混入了 Boost提供的BoostFlutterBinding 类,用作确保Flutter框架初始化

class MyApmWidgetsFlutterBinding extends ApmWidgetsFlutterBinding
    with BoostFlutterBinding {
  @override
  void handleAppLifecycleStateChanged(AppLifecycleState state) {
    // 添加自己的实现逻辑
    // print('AppLifecycleState changed to $state');
    super.handleAppLifecycleStateChanged(state);
  }

  static WidgetsBinding? ensureInitialized() {
    MyApmWidgetsFlutterBinding();
    return WidgetsBinding.instance;
  }
}