跳转到主要内容
PRODUCT DOCUMENTS

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

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

Flutter集成文档

介绍

Umeng Flutter APM SDK 能够全面监控Flutter端线上稳定性和性能的运行情况,洞悉设备运行体感。目前 SDK提供了监控dart异常、页面性能、页面帧率等能力,并Flutter Boost插件集成 支持版本v2.2.0

Flutter SDK Change Log

⚠️ 注意:

  1. 支持iOS和Android平台

  2. SDK 支持Flutter官方提供的Flutter SDK运行环境。

  3. 欢迎开发者加入Flutter APM开发者交流群

image

SDK集成简易架构图

B99F41E7-C09B-45A0-9F64-FD9D4236DF7B.png

Flutter SDK 运行搭配最低版本下限

  • Android

  • Common:>= 9.5.3

  • apm:>= 1.9.3

  • Flutter

  • Common: >= 1.2.6

  • apm: >= 2.1.3

  • iOS

  • Common:>= 7.3.8

  • apm:>= 1.8.4

重要

Flutter APM和Flutter Common SDK内部已集成了Android和iOS SDK,如果工程类型是Flutter App可以直接跳到步骤三,直接进入Flutter SDK集成步骤

步骤一、申请AppKey创建应用

⚠️ 注意:

  1. 如需在已创建的平台(iOS,Android)应用中集成Flutter SDK可忽略此步骤

1.1、进入APM后台添加应用

5889AF4D-9ACC-42B9-922C-8EAB38357C8F.png

1.2、新建应用

7E1BAA59-DCBD-4304-8A78-B755694C58ED.png

1.3、获取Appkey

8331F8A0-8E2A-48A7-B12C-A09906941A75.png

步骤二、合规声明和初始化时机

为了满足监管的规定通常我们需要在APP中通过《隐私政策》中向用户告知使用友盟SDK。我们可以根据《隐私政策》弹窗或者页面所在架构层来判断调用所在端的Common SDK 初始化方法,因为我们需要在用户同意操作的回调中调用初始化Init Common SDK的方法。

2.1 《隐私政策》写在Native端参考如下:

参考:U-APM 合规指南(iOS)

参考:U-APM合规指南(Android)

2.2 《隐私政策》写在Flutter端参考如下:

注意:我们提供了可以桥接Native Common SDK能力的Flutter Common SDK,即使《隐私政策》在Flutter端也需要必须先集成Native Common SDK。

import 'package:umeng_common_sdk/umeng_common_sdk.dart';

class _MyAppState extends State {
 @override
 void initState() {
 super.initState();
 // 如合规声明在Flutter端,请在同意操作回调中添加下列调用方法
 UmengCommonSdk.initCommon(
 'androidAppkey', 'iosAppkey', 'Umeng');
 UmengCommonSdk.setPageCollectionModeManual();
 }
}

Flutter Common SDK集成参考:https://developer.umeng.com/docs/119267/detail/174923

合规声明文档参考:https://developer.umeng.com/docs/193624/detail/194588

步骤三、对接 Flutter SDK

APM SDK支持工程Flutter版本范围

flutter: ">=2.0.0" // 适用于Flutter SDK 2.0以上版本

3.1 添加SDK

3.1.1 手动集成

在【友盟+】官网下载,选取Flutter【应用性能监控】SDK进行下载。下载地址

92F563B7-596E-40D4-A2EF-833AD1F09729.png

将下载后的SDK文件夹放进工程中,在pubspec.yaml中利用相对路径进行引用

name: umeng_apm_sdk_example
description: Demonstrates how to use the umeng_apm_sdk plugin.
version: 1.0.0
publish_to: 'none'

environment:
 sdk: ">=2.12.0 <3.0.0"
 flutter: ">=2.0.0"

dependencies:
 flutter:
 sdk: flutter

 umeng_common_sdk: ^1.2.6
 umeng_apm_sdk:
 path: '<sdk file>'

3.1.2 自动集成

打开 pubspec.yaml,添加以下依赖:

dependencies:
 umeng_apm_sdk: ^2.2.1
 umeng_common_sdk: ^1.2.4

在安装umeng_apm_sdk的时候,如果出现报错,报错示例如下图,提示http包与其他SDK的http包的版本产生冲突,这个时候需要在pubspec.yaml下通过dependency_overrides锁定一下http包的版本,因为http 1.x.x 配套是dart 3.0 其中还有很多工程环境使用的是低于dart 3.0的版本 所以我们把http的依赖到0.13.1的版本 对应到dart 2.12这个支持空安全的里程碑版本,这样umeng_apm_sdk向下兼容。

