注意:说明:
注意:目前 Flutter 强绑定终端运行,如果已经有了 Android 或 iOS 的应用,请直接使用对应的 AppKey,如没有请创建时选择 Android 或 iOS 应用。
一、自动集成
1. 安装。
·在项目的 pubspec.yaml 文件中添加 qapm_flutter 的依赖。
·运行 flutter pub get 更新依赖。
flutter pub get
2. 导入。
import 'package:qapm_flutter/qapm_flutter.dart';
二、Android 平台
配置 Gradle
1. 在工程级的 build.gradle 文件下,增加maven 依赖和qapm-plugin 插件。
buildscript { repositories { … // 添加maven源 maven { url 'https://qapm-maven.pkg.coding.net/repository/qapm_sdk/android_release/' } … } dependencies { // 添加qapm-plugin插件 classpath 'com.tencent.qapmplugin:qapm-plugin:3.4' }}allprojects { repositories { … // 添加maven源 maven { url 'https://qapm-maven.pkg.coding.net/repository/qapm_sdk/android_release/' } … }}
注意:说明:
注意:如果你的 gradle 版本小于7.4,则将 qapm-plugin 插件版本改为2.39。
2. 在 app 的 build.gradle 文件下,增加 qapm-plugin 的引用。
… // 引用插件 apply plugin: "qapm-plugin" … // 添加自动生成UUID的Task preBuild.dependsOn(UUIDGenerator)
三、配置权限
在 AndroidMainfest.xml 文件中增加以下权限。
<!–上报信息所需–><uses-permission android:name="android.permission.INTERNET" /><!–采集信息所需–><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /><uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
四、配置混淆
在 proguard 混淆配置文件中增加以下内容,避免打包报错或 SDK 不可用。
-dontwarn com.tencent.cos.xml.** { *; }-dontwarn com.tencent.qcloud.** { *; }-dontwarn com.squareup.okhttp.** { *; } -dontwarn okhttp3.** { *; } -keep class com.tencent.qapmsdk.** { *; }-dontwarn com.tencent.qapmsdk.** { *; }
五、iOS 平台
在 iOS 的工程路径下,执行pod install更新依赖。
pod install
六、初始化 QAPM SDK
1. 为保证能够捕获全局的异常,建议你将应用的void main() => runApp(MyApp());替换成以下代码。
·如果你的工程是纯 flutter 开发,或者原生(Android 和 iOS)并没有接入 QAPM,则参考以下方式初始化 QAPM。
void main() { // 初始化QAPM QAPMBuilder builder = QAPMBuilder(); // 目前AppKey还是沿用原生层的,所以这里需要在控制台创建对应平台的应用,并且分别设置 if (Platform.isAndroid) { builder.appKey = "2b6f3f82-11907"; } else if (Platform.isIOS) { builder.appKey = "26388a8d-3649"; } builder.model = "HUAWEI"; // 设置手机型号 builder.appVersion = "1.0"; // 设置原生应用版本,这里纯flutter开发可以和crossVersion填一样值,如是混合开发建议和原生侧协商 builder.crossVersion = "1.0"; // 跨端的应用版本 builder.deviceId = "uuid"; // 设置设备ID //目前上报的域名分为了三个不同的地址,分别是国内站、新加坡站、法兰克福站,根据实际需求选择一个环境上报即可 //国内站:https://app.rumt-zh.com //新加坡站:https://app.rumt-sg.com //法兰克福站:https://eu-frankfurt.rumapp.tencentcs.com builder.host = "https://app.rumt-zh.com"; // 设置上报域名 builder.needLog = true; // 是否需要开启日志,release下建议关闭 builder.userId = "11223344"; // 设置用户ID builder.funcSwitch = QAPM.MODE_CRASH; // 需要开启跨端的功能,这里目前仅支持crash // 确保去掉原有的WidgetsFlutterBinding.ensureInitialized() ,以免出现重复初始化绑定的异常造成无法正常初始化,SDK内部已通过initFlutterBinding入参带入继承的WidgetsFlutterBinding实现初始化操作 builder.initFlutterBinding = MyApmWidgetsFlutterBinding.ensureInitialized; // 启动SDK QAPM.init(builder, () { runApp(MyApp()); });}class MyApmWidgetsFlutterBinding extends QapmWidgetsFlutterBinding { @override void handleAppLifecycleStateChanged(AppLifecycleState state) { // 添加自己的实现逻辑 print('AppLifecycleState changed to $state'); super.handleAppLifecycleStateChanged(state); } static WidgetsBinding? ensureInitialized() { MyApmWidgetsFlutterBinding(); return WidgetsBinding.instance; }}
·如果你的工程是原生 + Flutter 都需要使用 QAPM 的混合开发场景,则参考以下方式初始化 QAPM。
// 设置与原生通信的桥const channel = MethodChannel("com.example.flutter/qapm");void main() async { QAPMBuilder builder = QAPMBuilder(); builder.needLog = true; // 是否需要开启日志,release下建议关闭 builder.crossVersion = "1.0"; // 跨端的应用版本 builder.funcSwitch = QAPM.MODE_CRASH; // 需要开启跨端的功能,这里目前仅支持crash // 确保去掉原有的WidgetsFlutterBinding.ensureInitialized() ,以免出现重复初始化绑定的异常造成无法正常初始化,SDK内部已通过initFlutterBinding入参带入继承的WidgetsFlutterBinding实现初始化操作 builder.initFlutterBinding = MyApmWidgetsFlutterBinding.ensureInitialized; QAPM.init(builder, () { runApp(MyApp()); }, beforeInitRunner: (builder) async { // 原生层通过channel,实现对应逻辑,并将对应值传递给flutter,需要确保原生和flutter初始化的参数一致!!! builder.appKey = await channel.invokeMethod("getAppKey") as String; // 目前AppKey还是沿用原生层的,所以这里需要在控制台创建对应平台的应用,并且分别设置 builder.model = await channel.invokeMethod("getModel") as String; // 设置手机型号,需要跨端开发和原生开发协商,设置一致的值 builder.appVersion = await channel.invokeMethod("getAppVersion") as String; // 设置原生应用版本,需要跨端开发和原生开发协商,设置一致的值 builder.deviceId = await channel.invokeMethod("getDeviceId") as String; // 设置设备ID,需要跨端开发和原生开发协商,设置一致的值 builder.host = await channel.invokeMethod("getHost") as String; // 设置上报域名,需要跨端开发和原生开发协商,设置一致的值 builder.userId = await channel.invokeMethod("getUserId") as String; // 设置用户ID,需要跨端开发和原生开发协商,设置一致的值 });}class MyApmWidgetsFlutterBinding extends QapmWidgetsFlutterBinding { @override void handleAppLifecycleStateChanged(AppLifecycleState state) { // 添加自己的实现逻辑 print('AppLifecycleState changed to $state'); super.handleAppLifecycleStateChanged(state); } static WidgetsBinding? ensureInitialized() { MyApmWidgetsFlutterBinding(); return WidgetsBinding.instance; }}
2. 在 App 中设置路由监听。
class _MyAppState extends State<MyApp> with WidgetsBindingObserver { @override void initState() { super.initState(); } @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar( title: const Text('APM Example'), ), body: Center( child: MyHome(), ), ), // 添加 QapmNavigatorObserver navigatorObservers: [ QapmNavigatorObserver() ], routes: { 'MainPage': (context) => MainPage(), 'FirstPage': (context) => FirstPage(), 'SecondPage': (context) => SecondPage(), }, ); }}
如果是接入了TRouter等混合栈的路由框架,由于其接管了原生的 Navigator,需要将 QapmNavigatorObserver 设置到混合栈框架中,代码如下:
runApp(MaterialApp( home: TRouteContainer(navigatorObservers: QapmNavigatorObserver(),),));
注意:TRouter 需要使用2.5.7+ 版本,否则部分生命周期会丢失。
七、验证接入是否成功
关键词搜索 QAPM_flutter,如出现以下日志(Android 为例),说明初始化成功了。
2025-01-06 21:29:35.330 20883-21019 flutter com….qapmsdk.qapm_flutter_example I [QAPM_flutter_CrashMonitor] [DEBUG] init FlutterExceptionHandler success