227 lines
6.2 KiB
Markdown
227 lines
6.2 KiB
Markdown
# web_android_shell
|
||
|
||
Android 平板专用 H5 壳应用 Monorepo,面向多品牌白标场景。
|
||
|
||
## 当前品牌
|
||
|
||
- `apps/aixue`:爱学蝶变
|
||
- `apps/test`:测试壳工程
|
||
- `apps/yunxiao`:云校嗨学
|
||
|
||
## 目录结构
|
||
|
||
```text
|
||
web_android_shell/
|
||
├── apps/ # 品牌应用(每个品牌一个 Flutter App)
|
||
│ ├── aixue/
|
||
│ ├── test/
|
||
│ └── yunxiao/
|
||
├── flavors/ # 品牌配置 + 品牌资源源文件
|
||
│ ├── aixue.yaml
|
||
│ ├── test.yaml
|
||
│ ├── yunxiao.yaml
|
||
│ ├── aixue/
|
||
│ ├── test/
|
||
│ └── yunxiao/
|
||
├── packages/
|
||
│ ├── web_shell_core/ # 核心壳能力库
|
||
│ └── web_android_shell/ # 历史包,当前不作为主入口维护
|
||
├── tool/
|
||
│ ├── generate_app.dart # 按 flavor 一键生成品牌 App
|
||
│ └── flutter_run_fresh.ps1 # Windows 调试脚本
|
||
└── doc/
|
||
└── architecture.md # 架构说明
|
||
```
|
||
|
||
## 执行指令
|
||
```text
|
||
dart run tool/generate_app.dart aixue
|
||
```
|
||
## 核心思路
|
||
|
||
- 应用启动优先读取本地默认启动配置 `assets/config/bootstrap.json`
|
||
- 如配置了 `bootstrap_config_url`,会继续拉取远程启动配置,并使用缓存兜底
|
||
- 如配置了 `upgrade_config_url`,首帧后异步检查版本更新
|
||
- 启动配置与升级配置已拆分,不再共用同一个 JSON
|
||
- 屏幕方向支持通过启动配置中的 `preferredOrientations` 控制
|
||
|
||
## 快速开始
|
||
|
||
### 运行已有品牌
|
||
|
||
建议优先使用仓库内 `.fvm` 的 Flutter / Dart,避免全局版本不一致。
|
||
|
||
Windows PowerShell:
|
||
|
||
```powershell
|
||
cd apps/aixue
|
||
..\..\.fvm\flutter_sdk\bin\flutter.bat run
|
||
```
|
||
|
||
macOS / zsh:
|
||
|
||
```bash
|
||
cd apps/aixue
|
||
../../.fvm/flutter_sdk/bin/flutter run
|
||
```
|
||
|
||
也可以替换为:
|
||
|
||
```powershell
|
||
cd apps/test
|
||
..\..\.fvm\flutter_sdk\bin\flutter.bat run
|
||
```
|
||
|
||
```bash
|
||
cd apps/yunxiao
|
||
../../.fvm/flutter_sdk/bin/flutter run
|
||
```
|
||
|
||
### 生成或重建品牌应用
|
||
|
||
请在仓库根目录执行。
|
||
|
||
Windows PowerShell:
|
||
|
||
```powershell
|
||
.\.fvm\flutter_sdk\bin\dart.bat run tool\generate_app.dart aixue
|
||
.\.fvm\flutter_sdk\bin\dart.bat run tool\generate_app.dart test
|
||
.\.fvm\flutter_sdk\bin\dart.bat run tool\generate_app.dart yunxiao
|
||
```
|
||
|
||
macOS / zsh:
|
||
|
||
```bash
|
||
./.fvm/flutter_sdk/bin/dart run tool/generate_app.dart aixue
|
||
./.fvm/flutter_sdk/bin/dart run tool/generate_app.dart test
|
||
./.fvm/flutter_sdk/bin/dart run tool/generate_app.dart yunxiao
|
||
```
|
||
|
||
注意:生成脚本会删除并重建已有的 `apps/<品牌名>/` 目录。
|
||
|
||
生成脚本会自动完成:
|
||
|
||
- 创建 Flutter Android 应用到 `apps/<品牌名>/`
|
||
- 添加 `web_shell_core` 依赖
|
||
- 修正 Android `namespace` 与 `applicationId`
|
||
- 生成 `MainActivity` 并继承 `CoreShellActivity`
|
||
- 生成品牌入口 `lib/main.dart`
|
||
- 生成本地默认启动配置 `assets/config/bootstrap.json`
|
||
- 复制品牌资源到 `assets/branding/`
|
||
- 注册 `assets/branding/` 与 `assets/config/`
|
||
- 生成 launcher icon 与 splash
|
||
- 注入 Android 签名配置
|
||
|
||
## Flavor 配置格式
|
||
|
||
每个品牌在 `flavors/<品牌名>.yaml` 中维护配置。
|
||
|
||
```yaml
|
||
app_name: "全学通"
|
||
application_id: "com.yuanxuan.quanxue"
|
||
app_key: "quanxue_prod"
|
||
default_url: "https://example.com/login"
|
||
bootstrap_config_url: "https://example.com/bootstrap.json"
|
||
upgrade_config_url: "https://example.com/upgrade.json"
|
||
preferred_orientations:
|
||
- "portraitUp"
|
||
- "portraitDown"
|
||
theme:
|
||
accent_color: "0xFF3ED37B"
|
||
bg_color: "0xFFFFFFFF"
|
||
text_color: "0xFF1F2937"
|
||
muted_text_color: "0xFF6B7280"
|
||
branding:
|
||
icon: "icon.png"
|
||
icon_background: "#FFFFFF"
|
||
splash: "splash.png"
|
||
splash_color: "#FFFFFF"
|
||
```
|
||
|
||
### 字段说明
|
||
|
||
- `default_url`:生成到本地默认启动配置 `assets/config/bootstrap.json`
|
||
- `bootstrap_config_url`:可选,远程启动配置地址;为空时不会写入 `main.dart`
|
||
- `upgrade_config_url`:可选,远程升级配置地址;为空时不会写入 `main.dart`
|
||
- `preferred_orientations`:首屏方向配置,支持:
|
||
- `portraitUp`
|
||
- `portraitDown`
|
||
- `landscapeLeft`
|
||
- `landscapeRight`
|
||
- `branding.icon`:同时用于普通应用图标和 Android 自适应图标前景
|
||
|
||
## 生成后的入口形态
|
||
|
||
生成器会把品牌入口写成统一模板:
|
||
|
||
```dart
|
||
runShellApp(
|
||
ShellEnvironment(
|
||
appName: '品牌名',
|
||
appKey: 'brand_key',
|
||
accentColor: const Color(0xFF3ED37B),
|
||
backgroundColor: const Color(0xFFFFFFFF),
|
||
textColor: const Color(0xFF1F2937),
|
||
mutedTextColor: const Color(0xFF6B7280),
|
||
splashImage: const AssetImage('assets/branding/splash.png'),
|
||
bootstrapConfigAsset: 'assets/config/bootstrap.json',
|
||
bootstrapConfigUrl: 'https://example.com/bootstrap.json',
|
||
upgradeConfigUrl: 'https://example.com/upgrade.json',
|
||
),
|
||
);
|
||
```
|
||
|
||
其中远程地址为空时,对应字段不会写入生成结果。
|
||
|
||
## 本地默认启动配置格式
|
||
|
||
生成器会自动生成 `assets/config/bootstrap.json`:
|
||
|
||
```json
|
||
{
|
||
"initialUrl": "https://example.com/login",
|
||
"preferredOrientations": [
|
||
"portraitUp",
|
||
"portraitDown"
|
||
]
|
||
}
|
||
```
|
||
|
||
## 品牌资源规格
|
||
|
||
| 资源 | 文件名 | 最小尺寸 | 格式 | 说明 |
|
||
|---|---|---|---|---|
|
||
| 应用图标 | `icon.png` | 1024×1024 | PNG | 同时用于生成各尺寸 launcher icon 与 Android 自适应图标前景 |
|
||
| 启动页图片 | `splash.png` | 1152×1152 | PNG | 用于生成 Android 12+ 与旧版启动页 |
|
||
|
||
品牌资源源文件放在 `flavors/<品牌名>/` 下,生成后会复制到 `apps/<品牌名>/assets/branding/`。
|
||
|
||
## 调试说明
|
||
|
||
部分教育平板设备在 `flutter run` 中断后,旧进程可能残留并影响 WebView 启动。
|
||
|
||
推荐做法:
|
||
|
||
- 调试结束时在 `flutter run` 控制台按 `q` 退出
|
||
- 或使用:
|
||
|
||
```powershell
|
||
.\tool\flutter_run_fresh.ps1
|
||
.\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` |
|
||
| 配置缓存 | `shared_preferences` |
|
||
| 网络与状态 | `http` · `connectivity_plus` |
|
||
| 原生层 | Java `CoreShellActivity` + Kotlin plugin |
|
||
|
||
## 平台约束
|
||
|
||
仅支持 Android 平板。
|