# 架构设计 ## 整体架构 ``` ┌──────────────────────────────────────────────────────┐ │ apps/quanxue apps/品牌B apps/品牌C │ 品牌应用层 │ (16 行 main.dart) │ 只传 ShellEnvironment ├──────────────────────────────────────────────────────┤ │ web_shell_core │ 核心库 │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ config │ │ engine │ │ bridge │ │ │ │ 环境配置 │ │ 兼容引擎 │ │ JS 桥接 │ │ │ └──────────┘ └──────────┘ └──────────┘ │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ services │ │ ui │ │ testing │ │ │ │ 宿主服务 │ │ 壳层界面 │ │ 测试钩子 │ │ │ └──────────┘ └──────────┘ └──────────┘ │ ├──────────────────────────────────────────────────────┤ │ CoreShellActivity (Java) │ 原生层 │ 进程隔离 · WebView 信息查询 · 深度重置 │ └──────────────────────────────────────────────────────┘ ``` ## 核心流程 ### 1. 启动流程 ``` main() → runShellApp(env) → WidgetsFlutterBinding.ensureInitialized() → 设置屏幕方向(竖屏锁定) → 进入沉浸式模式 → runApp(ShellApp) → Android? → WebShellPage(WebView 容器) → 其他? → UnsupportedPlatformPage(兜底页) ``` ### 2. WebView 启动与恢复 ``` WebShellPage.initState() → 查询 Android WebView 信息(SDK / 包名 / 版本号) → 生成兼容性策略(renderModes / useWideViewPort / aggressiveRecovery) → 创建 WebView(默认 texture 模式) → 首帧就绪后加载初始 URL → 启动看门狗计时器 → 超时? → 切换渲染模式(hybrid)→ 深度清理 → 自动重试 → 再超时? → 展示错误页 + 兼容性提示 ``` ### 3. JS Bridge 协议 ``` H5 页面 Flutter 壳 │ │ │ AppShellChannel. │ │ postMessage(JSON) │ │ ──────────────────────→ │ 解析 action + payload │ │ 执行对应 handler │ window. │ │ __appShellReceiveResponse│ │ ←────────────────────── │ 返回 { requestId, success, data/error } ``` **支持的 Action:** | Action | 说明 | 返回 | |---|---|---| | `pickImage` | 从图库选图(支持多选) | `[{name, uri, mimeType, size, dataUrl}]` | | `captureImage` | 相机拍照 | `{name, uri, mimeType, size, dataUrl}` | | `pickFile` | 文件选择 | `[{name, uri, mimeType, size, dataUrl}]` | | `openExternal` | 打开外部应用 | `boolean` | | `requestPermissions` | 请求系统权限 | `{type: statusName}` | | `reloadPage` | 重新加载当前页面 | `true` | | `goBack` | 返回上一页 | `boolean` | | `closeApp` | 关闭应用 | 无(直接退出) | ## 兼容性策略 | 条件 | 渲染模式 | 恢复策略 | |---|---|---| | SDK ≥ 29 + WebView ≥ 113 | texture 优先 | 标准恢复 | | SDK ≤ 28 或 WebView < 113 | hybrid 优先 | 激进恢复(2 次重试) | | F136A 设备 | hybrid 优先 | 激进恢复 + 建议更新 WebView | ## 新增品牌 1. 创建 `flavors/品牌名.yaml` 2. 运行 `dart run tool/generate_app.dart 品牌名` 3. 脚本自动生成完整的 Flutter App 在 `apps/品牌名/` 4. 修改图标后运行 `flutter pub run flutter_launcher_icons` 5. 构建 APK:`flutter build apk --release`