Skip to content

Flutter SDK 高级功能 ​


域名管理与自动测速 ​

SDK 通过 SdkInitConfig.baseDomain 获取「上报域名列表文件」,并发测速选择最快域名作为实际上报域名。

核心行为 ​

  • 初始化或调用 refreshDomainConfig() 时:
    • 使用 baseDomain 请求域名列表文件
    • 支持 JSON 数组或文本多行(每行一个/多个域名,逗号分隔)
    • 对所有候选域名发送 HEAD 请求测速,过滤掉不可达域名
    • 选择耗时最短的域名作为上报域名,并更新内部上报 URL
  • 运行期间:
    • 每隔 SdkConfig.domainRefreshInterval(默认 20 分钟)自动刷新域名列表并重新测速
    • 刷新成功且最快域名变化时,通过回调更新上报 URL

域名列表接口 ​

baseDomain 类型说明
「配置域名」:https://config.xxx.com域名列表接口:{baseDomain}/sdk/getAvailableDomainList?appId={appId};事件类型配置接口:{baseDomain}/sdk/getAllEventCode?appId={appId}
完整 URL:https://cdn.xxx.com/domain_list.json域名列表:直接请求该 URL;事件类型配置:从 URL 的 host 拼接固定路径

常用代码 ​

dart
// 启动时配置
SdkInitConfig.configure(baseDomain: 'https://config.your-company.com');

// 可选:后续拿到新配置时刷新
await AnalyticsSdk.instance.refreshDomainConfig();

事件类型配置 ​

SDK 从 baseDomain 拉取启用的事件类型列表,自动决定哪些事件需要上报,对业务方完全透明。

工作原理 ​

  1. 初始化时:从服务端拉取事件类型配置;拉取失败时尝试本地缓存;两者都没有时允许所有事件上报(向后兼容)
  2. 事件上报时:检查事件类型是否在配置中启用;未启用的事件自动过滤,不占用队列和网络
  3. 定时更新:每 10 分钟自动拉取最新配置;更新成功后保存到本地缓存;更新失败不影响当前配置

服务端配置示例 ​

json
[
  "app_page_view",
  "ad_impression",
  "video_event",
  "novel_event",
  "comic_event"
]

未在列表中的事件类型会被 SDK 静默过滤,控制台会输出「事件类型未在配置中启用」的提示。

手动刷新配置(可选) ​

dart
import 'package:analytics_sdk/manager/event_type_config_manager.dart';

// 立即拉取最新配置
await EventTypeConfigManager.instance.fetchAndUpdateConfig();

// 检查某个事件类型是否启用
bool isEnabled = EventTypeConfigManager.instance.isEventTypeEnabled('app_page_view');

// 获取所有启用的事件类型
Set<String> enabledTypes = EventTypeConfigManager.instance.enabledEventTypes;

用户类型管理 ​

dart
import 'package:analytics_sdk/enum/user_type_enum.dart';

// 用户登录时设置用户 ID 和类型
AnalyticsSdk.setUserIdAndType(
  userId: 'user_123',
  userTypeEnum: UserTypeEnum.vip,
);

// 仅更新用户类型(登录、升级会员、切换账号时调用)
AnalyticsSdk.instance.updateUserType(UserTypeEnum.vip.label);

// 用户登出(清空 uid 和 userType)
AnalyticsSdk.logoutUser();

sid(会话 ID)由 SessionManager 自动管理,无需手动干预。

自定义用户类型提供者 ​

dart
// 自定义用户类型提供者
AnalyticsSdk.userTypeProvider = () {
  // 从你的用户管理系统中获取当前用户类型
  if (UserService.isVip()) {
    return UserTypeEnum.vip.label;
  }
  return UserTypeEnum.normal.label;
};

页面名称映射 ​

SDK 提供 pageKey(页面标识)→ pageName(页面名称)的映射功能,供自动埋点和手动上报使用。

dart
import 'package:analytics_sdk/manager/page_name_manager.dart';

// 批量添加映射(推荐在 main() 中初始化)
PageNameMapper.addMappings({
  '/home': '首页',
  '/video_detail': '视频详情页',
  '/user_center': '个人中心',
  '/discover': '发现页',
});

// 添加单个映射
PageNameMapper.addMapping('home', '首页');

// 获取页面名称
String pageName = PageNameMapper.getPageName('home'); // 返回 '首页'

动态获取当前页面信息 ​

dart
import 'package:analytics_sdk/observer/page_lifecycle_observer.dart';
import 'package:analytics_sdk/manager/page_name_manager.dart';

// 获取当前页面的 pageKey
String currentPageKey = PageLifecycleObserver.currentPageKey;

// 通过 pageKey 获取对应的 pageName
String currentPageName = PageNameMapper.getPageName(currentPageKey);

// 在手动上报事件时使用
AnalyticsSdk.instance.track(AdImpressionEvent(
  pageKey: PageLifecycleObserver.currentPageKey,
  pageName: PageNameMapper.getPageName(PageLifecycleObserver.currentPageKey),
  adSlotKey: 'home_banner_1',
  adSlotName: '首页顶部Banner',
  adId: 'ad_123',
  adType: 'banner',
));

PageLifecycleObserver.currentPageKey 会在页面导航时自动更新;如果当前页面没有设置路由名称,可能返回默认值 /main 或空字符串。


事件数据结构 ​

所有事件上报时都包含以下公共字段(自动生成):

json
{
  "event": "event_type",
  "event_id": "md5_hash",
  "channel": "official",
  "app_id": "your_app_id",
  "uid": "user_123",
  "sid": "session_id",
  "client_ts": 1234567890,
  "device": "android",
  "device_id": "device_123",
  "device_brand": "Xiaomi",
  "device_model": "Mi 10",
  "payload": {
    // 具体事件的字段...
  }
}

event_id 生成规则: 基于事件的所有关键字段计算 MD5 值,相同内容生成相同 event_id,供服务端去重使用。


上报机制 ​

批量上报 ​

触发条件默认值
队列达到阈值20 条
定时触发每 20 秒
手动触发AnalyticsSdk.instance.flush()

本地持久化 ​

  • 启用后,事件自动保存到本地文件(data_plus_events_cache.jsonl)
  • 文件存储在应用文档目录,使用 JSONL 格式(每行一个 JSON 对象)
  • 应用重启后自动从缓存恢复事件并上报
  • 上报成功后自动清除缓存文件

重试机制 ​

  • 上报失败后使用指数退避算法重试
  • 初始延迟 2 秒,最大延迟 60 秒
  • 最大退避级别为 5
  • 成功上报后自动重置退避状态

事件去重 ​

  • 通用去重:每个事件都有唯一的 event_id(基于 MD5 计算),服务端可用于去重
  • 广告展示去重:客户端层面额外处理,同一广告 ID 只上报一次(详见广告事件)