这篇文章完整记录了基于 Web 项目编写 Android 自动化逻辑的实现过程:在 AssistsX 中运行,完成抖音 App 的未读消息检查与未读会话列表采集。
最终要实现的目标非常清晰:
- 自动拉起抖音 App
- 检测底部消息 Tab 是否存在未读红点
- 进入消息列表,逐页抓取所有未读会话
- 解析出昵称、未读数量、最后一条消息内容及时间
- 在日志浮窗中实时展示执行结果
Web 方案需要准备什么
请注意,这里不是要求你开发一个原生 Android 应用,而是编写一个 Web 插件,由 AssistsX 在 Android 端加载并执行。先梳理清楚所需的基础条件,后面再逐步展开。
先盘点需要的两端平台
实际上只需要两个端:
- 电脑端:用于开发 Web 项目,启动 Vite 开发服务器
- Android 手机端:安装 AssistsX,并开启无障碍服务
整体链路如下:Vue 页面和 assistsx-js 逻辑运行在 AssistsX 的 WebView 中,然后由 AssistsX 调用 Android 的无障碍能力对抖音 App 进行操作。
需要集成哪些核心库
核心库是 assistsx-js,它负责打通 Web 端代码与 Android 自动化能力。常用的能力包括:
- 节点查找:
findById、findByTags - 节点操作:点击、滚动
- 步骤编排:
Step.run、step.next - 浮窗与日志:用于实时展示执行过程
Web 项目选用什么框架
本项目采用 Vue 3、Vite、TypeScript、Vue Router 以及 assistsx-js。本质上它仍是一个前端项目,只是运行环境不再是普通浏览器,而是 AssistsX 内部的 WebView。
创建 Web 项目
从零搭建一个 assistsx-js 项目,直接使用脚手架创建即可:
npx create-assistsx-vue@latest my-app
cd my-app
npm run dev
该命令会生成一个 Vue 3 + Vite + TypeScript 项目,同时将 assistsx-js、路由、日志浮窗、测试面板以及基础 Step 代码一并配置好。后续只需将默认步骤替换成你自己的自动化逻辑。
如果想在当前目录初始化,也可以使用以下命令:
mkdir my-app && cd my-app
npx create-assistsx-vue@latest --here
npm run dev
本文所涉及的抖音未读消息功能,就是在类似的项目结构上继续实现的。
如果你已经拉取了本文源码,进入项目后安装依赖:
npm install
然后启动开发服务:
npm run dev
项目已将 Vite 配置为局域网可访问,因此手机和电脑处于同一 Wi-Fi 下时,手机可直接访问 https://<电脑IP>:5173。
配置插件信息
AssistsX 加载插件时会读取 public/config.json,其中包含插件名称、入口文件、图标等信息:
{
"name": "Message Automation",
"packageName": "com.dy.automation.example",
"index": "index.html",
"icon": "icon.png"
}
其中 index 对应 Web 项目的入口页面,packageName 是插件自身的包名标识,并非目标 App 的包名。
安装平台并加载插件
手机端需要先安装 AssistsX。安装后打开无障碍服务,并确保手机与电脑处于同一局域网。
在 AssistsX 中通过局域网加载插件的步骤并不复杂:
- 电脑先执行
npm run dev,手机与电脑连接同一个 Wi-Fi - 打开 AssistsX,点击首页的「+」号
- 选择「扫描局域网」,等待扫描结果
- 找到本项目的 dev 地址(
https://<电脑IP>:5173),点击「安装」 - 返回首页,即可看到插件,点击启动
分析抖音页面节点
编写 Android 自动化最关键的一步,不是急于写代码,而是先仔细观察页面节点结构。
例如,要点击底部的「消息」按钮,或判断某一行是否为未读消息,你需要清楚这些控件在无障碍节点中的形态。这里我们借助 AssistsX 的节点分析服务。
常见的操作流程如下:
- 手机上先打开抖音,停留在待分析的页面,比如首页或消息列表页
- 在 AssistsX 中开启节点分析
- 电脑浏览器访问 AssistsX 提供的局域网分析地址
- 在节点树中找到目标控件
分析时需要重点关注以下几个字段:
className:控件类型,例如android.widget.Button、android.widget.TextViewtext:界面上显示的文字,例如底部消息 Tab 上的未读数字des:无障碍描述,抖音消息行中经常将昵称、未读数、最后一条消息拼接在此处id:资源 ID,某些页面可以直接用它来定位控件
获取这些信息后,代码中即可使用 findByTags、findById、filterDes 等方法查找节点。这种方式比硬编码坐标更稳定,即使页面尺寸或手机分辨率发生变化,自动化逻辑也不易失效。

实现功能入口
插件主页仅放置两个操作入口:
- 检查未读消息
- 获取未读消息列表
点击按钮后会打开一个日志浮窗,并将要执行的动作通过 query 参数传递:
void float.open(`/examples/log-panel?action=${action}`, {
showBottomOperationArea: true,
})
日志浮窗承担两项职责:一边显示执行日志,一边启动自动化流程。
启动流程的代码大致如下:
await Step.run(appLaunch.launch, {
data: {
appName: "DY",
packageName: "com.ss.android.ugc.aweme",
finishMethod: douyinMain.checkMainPage,
...flowData,
},
});
这里先从 appLaunch.launch 步骤开始,负责拉起抖音 App。启动成功后,再进入 douyinMain.checkMainPage,判断当前是否处于抖音首页。
实现自动化流程
主要代码位于 src/steps/ 目录下。所有逻辑并未堆砌在一个函数中,而是拆分为多个步骤,通过 step.next() 依次推进。
整体流程如下:
启动抖音
↓
确认回到抖音首页
↓
检查底部消息 Tab 未读数
↓
如需收集列表,点击消息 Tab
↓
消息列表滚动到顶部
↓
逐页收集未读消息
检查未读消息较为直接:找到底部导航中的“消息,按钮”,然后查看其附近是否存在纯数字的 TextView。有数字即表示存在未读消息。
收集未读消息列表则稍显复杂。进入消息列表后,先找到屏幕中的 RecyclerView,再遍历其中的消息行。消息行本身通常是 android.widget.Button,未读角标位于右侧,具体内容包含在该行的 des 描述中。
例如,节点描述可能如下:
早上好咸鱼翻面,未读1条消息,hgff8分钟前
互动消息,未读1条消息,咸鱼翻面 近期访问过你的主页05/13
这里需要解析出四个字段:
nickname:昵称unreadCount:未读数量lastMessage:最后一条消息内容time:消息时间,最终会转换为时间戳
如果 des 中未包含“未读X条消息”字样,则说明该行不是未读消息,直接跳过。
列表滚动时存在一个小坑:上下页之间可能会重复扫描到同一条消息。因此,收集时会将已获取的数据保存在类变量中,若 nickname、unreadCount、lastMessage、time 四个字段完全相同,则视为重复数据并跳过。
日志中最终呈现的效果类似如下:
【未读消息】
昵称:早上好咸鱼翻面
未读:1 条
内容:hgff
时间:2026-05-30 08:12:00
运行功能
准备条件并不多:
- Android 手机上安装 AssistsX,并开启无障碍服务
- 手机已安装抖音 App
- 电脑与手机处于同一局域网
- 本机具备 Node.js 环境
启动项目:
npm install
npm run dev
插件安装完成后,在 AssistsX 首页打开即可。进入插件后,点击「检查未读消息」或「获取未读消息列表」开始运行。
运行过程中,日志浮窗会持续显示当前执行进度。如果流程出现偏差,或需要手动停止,可点击浮窗中的「停止」按钮,内部会调用:
Step.stop()
合规说明
本文内容仅用于学习如何通过 Web 方式开发 Android 自动化。实际使用中,请遵守相关平台规则与法律法规,避免用于违规采集、骚扰或其他不合规场景。