image.png

// 示例
dependencies:
 umeng_apm_sdk: ^2.2.1
 umeng_common_sdk: ^1.2.4
 
dependency_overrides
  http: ^x.x.x

3.2 初始化 SDK 探针

字段

含义

是否必填

类型

获取方式

name

应用或模块名称

是

string

pubspec.yaml => name

bver

应用或模块版本(+构建号)

是

string

pubspec.yaml => version

projectType

工程类型 (默认为0)

Flutter App = 0

Flutter Module = 1

否

int

env

设置业务环境

v2.2.0 版本及以上可支持

否

UmengApmEnv

image.png

flutterVersion

Flutter SDK 版本

否

string

flutter --version

319B59D3-CC31-4B35-98D5-5476928DF130.png

engineVersion

引擎版本

否

string

enableLog

是否开启SDK日志打印 (默认关闭)

否

bool

enableTrackingPageFps

开启监测页面帧率(默认关闭)

v2.1.3 版本及以上可支持

否

bool

enableTrackingPagePerf

开启监测页面性能(默认关闭)

v2.1.3 版本及以上可支持

否

bool

errorFilter

设置采集的异常黑白名单

否

Map

initFlutterBinding

ApmWidgetsFlutterBinding的覆写和初始化方法

否

Function

onError

抛出异常回调

否

Function

⚠️ 注意:

  1. 确保 bver 精确到构建号,可以使后台符号表解析能够映射到指定版本

3.2.1 初始化 UmengApmSdk

为保证能够捕获全局的异常,我们建议您将应用的 void main() => runApp(MyApp());替换成以下代码

import 'package:umeng_apm_sdk/umeng_apm_sdk.dart';
import 'package:umeng_common_sdk/umeng_common_sdk.dart';
import 'package:package_info_plus/package_info_plus.dart';

void main() {
 final UmengApmSdk umengApmSdk = UmengApmSdk(
 name: '应用或者模块名称',
 
 bver: '您的Flutter应用或模块版本 (比如 1.0.0+1 )',
 
 // 是否开启SDK运行时日志输出
 enableLog: true,
 
 // 您使用的flutter版本,默认为空,为方便定位访问,建议配置
 flutterVersion: '您使用的flutter版本',
 
 engineVersion: '您使用的flutter引擎版本',
 
 // 开启监测页面帧率(默认关闭) 版本 v2.1.3 可支持
 enableTrackingPageFps: true,
   
 // 开启监测页面性能(默认关闭)版本 v2.1.3 可支持
 enableTrackingPagePerf: true,
 
 // 带入继承ApmWidgetsFlutterBinding的覆写和初始化方法, 可用于自定义监听应用生命周期
 // 确保去掉原有的WidgetsFlutterBinding.ensureInitialized() ,以免出现重复初始化绑定的异常造成无法正常初始化,SDK内部已通过initFlutterBinding入参带入继承的WidgetsFlutterBinding实现初始化操作
 initFlutterBinding: MyApmWidgetsFlutterBinding.ensureInitialized,

 	// 抛出异常事件
 onError: (exception, stack) {
 	print(exception);
 },
 
 );
  umengApmSdk.init(appRunner: (observer) async {
  // 确保去掉原有的WidgetsFlutterBinding.ensureInitialized() ,以免出现重复初始化绑定的异常造成无法正常初始化,SDK内部已通过initFlutterBinding入参带入继承的WidgetsFlutterBinding实现初始化操作
  // 依赖ensureInitialized()初始化的代码可在此调用
  // 需要异步获取设置应用名称和版本号可在此回调中操作
  // SDK实例化的设置可先将name和bver 为 "",然后通过以下方式进行设置
  PackageInfo packageInfo = await PackageInfo.fromPlatform();
  String packageName = packageInfo.packageName;
	String buildNumber = packageInfo.buildNumber;
  String version = packageInfo.version;
  umengApmSdk.name = packageName; 
 	umengApmSdk.bver = '$version+$buildNumber';
 
 	return MyApp(observer);
 });
}

