Flutter性能分析插件profiler的使用

Flutter性能分析插件profiler的使用

入门指南

Contextual Profiler SDK 提供了一个全面且高效的解决方案,用于收集有关您的用户的重要信息。借助此强大的工具,您可以收集相关信息,从而进行深入分析并清楚地了解用户的使用行为、偏好和需求。

⚠️ 重要提示:此库不支持iOS设备。

请注意,此库目前仅适用于Android平台。在iOS设备上将无法运行。确保您的项目旨在使用Android平台之前,请集成此库。

查看完整的API以获取更多方法。

推荐配置

  • FLUTTER: >= 3.3.0
  • ANDROID API LEVEL: 21到33(我们推荐24到34)
  • MIN JAVA VERSION: jdk11
  • GRADLE DISTRIBUTION: gradle-7.5.1

安装

Android

Proguard

如果您在项目中使用了混淆工具,则需要排除该包,以便在发布版本中正常工作。

/android/app目录下创建一个名为proguard-rules.pro的新文件,并添加以下内容:

-keep class com.fivvy.profiler.** { *; }
-keep class * extends com.fivvy.profiler.** { *; }

-keepclassmembers class com.fivvy.profiler.** {
    *;
}

-keepattributes *Annotation*

/android/app/build.gradle文件中添加以下设置:

buildTypes {
    release {
        ...
        minifyEnabled true
        shrinkResources true
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
    }
}
Gradle 配置

必须向build.gradle(项目级)文件添加以下行:

allprojects {
    repositories {
        google()
        mavenCentral()
        maven {
            url "https://gitlab.com/api/v4/projects/58175283/packages/maven"
        }
    }
}

build.gradle(应用级)文件中添加以下行:

implementation 'com.fivvy:fivvy-lib:3.2.2@aar'

确保您还具有以下依赖项:

implementation 'androidx.security:security-crypto-ktx:1.1.0-alpha04'
权限
AndroidManifest

AndroidManifest.xml文件内android/app/src/main目录下,需要添加xmlns:tools属性到manifest标签中:

<manifest 
  <!-- 其他manifest属性 -->
  xmlns:tools="http://schemas.android.com/tools"
>

还需要在AndroidManifest.xml文件中添加以下权限:

<manifest>
  <!-- 其他应用程序标签 -->
  <uses-permission  android:name="android.permission.INTERNET" />
  <uses-permission  android:name="android.permission.PACKAGE_USAGE_STATS"  tools:ignore="ProtectedPermissions" />

  <!-- 应用程序列表 -->
  <queries>
    <!-- 应用程序包列表 [最多100个] -->
    <package android:name="com.whatsapp"/> <!-- WhatsApp Messenger -->
    <package android:name="com.facebook.katana"/> <!-- Facebook -->
    <package android:name="com.mercadopago.android"/> <!-- Mercado Pago -->
  </queries>

  <application>
    <!-- ... -->
  </application>
</manifest>

在应用中集成

在Android平台上,您必须在调用这些方法之前请求权限。

插件初始化

首先,您需要在要使用方法的Widget中预先实例化ContextualProfiler插件。

import 'package:profiler/plugin/contextual_profiler.dart';

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  // 添加这一行
  final _profilerPlugin = ContextualProfiler();

  // 您的代码
}

获取用户权限以检查应用程序的使用情况

这是一个专有的自定义对话框,您可以在应用中调用它,以轻松请求用户访问使用权限。

首先,您需要添加一个函数,将图像转换为字节数组。

Future<Uint8List> loadImageBytes(String assetPath) async {
  final ByteData data = await rootBundle.load(assetPath);
  return data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
}

然后实现以下方法:

Future<void> openAccessUsageSettings() async {
  String platformVersion;

  final Uint8List imageBytes = await loadImageBytes("assets/images/logo.png");

  final usageSetting = UsageSetting(
    language: "ES", // 如果选择,将默认文本设置为EN、ES或PR。
    // 如果使用ln值,则建议不要使用以下参数,因为ln会将正确的语言设置为默认文本。
    appName: 'Fivvy', // 字符串值,您的应用名称
    imagePath: imageBytes, // 此图像应位于android/app/src/main/res/drawable/logo.png
    appDescription: '激活权限', // 可选描述文本。推荐长度:3或4个单词
    modalText: 'Lorem ipsum 文本', // 可选模态文本。推荐长度:3或4个单词
    dialogTitle: "对话框标题", // 显示给用户的对话框标题,在重定向到设置屏幕以获取权限之前。
    dialogMessage1: "对话框消息1", // 显示给用户的对话框自定义消息,在重定向到设置屏幕以获取权限之前。
    dialogMessage2: "对话框消息2", // 显示给用户的另一个对话框自定义消息,在重定向到设置屏幕以获取权限之前。
    blacklist: null // (可选)设备制造商列表,对于这些设备,应避免使用使用设置。在某些设备上,特别是来自某些制造商的设备(如小米),在尝试访问使用设置时可能会显示系统警告。为了防止这些设备上的此操作,您可以:

    //- 传递 `null`:这将应用已知有此问题的制造商的默认列表。
    // - 提供制造商的自定义列表作为数组(`["manufacturer1", "manufacturer2"]`):这将防止在特定品牌设备上访问设置。
    //- 传递空数组 `[]`:这将在所有设备上允许访问设置,没有任何限制。

  );

  try {
    await _profilerPlugin.openUsageAccessSettings(usageSetting);
    platformVersion = '打开成功';
  } on PlatformException {
    platformVersion = '未能打开访问使用设置。';
  }

  if (!mounted) return;

  setState(() {
    _response = platformVersion;
  });
}

