flutter 壳子项目 用于web_view 使用
Go to file
YuanXuan 0bfb1e67e0 fix(ci): escape EXTRA_ARGS in Jenkinsfile GString
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
2026-03-24 10:17:29 +08:00
.vscode feat: 重构启动配置与升级配置分离,修复 WebView 错误浮层竞态条件 2026-03-20 17:23:03 +08:00
apps feat: add jenkinsfile 2026-03-24 10:07:56 +08:00
doc refactor: simplify icon assets and improve keystore resolution 2026-03-23 17:53:53 +08:00
flavors refactor: simplify icon assets and improve keystore resolution 2026-03-23 17:53:53 +08:00
packages refactor: simplify icon assets and improve keystore resolution 2026-03-23 17:53:53 +08:00
tool feat: add jenkinsfile 2026-03-24 10:07:56 +08:00
.fvmrc feat: init 改为 测试web 2026-03-20 09:56:02 +08:00
.gitignore feat: init 改为 测试web 2026-03-20 09:56:02 +08:00
Jenkinsfile fix(ci): escape EXTRA_ARGS in Jenkinsfile GString 2026-03-24 10:17:29 +08:00
README.md refactor: simplify icon assets and improve keystore resolution 2026-03-23 17:53:53 +08:00
analysis_options.yaml chore: 中文化日志注释 + 测试覆盖率 25→54 + iOS 清理 + 代码优化 2026-03-19 19:54:29 +08:00
pubspec.lock Refactor: migrate to Monorepo N-brand architecture with automated scaffolding 2026-03-19 16:58:03 +08:00
pubspec.yaml Refactor: migrate to Monorepo N-brand architecture with automated scaffolding 2026-03-19 16:58:03 +08:00

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 namespaceapplicationId
  • 生成 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.json
  • bootstrap_config_url:可选,远程启动配置地址;为空时不会写入 main.dart
  • upgrade_config_url:可选,远程升级配置地址;为空时不会写入 main.dart
  • preferred_orientations:首屏方向配置,支持:
    • portraitUp
    • portraitDown
    • landscapeLeft
    • landscapeRight
  • 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 平板。