web_shell_flutter/doc/architecture.md

4.4 KiB
Raw Blame History

架构设计

整体架构

┌──────────────────────────────────────────────────────┐
│  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? → WebShellPageWebView 容器)
    → 其他?   → 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. 构建 APKflutter build apk --release