主要变更: 1. 新增多风格音效资源与管理文档 2. 修复翻译服务空响应处理与Dio日志异常捕获 3. 完善Web端平台适配与路径获取Stub 4. 优化设备配对与文件传输功能 5. 新增角色命名常量与摇一摇检测器 6. 修复Riverpod dispose与鸿蒙导航路由 7. 新增每日通知服务与流体着色器 8. 优化备份服务与数据管理页面 9. 新增隐私设置附近设备发现选项 10. 重构诗词提供者支持历史记录 11. 完善桌面端构建配置与开发脚本 12. 清理旧版工具部署脚本
308 lines
9.9 KiB
Dart
308 lines
9.9 KiB
Dart
// ============================================================
|
|
// 闲言APP — 应用入口
|
|
// 创建时间: 2026-04-20
|
|
// 更新时间: 2026-05-20
|
|
// 作用: main 函数,初始化存储 + 液态玻璃 + 异常捕获 + 启动 App
|
|
// 上次更新: v6.7 修复Zone mismatch(ensureInitialized移入runZonedGuarded内)+Web端path_provider守卫
|
|
// ============================================================
|
|
|
|
import 'dart:async';
|
|
import 'dart:isolate' if (dart.library.js) 'core/utils/isolate_stub.dart';
|
|
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import 'package:catcher_2/catcher_2.dart';
|
|
import 'package:catcher_2/model/platform_type.dart';
|
|
import 'package:liquid_glass_widgets/liquid_glass_widgets.dart';
|
|
import 'package:flutter/services.dart';
|
|
|
|
import 'app/app.dart';
|
|
import 'core/services/network/deep_link_service.dart';
|
|
import 'core/services/notification/local_notification_service.dart';
|
|
import 'core/services/device/screen_wake_service.dart';
|
|
import 'core/services/readlater/sharing_receiver_service.dart';
|
|
import 'core/services/sound_service.dart';
|
|
import 'core/services/device/battery_optimization_service.dart';
|
|
import 'core/services/notification/readlater_reminder_service.dart';
|
|
import 'core/services/data/home_widget_service.dart';
|
|
import 'core/services/clipboard_monitor_service.dart';
|
|
import 'core/storage/app_kv_store.dart';
|
|
import 'core/storage/kv_storage.dart';
|
|
import 'core/utils/logger.dart';
|
|
import 'core/utils/platform_utils.dart' as pu;
|
|
import 'core/registry/page_registry.dart';
|
|
import 'core/router/app_router.dart';
|
|
import 'editor/services/3d/platform_3d_service.dart';
|
|
import 'features/inspiration/services/chat_migration_service.dart';
|
|
|
|
bool kvStorageReady = false;
|
|
bool _liquidGlassReady = false;
|
|
|
|
bool get liquidGlassReady => _liquidGlassReady;
|
|
|
|
void main() async {
|
|
runZonedGuarded(
|
|
() async {
|
|
WidgetsFlutterBinding.ensureInitialized();
|
|
|
|
if (pu.isOhos) Log.i('🟢 [OHOS] main() 开始执行');
|
|
|
|
FlutterError.onError = (FlutterErrorDetails details) {
|
|
FlutterError.presentError(details);
|
|
Log.e(
|
|
'🔥 FlutterError.onError',
|
|
details.exceptionAsString(),
|
|
details.stack,
|
|
);
|
|
};
|
|
|
|
if (!pu.isWeb) {
|
|
Isolate.current.addErrorListener(
|
|
RawReceivePort((Object? pair) {
|
|
final List<dynamic> errorAndStacktrace = pair as List<dynamic>;
|
|
Log.e(
|
|
'🔥 Isolate uncaught error',
|
|
errorAndStacktrace.first,
|
|
StackTrace.fromString(errorAndStacktrace.last.toString()),
|
|
);
|
|
}).sendPort,
|
|
);
|
|
}
|
|
|
|
if (!pu.isWeb) {
|
|
SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge);
|
|
SystemChrome.setSystemUIOverlayStyle(
|
|
const SystemUiOverlayStyle(
|
|
statusBarColor: Colors.transparent,
|
|
statusBarIconBrightness: Brightness.dark,
|
|
statusBarBrightness: Brightness.light,
|
|
systemNavigationBarColor: Colors.transparent,
|
|
systemNavigationBarIconBrightness: Brightness.dark,
|
|
systemNavigationBarDividerColor: Colors.transparent,
|
|
),
|
|
);
|
|
}
|
|
if (pu.isOhos) Log.i('🟢 [OHOS] SystemChrome 配置完成');
|
|
|
|
try {
|
|
await KvStorage.init();
|
|
kvStorageReady = true;
|
|
if (pu.isOhos) Log.i('🟢 [OHOS] KvStorage 初始化完成');
|
|
} catch (e, st) {
|
|
Log.e('KV 存储初始化失败', e, st);
|
|
}
|
|
|
|
try {
|
|
await AppKVStore.init();
|
|
if (pu.isOhos) Log.i('🟢 [OHOS] AppKVStore 初始化完成');
|
|
} catch (e, st) {
|
|
Log.e('AppKVStore 初始化失败', e, st);
|
|
}
|
|
|
|
try {
|
|
await LiquidGlassWidgets.initialize();
|
|
_liquidGlassReady = true;
|
|
Log.i('LiquidGlassWidgets 初始化完成 (ohos=${pu.isOhos})');
|
|
} catch (e, st) {
|
|
Log.e('LiquidGlassWidgets 初始化失败', e, st);
|
|
}
|
|
|
|
try {
|
|
await Platform3DService.instance.detectDeviceCapability();
|
|
if (pu.isOhos)
|
|
Log.i(
|
|
'🟢 [OHOS] 3D设备检测完成 (lowEnd=${Platform3DService.instance.isLowEnd})',
|
|
);
|
|
} catch (e, st) {
|
|
Log.e('3D平台设备检测失败', e, st);
|
|
}
|
|
|
|
try {
|
|
_validatePageRegistry();
|
|
} catch (e, st) {
|
|
Log.e('页面注册表验证失败', e, st);
|
|
}
|
|
|
|
if (!pu.isWeb) {
|
|
try {
|
|
await DeepLinkService.init();
|
|
if (pu.isOhos) Log.i('🟢 [OHOS] 深度链接服务初始化完成');
|
|
} catch (e, st) {
|
|
Log.e('深度链接服务初始化失败', e, st);
|
|
}
|
|
}
|
|
|
|
if (!pu.isWeb) {
|
|
try {
|
|
SharingReceiverService().init();
|
|
SharingReceiverService().setNavigatorKey(rootNavigatorKey);
|
|
if (pu.isOhos) Log.i('🟢 [OHOS] 分享接收服务初始化完成');
|
|
} catch (e, st) {
|
|
Log.e('分享接收服务初始化失败', e, st);
|
|
}
|
|
}
|
|
|
|
if (!pu.isWeb) {
|
|
try {
|
|
await LocalNotificationService.init();
|
|
if (pu.isOhos) Log.i('🟢 [OHOS] 本地通知服务初始化完成');
|
|
} catch (e, st) {
|
|
Log.e('本地通知服务初始化失败', e, st);
|
|
}
|
|
}
|
|
|
|
if (!pu.isWeb) {
|
|
try {
|
|
await ScreenWakeService.init();
|
|
if (pu.isOhos) Log.i('🟢 [OHOS] 屏幕常亮服务初始化完成');
|
|
} catch (e, st) {
|
|
Log.e('屏幕常亮服务初始化失败', e, st);
|
|
}
|
|
}
|
|
|
|
try {
|
|
await SoundService.init();
|
|
if (pu.isOhos) Log.i('🟢 [OHOS] 音效服务初始化完成');
|
|
} catch (e, st) {
|
|
Log.e('音效服务初始化失败', e, st);
|
|
}
|
|
|
|
if (!pu.isWeb) {
|
|
try {
|
|
await BatteryOptimizationService.init();
|
|
if (pu.isOhos) Log.i('🟢 [OHOS] 电池优化服务初始化完成');
|
|
} catch (e, st) {
|
|
Log.e('电池优化服务初始化失败', e, st);
|
|
}
|
|
}
|
|
|
|
if (!pu.isWeb) {
|
|
try {
|
|
await ReadlaterReminderService.startMonitoring();
|
|
if (pu.isOhos) Log.i('🟢 [OHOS] 稍后读提醒服务初始化完成');
|
|
} catch (e, st) {
|
|
Log.e('稍后读提醒服务初始化失败', e, st);
|
|
}
|
|
}
|
|
|
|
try {
|
|
await ChatMigrationService.migrateIfNeeded();
|
|
if (pu.isOhos) Log.i('🟢 [OHOS] 聊天数据迁移检查完成');
|
|
} catch (e, st) {
|
|
Log.e('聊天数据迁移检查失败', e, st);
|
|
}
|
|
|
|
if (!pu.isWeb) {
|
|
try {
|
|
await HomeWidgetService.instance.init();
|
|
if (pu.isOhos) Log.i('🟢 [OHOS] 桌面小组件服务初始化完成');
|
|
} catch (e, st) {
|
|
Log.e('桌面小组件服务初始化失败', e, st);
|
|
}
|
|
}
|
|
|
|
if (!pu.isWeb) {
|
|
try {
|
|
await ClipboardMonitorService.instance.initFromStore();
|
|
if (pu.isOhos) Log.i('🟢 [OHOS] 剪贴板监控服务初始化完成');
|
|
} catch (e, st) {
|
|
Log.e('剪贴板监控服务初始化失败', e, st);
|
|
}
|
|
}
|
|
|
|
if (pu.isOhos) {
|
|
Log.i('🟢 [OHOS] 所有服务初始化完成,准备 runApp (liquidGlass=$_liquidGlassReady)');
|
|
const app = ProviderScope(child: XianyanApp());
|
|
if (_liquidGlassReady) {
|
|
Catcher2(
|
|
runAppFunction: () {
|
|
runApp(LiquidGlassWidgets.wrap(child: app));
|
|
},
|
|
debugConfig: Catcher2Options(
|
|
SilentReportMode(),
|
|
[_RateLimitedHandler()],
|
|
localizationOptions: [
|
|
LocalizationOptions.buildDefaultChineseOptions(),
|
|
],
|
|
),
|
|
releaseConfig: Catcher2Options(SilentReportMode(), []),
|
|
profileConfig: Catcher2Options(SilentReportMode(), []),
|
|
);
|
|
} else {
|
|
Catcher2(
|
|
runAppFunction: () {
|
|
runApp(app);
|
|
},
|
|
debugConfig: Catcher2Options(
|
|
SilentReportMode(),
|
|
[_RateLimitedHandler()],
|
|
localizationOptions: [
|
|
LocalizationOptions.buildDefaultChineseOptions(),
|
|
],
|
|
),
|
|
releaseConfig: Catcher2Options(SilentReportMode(), []),
|
|
profileConfig: Catcher2Options(SilentReportMode(), []),
|
|
);
|
|
}
|
|
Log.i('🟢 [OHOS] runApp() 已调用');
|
|
} else {
|
|
Catcher2(
|
|
runAppFunction: () {
|
|
const app = ProviderScope(child: XianyanApp());
|
|
runApp(LiquidGlassWidgets.wrap(child: app));
|
|
},
|
|
debugConfig: Catcher2Options(
|
|
SilentReportMode(),
|
|
[_RateLimitedHandler()],
|
|
localizationOptions: [
|
|
LocalizationOptions.buildDefaultChineseOptions(),
|
|
],
|
|
),
|
|
releaseConfig: Catcher2Options(SilentReportMode(), []),
|
|
profileConfig: Catcher2Options(SilentReportMode(), []),
|
|
);
|
|
}
|
|
},
|
|
(Object error, StackTrace stack) {
|
|
Log.e('🔥 Zone uncaught error', error, stack);
|
|
},
|
|
);
|
|
}
|
|
|
|
class _RateLimitedHandler extends ReportHandler {
|
|
DateTime? _lastLog;
|
|
static const _cooldown = Duration(seconds: 5);
|
|
|
|
@override
|
|
Future<bool> handle(Report report, BuildContext? context) async {
|
|
final now = DateTime.now();
|
|
if (_lastLog == null || now.difference(_lastLog!) > _cooldown) {
|
|
_lastLog = now;
|
|
Log.e('Catcher2: ${report.error}');
|
|
}
|
|
return true;
|
|
}
|
|
|
|
@override
|
|
List<PlatformType> getSupportedPlatforms() => PlatformType.values.toList();
|
|
|
|
@override
|
|
bool isContextRequired() => false;
|
|
}
|
|
|
|
void _validatePageRegistry() {
|
|
final errors = PageRegistry.validateAll();
|
|
if (errors.isNotEmpty) {
|
|
for (final e in errors) {
|
|
Log.e('页面注册表验证失败: $e');
|
|
}
|
|
} else {
|
|
Log.i('页面注册表验证通过,共 ${PageRegistry.pageCount} 个页面已注册');
|
|
}
|
|
|
|
const route = AppRoutes.home;
|
|
if (!PageRegistry.isRouteRegistered(route)) {
|
|
Log.e('页面注册表验证: 首页路由 $route 未注册!');
|
|
}
|
|
}
|