fix(android): 图搜归位的返回动作不等页面稳定,预算空转导致归位失败 #292

Open
opened 2026-09-16 11:33:51 +08:00 by ila · 1 comment
Owner

来源:2026-09-16 本地真机验证 #290 时复现。用户原话:「刚才真机还是卡在无法识别图片界面,agent再次开始任务时,为什么没有成功回到首页呢」。

问题

上一次图搜失败后手机停在 PDD 深层页面(NewPageActivity)。下一个图搜任务启动时,归位状态机按了满预算的返回键仍未回到首页,报 IMAGE_SEARCH_ENTRY_NOT_FOUND。

本地任务 156:running 11:27:23 → failed 11:27:38,15 秒。MAX_RECOVERY_ACTIONS = 50,RECOVERY_STEP_MILLIS = 300,50 × (抓树 + 300ms) ≈ 15 秒,时长吻合。

根因

enterAndSelectImage 的 BACK 分支按完就走,不等页面稳定:

ImageSearchRecoveryAction.BACK -> driver.back()
...
pause(RECOVERY_STEP_MILLIS)   // 300ms

300ms 不足以让 PDD 完成一次页面切换。按下 BACK → 300ms 后抓树 → 抓到切换动画中间态 → 判据全不命中 → 归为 OTHER_PDD → 再按一次。预算在 15 秒内空转耗尽,App 可能一次完整返回都没做完。

[必须] 同一个坑在 CLICK_CAMERA 分支已经修过(该分支有 awaitPage(ENTRY_SETTLE_TIMEOUT_MILLIS),并留有注释说明「页面加载中时判据一个都不命中,会被判成 OTHER_PDD 并按下返回键」)。BACK 是唯一一个动作后不等待的分支,等于同一个坑只修了一半。

方案

  1. BACK 之后同样等待页面形态发生变化再进入下一轮判定,而不是固定 300ms 盲等。
  2. 连续多次归位动作后仍停留在 OTHER_PDD 时,改用 launcher intent 重新拉起 PDD 回首页,不再盲按返回。

非目标

  • 不改 MAX_RECOVERY_ACTIONS 的语义,不放宽任何失败判据。
  • 不改 RETRY_DIALOG 的处理(BACK 对它无效,已单独处理)。
  • 订单确认页仍然只允许返回,绝不点击任何支付/下单控件。

验收

  • 手机停在 PDD 深层页面时,新图搜任务能归位到首页并进入图搜入口。
  • 归位动作数显著小于预算上限(不再空转)。
  • 归位始终失败时仍然明确失败,不静默重试。
  • 已有归位用例(含重试弹窗、订单确认页、非 PDD 前台)行为不变。

验证

Android 单元测试;真机复现场景:先让一个图搜任务失败停在结果页,再发起新任务。

文档影响

归位行为属于内部状态机,入口、接口、错误码均不变,无长期文档影响。