还要在.yaml文件中添加资产:

flutter:
  assets:
    - assets/images/logo.png

另一种选项

然而,如果您想创建一个最适合您的应用的自定义对话框,有一个单独的功能可以考虑。假设您已经事先实例化了ContextualProfiler插件。

Future<void> openAccessUsageSettingsDirectly() async {
  String platformVersion;

  try {
    await _profilerPlugin.openUsageAccessSettingsDirectly(blacklist); // - blacklist (可选) 设备制造商列表,对于这些设备,应避免使用使用设置。在某些设备上,特别是来自某些制造商的设备(如小米),在尝试访问使用设置时可能会显示系统警告。为了防止这些设备上的此操作,您可以:

    //- 传递 `null`:这将应用已知有此问题的制造商的默认列表。
    // - 提供制造商的自定义列表作为数组(`["manufacturer1", "manufacturer2"]`):这将防止在特定品牌设备上访问设置。
    //- 传递空数组 `[]`:这将在所有设备上允许访问设置,没有任何限制。
    platformVersion = '打开成功';
  } on PlatformException {
    platformVersion = '未能打开访问使用设置。';
  }

  if (!mounted) return;

  setState(() {
    _response = platformVersion;
  });
}

将数据发送到Fivvy的分析服务

此功能将允许您的应用将每个用户的信息发送到Fivvy分析API。您必须在某个视图或加载组件中添加此功能,至少每天发送一次数据。

Future<void> initContextualDataCollection() async {
  String response;

  ContextualCredential initConfig = ContextualCredential(
      customerId: customerId,
      apiPassword: apiSecret,
      apiUsername: apiKey,
      authApiUrl: authApiUrl,
      sendDataApiUrl: sendDataApiUrl
  );

  try {
    await _profilerPlugin.initContextualDataCollection(initConfig);
    response = '数据发送成功';
  } on PlatformException {
    response = '发生错误。';
  }

  if (!mounted) return;

  setState(() {
    this._response = response;
  });
}

API

这里包含有关包的所有信息以及如何使用函数的方法。

方法 参数值 返回值 描述
initContextualDataCollection InitConfig {customerId: String, apiKey: String, apiSecret: String, appUsageDays: int, authApiUrl: String, sendDataApiUrl: String} Future&lt;ContextualData&gt; 启动数据收集,将其发送到Fivvy的分析数据API。
getDeviceInformation Future&lt;IHardwareAttributes&gt; 返回客户设备的硬件信息。
getAppUsage int 天数。表示最近的天数以获取每个应用的使用情况。 Future&lt;List&lt;IAppUsage&gt;&gt; 返回一个 IAppUsage 列表,代表 AndroidManifest.xml 中查询的所有应用,如果用户未授予使用权限则返回 null
getAppsInstalled Future&lt;List&lt;IInstalledApps&gt;&gt; 返回一个 IInstalledApps 列表,代表 AndroidManifest.xml 中查询的所有应用。
openUsageAccessSettings IUsageSetting Future&lt;bool&gt; 打开设置视图以授予应用使用权限。

接口

以下是SDK使用的接口:

/// `initContextualCollectionData` 参数对象接口
class InitConfig {
  String customerId;
  String apiKey;
  String apiSecret;
  int appUsageDays;
  String authApiUrl;
  String sendDataApiUrl;

  InitConfig({
    required this.customerId,
    required this.apiKey,
    required this.apiSecret,
    required this.appUsageDays,
    required this.authApiUrl,
    required this.sendDataApiUrl
  });
}

/// `getDeviceInformation` 返回接口
class IHardwareAttributes {
  String apiLevel;
  String deviceId;
  String device;
  String hardware;
  String brand;
  String manufacturer;
  String model;
  String product;
  String tags;
  String type;
  String base;
  String id;
  String host;
  String fingerprint;
  String incrementalVersion;
  String releaseVersion;
  String baseOs;
  String display;
  int batteryStatus;

  IHardwareAttributes({
    required this.apiLevel,
    required this.deviceId,
    required this.device,
    required this.hardware,
    required this.brand,
    required this.manufacturer,
    required this.model,
    required this.product,
    required this.tags,
    required this.type,
    required this.base,
    required this.id,
    required this.host,
    required this.fingerprint,
    required this.incrementalVersion,
    required this.releaseVersion,
    required this.baseOs,
    required this.display,
    required this.batteryStatus,
  });
}

