app_bootstrap.dart 3.79 KB
import 'dart:async';

import 'package:doublefeel_flutter/core/logging/app_diagnostic_log_store.dart';
import 'package:flutter/widgets.dart';
import 'package:get/get.dart';

import '../../core/config/app_environment_config.dart';
import '../../core/logging/app_logger.dart';
import '../../core/network/user_agent_provider.dart';
import '../../core/services/user_state_service.dart';
import '../../core/services/app_config_service.dart';
import '../../data/local/local_storage.dart';
import '../../data/local/user_account_storage.dart';
import '../../data/local/user_preferences_storage.dart';
import '../../core/services/loading_service.dart';
import '../../core/services/native_health_data_update_bridge.dart';
import '../../core/services/raw_data_service/platform_ios/apple_health_raw_data_core_service.dart';
import '../bindings/initial_binding.dart';

/// Application startup before [runApp].
abstract final class AppBootstrap {
  static Future<void> init() async {
    WidgetsFlutterBinding.ensureInitialized();
    AppleHealthRawDataCoreService.setExecutionEngineType('main');
    AppLogger.init();

    await UserAgentProvider.init();

    final local = await LocalStorage.open();

    final environmentConfig = AppEnvironmentConfig(local);
    await environmentConfig.init();

    final userPreferencesStorage =
        UserPreferencesStorage(local.sharedPreferences);
    await userPreferencesStorage.init();

    final userAccountStorage = UserAccountStorage(local.sharedPreferences);

    InitialBinding(
      environmentConfig: environmentConfig,
      userPreferencesStorage: userPreferencesStorage,
      userAccountStorage: userAccountStorage,
      localStorage: local,
    ).dependencies();

    // `UserPreferencesStorage.init` runs before GetX dependencies exist. Sync
    // here so every cold start invokes native `updateLoginInfo` after the
    // PlatformHostApi and HealthRawDataCoreService are ready.
    await userPreferencesStorage.syncLoginInfoToNative();

    NativeHealthDataUpdateBridge.initialize();

    LoadingService.init();

    if (local.termsAgreed) {
      await Get.find<UserStateService>().initializeSdks();
      unawaited(AppConfigService.to.fetch());
    }
  }

  static Future<void> initForBackground() async {
    WidgetsFlutterBinding.ensureInitialized();
    AppleHealthRawDataCoreService.setExecutionEngineType('temporary');
    AppLogger.init();

    await UserAgentProvider.init();

    final local = await LocalStorage.open();

    final environmentConfig = AppEnvironmentConfig(local);
    await environmentConfig.init();
    // 1. 【核心】只读取已保存的地区与环境,不要在后台调用 _detectRegion() 重新探测并写入 SharedPreferences,防止误切海外服
    // environmentConfig.environment.value = await local.readEnvironment();
    // environmentConfig.region.value =
    //     await local.readRegion() ?? AppRegion.china;

    final userPreferencesStorage =
        UserPreferencesStorage(local.sharedPreferences);
    await userPreferencesStorage.init();

    final userAccountStorage = UserAccountStorage(local.sharedPreferences);

    InitialBinding(
      environmentConfig: environmentConfig,
      userPreferencesStorage: userPreferencesStorage,
      userAccountStorage: userAccountStorage,
      localStorage: local,
    ).dependencies();

    await userPreferencesStorage.syncLoginInfoToNative();

    NativeHealthDataUpdateBridge.initialize();
    // 2. 后台无 UI,不需要初始化全局 Loading 弹窗
    LoadingService.init();
    // 3. 后台计算不需要重复初始化融云/分析等前台 SDK
    if (local.termsAgreed) {
      await Get.find<UserStateService>().initializeSdks();
      unawaited(AppConfigService.to.fetch());
    }
    AppDiagnosticLogStore.instance.log(
      category: 'initForBackground',
      action: 'success',
      details: {},
    );
  }
}