> 来源:2026-09-16 本地真机验证 #290 时复现。用户原话:「刚才真机还是卡在无法识别图片界面,agent再次开始任务时,为什么没有成功回到首页呢」。 ## 问题 上一次图搜失败后手机停在 PDD 深层页面(`NewPageActivity`)。下一个图搜任务启动时,归位状态机按了满预算的返回键仍未回到首页,报 `IMAGE_SEARCH_ENTRY_NOT_FOUND`。 本地任务 156:`running` 11:27:23 → `failed` 11:27:38,**15 秒**。`MAX_RECOVERY_ACTIONS = 50`,`RECOVERY_STEP_MILLIS = 300`,50 × (抓树 + 300ms) ≈ 15 秒,时长吻合。 ## 根因 `enterAndSelectImage` 的 `BACK` 分支按完就走,不等页面稳定: ```kotlin ImageSearchRecoveryAction.BACK -> driver.back() ... pause(RECOVERY_STEP_MILLIS) // 300ms ``` 300ms 不足以让 PDD 完成一次页面切换。按下 BACK → 300ms 后抓树 → 抓到切换动画中间态 → 判据全不命中 → 归为 `OTHER_PDD` → 再按一次。预算在 15 秒内空转耗尽,App 可能一次完整返回都没做完。 `[必须]` 同一个坑在 `CLICK_CAMERA` 分支已经修过(该分支有 `awaitPage(ENTRY_SETTLE_TIMEOUT_MILLIS)`,并留有注释说明「页面加载中时判据一个都不命中,会被判成 OTHER_PDD 并按下返回键」)。`BACK` 是唯一一个动作后不等待的分支,等于同一个坑只修了一半。 ## 方案 1. `BACK` 之后同样等待页面形态发生变化再进入下一轮判定,而不是固定 300ms 盲等。 2. 连续多次归位动作后仍停留在 `OTHER_PDD` 时,改用 launcher intent 重新拉起 PDD 回首页,不再盲按返回。 ## 非目标 - 不改 `MAX_RECOVERY_ACTIONS` 的语义,不放宽任何失败判据。 - 不改 `RETRY_DIALOG` 的处理(BACK 对它无效,已单独处理)。 - 订单确认页仍然只允许返回,绝不点击任何支付/下单控件。 ## 验收 - [ ] 手机停在 PDD 深层页面时,新图搜任务能归位到首页并进入图搜入口。 - [ ] 归位动作数显著小于预算上限(不再空转)。 - [ ] 归位始终失败时仍然明确失败,不静默重试。 - [ ] 已有归位用例(含重试弹窗、订单确认页、非 PDD 前台)行为不变。 ## 验证 Android 单元测试;真机复现场景:先让一个图搜任务失败停在结果页,再发起新任务。 ## 文档影响 归位行为属于内部状态机,入口、接口、错误码均不变,无长期文档影响。
Author
Owner

实施

提交 bb097a6。

  • enterAndSelectImage 的 BACK 分支改为 awaitPage(BACK_SETTLE_TIMEOUT_MILLIS) { it != kind },等页面形态真的变化再判下一步。
  • 连续 MAX_STALLED_BACKS = 3 次推不动,调用新增的 resetPddToHome() 清栈回首页。
  • resetPddToHome 与 launchPddToForeground 分开:后者只带 FLAG_ACTIVITY_NEW_TASK,会连同深层页面一起恢复,采集当前页的流程正需要那个行为;归位要的是相反效果,单独加 FLAG_ACTIVITY_CLEAR_TOP。

已验证

新增 ImageSearchBackRecoveryTest(2 个用例):页面推不动时触发清栈重启且仍明确失败;页面能被推动时不触发。Android 全量单测 372 通过、0 失败。

未验证

真机未复验。需要构造场景:先让一个图搜任务失败停在结果页,再发起新任务。当前 APK versionCode 未 bump,无法通过版本管理分发。

状态

待验收。

## 实施 提交 `bb097a6`。 - `enterAndSelectImage` 的 `BACK` 分支改为 `awaitPage(BACK_SETTLE_TIMEOUT_MILLIS) { it != kind }`,等页面形态真的变化再判下一步。 - 连续 `MAX_STALLED_BACKS = 3` 次推不动,调用新增的 `resetPddToHome()` 清栈回首页。 - `resetPddToHome` 与 `launchPddToForeground` 分开:后者只带 `FLAG_ACTIVITY_NEW_TASK`,会连同深层页面一起恢复,采集当前页的流程正需要那个行为;归位要的是相反效果,单独加 `FLAG_ACTIVITY_CLEAR_TOP`。 ## 已验证 新增 `ImageSearchBackRecoveryTest`(2 个用例):页面推不动时触发清栈重启且仍明确失败;页面能被推动时不触发。Android 全量单测 **372 通过、0 失败**。 ## 未验证 真机未复验。需要构造场景:先让一个图搜任务失败停在结果页,再发起新任务。当前 APK `versionCode` 未 bump,无法通过版本管理分发。 ## 状态 待验收。
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: OPC/goauto#292