160 lines
4.7 KiB
Dart
160 lines
4.7 KiB
Dart
import 'dart:async';
|
||
|
||
import 'package:flutter/widgets.dart';
|
||
|
||
import 'package:yx_tracking_flutter/src/config/analytics_config.dart';
|
||
import 'package:yx_tracking_flutter/src/core/analytics_core.dart';
|
||
import 'package:yx_tracking_flutter/src/core/interceptors.dart';
|
||
import 'package:yx_tracking_flutter/src/model/device_info.dart';
|
||
import 'package:yx_tracking_flutter/src/model/recent_event_summary.dart';
|
||
import 'package:yx_tracking_flutter/src/model/user_info.dart';
|
||
|
||
export 'src/config/analytics_config.dart';
|
||
export 'src/core/interceptors.dart';
|
||
export 'src/model/device_info.dart';
|
||
export 'src/model/event.dart';
|
||
export 'src/model/recent_event_summary.dart';
|
||
export 'src/model/user_info.dart';
|
||
|
||
/// 对外唯一入口(Facade)。
|
||
class Analytics {
|
||
/// 私有构造,避免外部实例化。
|
||
Analytics._();
|
||
|
||
/// 获取一个实例(用于满足 lint 对构造器的要求)。
|
||
factory Analytics.instance() => Analytics._();
|
||
|
||
static AnalyticsCore _core = AnalyticsCore();
|
||
static _AnalyticsLifecycleObserver? _lifecycleObserver;
|
||
|
||
@visibleForTesting
|
||
|
||
/// 测试钩子:读取当前核心实现。
|
||
static AnalyticsCore get coreForTesting => _core;
|
||
|
||
@visibleForTesting
|
||
|
||
/// 测试钩子:覆盖内部核心实现。
|
||
static set coreForTesting(AnalyticsCore core) => _core = core;
|
||
|
||
/// 初始化 SDK。
|
||
static Future<void> init(AnalyticsConfig config) => _core.init(config);
|
||
|
||
/// 记录事件。
|
||
static Future<void> track(
|
||
String eventType, {
|
||
Map<String, dynamic>? eventParams,
|
||
Map<String, dynamic>? customTags,
|
||
int? timestamp,
|
||
}) {
|
||
return _core.track(
|
||
eventType,
|
||
eventParams: eventParams,
|
||
customTags: customTags,
|
||
timestamp: timestamp,
|
||
);
|
||
}
|
||
|
||
/// 设置用户信息。
|
||
static Future<void> setUser(UserInfo? userInfo) => _core.setUser(userInfo);
|
||
|
||
/// 覆盖设备信息。
|
||
static Future<void> setDeviceInfo(DeviceInfo deviceInfo) =>
|
||
_core.setDeviceInfo(deviceInfo);
|
||
|
||
/// 触发一次上报。
|
||
static Future<void> flush({bool force = false}) => _core.flush(force: force);
|
||
|
||
/// 当前本地缓存事件数量(用于调试/演示)。
|
||
static Future<int> cachedEventCount() => _core.cachedEventCount();
|
||
|
||
/// 最近事件摘要(用于调试面板)。
|
||
static Future<List<RecentEventSummary>> cachedRecentEvents({
|
||
int limit = 20,
|
||
}) =>
|
||
_core.cachedRecentEvents(limit: limit);
|
||
|
||
/// Phase 2:手动触发一次配置刷新(默认强制刷新)。
|
||
static Future<void> refreshConfig({bool force = true}) =>
|
||
_core.refreshConfig(force: force);
|
||
|
||
/// Phase 3:立即上报一次 SDK 指标(调试/测试用)。
|
||
static Future<void> reportMetricsNow() => _core.reportMetricsNow();
|
||
|
||
/// Phase 3:注册事件拦截器。
|
||
static void addInterceptor(AnalyticsInterceptor interceptor) {
|
||
_core.addInterceptor(interceptor);
|
||
}
|
||
|
||
/// 动态设置 Debug 开关。
|
||
static void setDebug({required bool enabled}) {
|
||
unawaited(_core.setDebug(enabled: enabled));
|
||
}
|
||
|
||
/// 可选:当宿主确定不再需要 SDK 时调用。
|
||
static Future<void> dispose() async {
|
||
unbindLifecycleObserver();
|
||
await _core.dispose();
|
||
}
|
||
|
||
/// 可选:绑定应用生命周期监听,进入后台时自动 flush。
|
||
static void bindLifecycleObserver({
|
||
bool flushOnBackground = true,
|
||
bool flushOnDetached = true,
|
||
}) {
|
||
if (_lifecycleObserver != null) {
|
||
return;
|
||
}
|
||
WidgetsFlutterBinding.ensureInitialized();
|
||
final observer = _AnalyticsLifecycleObserver(
|
||
flushOnBackground: flushOnBackground,
|
||
flushOnDetached: flushOnDetached,
|
||
onFlush: () {
|
||
unawaited(_core.flush(force: true));
|
||
},
|
||
);
|
||
_lifecycleObserver = observer;
|
||
WidgetsBinding.instance.addObserver(observer);
|
||
}
|
||
|
||
/// 解绑生命周期监听,避免重复注册或泄漏。
|
||
static void unbindLifecycleObserver() {
|
||
final observer = _lifecycleObserver;
|
||
if (observer == null) {
|
||
return;
|
||
}
|
||
WidgetsBinding.instance.removeObserver(observer);
|
||
_lifecycleObserver = null;
|
||
}
|
||
}
|
||
|
||
class _AnalyticsLifecycleObserver extends WidgetsBindingObserver {
|
||
_AnalyticsLifecycleObserver({
|
||
required this.flushOnBackground,
|
||
required this.flushOnDetached,
|
||
required this.onFlush,
|
||
});
|
||
|
||
final bool flushOnBackground;
|
||
final bool flushOnDetached;
|
||
final VoidCallback onFlush;
|
||
|
||
@override
|
||
void didChangeAppLifecycleState(AppLifecycleState state) {
|
||
switch (state) {
|
||
case AppLifecycleState.inactive:
|
||
case AppLifecycleState.paused:
|
||
case AppLifecycleState.hidden:
|
||
if (flushOnBackground) {
|
||
onFlush();
|
||
}
|
||
case AppLifecycleState.detached:
|
||
if (flushOnDetached) {
|
||
onFlush();
|
||
}
|
||
case AppLifecycleState.resumed:
|
||
break;
|
||
}
|
||
}
|
||
}
|