// 如果使用Flutter Boost插件需要通过 with 混入了 Boost提供的BoostFlutterBinding 类 
// class MyApmWidgetsFlutterBinding extends ApmWidgetsFlutterBinding with BoostFlutterBinding {}
// 具体参考下方3.2.2的部分
class MyApmWidgetsFlutterBinding extends ApmWidgetsFlutterBinding {
 @override
 void handleAppLifecycleStateChanged(AppLifecycleState state) {
 // 添加自己的实现逻辑
 print('AppLifecycleState changed to $state');
 super.handleAppLifecycleStateChanged(state);
 }

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

class MyApp extends StatelessWidget {
 MyApp([this._navigatorObserver]);

 NavigatorObserver? _navigatorObserver;
 @override
 Widget build(BuildContext context) {
 return MaterialApp(
 theme: ThemeData(
 visualDensity: VisualDensity.adaptivePlatformDensity,
 ),
 routes: routes,
 initialRoute: "/",
 navigatorObservers: <NavigatorObserver>[
 // 带入ApmNavigatorObserver实例用于路由监听
 _navigatorObserver ?? ApmNavigatorObserver.singleInstance
 ],
 );
 }
}

⚠️ 注意:

  1. 确保去掉原有的WidgetsFlutterBinding.ensureInitialized() ,以免出现重复初始化绑定的异常造成无法正常初始化,SDK内部已通过initFlutterBinding入参带入继承的WidgetsFlutterBinding实现初始化操作

3.2.2 注册Flutter Boost插件监听器

支持 Flutter Boost插件(v2.2.0及以上版本支持)

3.2.3 注册监听器(非Flutter Boost插件环境使用)

我们需要在 MyApp中注册监听器,将ApmNavigatorObserver.singleInstance添加到应用的navigatorObservers 列表中

UmengApmSdk(
 name: '应用或者模块名称',
 ......
 
 ).init(appRunner: (observer) 
 // 入参 ApmNavigatorObserver 实例
 return MyApp(observer);
 });
}

class MyApp extends StatelessWidget {
 MyApp([this._navigatorObserver]);

 NavigatorObserver? _navigatorObserver;
 @override
 Widget build(BuildContext context) {
 return MaterialApp(
 theme: ThemeData(
 visualDensity: VisualDensity.adaptivePlatformDensity,
 ),
 routes: routes,
 initialRoute: "/",
 navigatorObservers: <NavigatorObserver>[
 // 带入ApmNavigatorObserver实例用于路由监听
 _navigatorObserver ?? ApmNavigatorObserver.singleInstance
 ],
 );
 }
}

⚠️ 注意:

  1. 如果不带入SDK监听器将无法获知页面(PV)入栈退栈行为,错误率(Dart异常数/FlutterPV次数)将异常攀升。

3.2.4 监听滚动FPS(v2.1.3 及以上版本支持)

使用SDK ApmScrollController实例,注册滚动控制器用于监听滚动事件。

import 'package:flutter/material.dart';
// 添加SDK
import 'package:umeng_apm_sdk/umeng_apm_sdk.dart';

class ScrollLazyLoadPage extends StatefulWidget {
  @override
  _ScrollLazyLoadPageState createState() => _ScrollLazyLoadPageState();
}

class _ScrollLazyLoadPageState extends State<ScrollLazyLoadPage> {
  List<String> imageUrls = [];
  int page = 1;
  
  // 使用APM滚动控制器(ApmScrollController)
  ScrollController _scrollController = ApmScrollController();
  bool isLoading = false;

  @override
  void initState() {
    super.initState();
    fetchData();

    _scrollController.addListener(() {
      if (_scrollController.position.pixels ==
          _scrollController.position.maxScrollExtent) {
        fetchData();
      }
    });
  }

  Future<void> fetchData() async {
    if (!isLoading) {
      setState(() {
        isLoading = true;
      });

      // Simulating a delay of 2 seconds
      await Future.delayed(Duration(seconds: 2));

      final List<String> urls = [
        'https://www.example.cn/community/01jz5vsgfkgclicuhmruvn3633.jpg',
        .......
 
      ];

      try {
        setState(() {
          imageUrls.addAll(urls);
          isLoading = false;
        });
      } catch (e) {}
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Scroll Lazy Load Demo'),
      ),
      body: GridView.builder(
        controller: _scrollController,
        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
          crossAxisCount: 2,
          mainAxisSpacing: 10,
          crossAxisSpacing: 10,
        ),
        itemCount: imageUrls.length + 1,
        itemBuilder: (context, index) {
          if (index == imageUrls.length) {
            return Center(
              child:
                  isLoading ? CircularProgressIndicator() : SizedBox.shrink(),
            );
          }
          return Card(
            child: Image.network(
              imageUrls[index],
              fit: BoxFit.cover,
            ),
          );
        },
      ),
    );
  }
}