/// `getAppUsage` 返回对象接口
class IAppUsage {
  String appName;
  int usage;
  String packageName;

  IAppUsage({
    required this.appName,
    required this.usage,
    required this.packageName,
  });
}

/// `getAppsInstalled` 返回对象接口
class IInstalledApps {
  String? appName;
  String packageName;
  String? category;
  String? installTime;
  String? lastUpdateTime;
  String? versionCode;
  String? versionName;

  IInstalledApps({
    this.appName,
    required this.packageName,
    this.category,
    this.installTime,
    this.lastUpdateTime,
    this.versionCode,
    this.versionName,
  });
}

/// `openUsageSettings` 参数对象接口
class IUsageSetting {
  String? language;
  Uint8List? imagePath;
  String? appName;
  String? appDescription;
  String? modalText;
  String? dialogTitle;
  String? dialogMessage1;
  String? dialogMessage2;
  List<String>? blacklist;

  IUsageSetting({
    this.language,
    this.imagePath,
    this.appName,
    this.appDescription,
    this.modalText,
    this.dialogTitle,
    this.dialogMessage1,
    this.dialogMessage2,
    this.blacklist,
  });
}

调试模式

调试模式配置

要启用并正确使用调试模式,请遵循以下步骤:

调试模式的要求
  1. 项目必须生成 <code>BuildConfig</code> 类,这是在Android上配置的Flutter项目的标准。如果您的项目没有生成 <code>BuildConfig</code>,请转到第2步。

  2. 如果 <code>BuildConfig</code> 没有自动生成或不包括所需属性:

    • 打开位于 <code>/android/app</code><code>build.gradle</code> 文件。
    • 添加以下配置:
android {
    ...
    buildFeatures {
       buildConfig true
   }
}

更多关于Flutter性能分析插件profiler的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter性能分析插件profiler的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter开发中,性能分析是确保应用流畅运行的关键步骤之一。Flutter提供了一个强大的性能分析工具——Profiler,它能够帮助开发者识别并解决性能瓶颈。以下是如何使用Flutter Profiler插件的一些具体代码示例和步骤,以便你能更深入地理解和应用它。

1. 安装Flutter Profiler插件

Flutter Profiler插件通常与DevTools一起使用,DevTools是Flutter的一套网页工具,用于调试和分析Flutter应用。你无需单独安装Profiler插件,因为它已经集成在DevTools中。

2. 启动DevTools

首先,确保你的Flutter SDK是最新的,然后可以通过命令行启动DevTools:

flutter pub global activate devtools
flutter devtools

这将打开DevTools的网页界面。

3. 连接你的Flutter应用

在DevTools中,点击“Connect to a Flutter application”按钮,并按照提示在你的Flutter应用中添加以下代码以启用调试连接:

import 'package:flutter_tools/flutter_tools.dart' as flutter_tools;

void main() {
  // Enable service extensions.
  flutter_tools.enableFlutterDriverExtension();
  runApp(MyApp());
}

注意:通常在生产代码中不会启用flutter_tools.enableFlutterDriverExtension(),这里仅用于调试目的。

4. 使用Profiler进行分析

一旦你的应用与DevTools连接成功,你可以导航到“Profiler”标签页。在这里,你可以看到应用的性能数据,包括CPU、GPU使用情况,以及每一帧的构建时间等。

5. 代码示例:性能敏感区域标记

为了更好地分析性能,你可以在代码中标记出性能敏感的区域,这样Profiler就能提供更详细的信息。使用Timeline类可以很方便地实现这一点:

import 'dart:developer';

void expensiveOperation() {
  // 开始标记性能敏感区域
  Timeline.startSync('Expensive Operation');

  // 模拟一个耗时操作
  for (int i = 0; i < 1000000; i++) {
    // 耗时计算
  }

  // 结束标记
  Timeline.finishSync();
}

void main() {
  runApp(MaterialApp(
    home: Scaffold(
      appBar: AppBar(title: Text('Flutter Profiler Demo')),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            expensiveOperation();
          },
          child: Text('Run Expensive Operation'),
        ),
      ),
    ),
  ));
}

在上面的代码中,Timeline.startSync('Expensive Operation')Timeline.finishSync()标记出了一个性能敏感区域。当你在DevTools的Profiler中查看时,你可以看到这部分操作的详细性能数据。

6. 分析性能数据

在Profiler界面,你可以查看不同时间段的性能数据,包括CPU使用率、内存使用情况、每一帧的构建和渲染时间等。通过分析这些数据,你可以识别出性能瓶颈,比如某一帧的构建时间过长,或者某个操作的CPU使用率异常高等。

总结

Flutter Profiler是一个非常强大的工具,它能够帮助你深入了解应用的性能表现,并找出潜在的性能问题。通过上述步骤和代码示例,你可以开始使用Profiler来分析你的Flutter应用,并优化其性能。记住,性能优化是一个持续的过程,需要不断地监控和调整。

回到顶部