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;
}
}