KO koko
Android / 2026SCROLL TO EXPLORE
返回瀑布流
04 / DEBUGlogcat · dumpsys · 复现 · 回滚2279 lines

一套可重复的设备调试流程

把日志、抓取、复现和回滚串成一条命令链,减少“只在我机器上出现”。

一套可重复的设备调试流程

把日志、抓取、复现和回滚串成一条命令链,减少“只在我机器上出现”。

这是一份面向自己开发设备的工程解析。示例强调输入、输出、失败证据和可回滚操作,不把一次实验结果扩展成所有设备都成立的结论。

阅读方式

每个章节都按“目标、动作、观察、结论”组织。先固定环境,再改变一个变量;先保存证据,再判断下一步。

1. 设备准备

目标

这一节把“设备准备”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

2. ADB 三段式架构

目标

这一节把“ADB 三段式架构”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

3. 设备授权

目标

这一节把“设备授权”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

4. ABI 判断

目标

这一节把“ABI 判断”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

5. 系统版本记录

目标

这一节把“系统版本记录”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

6. 日志清理

目标

这一节把“日志清理”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

7. logcat 过滤

目标

这一节把“logcat 过滤”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

8. dumpsys 采集

目标

这一节把“dumpsys 采集”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

9. 进程检查

目标

这一节把“进程检查”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

10. 文件检查

目标

这一节把“文件检查”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

11. 端口检查

目标

这一节把“端口检查”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

12. 抓取 tombstone

目标

这一节把“抓取 tombstone”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

13. 符号化

目标

这一节把“符号化”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

14. 复现脚本

目标

这一节把“复现脚本”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

15. 环境快照

目标

这一节把“环境快照”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

16. 命令退出码

目标

这一节把“命令退出码”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

17. 临时目录

目标

这一节把“临时目录”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

18. 权限排查

目标

这一节把“权限排查”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

19. SELinux 观察

目标

这一节把“SELinux 观察”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

20. 应用 UID

目标

这一节把“应用 UID”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

21. shell UID

目标

这一节把“shell UID”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

22. root UID

目标

这一节把“root UID”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

23. 网络调试

目标

这一节把“网络调试”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

24. 无线 ADB

目标

这一节把“无线 ADB”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

25. 设备离线

目标

这一节把“设备离线”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

26. 安装回滚

目标

这一节把“安装回滚”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

27. 数据清理

目标

这一节把“数据清理”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

28. 冷启动

目标

这一节把“冷启动”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

29. 热启动

目标

这一节把“热启动”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

30. 性能基线

目标

这一节把“性能基线”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

31. 线程采样

目标

这一节把“线程采样”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

32. 内存采样

目标

这一节把“内存采样”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

33. 电量影响

目标

这一节把“电量影响”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

34. 后台限制

目标

这一节把“后台限制”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

35. 厂商差异

目标

这一节把“厂商差异”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

36. 自动化脚本

目标

这一节把“自动化脚本”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

37. 失败证据

目标

这一节把“失败证据”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

38. 问题最小化

目标

这一节把“问题最小化”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

39. 修复验证

目标

这一节把“修复验证”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

40. 发布前检查

目标

这一节把“发布前检查”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

41. 设备准备

目标

这一节把“设备准备”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

42. ADB 三段式架构

目标

这一节把“ADB 三段式架构”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

43. 设备授权

目标

这一节把“设备授权”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

44. ABI 判断

目标

这一节把“ABI 判断”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

45. 系统版本记录

目标

这一节把“系统版本记录”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

46. 日志清理

目标

这一节把“日志清理”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

47. logcat 过滤

目标

这一节把“logcat 过滤”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

48. dumpsys 采集

目标

这一节把“dumpsys 采集”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

49. 进程检查

目标

这一节把“进程检查”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

50. 文件检查

目标

这一节把“文件检查”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

51. 端口检查

目标

这一节把“端口检查”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

52. 抓取 tombstone

目标

这一节把“抓取 tombstone”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

53. 符号化

目标

这一节把“符号化”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

54. 复现脚本

目标

这一节把“复现脚本”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

55. 环境快照

目标

这一节把“环境快照”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

56. 命令退出码

目标

这一节把“命令退出码”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

57. 临时目录

目标

这一节把“临时目录”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

58. 权限排查

目标

这一节把“权限排查”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

59. SELinux 观察

目标

这一节把“SELinux 观察”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

60. 应用 UID

目标

这一节把“应用 UID”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

61. shell UID

目标

这一节把“shell UID”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

62. root UID

目标

这一节把“root UID”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

63. 网络调试

目标

这一节把“网络调试”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

64. 无线 ADB

目标

这一节把“无线 ADB”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

65. 设备离线

目标

这一节把“设备离线”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

66. 安装回滚

目标

这一节把“安装回滚”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

67. 数据清理

目标

这一节把“数据清理”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

68. 冷启动

目标

这一节把“冷启动”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

69. 热启动

目标

这一节把“热启动”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

70. 性能基线

目标

这一节把“性能基线”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

71. 线程采样

目标

这一节把“线程采样”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

72. 内存采样

目标

这一节把“内存采样”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

73. 电量影响

目标

这一节把“电量影响”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

74. 后台限制

目标

这一节把“后台限制”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

75. 厂商差异

目标

这一节把“厂商差异”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

76. 自动化脚本

目标

这一节把“自动化脚本”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

77. 失败证据

目标

这一节把“失败证据”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

78. 问题最小化

目标

这一节把“问题最小化”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

79. 修复验证

目标

这一节把“修复验证”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

80. 发布前检查

目标

这一节把“发布前检查”放到完整调用链中,先说明它解决的实际问题,再给出可以在本地复现的最小步骤。

执行

adb wait-for-device
adb shell "getprop ro.build.version.sdk"
adb shell "id && ps -A | head"

观察

  • 输入:自己的构建产物、明确的参数和当前设备环境。
  • 输出:日志、退出码、文件状态、连接状态或界面反馈。
  • 失败证据:保留完整命令、设备版本、UID 和发生顺序。

结论

如果结果与预期不同,先缩小变量范围,不要直接增加权限或替换整条链路。可复现的失败比模糊的“偶尔成功”更有价值。

收束

当接口、设备、进程和界面状态都能被记录,底层工具才真正具备长期维护的基础。