3.2.5 自定义异常

captureException(类型:Function)

入参配置

含义

是否必传

类型

exception

异常摘要

是

Exception

stack

异常堆栈

否

String

extra

自定义属性

否

Map<String, dynamic>

案例一
import 'package:umeng_apm_sdk/umeng_apm_sdk.dart';

void main() {
	Isolate isolate = await Isolate.spawn(runIsolate, []);

 // 监听isolate异常
 isolate.addErrorListener(RawReceivePort((pair) {
 var error = pair[0];
 var stacktrace = pair[1];
 // 主动采集isolate异常
 ExceptionTrace.captureException(
 exception: Exception(error),
 stack: stacktrace.toString());
 
 }).sendPort);
}
案例二
import 'package:umeng_apm_sdk/umeng_apm_sdk.dart';

void main() {
	try {
 List<String> numList = ['1', '2'];
 print(numList[5]);
 } catch (e) {
 
 // 主动捕获上报代码执行异常
 ExceptionTrace.captureException(
 exception: Exception(e), extra: {"user": '123'});
 }
}

3.2.5 黑白名单设置 ErrorFilter

用于设置采集的项的黑白名单,可以在黑名单和白名单中选择其一,如果选择白名单的方式,那么只有符合标准的页面会被采集,如果选择的是黑名单的方式,那么符合标准的页面不会被采集

此项非必须参数,用于判断是否过滤日志,包含如下属性

属性

含义

默认

类型

mode

匹配模式

当值为ignore,表示黑名单模式,命中规则的不上报 当值为match,表示白名单模式命中规则的上报

ignore

枚举值 ignore|match

rules

匹配规则集合,当类型为数组时,表示规则集合,规则之间为或的关系,只要任意一个规则命中,则规则集命中。

[],该默认值表示黑名单为空,日志全部上报

Array<string | RegExp >

void main() {
 UmengApmSdk(
 name: '应用或者模块名称',
 // 过滤异常筛选
 errorFilter: {
 "mode": "match",
 "rules": [RegExp('RangeError')],
 }
 	....
 ).init(appRunner: (observer) 
 return MyApp(observer);
 });
}

步骤四、Native SDK 配置

注意:

集成Flutter SDK(已内置原生APM和Common SDK依赖)不需要在原生项目中引入原生SDK,如果您的原生项目中的Cocoapods或手动集成依赖库内存在友盟SDK依赖(原生UMCommon、原生UMAPM),需要删掉,否则可能会导致SDK冲突。

// Podfile
target 'UMPlusDemo'do
 // pod 'UMCommon'
 // pod 'UMAPM'
 // pod 'UMDevice'
end

4.1 iOS

4.1.1 初始化并开启原生采集开关配置项

重点关注:如果您还想采集Native 崩溃、ANR等日志可以参考下面设置

如下代码如需支持Swift 配置参考如下文档:https://developer.umeng.com/docs/193624/detail/194595#p-9wu-kzn-of8

U-APM iOS采集开关配置项(UMAPMConfig)说明请参考此文档:https://developer.umeng.com/docs/193624/detail/291394#h3-v47-jej-ofq

/** 初始化友盟所有组件产品接口函数
 @param appKey 开发者在友盟官网申请的appkey.
 @param channel 渠道标识,可设置nil表示"App Store".
 */
+(void)initWithAppkey:(NSString*)appkey channel:(NSString*)channel;

/************ 开始集成 ************/
// 在.m文件中加入如下代码
#import <UMCommon/UMCommon.h>
#import <UMAPM/UMCrashConfigure.h>
#import <UMAPM/UMLaunch.h>
#import <UMAPM/UMAPMConfig.h>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
 //在初始化appkey前调用,防止iOS13及以下同时使用NSURLProtocol和U-APM网络模块冲突。(未使用NSURLProtocol或者先初始化NSURLProtocol,可不调用此函数)
 //[UMCrashConfigure enableNetworkForProtocol:NO];
 UMAPMConfig* config = [UMAPMConfig defaultConfig];
 config.crashAndBlockMonitorEnable = YES;
 config.launchMonitorEnable = YES;
 config.memMonitorEnable = NO;
 config.oomMonitorEnable = NO;
 config.networkEnable = YES;
 [UMCrashConfigure setAPMConfig:config];//必须配置,请注意

	// flutter_module调用及同意隐私政策代码...

 // 务必要在同意隐私政策后初始化
 [UMConfigure initWithAppkey:@"这里填写您的Appkey" channel:@"App Store"];
 return YES;
}

