- 将 ShellRemoteConfig 拆分为 ShellBootstrapConfig(启动配置)和 ShellUpgradeConfig(升级配置) - ShellBootstrapConfig 支持 initialUrl 和 preferredOrientations - ShellUpgradeService 改为独立获取升级配置,不再依赖启动配置 - ShellEnvironment 新增 bootstrapConfigAsset / bootstrapConfigUrl / upgradeConfigUrl / copyWith - 修复 WebView 错误浮层被 onPageFinished 重置的竞态条件 - 修复 Offstage 导致 Stack 坍缩为零尺寸的白屏问题,改用 Visibility - 增强 recovery.dart 对原始 net::ERR_* 字符串的友好翻译 - 重新生成 3 个品牌应用(aixue / test / yunxiao)的图标和启动页资源 - aixue 应用改用 bootstrapConfigAsset 加载本地启动配置 - 移除 launch.json 中已废弃的 quanxue 配置 |
||
|---|---|---|
| .. | ||
| android | ||
| lib | ||
| test | ||
| test_assets | ||
| .gitignore | ||
| .metadata | ||
| CHANGELOG.md | ||
| LICENSE | ||
| README.md | ||
| analysis_options.yaml | ||
| pubspec.yaml | ||
README.md
web_shell_core
Android 平板专用的 H5 壳核心库。所有品牌应用共享此库,只需传入 ShellEnvironment 即可启动。
功能
| 模块 | 说明 |
|---|---|
| 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 | 启动加载动画 · 错误恢复页 · 进度条 · 不支持平台兜底页 |
| 启动配置 | 支持本地默认启动配置文件 + 远程启动配置缓存 |
| 版本检查 | 升级配置独立请求,不再与启动配置共用一个 JSON |
使用方式
1. 准备本地默认启动配置文件
assets/config/bootstrap.json
{
"initialUrl": "https://example.com/login",
"preferredOrientations": ["portraitUp", "portraitDown"]
}
2. 在应用入口传入环境配置
import 'package:flutter/material.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),
bootstrapConfigAsset: 'assets/config/bootstrap.json',
bootstrapConfigUrl: 'https://example.com/bootstrap.json',
upgradeConfigUrl: 'https://example.com/upgrade.json',
),
);
}
3. 远程启动配置格式
{
"data": {
"initialUrl": "https://example.com/login",
"preferredOrientations": ["portraitUp", "portraitDown"]
}
}
4. 远程升级配置格式
{
"data": {
"versionName": "1.0.1",
"version": 101,
"isForce": 0,
"remark": "1. 修复已知问题\n2. 优化启动体验",
"filePath": "https://example.com/app-release.apk",
"fileSize": 25000
}
}
代码结构
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/
│ ├── config_service.dart # 启动配置读取与缓存
│ ├── media_service.dart # 相机/图库/文件 + 序列化
│ ├── permission_service.dart # 权限类型映射
│ ├── navigation_service.dart # URL 路由 + 外链跳转
│ └── upgrade_service.dart # 升级配置请求与弹窗转换
├── 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)
测试
cd packages/web_shell_core
flutter test
当前测试覆盖:
- 平台检测 · URL 解析 · 兼容性策略 · 错误映射
- Bridge 注入/响应/异常处理 · 媒体序列化 · 权限映射
- 导航路由 · 启动配置解析 · 方向配置 · 组件渲染
平台约束
仅支持 Android。其他平台会展示兜底提示页。
Android 原生层
CoreShellActivity(Java)提供:
- WebView 数据目录隔离(避免多进程冲突)
- 旧进程自动终止
- WebView 信息查询(SDK 版本、WebView 包名/版本号)
- WebView 状态深度重置