463 lines
22 KiB
Markdown
463 lines
22 KiB
Markdown
# 设备自动化后台(platform-tools)
|
||
|
||
基于 **STF(Smartphone Test Farm)+ uiautomator2 + Flask** 的 Android 多设备自动化任务执行平台。
|
||
|
||
提供 Web 管理后台,支持多设备并发任务执行、定时调度、设备分组管理、APK 批量安装、UI 元素抓取等功能。内置抖音养号任务和通用步骤任务,可扩展任意 App 的自动化操作。
|
||
|
||
---
|
||
|
||
## 目录
|
||
|
||
- [快速上手](#快速上手)
|
||
- [项目结构](#项目结构)
|
||
- [核心概念](#核心概念)
|
||
- [配置说明](#配置说明)
|
||
- [Web 管理后台](#web-管理后台)
|
||
- [任务系统](#任务系统)
|
||
- [日志系统](#日志系统)
|
||
- [常用脚本](#常用脚本)
|
||
- [常见问题](#常见问题)
|
||
- [更多文档](#更多文档)
|
||
|
||
---
|
||
|
||
## 快速上手
|
||
|
||
### 环境要求
|
||
|
||
- **Python 3.10+**(推荐 3.12)
|
||
- **OpenSTF 服务**:已部署并运行,设备已接入 STF
|
||
- **Windows / Linux / macOS**均可(adb 二进制需放对应平台版本到 `bin/adb/`)
|
||
- 设备需开启 **USB 调试**或通过 **adb 网络连接**(IP:5555)接入
|
||
|
||
### 三步启动
|
||
|
||
```bash
|
||
# 1. 安装依赖
|
||
pip install -r requirements.txt
|
||
|
||
# 2. 修改配置(STF 地址、token、adb 路径等)
|
||
# 编辑 config.py 中的 STF_URL 和 STF_TOKEN
|
||
|
||
# 3. 启动 Web 后台
|
||
python web_server.py
|
||
```
|
||
|
||
启动后访问 **http://localhost:18050/**,默认账号 `admin` / `admin123`。
|
||
|
||
### 验证启动
|
||
|
||
控制台看到以下日志即表示启动成功:
|
||
|
||
```
|
||
[INFO] [core.worker] 心跳看门狗已启动
|
||
[INFO] [core.tm] 从数据库加载 X 个分组, X 个任务
|
||
[INFO] [web] 管理后台: http://localhost:18050/ (admin/admin123)
|
||
[INFO] [web] 启动服务: http://localhost:18050/
|
||
```
|
||
|
||
### 首次使用流程
|
||
|
||
1. **登录后台** → 用 `admin/admin123` 登录,建议立即修改密码
|
||
2. **查看设备** → 首页"监控"Tab 自动展示 STF 设备池状态
|
||
3. **创建分组**(可选)→ "分组"Tab 按批次/项目给设备分组
|
||
4. **创建任务** → "任务"Tab 新建任务,选择任务类型、目标设备、参数、调度
|
||
5. **执行任务** → 任务列表点"立即执行",或在"监控"Tab 勾选设备批量操作
|
||
6. **查看日志** → "日志"Tab 实时查看运行日志
|
||
|
||
---
|
||
|
||
## 项目结构
|
||
|
||
```
|
||
platform-tools/
|
||
├── config.py # 根配置(部署配置统一从 .env 读,模板见 .env.example)
|
||
├── web_server.py # Flask 入口(API + 登录 + 单页应用)
|
||
├── requirements.txt # Python 依赖清单
|
||
│
|
||
├── core/ # 核心基础设施层
|
||
│ ├── logger.py # 统一日志(分文件、10MB 滚动)
|
||
│ ├── stf_client.py # STF REST API 封装(占用/释放/远程连接)
|
||
│ ├── adb_helper.py # adb 命令封装(全局锁,绝不 kill-server)
|
||
│ ├── device_worker.py # BaseWorker 基类 + STFDevice + 心跳看门狗
|
||
│ ├── task_manager.py # TaskManager 调度器 + 前台App扫描器
|
||
│ ├── u2_helper.py # uiautomator2 通用辅助函数
|
||
│ ├── uiauto_helper.py # uiautodev 元素抓取客户端
|
||
│ ├── apk_manager.py # APK 上传/解析/批量安装
|
||
│ ├── ocr.py # 屏幕 OCR(RapidOCR,条件判断 OCR 选择器)
|
||
│ ├── ssh_client.py # SSH 统一执行(paramiko 纯密码 / 免密密钥)
|
||
│ ├── stf_device_mgmt.py # STF 设备池管理(读写 220 脚本 + adb connect/disconnect)
|
||
│ ├── tailscale_client.py # Tailscale API v2 客户端
|
||
│ ├── models.py # SQLAlchemy 数据模型 + 数据库初始化
|
||
│ └── actions/ # 全局 Action 框架
|
||
│
|
||
├── tasks/ # 任务定义层(每个 App 一个子包)
|
||
│ ├── __init__.py # 全局任务注册表
|
||
│ ├── base.py # BaseTask 基类 + @register_task 装饰器
|
||
│ ├── douyin/ # 抖音养号任务
|
||
│ └── generic/ # 通用步骤任务(可视化编辑器编排)
|
||
│ └── task.py # 步骤执行引擎(open_app/click/swipe/if_el...)
|
||
│
|
||
├── templates/admin/ # 前端页面
|
||
│ ├── monitor.html # 单页应用(监控/任务/分组/日志/用户/维护/工具)
|
||
│ └── login.html # 登录页
|
||
│
|
||
├── static/admin/ # 前端 JS 模块(monitor.html 按依赖顺序加载)
|
||
│ ├── base.js # 通用基础:API/CSRF/权限/Tab切换/子分栏/模态框
|
||
│ ├── list.js # 统一列表组件(搜索+分页+排序)
|
||
│ ├── monitor.js # 监控页(设备表/截图/异常汇总)
|
||
│ ├── editor.js # 步骤编辑器(拖拽/条件判断/元素抓取)
|
||
│ ├── tasks.js # 任务 Tab + 自定义动作
|
||
│ ├── tools.js # 工具 Tab(剪贴板/应用版本/STF设备/adb终端/Tailscale)
|
||
│ ├── apps.js # 工具 Tab-应用管理(APK/设备已装应用)
|
||
│ ├── admin.js # 管理 Tab(分组/日志/用户)+ 初始化
|
||
│ └── custom.css # 自定义样式
|
||
│
|
||
├── data/ # 运行时数据
|
||
│ ├── users.db # SQLite(用户/分组/任务/自定义动作/APK记录)
|
||
│ └── apks/ # 上传的 APK 文件存储
|
||
│
|
||
├── logs/ # 日志文件(自动生成,10MB 滚动保留 5 份)
|
||
├── bin/adb/ # adb 可执行文件(Windows: adb.exe + dll)
|
||
├── scripts/ # 实用脚本
|
||
│ ├── pack.py # 打包项目为 zip(排除运行时产物)
|
||
│ └── supervise.sh # 进程守护(崩溃自动重启)
|
||
└── doc/ # 项目文档
|
||
├── API.md # API 文档
|
||
├── ARCHITECTURE.md # 架构详解
|
||
├── DEPLOY.md # 部署指南
|
||
├── DEVELOPMENT.md # 开发指南
|
||
└── TASK_DEV.md # 任务开发指南(新增 App 任务模板)
|
||
├── ARCHITECTURE.md # 架构详解
|
||
├── DEPLOY.md # 部署指南
|
||
└── API.md # API 接口文档
|
||
```
|
||
|
||
---
|
||
|
||
## 核心概念
|
||
|
||
### 设备生命周期
|
||
|
||
```
|
||
STF occupy(占用设备)
|
||
↓
|
||
STF remoteConnect(建立远程 ADB 隧道)
|
||
↓
|
||
adb connect(连接远程设备)
|
||
↓
|
||
u2.connect(连接 uiautomator2,自动推送 atx-agent)
|
||
↓
|
||
Worker.run_task(执行业务逻辑)
|
||
↓
|
||
adb disconnect + STF release(释放设备)
|
||
```
|
||
|
||
> 直连模式:当设备 serial 为 `IP:5555` 格式时,直接 adb connect,不走 STF 桥接,更稳定。
|
||
|
||
### Worker — 单设备执行线程
|
||
|
||
每台设备对应一个 `Worker` 线程,继承 `BaseWorker`(`core/device_worker.py`)。基类已封装:
|
||
|
||
- STF 设备占用/释放(try/finally 保证释放)
|
||
- adb 连接 + u2.connect(带 30 秒超时保护)
|
||
- 状态上报(实时推送到前端监控大屏)
|
||
- 异常捕获(设备离线不重试,其他异常按策略重试)
|
||
- stop 停止信号(循环里检查 `self.stopped()`)
|
||
- 心跳看门狗(120 秒无心跳自动标记卡死)
|
||
|
||
子类只需实现 `run_task(d)` 方法专注业务逻辑。
|
||
|
||
### TaskType — 任务类型
|
||
|
||
| 任务类型 | task_type | 说明 |
|
||
|---------|-----------|------|
|
||
| 抖音养号 | `douyin_nurture` | 自动看视频 + 随机点赞,被退出自动重连 |
|
||
| 通用步骤 | `generic_steps` | 可视化步骤编辑器编排流程,支持循环/点击/滑动等 |
|
||
|
||
### TaskJob — 任务计划
|
||
|
||
一个 TaskJob 描述"什么时候、在哪些设备上、用什么参数执行什么任务":
|
||
|
||
| 字段 | 说明 | 示例 |
|
||
|------|------|------|
|
||
| `task_type` | 任务类型 | `"douyin_nurture"` |
|
||
| `target` | 目标设备 | `{"mode": "all"}` 或 `{"mode": "group", "group_name": "A组"}` 或 `{"mode": "serial", "serial": "192.168.1.100:5555"}` |
|
||
| `params` | 任务参数(与默认值深合并) | `{"watch_count": 50, "actions": {"like": {"params": {"rate": 0.5}}}}` |
|
||
| `schedule` | 调度策略 | `{"mode": "once"}` 或 `{"mode": "cron", "cron": "0 9 * * *"}` 或 `{"mode": "cron_stop", "cron": "0 9 * * *", "stop_cron": "0 18 * * *"}` |
|
||
| `retry` | 重试策略 | `{"max_attempts": 3, "delay": 60}` |
|
||
| `enabled` | 是否启用 | `true` |
|
||
|
||
### 调度模式
|
||
|
||
| 模式 | 行为 |
|
||
|------|------|
|
||
| `once` | 手动执行(前端点"立即执行") |
|
||
| `cron` | 定时启动:到 cron 时间点自动启动所有目标设备 |
|
||
| `cron_stop` | 定时启停:启动 cron 到点启动,停止 cron 到点停止本任务 worker |
|
||
|
||
**简单设置**:编辑任务时选"定时启动/定时启动+停止"后,频率用下拉选择——每天(选时间)、每小时(整点)、每隔 N 小时、每周(选星期+时间)——cron 表达式自动生成,不需要懂 cron 语法。老手可在"自定义 cron(高级)"里直接填。
|
||
|
||
cron 表达式为标准 5 段格式:`分 时 日 月 周`(如 `0 9 * * *` = 每天 9:00,`0 */2 * * *` = 每 2 小时整点,周 `0`/`7` 均为周日)
|
||
|
||
**运行窗口**:任务可勾选"启用运行窗口",设置每天允许运行的时间段(如 `21:00-09:00` = 晚 9 点到次日早 9 点,支持跨午夜)。窗口外**定时触发和手动执行都不会启动**(手动执行会提示"当前不在运行窗口内")。典型用法:`每小时`定时 + 窗口 `09:00-21:00`,即只在白天每小时跑一次。
|
||
|
||
### 设备分组
|
||
|
||
设备分组存于 SQLite,便于按批次/项目分组下发任务。一个 Job 指定 `target.mode="group"` 时,调度器展开为组内全部设备。
|
||
|
||
### 进度上报
|
||
|
||
Worker 通过 `self.set_progress()` 上报通用进度字段,前端统一解析展示:
|
||
|
||
```python
|
||
self.set_progress(done=5, total=80, unit="视频",
|
||
action_counts={"like": 3})
|
||
```
|
||
|
||
前端展示:进度条 + `5/80 视频` + `点赞 3` 徽章。
|
||
|
||
---
|
||
|
||
## 配置说明
|
||
|
||
所有核心配置在 [config.py](file:///d:/platform-tools/config.py),**任务参数不放在这里**(放各自 `tasks/xxx.py` 顶部)。
|
||
|
||
| 配置项 | 默认值 | 说明 |
|
||
|-------|--------|------|
|
||
| `STF_URL` | `http://192.168.20.220:7100` | OpenSTF 服务地址 |
|
||
| `STF_TOKEN` | (.env 配置) | STF API Token,在 STF 个人设置里生成(密钥类配置统一放 `.env`) |
|
||
| `ADB_PATH` | 自动识别 | adb 二进制路径,自动区分 Windows/Linux |
|
||
| `WEB_HOST` | `0.0.0.0` | Web 监听地址(0.0.0.0 支持局域网访问) |
|
||
| `WEB_PORT` | `18050` | Web 端口(避开 Windows 动态端口范围) |
|
||
| `DATA_DIR` | `data/` | 持久化数据目录 |
|
||
| `APK_DIR` | `data/apks/` | APK 文件存储目录 |
|
||
| `STF_SSH_TARGET` | `[email protected]` | 维护页重启 STF / STF 设备管理的 SSH 目标(需免密) |
|
||
| `STF_DOCKER_CONTAINER` | `stf` | 220 上 STF Docker 容器名 |
|
||
| `STF_ADB_CONTAINER` | `adb` | 220 上 adb Docker 容器名(STF 设备管理执行 adb 用) |
|
||
| `STF_SCRIPT_PATH` | `/mnt/data/openstf/connect_devices.sh` | STF 设备池脚本路径(DEVICES 列表由此维护) |
|
||
| `TAILSCALE_API_KEY` | (.env 配置) | Tailscale 管理 API key(Settings → API Access Tokens) |
|
||
| `TAILSCALE_TAILNET` | 按邮箱前缀 | tailnet 名/ID |
|
||
|
||
**必须修改的配置**:`.env` 里的 `STF_TOKEN`(密钥类统一放 `.env`,不入 git);`STF_URL` 在 `config.py`。
|
||
|
||
---
|
||
|
||
## Web 管理后台
|
||
|
||
### 页面结构
|
||
|
||
单页应用(`templates/admin/monitor.html`),7 个 Tab;任务/工具 Tab 内部再有页内子分栏:
|
||
|
||
| Tab | 功能 | 可见性 |
|
||
|-----|------|--------|
|
||
| 监控 | 设备状态大屏:在线/离线、运行任务、当前动作、进度条、前台 App、截图、停止 | 所有登录用户(设备操作按钮需"设备控制"权限) |
|
||
| 任务 | 子分栏:任务计划(CRUD/启用停用/立即执行/下次运行时间/**离线设备自动跳过**)、自定义动作(打包复用) | 所有登录用户可看,写操作需"任务管理"权限 |
|
||
| 分组 | 设备分组管理:创建/编辑/删除分组 | 所有登录用户可看,写操作需"任务管理"权限 |
|
||
| 日志 | 实时日志查看:按模块切换(core/task/web/action) | 需"日志查看"权限 |
|
||
| 用户 | 用户管理:创建/删除/修改密码/分配权限 | 仅管理员 |
|
||
| 维护 | STF 服务:一键重启容器 | 仅管理员 |
|
||
| 工具 | 子分栏:剪贴板注入、adb 远程终端(快捷命令/自动 `-s`/卸载 STF agent)、Tailscale 管理(改名/授权/密钥不过期/设置IP/auth key)、应用管理(APK 上传安装)、应用版本管理(按包名查所有设备版本)、设备已装应用、STF 设备管理(读写 220 脚本维护设备池) | 仅管理员 |
|
||
|
||
任务/工具 Tab 的子分栏会记住上次选中的位置;无权限的 tab 和按钮自动隐藏。
|
||
|
||
### 用户与权限
|
||
|
||
默认账号 `admin` / `admin123`(管理员,拥有全部权限)。管理员可在"用户"Tab 创建普通用户并分配权限:
|
||
|
||
| 权限位 | 说明 | 覆盖功能 |
|
||
|--------|------|---------|
|
||
| 任务管理 `tasks` | 任务/自定义动作/分组的增删改、启停、立即执行 | 任务 Tab、分组 Tab 的写操作 |
|
||
| 设备控制 `devices` | 停止设备、释放占用、清除异常、前台扫描、元素抓取 | 监控 Tab 的设备操作按钮、步骤编辑器的"抓取元素" |
|
||
| 应用管理 `apks` | APK 上传、安装、删除 | 应用管理/设备已装应用(当前并入工具 Tab,工具页整体仅管理员可见) |
|
||
| 日志查看 `logs` | 日志页 | 日志 Tab |
|
||
|
||
规则:
|
||
- **管理员拥有全部权限**,不受权限位限制
|
||
- 查看类接口(设备/任务/分组列表、状态、截图)所有登录用户可用
|
||
- **用户管理仅管理员可用**;不能删除/取消最后一个管理员
|
||
- 无权限的 tab 和按钮在界面上自动隐藏(后端同样拦截,返回 403)
|
||
|
||
### 前台 App 扫描
|
||
|
||
监控页"扫描前台App"按钮,获取所有设备当前前台 App。**不打扰设备**:
|
||
|
||
| 设备状态 | 处理方式 |
|
||
|---------|---------|
|
||
| worker 运行中 | 复用已有 ADB 连接查询 |
|
||
| 自己占用 | 通过 STF remoteConnect 隧道查询(不 occupy/release) |
|
||
| 完全空闲 | 返回"空闲"(不主动 adb connect,避免 STF 误判离线) |
|
||
| 他人占用 | 标记"(他人占用)" |
|
||
|
||
### 截图功能
|
||
|
||
监控页每台设备可查看实时截图。用 `adb exec-out screencap -p`,只读操作,**任务运行中也能安全调用**(不抢占 u2 的 atx-agent 通道)。
|
||
|
||
### 元素抓取
|
||
|
||
任务编辑器的"抓取元素"按钮可拉取设备当前 UI 元素树,点击元素一键回填选择器。依赖本地运行的 uiautodev 服务(端口 20242),`web_server.py` 启动时会自动拉起。
|
||
|
||
---
|
||
|
||
## 任务系统
|
||
|
||
### 抖音养号(douyin_nurture)
|
||
|
||
自动观看抖音视频,按配置随机执行点赞操作。参数(在 `tasks/douyin/task.py` 顶部):
|
||
|
||
| 参数 | 默认值 | 说明 |
|
||
|------|--------|------|
|
||
| `watch_count` | 80 | 观看视频数量(0=不限,靠时长停止) |
|
||
| `watch_min` / `watch_max` | 5.0 / 35.0 | 单视频观看时长范围(秒) |
|
||
| `max_duration` | 0 | 最大运行时长(秒),0=不限时 |
|
||
| `swipe_min` / `swipe_max` | 0.25 / 0.50 | 上滑手势时长范围(秒) |
|
||
| `gap_min` / `gap_max` | 1.0 / 3.0 | 视频间隔时长范围(秒) |
|
||
| `actions.like.enabled` | true | 是否启用点赞 |
|
||
| `actions.like.params.rate` | 0.3 | 点赞概率(0~1) |
|
||
| `actions.like.params.method` | by_element | 点赞方式:by_element(找红心) / double_click(双击) |
|
||
|
||
终止条件(哪个先到就停):`watch_count` 数量到 / `max_duration` 时长到 / 手动停止。
|
||
|
||
### 通用步骤(generic_steps)
|
||
|
||
通过可视化步骤编辑器编排任务流程,worker 按步骤顺序执行。支持的步骤类型:
|
||
|
||
| 步骤类型 | 说明 |
|
||
|---------|------|
|
||
| `open_app` | 启动 App(指定包名,可选等待首页) |
|
||
| `stop_app` | 强制结束 App(am force-stop,清后台,下次打开冷启动) |
|
||
| `screen_on` | 亮屏(息屏时唤醒并滑动解锁) |
|
||
| `screen_off` | 息屏 |
|
||
| `keep_screen` | 保持亮屏/恢复自动息屏(充电时屏幕常亮,适合长任务) |
|
||
| `key_event` | 按键:返回/Home/回车/菜单等(退出评论、返回上一页) |
|
||
| `swipe` | 滑动(上/下/左/右,可配置时长) |
|
||
| `swipe_until` | 滑动直到元素出现(最多 N 次,可选找到后点击) |
|
||
| `click_xy` | 点击坐标(屏幕百分比,无选择器时兜底) |
|
||
| `long_click` | 长按元素(选择器 + 时长) |
|
||
| `wait_el` | 等待元素出现(条件等待,替代固定时长) |
|
||
| `input_text` | 输入文字(随机候选/指定文字,可选输入前先清空) |
|
||
| `click` | 点击元素(支持 xpath/description/resourceId/text 选择器) |
|
||
| `wait` | 等待(可配置时长范围) |
|
||
| `loop` | 循环块(含子步骤,可配置循环次数) |
|
||
| `group` | 动作组(含子步骤,按序执行一次) |
|
||
| `if_el` | 条件判断:找元素(支持 xpath 等选择器或 **OCR识别** 截屏匹配图片文字),命中执行"找到时"分支,未命中执行"未找到时"分支;OCR 命中可自动点击。分支可嵌套循环/条件判断 |
|
||
|
||
步骤编辑器特性:操作库按分类分组、卡片可拖拽排序/跨层级嵌套(循环套循环)、☑ 多选打包自定义动作、
|
||
"测试此步骤"真机验证、"抓取元素"回填选择器、条件判断的 OCR 识别依赖 `rapidocr_onnxruntime`(跨平台)。
|
||
|
||
### 新增 App 任务
|
||
|
||
参照 `tasks/douyin/` 结构,6 步即可新增一个 App 任务,详见 [doc/TASK_DEV.md](doc/TASK_DEV.md)。
|
||
|
||
---
|
||
|
||
## 日志系统
|
||
|
||
日志按模块分文件,自动滚动(10MB 一份,保留 5 份历史):
|
||
|
||
| 文件 | 模块前缀 | 内容 |
|
||
|------|---------|------|
|
||
| `logs/core.log` | `core.*` | STF/adb/worker/task_manager 核心程序 |
|
||
| `logs/task.log` | `task.*` | 任务执行(worker 业务逻辑) |
|
||
| `logs/web.log` | `web.*` | Web 请求/管理 |
|
||
| `logs/action.log` | `action.*` | 操作执行(点赞/评论等) |
|
||
|
||
使用方式:
|
||
|
||
```python
|
||
from core.logger import get_logger
|
||
log = get_logger("task.douyin") # 写入 task.log
|
||
log.info(f"[{self.serial}] 开始任务")
|
||
```
|
||
|
||
Web 后台"日志"Tab 可实时查看各模块日志。
|
||
|
||
---
|
||
|
||
## 常用脚本
|
||
|
||
| 脚本 | 用途 |
|
||
|------|------|
|
||
| `python web_server.py` | 启动 Web 管理后台 |
|
||
| `python scripts/pack.py` | 打包项目为 zip(排除日志/数据库/APK) |
|
||
| `bash scripts/supervise.sh` | 进程守护(web_server 崩溃自动重启) |
|
||
|
||
---
|
||
|
||
## 常见问题
|
||
|
||
### 端口被占用(WinError 10013/10048)
|
||
|
||
`web_server.py` 会自动重试候选端口(原端口 → 127.0.0.1:原端口 → 127.0.0.1:原端口+1~+5)。如果全部失败,检查 Windows 动态端口范围:
|
||
|
||
```bash
|
||
netsh interface ipv4 show excludedportrange protocol=tcp
|
||
```
|
||
|
||
修改 `config.py` 中的 `WEB_PORT` 到一个不在排除范围内的端口。
|
||
|
||
### STF 设备显示离线但实际在线
|
||
|
||
STF 状态有缓存,`present=True` 不代表设备真在线。用"扫描前台App"按钮复测,或直接尝试执行任务。
|
||
|
||
### 设备一直被占用无法释放
|
||
|
||
监控页点"**强制释放占用**"按钮释放当前账户占用的所有设备;
|
||
无人值守场景可在 `.env` 设置 `AUTO_RELEASE_STALE_OCCUPY=true`(单实例)启动自动清理。
|
||
|
||
### u2.connect 卡死
|
||
|
||
`u2.connect()` 在 atx-agent 无响应时会永久 hang。基类已用 `ThreadPoolExecutor + 30 秒超时` 保护,超时自动放弃。如果频繁超时,检查设备 atx-agent 是否正常(重启设备或重新推送 atx-agent)。
|
||
|
||
### 任务运行中看门狗误杀
|
||
|
||
看门狗 120 秒无心跳会标记卡死。长耗时操作(如长视频等待)需在循环内周期性调用 `self.heartbeat()`。
|
||
|
||
### 中文输入失败
|
||
|
||
uiautomator2 默认 IME 不支持中文,需切到 FastInput 输入法:
|
||
|
||
```python
|
||
try:
|
||
d.set_fastinput_ime(True)
|
||
d.send_keys("中文内容")
|
||
finally:
|
||
d.set_fastinput_ime(False)
|
||
```
|
||
|
||
### 修改 core/ 后不生效
|
||
|
||
`web_server.py` 以 `debug=False` 运行,Python 不会热重载。修改 `core/` 目录下的文件后**必须重启 web_server 进程**。
|
||
|
||
### 元素抓取按钮不可用
|
||
|
||
依赖 uiautodev 服务(端口 20242)。确保已安装 `pip install uiautodev`。`web_server.py` 启动时会自动拉起该服务。
|
||
|
||
---
|
||
|
||
## 更多文档
|
||
|
||
| 文档 | 内容 |
|
||
|------|------|
|
||
| [doc/DEVELOPMENT.md](doc/DEVELOPMENT.md) | **开发手册**:开发流程、git 工作流、技术红线、环境、本地开发 |
|
||
| [doc/TASK_DEV.md](doc/TASK_DEV.md) | 任务开发指南(新增 App 任务的完整模板和规范) |
|
||
| [doc/ARCHITECTURE.md](doc/ARCHITECTURE.md) | 架构详解(分层设计、数据流、关键设计决策) |
|
||
| [doc/DEPLOY.md](doc/DEPLOY.md) | 部署指南(环境准备、STF 配置、生产部署) |
|
||
| [doc/API.md](doc/API.md) | API 接口文档(全部 HTTP 接口说明) |
|
||
|
||
> **注意**:所有 git 操作(含 push 到 dev)都需负责人确认后才能执行,详见开发手册。修改 `core/`、`tasks/`、`templates/` 后需重启服务/强刷浏览器才生效。
|
||
|
||
---
|
||
|
||
## 技术栈
|
||
|
||
| 组件 | 用途 |
|
||
|------|------|
|
||
| Flask + Flask-Login | Web 后台 + 用户认证 |
|
||
| Flask-SQLAlchemy | SQLite 数据持久化 |
|
||
| APScheduler | 定时任务调度 |
|
||
| uiautomator2 | Android UI 自动化 |
|
||
| uiautodev | UI 元素抓取(步骤编辑器"抓取元素") |
|
||
| pyaxmlparser | APK 元信息解析 |
|
||
| OpenSTF | 设备农场管理(占用/释放/远程 ADB) |
|