⚠️ 注意

  • 已集成过iOS APM SDK的应用,请在工程环境下执行pod update 确保SDK 版本更新到1.8.4及以上

4.2 Android

注意:集成Flutter SDK不需要在原生项目中引入原生SDK,如果您的原生项目中的build.gradle存在友盟SDK依赖(原生com.umeng.umsdk:common、com.umeng.umsdk:asms、com.umeng.umsdk:apm),需要注释或者删掉,否则可能会导致SDK冲突。

// build.gradle
dependencies {
	/* 删除或注释原生项目有关友盟APM和Common相关的SDK,以下为示例 */
	// implementation 'com.umeng.umsdk:common:9.4.4'
 	// implementation 'com.umeng.umsdk:asms:1.4.1'
 	// implementation 'com.umeng.umsdk:apm:1.5.2'
 implementation 'androidx.appcompat:appcompat:1.6.1'
 implementation 'com.google.android.material:material:1.9.0'
 implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
 testImplementation 'junit:junit:4.13.2'
 androidTestImplementation 'androidx.test.ext:junit:1.1.5'
 androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
}

4.2.1 预初始化并开启原生采集开关配置项

如果App不能保证在Appcalition.onCreate函数中调用UMConfigure.init初始化函数,则必须在Appcalition.onCreate函数中调用此预初始化函数。对于有延迟初始化SDK需求的开发者(不能在Application.onCreate函数中调用UMConfigure.init初始化函数),必须在Application.onCreate函数中调用UMConfigure.preInit预初始化函数(preInit耗时极少,不会影响冷启动体验),而后UMConfigure.init函数可以按需延迟调用(可以放到后台线程中延时调用,可以延迟,但还是必须调用)。如果您的App已经是在Application.onCreate函数中调用UMConfigure.init进行初始化,则无需额外调用UMConfigure.preInit预初始化函数。

public static void preInit(Context context,String appkey,String channel)
<!-- 在AndroidManifest.xml中加入如下必须的权限 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
// 在.java文件中引入原生SDK包
import com.umeng.umcrash.UMCrash;
import com.umeng.commonsdk.UMConfigure;

// 在application.onCreate内配置各模块开关并预初始化SDK
Bundle bundle = new Bundle();

// 重点关注:如果您还想采集Native 崩溃、ANR等日志可以参考下面设置
bundle.putBoolean(UMCrash.KEY_ENABLE_CRASH_JAVA, true);
bundle.putBoolean(UMCrash.KEY_ENABLE_CRASH_NATIVE, true);
bundle.putBoolean(UMCrash.KEY_ENABLE_CRASH_ALL, true);
bundle.putBoolean(UMCrash.KEY_ENABLE_ANR, false);
bundle.putBoolean(UMCrash.KEY_ENABLE_PA, false);
bundle.putBoolean(UMCrash.KEY_ENABLE_LAUNCH, false);
bundle.putBoolean(UMCrash.KEY_ENABLE_MEM, false);
bundle.putBoolean(UMCrash.KEY_ENABLE_H5PAGE, false);
undle.putBoolean(UMCrash.KEY_ENABLE_POWER, false);
UMCrash.initConfig(bundle);
// 开启模块开关,上述模块开关一定要在init前调用。
UMConfigure.preInit(getApplicationContext(), "59892f08310c9307b60023d0", "UMENG", UMConfigure.DEVICE_TYPE_PHONE, "");


/************ 以下代码在纯Flutter项目中无需调用,flutter_module需要调用在预初始化后正式初始化SDK *************/

// 判断是否同意隐私协议,如果用户同意协议直接初始化umsdk,此处代码详情请参考demo https://github.com/umeng/MultiFunctionAndroidDemo
if (sharedPreferencesHelper.getSharedPreference("uminit", "").equals("1")) {
	//友盟正式初始化
 UmInitConfig umInitConfig = new UmInitConfig();
	umInitConfig.UMinit(getApplicationContext());
}

4.2.3 混淆设置

⚠️ 注意:Android下如果不设置忽略混淆,APM将无法正常运行

参考:接入与基础功能-混淆设置

步骤五、运行验证

恭喜您!至此,您的App已经成功接入了Flutter 监控啦。

接下来,可以运行您的APP,等待1到5分钟左右即可在平台上查看数据了!

