该技能面向需要在应用中删除与新版功能重复的旧实现,并避免因共享句柄导致误删或残留的场景。
用途:当一个应用内部实现替换了原先将工作交给进程外部完成的旧实现时,旧实现必须被删除而非仅隐藏。两个效果作用于同一输出会相乘,用户会归咎于可见的那个入口;仅隐藏入口点会让另一个效果继续附着。
主要能力与审计要点:
- 识别句柄的真实用户:看似属于被删功能的句柄(如音频会话标识符)可能在移除旧集成后仍被其他功能使用(如音量归一化附着于同一会话)。删除它会连带移除不相关功能,且编译错误会出现在看似无关的文件中。应找到真实用户,若保留该句柄,在声明注释中写明真实用户。
- 处理已附着的外部效果:监听者绑定在会话上而非代码路径上,进程结束前不会解绑。因此变更后首次运行仍会表现为旧行为,需每次判断前强制停止应用。
- 删除跨平台空实现桩:跨平台集成通常有一个真实实现和多个空操作。移除真实实现时,应同一变更中删除声明、平台 actual 实现及接口方法这一整组,避免留下“部分平台支持”的假象。
- 清理设置项与字符串资源:超过其生命周期的设置行会无操作或抛异常,需检索设置界面、字符串和偏好键,尤其是字符串资源能逃过所有编译器检查。
- 检查非代码可达性:“无引用”不等于“不可达”。广播动作、intent 过滤器、清单条目、反射和依赖注入模块注册均可无 Kotlin 引用而可达。仅靠编译器验证会留下清单中已删除能力的声明。
- 处理存储偏好:旧功能开关仍在存储中且对现有用户为 true,需明确决定下次启动删除该键或保留并记录原因,避免静默遗弃。
- 不要用标志位保留已删除路径:一旦启用会重现相乘问题,且无 UI 的标志无人测试。若旧集成必须存活一个版本,应保持可见并使其与新版互斥。
使用方式(验证): 移除通过“不存在”来验证,将缺失变为期望计数为零的命令,将保留变为期望计数大于零的命令。示例命令:
被删除链中的每个名称——调用点、监听器回调、常量、桩、设置行
for sym in notifyEffectIntent shouldOpenEffectSession openExternalEffect EFFECT_SESSION_ACTION; do printf '%-32s %s\n' "$sym" "$(grep -rn --include='.kt' --include='.xml' "$sym" . | wc -l)" done # 每行必须打印 0
故意保留的句柄及其真实用户——两者都必须非零
grep -rn --include='.kt' 'audioSessionId' . | wc -l grep -rn --include='.kt' 'LoudnessEnhancer' . | wc -l
需包含 --include='*.xml' 并对清单文件执行一遍检查,仅 Kotlin 的 grep 会报告干净移除,而 intent 过滤器仍宣传该功能。
然后按顺序进行运行时检查:强制停止应用、重新启动、启用新实现、确认响应仅与新实现匹配。跳过强制停止将测量到前一进程。
适用场景:Android/Kotlin 项目中下线与新版重叠的旧功能,尤其是涉及共享音频会话等跨模块句柄、跨平台实现和设置项的场景。
限制:资料未提供该技能的具体安装方式、依赖要求、平台版本支持范围或自动化程度;内容基于 Kotlin/Android 示例,其他语言或平台需自行调整审计步骤。