Flutter性能监控插件tingyun_flutter_plugin的使用
Flutter性能监控插件tingyun_flutter_plugin的使用
环境要求
- Dart Version: >= 2.4.0
- Flutter Version: >= 1.12.0
嵌码步骤
1、原生项目嵌码
请确保嵌码 APP 原生部分已集成 TingYun_SDK,如未集成可参照原生项目部署文档完成嵌码。
-
Android 部署文档
https://wukongdoc.tingyun.com/app/sdk_deploy/Android/Android_Gradle.html -
iOS 部署文档
由于「Flutter插件嵌码」会通过pod install
引入 iOS SDK,所以请从<code>添加 TingYun SDK</code>
开始嵌码。
https://wukongdoc.tingyun.com/app/sdk_deploy/iOS/deploy.html
2、Flutter 插件嵌码
2.1、添加依赖
在项目的「pubspec.yaml」文件中添加「TingYun Flutter」插件,目前支持【远程依赖】及【本地依赖】两种部署方式。
- 远程依赖
dependencies:
tingyun_flutter_plugin: ^1.0.0
- 本地依赖
dependencies:
tingyun_flutter_plugin:
path: tingyun_flutter_plugin //tingyun_flutter_plugin 需替换为本地 TingYun flutter 插件的目录
添加后需要在项目「根目录下」执行 flutter packages get
命令。
注意:iOS 添加依赖需在项目 ios
目录下执行 pod install
。
2.2、Flutter 插件初始化
需在 <code>runApp()</code>
方法前添加 <code>Tingyun().startWithoutWidget()</code>
方法,为了采集 zone 的错误,需在外层包裹 <code>runZonedGuarded</code>
,并传入 <code>Tingyun().reportZoneStacktrace</code>
。
import 'package:tingyun_flutter_plugin/tingyun_flutter_plugin.dart';
void main() {
runZonedGuarded(() async {
Tingyun().startWithoutWidget();
runApp(MyApp());
}, Tingyun().reportZoneStacktrace);
}
运行项目工程后控制台会显示以下日志:
tingyun flutter impl start
get configure from tingyun:xxx //xxx 为从 native 端 SDK 获取到的功能开关配置情况
//初始化成功时候显示
tingyun flutter plugin success!
//初始化失败时显示
tingyun flutter plugin failed to initialize. Error: xxx //xxx 为错误描述
2.3、兼容异常数据
由于 Flutter 只允许单一 handler 收集 error 数据,听云提供了相关参数以便兼容 App 自身采集 error 的场景。
- 控制参数
/**
因为flutter error 的捕获机制原因,需要提供2个不同的函数来进行处理,
onError 是flutter框架没有捕获到的异常的时候,通过runZoned来捕获的error的回调函数
flutterOnError 是flutter框架通过Flutter.onError来捕获异常的回调函数
@onError: 需要传入原型为 void FunctiononError(Object, StackTrace)的函数,
@flutterOnError: 需要传入原型为 void FunctionFlutterError(FlutterErrorDetails details)的函数
*/
Tingyun().startWithoutWidget(onError: onCustomError, flutterOnError: onCustomFlutterError);
- 代码示例
void main() {
runZonedGuarded(() async {
Tingyun().startWithoutWidget(onError: onCustomError, flutterOnError: onCustomFlutterError);
runApp(MyApp());
}, Tingyun().reportZoneStacktrace);
}
void onCustomError(Object object, StackTrace stackTrace){
print('onCustomError happened');
}
void onCustomFlutterError(FlutterErrorDetails details){
print('onCustomFlutterError happened');
}
3、Android WebView 数据采集
由于操作系统差异,TIngYun_iOS_SDK 默认支持自动采集 WebView 数据,Android 则需按以下步骤添加相关设置。
设置 WebChromeClient
Android 采集 WebView 数据需要设置 WebChromeClient,并在 onProgressChanged()
中调用 TingYun_Android_SDK 提供的 initJSMonitor()
方法。
举例
以【webview_flutter-0.3.24】为例:
- 打开
webview_flutter-0.3.24
android 目录下的build.gradle
文件并添加 TingYun_Android_SDK 依赖:
dependencies {
compileOnly "com.networkbench:tingyun-ea-agent-android:2.17.4"
}
- 在
WebChromeClient
中重写onProgressChanged()
,并添加 TingYun_SDK 的initJSMonitor()
方法:
private class FlutterWebChromeClient extends WebChromeClient {
@Override
public void onProgressChanged(WebView view, int newProgress) {
try {
Class.forName("com.networkbench.agent.impl.instrumentation.NBSWebChromeClient");
com.networkbench.agent.impl.instrumentation.NBSWebChromeClient.initJSMonitor(view, newProgress);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
super.onProgressChanged(view, newProgress);
}
... ...
}
API接口
1、自定义网络请求
TingYun_SDK 通过设置 HttpOverrides.global
自动采集网络数据,目前支持「httpClient」以及基于 HttpClient
封装的「dio、http」等网络库。
- 相关接口
/*
@url:网络请求的完整 url
*/
TYWebRequestTiming timing = await Tingyun().createWebRequest(String url);// 创建一条网络性能数据
timing.start();// 请求开始
/*
@code:请求的状态码
*/
timing.stop(int code);// 请求结束
- 代码示例
var url = "https://www.tingyun.com";
TYWebRequestTiming timing = await Tingyun().createWebRequest(url);
timing.startWebRequestTiming();
var response = await http.get(url)
.then((response) {
timing.stop(response.statusCode);// 请求结束
return response;
});
2、自定义启动结束点
TingYun_SDK 默认计算 SDK 初始化开始至第一个页面加载结束的时间为「冷启动耗时」,研发人员可以根据自身应用需求更改计算「冷启动耗时」的结束点。
-
项目要求
- Android 项目
采集冷启动(含首次启动)数据需实现自定义的 Application 类。 - iOS 项目
采集启动数据需要在 main 函数中嵌码。
- Android 项目
-
开启自定义启动开关 需在 native 部分初始化 TingYun_SDK 时调用相关接口。
- Android 接口
/* [@isCustom](/user/isCustom):是否启用自定义启动,默认 false,如需开启,置为 true */ NBSAppAgent.isCustomAppStart(boolean isCustom);
- iOS 接口
/** 是否启用自定义启动,在启动SDK之前调用,默认 NO,如需开启,置为 YES */ + (void)customLanuchEnd:(BOOL)enable;
- 代码示例
- Android 示例
public class MyApplication extends Application { @Override public void onCreate() { NBSAppAgent.setLicenseKey("AppKey") .isCustomAppStart(true)//在初始化SDK时调用,开启自定义启动时间功能 .start(this.getApplicationContext()); } }
- iOS 示例
int main(int argc, char* argv[]) { @autoreleasepool { [NBSAppAgent customLanuchEnd:YES]; [NBSAppAgent setRedirectURL:@"Dc_Redirect"]; [NBSAppAgent startWithAppID:@"AppKey"]; return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } }
-
设置自定义启动的结束点 需要开启「自定义启动开关」,当自定义启动开关设置为 true 时,自定义启动结束点的接口设置才会生效。
- 相关接口
Tingyun().setCustomOnResumeEndIns();
- 代码示例
Widget build(BuildContext context) { Tingyun().setCustomOnResumeEndIns(); return Scaffold( body: Column( crossAxisAlignment: CrossAxisAlignment.center, ..... )); }
3、自定义用户操作
支持通过埋点方式采集操作数据,可支持 root 和 sub 两层 trace(注意:这里两层是指 sub trace 允许有多个并非两个)。
-
接口限制
- 操作数据截至到 root 节点结束。
- 多组埋点 root 节点不能交叉调用。
-
相关接口
/*
@name:操作名称
*/
TingyunRootAction rootAction = Tingyun().enterAction(String name);//创建一个操作
/*
@name:子 Action 名称
*/
TingyunAction subAction = rootAction.enterAction(String name);//创建一个子 Action
subAction.leaveAction();//子 Action 完成
/*
@props:附加信息
@tag:tag 标识
*/
rootAction.leaveAction({Map<String, dynamic> props, String tag = ""});//操作完成
- 代码示例
TingyunRootAction rootAction = Tingyun().enterAction('my button enter');
TingyunAction subAction1 = rootAction.enterAction('sub1 button enter');
subAction1.leaveAction();
TingyunAction subAction2 = rootAction.enterAction('sub2 button enter');
subAction2.leaveAction();
rootAction.leaveAction(props:{"key1":"value1","key2":"value2"},tag: "tag");
4、自定义错误
使用「自定义错误」接口可以采集研发人员「try / catch 异常」和「业务错误」并在听云平台「异常分析」→「错误」中进行展示,可以帮助研发人员收集异常和错误。
- 相关接口
/*
@message:不可以传空,最大长度 1024 字节,超出截取前 1024 字节
@stackTrace:上传 exception 取到抛出时的堆栈
@props:value 值支持 Number, String, Array, Map 类型,最大限制128k,若超出最大限制上传为空
*/
Tingyun().reportError(String message, String stackTrace, {Map<String, dynamic> props});
- 代码示例
try {
throw new StateError('This is an async Dart exception.');
} catch (exception, stack) {
Tingyun().reportError(exception.toString(), stack.toString(),props: {"ke y1":"value1","key2":"value2"});
}
5、设置用户标识
通过添加「用户标识」可在听云报表平台通过该标识检索到具体用户的性能问题。
- 相关接口
/*
@userIdentifier:最多包含64个字符,超出截取前64字符,支持中文、英文、数字、下划线,但不能包含空格或其他的转义字符
*/
Tingyun().setUserIdentifier(String userIdentifier);
- 代码示例
Tingyun().setUserIdentifier("zhangsan@tingyun.com");
6、记录用户路径(面包屑)
研发人员可以在应用程序的任意位置调用「面包屑」接口进行埋点。当应用程序发生崩溃时,SDK 会按代码的触发顺序收集埋点信息并在崩溃轨迹中高亮显示,以协助研发人员在应用崩溃时了解代码调用逻辑。
- 相关接口
/*
@breadcrumb:自定义信息,最多包含100个字符,超出截取前100字符,支持中文、英文、数字、下划线
*/
Tingyun().leaveBreadcrumb(String breadcrumb);
- 代码示例
Tingyun().leaveBreadcrumb("添加购物车");
7、自定义附加信息
在应用发生崩溃的时候,研发人员往往需要更多的信息以收集现场环境,可以通过调用「自定义崩溃附加信息」接口上传额外信息,协助分析崩溃问题。
- 相关接口
/*
只保留最新的10条数据,随崩溃上传
@key:key 值
@value:value 值,最大长度限制100,超出则截取前100
*/
Tingyun().setUserCrashMessage(String key, String value);
- 代码示例
Tingyun().setUserCrashMessage("当前页面", "Main");
更多关于Flutter性能监控插件tingyun_flutter_plugin的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter性能监控插件tingyun_flutter_plugin的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
tingyun_flutter_plugin
是一个用于 Flutter 应用的性能监控插件,它可以帮助开发者监控应用的性能指标,如启动时间、页面加载时间、网络请求时间等。以下是如何使用 tingyun_flutter_plugin
的基本步骤:
1. 添加依赖
首先,你需要在 pubspec.yaml
文件中添加 tingyun_flutter_plugin
依赖:
dependencies:
flutter:
sdk: flutter
tingyun_flutter_plugin: ^版本号
请将 ^版本号
替换为最新的插件版本号。
2. 初始化插件
在你的 Flutter 应用启动时,初始化 tingyun_flutter_plugin
。通常可以在 main.dart
文件中进行初始化:
import 'package:flutter/material.dart';
import 'package:tingyun_flutter_plugin/tingyun_flutter_plugin.dart';
void main() {
// 初始化 Tingyun 插件
TingyunFlutterPlugin.init(
appKey: '你的AppKey', // 替换为你的 Tingyun AppKey
channel: 'your_channel', // 渠道号,可选
debugMode: true, // 是否开启调试模式,可选
);
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
3. 监控页面加载时间
你可以使用 TingyunFlutterPlugin
来监控页面的加载时间。在页面加载时调用 startTrackPage
,在页面卸载时调用 stopTrackPage
:
import 'package:flutter/material.dart';
import 'package:tingyun_flutter_plugin/tingyun_flutter_plugin.dart';
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
void initState() {
super.initState();
// 开始监控页面加载时间
TingyunFlutterPlugin.startTrackPage('MyHomePage');
}
@override
void dispose() {
// 停止监控页面加载时间
TingyunFlutterPlugin.stopTrackPage('MyHomePage');
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Home Page'),
),
body: Center(
child: Text('Hello, Tingyun!'),
),
);
}
}
4. 监控网络请求
tingyun_flutter_plugin
也支持监控网络请求。你可以在发起网络请求时调用 startTrackHttp
,在请求完成时调用 stopTrackHttp
:
import 'dart:io';
import 'package:http/http.dart' as http;
import 'package:tingyun_flutter_plugin/tingyun_flutter_plugin.dart';
Future<void> fetchData() async {
var url = Uri.parse('https://example.com/api/data');
var requestId = TingyunFlutterPlugin.startTrackHttp(url.toString());
try {
var response = await http.get(url);
TingyunFlutterPlugin.stopTrackHttp(requestId, response.statusCode, response.contentLength ?? 0);
} on SocketException catch (e) {
TingyunFlutterPlugin.stopTrackHttp(requestId, 500, 0);
}
}
5. 自定义事件
你还可以使用 TingyunFlutterPlugin
来记录自定义事件:
TingyunFlutterPlugin.trackEvent('custom_event', {'key1': 'value1', 'key2': 'value2'});
6. 调试模式
在开发阶段,你可以开启调试模式来查看更多的日志信息:
TingyunFlutterPlugin.setDebugMode(true);
7. 发布应用
在发布应用时,确保关闭调试模式:
TingyunFlutterPlugin.setDebugMode(false);