因为设备采样率的关系,测试设备并一定会直接命中日志采样,所以我们需要在验证前将测试设备添加白名

单或者将Flutter PV采样率调至100%以确保测试设备可以命中日志采样

【PV采样率】解释:设备启动后产生的页面访问行为会采集异常、性能、帧率的日志,通过云配采样率控制以设备为维度的采集行为。例 PV采样率 5% 100台

设备通过端上的随机计算是否能命中那5%的概率,命中即可通过PV行为采集各类型日志。目前我们根据不同的应用权限提供了设备PV采样率和单设备日志最大条数上报的设置功能

⚠️ 提示:

  1. 免费版设备Flutter PV采样率 默认 5% 不可更改

  2. 专业版 设备Flutter PV采样率 最高 5% 尊享版设备最高可设置100% 可在 开通管理- 修改配置中 更改

  3. 支持单设备每天上报Dart异常日志的上限,免费版最高20条/天,专业版最高支持40条/天,尊享版最高支持120条/天

  4. 支持单设备每天上报性能(PV、页面性能&帧率)日志条数的上限 免费版最高支持200条/天,专业版最高支持500条/天,尊享版最高支持1000条/天

运行验证方式

使用权限

使用场景

采样生效时间

通用采样设备(设备白名单)

免费版、专业版、尊享版

对专门的单个或者多个测试设备进行验证

设置8小时后,设备重新冷启动生效

强制生效步骤

1. SDK初始化,获取umid

2. 将此设备的umid添加到采样白名单(线上缓存最多需要5分钟生效)

3. 不要卸载安装App,修改客户端时间为8小时后

4. 重新冷启动,即可拉取到最新云配置,此设备白名单功能生效

调整Flutter采样率至100%

专业版、尊享版

付费版应用权限下适合未上架应用对测试设备进行验证,采样率调整会对设置比例下的访问设备生效。

设置8小时后,设备重新冷启动生效

强制生效步骤

1. SDK初始化,获取umid

2. 将此设备的umid添加到采样白名单(线上缓存最多需要5分钟生效)

3. 不要卸载安装App,修改客户端时间为8小时后

4. 重新冷启动,即可拉取到最新云配置,此设备白名单功能生效

5.1 验证前准备方式一

5.1.1 打开设备通用采样设置

添加白名单设备不受采样率限制,可直接用来测试日志上报情况

DD798846-9C8F-400A-9F0D-209918B44AE9.png

5.1.2 添加采样设备白名单

  • 获取UMID 方式一 通过日志查看 (支持版本 v2.1.3)

    • lQLPJx7i_rOmwdfNBELNCq6wxy_vJZKZmNwFRg-NtoC0AA_2734_1090.png

  • 获取UMID 方式二通过脚本获取打印UMID

    • Android :UMConfigure.getUMIDString(this);

    • iOS:[UMConfigure umidString]

将获得的UMID 填写到应用后台 设备管理 -> 通用采样设置

7A4384FD-F7EC-4096-BECD-7E8D3021DDA9.png

⚠️ 注意:

  1. 设置完成后设备白名单状态更新8小时以内客户端可生效,请提前添加测试设备umid

希望强制生效参考如下

运行验证方式

使用权限

使用场景

采样生效时间

通用采样设备(设备白名单)

免费版、专业版、尊享版

对专门的单个或者多个测试设备进行验证

设置8小时后,设备重新冷启动生效

强制生效步骤

1. SDK初始化,获取umid

2. 将此设备的umid添加到采样白名单(线上缓存最多需要5分钟生效)

3. 不要卸载安装App,修改客户端时间为8小时后

4. 重新冷启动,即可拉取到最新云配置,此设备白名单功能生效

5.2 验证前准备方式二

5.2.1 调整采样率

调整Flutter分析PV采样率至100% (免费版无法操作)

07EA6360-8B23-4488-A222-337D556D62D0.png

运行验证方式

使用权限

使用场景

采样生效时间

调整Flutter采样率至100%

专业版、尊享版

付费版应用权限下适合未上架应用对测试设备进行验证,采样率调整会对设置比例下的访问设备生效。

设置8小时后,设备重新冷启动生效

强制生效

  1. 可通过更改设备8小时后时间,再次冷启动强制更新缓存,可立即生效

  2. 在后台设置完采样率 5分钟后,卸载应用,再次安装冷启动应用后,可立即生效

5.2 验证SDK运行

查看日志面板

FAC3DC4D-ACBC-48A5-A369-299207CCB92C.png