Groovy interpolated $EXTRA_ARGS as a pipeline binding property, which raised MissingPropertyException and skipped flutter build apk. Prefix dollar signs with backslash so the shell receives literal $EXTRA_ARGS. Made-with: Cursor |
||
|---|---|---|
| .vscode | ||
| apps | ||
| doc | ||
| flavors | ||
| packages | ||
| tool | ||
| .fvmrc | ||
| .gitignore | ||
| Jenkinsfile | ||
| README.md | ||
| analysis_options.yaml | ||
| pubspec.lock | ||
| pubspec.yaml | ||
README.md
web_android_shell
Android 平板专用 H5 壳应用 Monorepo,面向多品牌白标场景。
当前品牌
apps/aixue:爱学蝶变apps/test:测试壳工程apps/yunxiao:云校嗨学
目录结构
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 # 架构说明
执行指令
dart run tool/generate_app.dart aixue
核心思路
- 应用启动优先读取本地默认启动配置
assets/config/bootstrap.json - 如配置了
bootstrap_config_url,会继续拉取远程启动配置,并使用缓存兜底 - 如配置了
upgrade_config_url,首帧后异步检查版本更新 - 启动配置与升级配置已拆分,不再共用同一个 JSON
- 屏幕方向支持通过启动配置中的
preferredOrientations控制
快速开始
运行已有品牌
建议优先使用仓库内 .fvm 的 Flutter / Dart,避免全局版本不一致。
Windows PowerShell:
cd apps/aixue
..\..\.fvm\flutter_sdk\bin\flutter.bat run
macOS / zsh:
cd apps/aixue
../../.fvm/flutter_sdk/bin/flutter run
也可以替换为:
cd apps/test
..\..\.fvm\flutter_sdk\bin\flutter.bat run
cd apps/yunxiao
../../.fvm/flutter_sdk/bin/flutter run
生成或重建品牌应用
请在仓库根目录执行。
Windows 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:
./.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 中维护配置。
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.jsonbootstrap_config_url:可选,远程启动配置地址;为空时不会写入main.dartupgrade_config_url:可选,远程升级配置地址;为空时不会写入main.dartpreferred_orientations:首屏方向配置,支持:portraitUpportraitDownlandscapeLeftlandscapeRight
branding.icon:同时用于普通应用图标和 Android 自适应图标前景
生成后的入口形态
生成器会把品牌入口写成统一模板:
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:
{
"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退出 - 或使用:
.\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 平板。