Files
m-stecmd/docs/安卓客户端主框架架构说明.md
阿猫 a976bf525a chore(merge): Update documentation files and file index
- Update Android client architecture documentation
- Update Android client feature specification
- Update Android client development plan
- Refresh file index metadata
2026-09-03 13:48:09 +08:00

7.1 KiB
Raw Blame History

安卓客户端主框架架构说明

S0 工程骨架交付2026-09-03。本文档说明主框架分层、模块职责、关键约定与业务挂载方法是 S1S4 功能开发的挂载依据。

1. 架构总览

flowchart TD
    APP[":app 业务壳<br/>导航 · 主题 · 权限 · 配置注入<br/>M1M6 页面挂载点"]
    subgraph CORE["core 基础层"]
        NET[":core:network<br/>鉴权三要素 · 统一解析"]
        DB[":core:database<br/>Room · 上传队列"]
        BLE[":core:ble<br/>扫描 · GATT 封装"]
        COMMON[":core:common<br/>AppResult · UiState · 日志"]
    end
    PROTO[":ble-protocol<br/>IE-1000 / VM208 帧解析<br/>纯 Kotlin JVM · 零依赖"]

    APP --> NET
    APP --> DB
    APP --> BLE
    APP --> PROTO
    NET --> COMMON
    DB --> COMMON
    BLE --> COMMON
    BLE -. "Notify 字节流" .-> PROTO

依赖规则(静态校验脚本强制核查):

规则 说明
app → core:* + ble-protocol 业务壳是唯一允许依赖全部模块的层
core:{network,database,ble} → core:common core 模块横向互不依赖
ble-protocol 零依赖 纯 Kotlin JVM无 Android / 第三方框架依赖
业务代码禁止绕过 core 层 S1+ feature 只允许经 core 能力访问网络/存储/蓝牙

2. 模块职责与关键类

模块 职责 关键类
:app 单 Activity 导航壳、5 Tab、权限、配置注入 SteCmdApplication MainActivity FeatureMount config/ConfigRepository
:core:common 统一结果/视图状态/日志门面 AppResult UiState AppLog
:core:network 平台 HTTP 框架:鉴权三要素 + 返回码统一解析 NetworkConfig TokenProvider AuthInterceptor ApiEnvelope ApiError NetworkModule
:core:database Room 离线优先存储 + 上传队列参考实现 AppDatabase UploadQueueEntity UploadQueueDao DatabaseModule
:core:ble BLE 扫描(名称前缀过滤)与 GATT 连接骨架 BleScanner BleConnector BleSession BleUuids DeviceType
:ble-protocol 两类设备协议帧解析/编码(独立单测) Ie1000FrameParser Vm208FrameParser Vm208CommandEncoder Ie1000Reading Vm208Reading

3. 关键约定

