### 详细变更:
1. **文档与配置**:更新AGENTS.md添加命令超时约束,升级Rive依赖至0.14.7并替换平台插件引用
2. **UI优化**:重构AppInfo页面布局、移除图表冗余配置、锁定部分系统设置项
3. **功能增强**:
- 新增工具面板拖拽状态管理与介绍弹窗
- 新增进度页面编辑/重排/清空用户进度功能
- 新增摇一摇路由作用域拦截逻辑
4. **体验优化**:
- 统一外部链接跳转弹窗,添加文件打开确认逻辑
- 修复设备卡片IP溢出、Android权限声明问题
- 后台任务初始化增加协议校验
5. **代码重构**:拆分工具面板配置、拖拽逻辑与动画参数,优化状态管理代码
6. **工具脚本**:新增协议文件上传脚本
236 lines
7.4 KiB
Dart
236 lines
7.4 KiB
Dart
// ============================================================
|
||
// 闲言APP — 应用入口
|
||
// 创建时间: 2026-04-20
|
||
// 更新时间: 2026-05-30
|
||
// 作用: main 函数,初始化存储 + 液态玻璃 + 异常捕获 + 启动 App
|
||
// 上次更新: 拆分权限敏感初始化到PostAgreementInitializer,协议同意前不访问任何权限
|
||
// ============================================================
|
||
|
||
import 'dart:async';
|
||
import 'dart:isolate'
|
||
if (dart.library.js) 'core/utils/platform/isolate_stub.dart';
|
||
|
||
import 'package:flutter/material.dart';
|
||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||
import 'package:liquid_glass_widgets/liquid_glass_widgets.dart';
|
||
import 'package:flutter/services.dart';
|
||
import 'package:bitsdojo_window/bitsdojo_window.dart';
|
||
|
||
import 'app/app.dart';
|
||
import 'core/services/network/deep_link_service.dart';
|
||
import 'core/services/performance/performance_orchestrator.dart';
|
||
import 'core/services/error/crash_monitor.dart';
|
||
import 'core/services/device/haptic_service.dart';
|
||
import 'core/storage/kv_storage.dart';
|
||
import 'core/services/error/global_error_handler.dart';
|
||
import 'core/services/post_agreement_initializer.dart';
|
||
import 'core/utils/logger.dart';
|
||
import 'core/utils/platform/platform_utils.dart' as pu;
|
||
import 'core/registry/page_registry.dart';
|
||
import 'core/router/app_router.dart';
|
||
import 'core/services/catcher2_config_service.dart';
|
||
import 'editor/services/3d/platform_3d_service.dart';
|
||
import 'features/template/services/wallpaper_favorite_service.dart';
|
||
import 'features/template/services/wallpaper_health_service.dart';
|
||
import 'features/mine/settings/services/settings_change_logger.dart';
|
||
|
||
bool kvStorageReady = false;
|
||
bool _liquidGlassReady = false;
|
||
|
||
bool get liquidGlassReady => _liquidGlassReady;
|
||
|
||
void main() async {
|
||
runZonedGuarded(
|
||
() async {
|
||
WidgetsFlutterBinding.ensureInitialized();
|
||
|
||
if (pu.isDesktop) {
|
||
doWhenWindowReady(() {
|
||
appWindow.minSize = const Size(400, 600);
|
||
appWindow.title = '闲言';
|
||
appWindow.show();
|
||
});
|
||
}
|
||
|
||
if (pu.isOhos) Log.i('🟢 [OHOS] main() 开始执行');
|
||
|
||
FlutterError.onError = (FlutterErrorDetails details) {
|
||
FlutterError.presentError(details);
|
||
Log.e(
|
||
'🔥 FlutterError.onError',
|
||
details.exceptionAsString(),
|
||
details.stack,
|
||
);
|
||
};
|
||
|
||
GlobalErrorHandler.init();
|
||
|
||
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);
|
||
}
|
||
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 HapticService.init();
|
||
Log.i('触觉反馈服务初始化完成');
|
||
} catch (e, st) {
|
||
Log.e('触觉反馈服务初始化失败', e, st);
|
||
}
|
||
|
||
try {
|
||
await WallpaperFavoriteService.init();
|
||
Log.i('壁纸收藏服务初始化完成');
|
||
} catch (e, st) {
|
||
Log.e('壁纸收藏服务初始化失败', e, st);
|
||
}
|
||
|
||
try {
|
||
PerformanceOrchestrator.instance.init();
|
||
Log.i('PerformanceOrchestrator 初始化完成');
|
||
} catch (e, st) {
|
||
Log.e('PerformanceOrchestrator 初始化失败', 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);
|
||
}
|
||
}
|
||
|
||
try {
|
||
await CrashMonitor.instance.init();
|
||
Log.i('崩溃监控服务初始化完成');
|
||
} catch (e, st) {
|
||
Log.e('崩溃监控服务初始化失败', e, st);
|
||
}
|
||
|
||
try {
|
||
await WallpaperHealthService.init();
|
||
Log.i('壁纸源健康检测服务初始化完成');
|
||
} catch (e, st) {
|
||
Log.e('壁纸源健康检测服务初始化失败', e, st);
|
||
}
|
||
|
||
try {
|
||
await SettingsChangeLogger.init();
|
||
Log.i('设置变更日志服务初始化完成');
|
||
} catch (e, st) {
|
||
Log.e('设置变更日志服务初始化失败', e, st);
|
||
}
|
||
|
||
try {
|
||
if (WallpaperHealthService.shouldCheck()) {
|
||
WallpaperHealthService.checkAllSources();
|
||
}
|
||
} catch (e, st) {
|
||
Log.e('壁纸源健康检测启动检查失败', e, st);
|
||
}
|
||
|
||
if (PostAgreementInitializer.shouldInit()) {
|
||
Log.i('检测到老用户已完成引导,立即初始化权限敏感服务');
|
||
try {
|
||
await PostAgreementInitializer.init();
|
||
} catch (e, st) {
|
||
Log.e('老用户权限敏感服务初始化失败', e, st);
|
||
}
|
||
} else {
|
||
Log.i('新用户未同意协议,权限敏感服务延迟到协议同意后初始化');
|
||
}
|
||
|
||
if (pu.isOhos) {
|
||
Log.i('🟢 [OHOS] 所有服务初始化完成,准备 runApp (liquidGlass=$_liquidGlassReady)');
|
||
const app = ProviderScope(child: XianyanApp());
|
||
if (_liquidGlassReady) {
|
||
Catcher2ConfigService.instance.init(
|
||
runAppFunction: () {
|
||
runApp(LiquidGlassWidgets.wrap(child: app));
|
||
},
|
||
);
|
||
} else {
|
||
Catcher2ConfigService.instance.init(
|
||
runAppFunction: () {
|
||
runApp(app);
|
||
},
|
||
);
|
||
}
|
||
Log.i('🟢 [OHOS] runApp() 已调用');
|
||
} else {
|
||
Catcher2ConfigService.instance.init(
|
||
runAppFunction: () {
|
||
const app = ProviderScope(child: XianyanApp());
|
||
runApp(LiquidGlassWidgets.wrap(child: app));
|
||
},
|
||
);
|
||
}
|
||
},
|
||
(Object error, StackTrace stack) {
|
||
GlobalErrorHandler.handleZoneError(error, stack);
|
||
Log.e('🔥 Zone uncaught error', error, stack);
|
||
},
|
||
);
|
||
}
|
||
|
||
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 未注册!');
|
||
}
|
||
}
|