From c8f19f9c842a6dff5d011b958f8846528d88c082 Mon Sep 17 00:00:00 2001 From: AskaEth Date: Wed, 7 Oct 2026 00:18:51 +0800 Subject: [PATCH] =?UTF-8?q?docs(05):=20=E9=94=9A=E7=82=B9=E8=A1=A5?= =?UTF-8?q?=E8=AE=B0=E4=B8=89=E5=8D=81=E4=B8=83=20=E2=80=94=E2=80=94=20?= =?UTF-8?q?=E9=95=BF=E8=B7=91=E7=AC=AC3=E6=AC=A1=E5=AE=9A=E6=A1=88?= =?UTF-8?q?=EF=BC=8830min=20=E6=9C=89=E6=95=88=E9=80=9A=E8=BF=87=EF=BC=9B2?= =?UTF-8?q?h=20=E5=A4=B1=E8=B4=A5=E6=98=AF=E6=A8=A1=E6=8B=9F=E5=99=A8=20sy?= =?UTF-8?q?stem=5Fserver=20=E5=B4=A9=E6=BA=83=E8=BF=9E=E5=B8=A6=E6=9D=80?= =?UTF-8?q?=E8=BF=9B=E7=A8=8B=EF=BC=8C=E4=BA=94=E6=9D=A1=E8=AF=81=E6=8D=AE?= =?UTF-8?q?=EF=BC=89+=20Android=2014=20=E5=88=92=E6=8E=89=E4=BC=9A?= =?UTF-8?q?=E7=BB=88=E6=AD=A2=20dataSync=20=E5=89=8D=E5=8F=B0=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=EF=BC=88=E9=AA=8C=E6=94=B6=E9=80=A0=E5=9C=BA=E6=99=AF?= =?UTF-8?q?=E6=94=B9=E7=94=A8=E8=BF=94=E5=9B=9E=E9=94=AE=20finish=20Activi?= =?UTF-8?q?ty=EF=BC=89+=20W57=20=E7=AB=AF=E5=88=B0=E7=AB=AF=E9=AA=8C?= =?UTF-8?q?=E6=94=B6=E9=80=9A=E8=BF=87=EF=BC=88=E5=90=AB=E6=9C=AA=E5=81=9A?= =?UTF-8?q?=E6=94=B9=E5=89=8D=E5=AF=B9=E7=85=A7=E7=9A=84=E5=A6=82=E5=AE=9E?= =?UTF-8?q?=E8=AF=B4=E6=98=8E=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- devdocs/05-开发进度与交接.md | 61 ++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/devdocs/05-开发进度与交接.md b/devdocs/05-开发进度与交接.md index 5c8866f..06a6a0c 100644 --- a/devdocs/05-开发进度与交接.md +++ b/devdocs/05-开发进度与交接.md @@ -1960,3 +1960,64 @@ pidof top.yeij.cyrene # 期望:与前面同一个 PID( **★ 顺带推翻了一条猜想**:锚点三十五 §7 猜「上次复查时进程不在」可能是**保活开关没开**。这次 App 一启动我就查了——**服务立刻就在跑**(开关是开的)。所以那条猜想**是错的**,上次进程消失是**别的**原因(可能是系统低内存强杀,也可能是被手动划掉——**仍未定**,别当结论)。 **当前转发**:`tcp:80 → tcp:18090`(假后端)、`tcp:10942 → tcp:10942`(真后端)。要回真后端改这一条即可。 + +## ★★ 锚点补记三十七 · 长跑第 3 次定案(模拟器崩,不是 App 的问题)+ W57 端到端验收通过(2026-10-07 00:30) + +### 1. 长跑第 3 次结果:**30 分钟有效通过;2 小时那次失败是模拟器自己崩了** + +原始输出: + +``` +=== 30min 抽查 @ 22:46:34 === === 2h 复查 @ 00:16:34 === +pid: 31092 pid: (空) +服务: 3 服务: 0 +前台: launcher(仍在后台) 前台: Window{4f748ad …launcher} +ws: 1 ws: 0 + 注入 delivered=0 / proactive 通知数 0 +``` + +**30 分钟那一条是有效证据**:pid 与基线一致(31092)、服务 3 条、仍在后台、WS 还连着 ⇒ **半小时后台存活成立**。 + +**2 小时那一条的失败与 App 无关**,证据链(五条独立): + +1. `logcat` 在**模拟器时间 16:02(≈宿主 00:08,正卡在两次抽查之间)**出现整段**开机序列**(`sys.boot_completed=1`、lmkd 启动、apexd…)。 +2. 但 `/proc/uptime` = **10.19 小时,没变** ⇒ **不是整机重启,是 system_server(framework)崩溃后重启**。 +3. launcher 的 window id 从 `2cbfcc8` → `4f748ad` ⇒ launcher 也重启过(对上)。 +4. `dumpsys activity exit-info top.yeij.cyrene`(共 16 条)里**没有 pid 31092 的退出记录**,最新一条还是宿主 21:29 我装包那次(`reason=16 PACKAGE UPDATED`)⇒ 走的**不是**正常进程退出路径。 +5. 通知栏里那条 `keep_alive` 通知**还残留着** ⇒ 进程非正常死亡(系统没来得及清)。 + +**结论**:模拟器 framework 崩 ⇒ 连带杀掉所有 App ⇒ 与客户端保活能力无关。**但也不能反过来当「保活能撑 2 小时」的证据**(那次没跑到)。模拟器这台机器(摘要里就记过「极不稳、launcher ANR 过、system_server 会崩」)**不适合做小时级长跑**,要拿这个结论得上真机。 + +### 2. ⚠️ 一条要紧的平台发现:Android 14 起「从最近任务划掉」会终止 `dataSync` 前台服务 + +原本 W57 的验收步骤是照「把卡片划掉」写的 —— 那**测不出 W57**:Android 14 改变了行为,用户划掉 App 时它的前台服务会被一并终止(我们的服务类型是 `dataSync`),进程随之死掉,于是「Activity 没了但进程还在」这个场景**根本造不出来**。 + +**改用正确造法**(本次采用,成功): +``` +adb shell am start -n top.yeij.cyrene/.app.MainActivity # 确保 Activity 在前台 +adb shell input keyevent 4 ×4 # 逐层返回直到 Activity finish +``` +判据:**前台变成 launcher**(Activity 已 finish)+ **pid 不变** + **服务条数不变** + **WS 仍连着** ⇒ 场景成立。 + +### 3. W57 端到端验收:**通过**(`emulator-5554` + 假后端 18090,含 W57 的 APK = `900d191`) + +| 步骤 | 实测值 | +|---|---| +| 通知权限 | `POST_NOTIFICATIONS: granted=true` | +| 装包含 W57 的 APK 后 | `pid=3180`、`KeepAliveService` **3 条**(开关本来就是开的,服务随启动自起) | +| 造场景(返回键 ×4) | 前台 = **launcher**(Activity finish)、**pid 仍 3180**、服务 **3 条**、假后端 `wsClients=1` | +| 注入前 `channel=proactive` | **0** | +| 注入 `proactive_message`(content「W57验收:Activity 没了也要弹」) | `delivered=1` | +| 注入后 `channel=proactive` | **1** | +| 通知内容 | `android.title=昔涟`、`android.text=W57验收:Activity 没了也要弹`(`bigText` 同) | +| 注入后 pid | **3180**(与场景建立前同一个 ⇒ **同一进程**,不是重启后补弹) | + +⇒ **Activity 已销毁、进程靠前台服务活着时,「她主动说的话」照常弹通知。** 这正是 W57 要修的那一档。 + +**⚠️ 如实说明我们没做的**:**没有做「改前不弹」的对照实验**(要另出 W57 之前的 APK、再走一遍,会占构建锁和一次装包)。所以「改前确实不弹」这一半靠的是**代码级确定性证据**(订阅挂在 `viewModelScope`、`replay=0` 的 SharedFlow 丢弃无订阅者的 emit)与 9 条单测,**不是**实验证据。**别把它说成「实验证明改前是坏的」。** + +### 4. 环境现状(收工前) +- HEAD = **`900d191`** = `origin/android`;worktree/分支/构建锁**全清**;主仓唯一脏 = `devdocs/02`(后端在途 + 我那条 markup 登记)。 +- 模拟器上装的是**含 W57 的 APK**;App 现在**进程活着但 Activity 已 finish**(前台 launcher),登录的是假后端 `localhost`。 +- 转发:`tcp:80 → tcp:18090`(假后端)、`tcp:10942 → tcp:10942`(真后端)。**要回真后端只改 `tcp:80` 一条。** +- 假后端 18090 进程仍在。