3.1 鉴权三要素流(接口文档 1.2

ConfigRepository(DataStore+内存快照, app 壳实现 NetworkConfig/TokenProvider)
    └→ AuthInterceptor(core:network): 请求头注入 SecretKey / SystemCode / Token
         · Token 为空跳过(登录/验证码接口天然不携带)
         · 密钥值不进代码库M7-04运行期经 S1 配置页写入 DataStore

Hilt 绑定:config/AppModule.kt@BindsConfigRepository 绑定为 NetworkConfigTokenProvider,补全 NetworkModule 依赖图。

3.2 返回码统一解析(接口文档 1.1

code 语义 异常类型
"200" 成功 —(ApiEnvelope.bodyOrThrow() 返回 data
"500" 业务失败 ApiError.ServerError
"429" 一分钟内同条数据频繁请求超限 ApiError.TooManyRequests
"403" 同条数据连续报错超限(平台锁定) ApiError.Locked
传输层失败 超时/断网 ApiError.NetworkError

code 为字符串类型S1+ 业务层只捕获 ApiError 并按子类提示。

3.3 协议解析流BLE Notify → 上传队列)

BleSession.notifyBytes(ByteArray 流)
    └→ Ie1000FrameParser / Vm208FrameParser.feed(bytes)   ← 内部缓冲,天然处理粘包/残包
         └→ Ie1000Reading / Vm208Reading
              └→ 组装上传 JSON → UploadQueueDao.enqueue()  ← 离线优先,网络可用后补传
  • IE-1000'Y' + 4B float(压力,小端) + 'T' + 4B float(温度) + 0D0A12 字节定长;
  • VM208CC F原值 T原值 E原值 S质量 AA + 0D0A,缩放 /10 /10 /100
  • VM208 激励命令:0F 0F 06 0A XX XX 0D 0A(大端 16 位),Vm208CommandEncoder
  • ⚠ VM208 服务 UUID 原文档仅 31 位十六进制,BleUuids 按末位补 0 占位,S2 真机联调时用 nRF Connect 校准

3.4 网络安全白名单

app/src/main/res/xml/network_security_config.xml:默认全域禁明文;仅接口文档 1.2.4 测试 IP 106.15.183.20 开放 cleartext联调用发布前如生产全 HTTPS 可移除该 domain-config

4. 业务挂载指南S1 挂载步骤)

挂载机制:FeatureMount.mounts 注册表声明每个 Tab 的 Fragment 类;导航壳只认注册表,业务页替换注册项即可。

以 S1 首页M2 项目列表)为例:

  1. 建 Fragmentapp/src/main/kotlin/com/stec/cmd/feature/home/HomeFragment.kt@AndroidEntryPoint + ViewBinding或迁移至团队选定的 UI 方案);
  2. 建 ViewModelHomeViewModel,注入 S1 新建的 Retrofit Service声明在 core:network 或独立 feature 模块);
  3. 换注册项FeatureMount.mountsTab.HOMEfragmentClassHomeFragment::class.java(占位)改为业务 Fragment
  4. 加接口Retrofit Service 方法返回 ApiEnvelope<T>,调用侧 bodyOrThrow() 拿业务数据、捕获 ApiError
  5. 跑校验./gradlew :app:assembleDebug,并确认静态校验脚本(见 §6通过menu↔FeatureMount id 对应关系不受影响)。

M1我的额外步骤配置页 UI 读写 ConfigRepository.updateConnection()/updateToken()M1-06

5. 目录结构对照

SteCmdAndroid/
├─ app/                      # 业务壳(本表 §2 :app
├─ core/
│  ├─ common/                # AppResult / UiState / AppLog
│  ├─ network/               # AuthInterceptor / ApiEnvelope / ApiError / NetworkModule
│  ├─ database/              # AppDatabase / UploadQueue 实体与 DAO / DatabaseModule
│  └─ ble/                   # BleScanner / BleConnector / BleSession / BleUuids / DeviceType
├─ ble-protocol/             # 协议解析src/main + src/test 冒烟单测)
├─ gradle/
│  └─ libs.versions.toml     # 版本目录:全工程唯一版本事实源
├─ docs/                     # 规划文档、协议原文、本说明
├─ settings.gradle.kts       # 6 模块注册
└─ build.gradle.kts          # 根插件版本声明apply false

6. 环境与验证

场景 命令 / 操作
首次打开 Android StudioJDK 17打开工程根目录等待 Gradle Sync
编译 ./gradlew :app:assembleDebug
协议单测 ./gradlew :ble-protocol:test
静态校验(本机已通过 198 项) python3 /tmp/verify_core.py && python3 /tmp/verify_app.py(脚本随会话生成)
真机联调 配置页写入三要素 + 测试地址后先验证登录M1-01

7. 已知遗留S1 前处理)

  1. Gradle Sync / 编译 / 单测尚未在真实环境执行(交付环境无 JDK/Android SDK
  2. VM208 服务 UUID 需真机校准§3.3
  3. splash 与导航图标为几何占位S6 发布前替换正式视觉;
  4. 密钥SecretKey/SystemCode首次运行需经配置页写入协议文档附带密钥文件仅用于联调不得入库。