docs: 完善全部项目文档
- 重写根 README.md(项目结构 + 快速开始 + 品牌配置 + 调试说明 + 技术栈) - 重写 web_shell_core/README.md(功能表 + 使用方式 + 代码结构 + 测试 + 原生层) - 重写 apps/quanxue/README.md(品牌应用说明) - 更新 packages/web_android_shell/README.md(迁移通知) - 填充 web_shell_core/CHANGELOG.md(0.0.1 初始发布内容) - 新增 doc/architecture.md(分层架构 + 启动流程 + Bridge 协议 + 兼容策略) - 修正 pubspec.yaml 中的占位 description
This commit is contained in:
parent
97be25b332
commit
115713d8f4
88
README.md
88
README.md
|
|
@ -1,28 +1,86 @@
|
||||||
# web_android_shell
|
# web_android_shell
|
||||||
|
|
||||||
Android 平板专用 H5 壳项目。
|
Android 平板专用 H5 壳应用 — Monorepo 多品牌架构。
|
||||||
|
|
||||||
|
## 项目结构
|
||||||
|
|
||||||
|
```
|
||||||
|
web_android_shell/
|
||||||
|
├── apps/ # 品牌应用(每个品牌一个 Flutter App)
|
||||||
|
│ └── quanxue/ # 全学通
|
||||||
|
├── packages/
|
||||||
|
│ ├── web_shell_core/ # 核心库(WebView 引擎 + Bridge + 服务)
|
||||||
|
│ └── web_android_shell/ # 旧版入口(已迁移至 apps/quanxue)
|
||||||
|
├── flavors/ # 品牌配置 YAML
|
||||||
|
│ └── quanxue.yaml
|
||||||
|
├── tool/
|
||||||
|
│ ├── generate_app.dart # 一键生成新品牌应用
|
||||||
|
│ └── flutter_run_fresh.ps1 # Windows 调试脚本(自动杀旧进程)
|
||||||
|
└── doc/ # 项目文档
|
||||||
|
```
|
||||||
|
|
||||||
|
## 快速开始
|
||||||
|
|
||||||
|
### 1. 运行已有品牌
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd apps/quanxue
|
||||||
|
flutter run
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 生成新品牌
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1) 在 flavors/ 下创建品牌配置
|
||||||
|
cp flavors/quanxue.yaml flavors/新品牌.yaml
|
||||||
|
# 2) 修改配置中的 app_name, application_id, app_key, theme
|
||||||
|
# 3) 运行生成脚本
|
||||||
|
dart run tool/generate_app.dart 新品牌
|
||||||
|
```
|
||||||
|
|
||||||
|
生成脚本会自动完成:
|
||||||
|
- 创建 Flutter 应用 → `apps/新品牌/`
|
||||||
|
- 添加 `web_shell_core` 依赖
|
||||||
|
- 覆写 `MainActivity` 继承 `CoreShellActivity`
|
||||||
|
- 生成品牌入口 `main.dart`
|
||||||
|
- 配置 `flutter_launcher_icons`
|
||||||
|
|
||||||
|
### 3. 品牌配置格式
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
app_name: "全学通" # 应用名
|
||||||
|
application_id: "com.wanmake.quanxue" # 包名
|
||||||
|
app_key: "quanxue_prod" # 业务标识
|
||||||
|
theme:
|
||||||
|
accent_color: "0xFF3ED37B" # 主题色
|
||||||
|
bg_color: "0xFFFFFFFF" # 背景色
|
||||||
|
text_color: "0xFF1F2937" # 主文字色
|
||||||
|
muted_text_color: "0xFF6B7280" # 次要文字色
|
||||||
|
```
|
||||||
|
|
||||||
## 调试说明
|
## 调试说明
|
||||||
|
|
||||||
这个项目在部分设备上,如果直接用 `Ctrl+C` 结束 `flutter run`,设备里的上一次 App 进程可能还留在后台,下一次运行时会影响内嵌 WebView 启动。
|
部分教育平板设备使用 `Ctrl+C` 结束 `flutter run` 后,旧进程可能留在后台影响 WebView 启动。
|
||||||
|
|
||||||
更稳的做法:
|
**推荐做法:**
|
||||||
|
- 调试结束时在 `flutter run` 控制台按 `q` 退出
|
||||||
- 调试结束时优先在 `flutter run` 里按 `q`
|
- 或使用调试脚本自动杀旧进程再启动:
|
||||||
- 或者使用项目自带脚本,先自动杀掉旧进程再启动
|
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
.\tool\flutter_run_fresh.ps1
|
.\tool\flutter_run_fresh.ps1 # 自动选设备
|
||||||
|
.\tool\flutter_run_fresh.ps1 -d F136A # 指定设备
|
||||||
```
|
```
|
||||||
|
|
||||||
如果要指定设备,也可以继续透传给 `flutter run`:
|
## 技术栈
|
||||||
|
|
||||||
```powershell
|
| 组件 | 技术 |
|
||||||
.\tool\flutter_run_fresh.ps1 -d F136A
|
|---|---|
|
||||||
```
|
| 框架 | Flutter 3.x (Dart 3.11+) |
|
||||||
|
| WebView | `webview_flutter` + `webview_flutter_android` |
|
||||||
|
| 宿主能力 | `image_picker` · `file_picker` · `permission_handler` · `url_launcher` |
|
||||||
|
| 原生层 | Kotlin Plugin + Java `CoreShellActivity` |
|
||||||
|
| 代码规范 | `very_good_analysis` |
|
||||||
|
|
||||||
脚本会自动:
|
## 平台约束
|
||||||
|
|
||||||
- 读取 `android/local.properties` 中的 `sdk.dir`
|
**仅支持 Android 平板。** iOS / Web / Desktop 平台已移除。
|
||||||
- 调用 `adb shell am force-stop com.yuanxuan.webshell.web_android_shell`
|
|
||||||
- 然后执行 `flutter run`
|
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,35 @@
|
||||||
# quanxue
|
# 全学通 (quanxue)
|
||||||
|
|
||||||
A new Flutter project.
|
「全学通」品牌的 Android 平板 H5 壳应用。
|
||||||
|
|
||||||
## Getting Started
|
## 概述
|
||||||
|
|
||||||
This project is a starting point for a Flutter application.
|
本应用是 `web_shell_core` 核心库的品牌实例。`main.dart` 仅 16 行代码,只负责传入品牌配置,所有业务逻辑由核心库提供。
|
||||||
|
|
||||||
A few resources to get you started if this is your first Flutter project:
|
## 运行
|
||||||
|
|
||||||
- [Learn Flutter](https://docs.flutter.dev/get-started/learn-flutter)
|
```bash
|
||||||
- [Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
|
flutter run
|
||||||
- [Flutter learning resources](https://docs.flutter.dev/reference/learning-resources)
|
```
|
||||||
|
|
||||||
For help getting started with Flutter development, view the
|
## 配置
|
||||||
[online documentation](https://docs.flutter.dev/), which offers tutorials,
|
|
||||||
samples, guidance on mobile development, and a full API reference.
|
| 配置项 | 值 |
|
||||||
|
|---|---|
|
||||||
|
| 应用名 | 全学通 |
|
||||||
|
| 包名 | `com.wanmake.quanxue` |
|
||||||
|
| 业务标识 | `quanxue_prod` |
|
||||||
|
| 主题色 | `#3ED37B` |
|
||||||
|
|
||||||
|
品牌配置源文件:[`flavors/quanxue.yaml`](../../flavors/quanxue.yaml)
|
||||||
|
|
||||||
|
## 构建
|
||||||
|
|
||||||
|
```bash
|
||||||
|
flutter build apk --release
|
||||||
|
```
|
||||||
|
|
||||||
|
## 依赖
|
||||||
|
|
||||||
|
- `web_shell_core`(本地 path 引用)
|
||||||
|
- `cupertino_icons`(兼容历史代码)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
name: quanxue
|
name: quanxue
|
||||||
description: "A new Flutter project."
|
description: "全学通 — Android 平板 H5 壳应用。"
|
||||||
# 阻止误发布到 pub.dev。
|
# 阻止误发布到 pub.dev。
|
||||||
publish_to: 'none'
|
publish_to: 'none'
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,93 @@
|
||||||
|
# 架构设计
|
||||||
|
|
||||||
|
## 整体架构
|
||||||
|
|
||||||
|
```
|
||||||
|
┌──────────────────────────────────────────────────────┐
|
||||||
|
│ 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`
|
||||||
125
doc/plan.md
125
doc/plan.md
|
|
@ -1,125 +0,0 @@
|
||||||
# Role & Context
|
|
||||||
|
|
||||||
你是一个精通 Flutter 混合架构(Hybrid App)与移动端 APM(应用性能监控)的资深架构师。
|
|
||||||
|
|
||||||
当前任务:为一款基于“单工程多风味(Flavors)”架构的教育平板应用(包含“劝学”和“点智学”两个 Flavor)生成核心 MVP 代码框架与监控埋点方案。
|
|
||||||
|
|
||||||
底层环境约定:兼容 Android 14(量产基线)并向下兼容处理 Android 15 的 WindowInsets(Edge-to-Edge)特性。
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Product Architecture (Flutter 壳与 H5 的边界界定)
|
|
||||||
|
|
||||||
本 MVP 采用“瘦壳重网页”模式:
|
|
||||||
|
|
||||||
1. **Flutter 壳职责:** 仅负责生命周期管理、沉浸式/Kiosk 模式控制、设备硬件能力桥接(相机/录音/持久化存储)、全局骨架屏(Loading)、以及高可用 WebView 容器的维护。
|
|
||||||
|
|
||||||
2. **H5 职责:** 承载所有教学业务逻辑(题库、视频播放、个人中心)。
|
|
||||||
|
|
||||||
3. **通信机制:** 统一通过注入的 `JSBridge` 进行双向通信。
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# MVP Core Modules (核心功能模块需求)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## 1. 动态环境与配置引擎 (Config Engine)
|
|
||||||
|
|
||||||
- **需求:** 读取 `--dart-define=APP_FLAVOR`。
|
|
||||||
|
|
||||||
- **功能:** 根据 Flavor 动态下发不同的 `baseUrl`(H5 首页地址)、主题色、以及持久化缓存策略。
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## 2. 高可用 WebView 容器 (Core Web Container)
|
|
||||||
|
|
||||||
- **核心依赖:** 使用 `webview_flutter` 或 `flutter_inappwebview`。
|
|
||||||
|
|
||||||
- **Android 15 兼容性(关键):** WebView Widget 必须包裹在自定义的 `SafeArea` 或响应 `WindowInsets` 的布局中,将顶部的 `statusBarHeight` 和底部的 `navigationBarHeight` 动态获取,并作为 URL 参数或注入的 JS 变量传给 H5,供前端写 CSS 避让区。
|
|
||||||
|
|
||||||
- **Cookie 策略:** 必须显式开启 `Third-Party Cookies` 和 `DOM Storage`,确保跨域 SSO 单点登录不掉线。
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## 3. 标准化 JSBridge 协议层
|
|
||||||
|
|
||||||
要求实现一个健壮的 JSBridge 类,至少包含以下基础方法,供 H5 调用:
|
|
||||||
|
|
||||||
- `getDeviceInfo()`: 返回系统版本、电量、当前网络状态(WiFi/4G)。
|
|
||||||
|
|
||||||
- `setImmersiveMode(boolean)`: 控制隐藏/显示系统状态栏和底部导航栏。
|
|
||||||
|
|
||||||
- `openCamera(config)`: 唤起原生相机并返回 Base64 或文件路径。
|
|
||||||
|
|
||||||
- `reportEvent(eventName, params)`: H5 将核心业务埋点转发给 Flutter 壳进行统一上报。
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## 4. Kiosk Mode (专注模式/设备管控)
|
|
||||||
|
|
||||||
- 预留 `MethodChannel` 接口,命名为 `DeviceControlChannel`。
|
|
||||||
|
|
||||||
- 包含方法 `enableKioskMode()` 和 `disableKioskMode()`(具体 Android 原生端 `startLockTask` 逻辑暂用 TODO 占位,需定义好 Dart 侧的调用规范)。
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# APM & Observability Metrics (应用性能与稳定性指标体系)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
请在代码中创建一个 `AppMonitor` 单例类,负责拦截并上报以下三大类核心指标(目前先在控制台打印日志,预留后续接入 Firebase / Sentry / 自研后端的接口):
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## 1. 容器加载性能指标 (Performance)
|
|
||||||
|
|
||||||
- `Shell_Launch_Time`: Flutter 引擎初始化到原生首屏(Splash 结束)的耗时。
|
|
||||||
|
|
||||||
- `WebView_Init_Time`: 从触发加载到 WebView 实例创建完成的耗时。
|
|
||||||
|
|
||||||
- `H5_TTFB (Time to First Byte)`: Web 页面发出请求到收到第一个字节的耗时(需注入 JS 获取)。
|
|
||||||
|
|
||||||
- `H5_FCP (First Contentful Paint)`: 白屏时间(从 `onPageStarted` 到 `onPageFinished`,结合 JS 注入获取真实渲染时间)。
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## 2. 稳定性指标 (Stability)
|
|
||||||
|
|
||||||
- `WebView_Crash_Rate`: 捕获 `onWebResourceError`,特别是 `OOM`(内存溢出)导致的白屏终止。
|
|
||||||
|
|
||||||
- `JSBridge_Fail_Count`: 统计 H5 调用原生能力失败的次数与错误码(如权限被拒、参数格式错误)。
|
|
||||||
|
|
||||||
- `Http_Error_Rate`: 拦截并统计 WebView 内发生的 404/500 等静态资源或接口请求错误。
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## 3. 业务与设备指标 (Business & Device)
|
|
||||||
|
|
||||||
- `Session_Duration`: 从应用 `resumed` 到 `paused` 的有效停留时间。
|
|
||||||
|
|
||||||
- `Network_Switch_Count`: 监听网络状态,记录用户在弱网/断网环境下的掉线频次。
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Execution Steps for Code X (执行步骤)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
请一步步为我生成上述方案的代码骨架:
|
|
||||||
|
|
||||||
1. **Step 1:** 生成目录结构建议(基于 feature 驱动或分层架构)。
|
|
||||||
|
|
||||||
2. **Step 2:** 生成 `Config Engine` 与 `AppMonitor` 的单例类代码,实现核心指标的日志打印结构。
|
|
||||||
|
|
||||||
3. **Step 3:** 编写核心的 `HybridWebView` Widget,包含 Insets 处理、Cookie 策略配置和首屏加载时间计算。
|
|
||||||
|
|
||||||
4. **Step 4:** 编写 `JSBridge` 核心处理类,实现拦截 H5 消息并路由到对应原生方法的逻辑。
|
|
||||||
|
|
@ -1,28 +1,7 @@
|
||||||
# web_android_shell
|
# web_android_shell(已迁移)
|
||||||
|
|
||||||
H5 壳子项目。
|
> ⚠️ 本包为旧版入口,已迁移至 Monorepo 架构。
|
||||||
|
|
||||||
## 调试说明
|
当前用途:为旧版 `MainActivity` 提供壳层入口,调用 `web_shell_core` 启动应用。
|
||||||
|
|
||||||
这个项目在部分设备上,如果直接用 `Ctrl+C` 结束 `flutter run`,设备里的上一次 App 进程可能还留在后台,下一次运行时会影响内嵌 WebView 启动。
|
新品牌应用请使用 `apps/` 目录下的独立应用,参考 [`apps/quanxue/`](../../apps/quanxue/)。
|
||||||
|
|
||||||
更稳的做法:
|
|
||||||
|
|
||||||
- 调试结束时优先在 `flutter run` 里按 `q`
|
|
||||||
- 或者使用项目自带脚本,先自动杀掉旧进程再启动
|
|
||||||
|
|
||||||
```powershell
|
|
||||||
.\tool\flutter_run_fresh.ps1
|
|
||||||
```
|
|
||||||
|
|
||||||
如果要指定设备,也可以继续透传给 `flutter run`:
|
|
||||||
|
|
||||||
```powershell
|
|
||||||
.\tool\flutter_run_fresh.ps1 -d F136A
|
|
||||||
```
|
|
||||||
|
|
||||||
脚本会自动:
|
|
||||||
|
|
||||||
- 读取 `android/local.properties` 中的 `sdk.dir`
|
|
||||||
- 调用 `adb shell am force-stop com.yuanxuan.webshell.web_android_shell`
|
|
||||||
- 然后执行 `flutter run`
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,16 @@
|
||||||
|
# Changelog
|
||||||
|
|
||||||
## 0.0.1
|
## 0.0.1
|
||||||
|
|
||||||
* TODO: Describe initial release.
|
### 新增
|
||||||
|
- 从 `web_android_shell` 提取核心库,支持多品牌白标架构
|
||||||
|
- `runShellApp()` 唯一入口 + `ShellEnvironment` 品牌配置
|
||||||
|
- 15 个模块文件拆分(config / engine / bridge / services / ui)
|
||||||
|
- Android WebView 兼容性自动检测(`AndroidWebViewInfo` + `AndroidCompatibilityPlan`)
|
||||||
|
- 双渲染模式(texture / hybrid)自动切换 + 启动看门狗恢复链
|
||||||
|
- `window.AppShell` JS Bridge 协议(8 种 Action)
|
||||||
|
- 旧相机 JS 兼容层(`openCamera` / `captureImage` monkey-patch)
|
||||||
|
- 媒体序列化支持 `base64` / `dataUrl` / `uri` 三种格式
|
||||||
|
- 54 个单元测试 + Widget 测试
|
||||||
|
- `CoreShellActivity` 原生层(进程隔离 + WebView 信息查询 + 深度重置)
|
||||||
|
- 全中文 `debugPrint` 日志
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,92 @@
|
||||||
# web_shell_core
|
# web_shell_core
|
||||||
|
|
||||||
Android 平板专用的 H5 壳核心库,负责:
|
Android 平板专用的 H5 壳核心库。所有品牌应用共享此库,只需传入 `ShellEnvironment` 即可启动。
|
||||||
|
|
||||||
- WebView 启动与恢复
|
## 功能
|
||||||
- H5 / Native JS Bridge
|
|
||||||
- 文件、相机、权限等宿主能力
|
| 模块 | 说明 |
|
||||||
- 品牌化壳层 UI
|
|---|---|
|
||||||
|
| **WebView 引擎** | 自动兼容低版本 Android WebView,支持 texture / hybrid 双渲染模式自动切换 |
|
||||||
|
| **启动恢复** | 看门狗超时检测 → 渲染模式降级 → 深度清理 → 自动重试 |
|
||||||
|
| **JS Bridge** | `window.AppShell` 协议,支持 8 种 Action(pickImage · captureImage · pickFile · openExternal · requestPermissions · reloadPage · goBack · closeApp) |
|
||||||
|
| **旧相机兼容** | Monkey-patch `openCamera` / `captureImage` 兼容老 H5 页面 |
|
||||||
|
| **媒体服务** | 相机拍照 · 图库选图 · 文件选择 · base64 / dataUrl / uri 三种序列化格式 |
|
||||||
|
| **权限服务** | camera · microphone · location · photos · videos · storage 统一映射 |
|
||||||
|
| **导航服务** | URL scheme 白名单路由,非 WebView 协议自动跳转外部应用 |
|
||||||
|
| **壳层 UI** | 启动加载动画 · 错误恢复页 · 进度条 · 不支持平台兜底页 |
|
||||||
|
|
||||||
|
## 使用方式
|
||||||
|
|
||||||
|
```dart
|
||||||
|
import 'package:web_shell_core/web_shell_core.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
runShellApp(
|
||||||
|
ShellEnvironment(
|
||||||
|
appName: '全学通',
|
||||||
|
appKey: 'quanxue_prod',
|
||||||
|
accentColor: Color(0xFF3ED37B),
|
||||||
|
backgroundColor: Color(0xFFFFFFFF),
|
||||||
|
textColor: Color(0xFF1F2937),
|
||||||
|
mutedTextColor: Color(0xFF6B7280),
|
||||||
|
initialUrl: 'example.com/login', // 可选,不传使用默认地址
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 代码结构
|
||||||
|
|
||||||
|
```
|
||||||
|
lib/
|
||||||
|
├── core_app.dart # 库入口 + part 指令 + runShellApp()
|
||||||
|
├── web_shell_core.dart # 公开 API 导出
|
||||||
|
└── src/
|
||||||
|
├── config/
|
||||||
|
│ ├── shell_environment.dart # 品牌配置数据类
|
||||||
|
│ └── url_resolver.dart # URL 解析与归一化
|
||||||
|
├── engine/
|
||||||
|
│ ├── compatibility.dart # Android WebView 兼容检测
|
||||||
|
│ └── recovery.dart # 启动看门狗 + 错误映射
|
||||||
|
├── bridge/
|
||||||
|
│ ├── bridge_protocol.dart # JS Bridge 注入与响应
|
||||||
|
│ ├── bridge_actions.dart # Action handler(占位)
|
||||||
|
│ └── legacy_camera_compat.dart # 旧相机 JS 兼容层
|
||||||
|
├── services/
|
||||||
|
│ ├── media_service.dart # 相机/图库/文件 + 序列化
|
||||||
|
│ ├── permission_service.dart # 权限类型映射
|
||||||
|
│ └── navigation_service.dart # URL 路由 + 外链跳转
|
||||||
|
├── ui/
|
||||||
|
│ ├── shell_app.dart # MaterialApp 入口
|
||||||
|
│ ├── shell_page.dart # WebView 主页面
|
||||||
|
│ ├── launch_overlay.dart # 启动加载动画
|
||||||
|
│ ├── error_overlay.dart # 错误恢复页
|
||||||
|
│ ├── progress_bar.dart # 顶部进度条
|
||||||
|
│ └── unsupported_platform_page.dart # 平台兜底页
|
||||||
|
└── testing/
|
||||||
|
└── test_hooks.dart # 测试钩子(@visibleForTesting)
|
||||||
|
```
|
||||||
|
|
||||||
|
## 测试
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd packages/web_shell_core
|
||||||
|
flutter test
|
||||||
|
```
|
||||||
|
|
||||||
|
当前 **54 个测试用例**,覆盖:
|
||||||
|
- 平台检测 · URL 解析 · 兼容性策略 · 错误映射
|
||||||
|
- Bridge 注入/响应/异常处理 · 媒体序列化 · 权限映射
|
||||||
|
- 导航路由 · 所有独立 UI 组件
|
||||||
|
|
||||||
## 平台约束
|
## 平台约束
|
||||||
|
|
||||||
当前仅支持 Android。
|
仅支持 **Android**。其他平台会展示兜底提示页。
|
||||||
|
|
||||||
|
## Android 原生层
|
||||||
|
|
||||||
|
`CoreShellActivity`(Java)提供:
|
||||||
|
- WebView 数据目录隔离(避免多进程冲突)
|
||||||
|
- 旧进程自动终止
|
||||||
|
- WebView 信息查询(SDK 版本、WebView 包名/版本号)
|
||||||
|
- WebView 状态深度重置
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
name: web_shell_core
|
name: web_shell_core
|
||||||
description: "A new Flutter plugin project."
|
description: "Android 平板专用 H5 壳核心库,提供 WebView 引擎、JS Bridge 和宿主服务。"
|
||||||
version: 0.0.1
|
version: 0.0.1
|
||||||
homepage:
|
homepage:
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue