比较目的与适用条件
比较前台与锁屏,是为了回答:同一套配置下,系统是否仍把 Clash Meta for Android 当作当前 VPN,以及离开可交互界面后生命周期有没有变化。该应用是 Clash.Meta 的图形界面,最低 Android 5.0,建议 7.0 及以上。比较必须在同一用户(或同一工作资料)上进行,因为每个用户只能运行一个活动 VPN 服务。
适用条件:已经通过系统连接请求对话框,VPN 列表中能看到该应用;测试期间不要切换到其他 VPN,也不要“忘记”当前应用。锁屏环境代表应用不在前台可交互状态,可能触发 Android 8.0 及以上的后台限制。前台环境代表用户可以点按应用提供的启动/停止控件,并且点按活动通知能回到应用。
始终开启 VPN 在 Android 7.0 及以上可用,由系统在开机后启动并维持服务。比较时要先固定该选项是开还是关,否则两次结果不能互相对照。
前台基线怎么采
屏幕保持亮起,应用位于前台,按同一清单记录,不添加主观描述。
记录状态栏是否有 VPN(钥匙)图标。这是系统级活动连接标志。
记录是否存在服务活动期间的不可消除通知,通知是否包含连接状态或网络统计。点按该通知应能把应用带到前台;若前台测试时通知就不存在,锁屏对比没有基线。
记录快捷设置是否出现活动连接信息面板,点按标签能否看到更多信息及设置链接。
记录设置 > 网络和互联网 > VPN 中的条目状态,包括是否仅被授权、是否打开始终开启、是否打开阻止不使用 VPN 的连接。后一项会在 VPN 尚未连上时警告可能没有互联网,并拦截非 VPN 流量。
记录应用侧是否仍提供手动启动和停止。始终开启由系统和设置应用控制连接时,应用应避免再用自己的断开界面与系统抢控制权;比较前台/锁屏前,先写明当前是“应用启动的服务”还是“系统按始终开启拉起的服务”。可用是否向 com.github.kr328.clash.ExternalControlActivity 发送过 START_CLASH 来辅助标记;未带标记而被拉起的实例,可按文档思路视为系统侧始终开启启动。
若前台基线里图标、通知、快捷设置任一缺失,先完成准备与 establish() 流程:未准备或权限撤销时无法建立本地 TUN,锁屏对比无效。
锁屏环境怎么采、如何下结论及失败下一步
在不改变配置、不切换 VPN 的前提下锁屏。亮屏后立即重复前台那份清单,只允许增加“锁屏持续时长”和“期间是否出现始终开启失败通知”两列。Android 8.0 及以上在始终开启断开或无法连接时会显示不可消除通知。
结论规则要写死。前台三项系统 UI 齐全、锁屏后仍齐全:系统仍认定 VPN 活动,前台与锁屏在“服务是否存在”这一层没有差异;若此时业务不通,应去查网关、路由、允许/拒绝应用列表,而不是当成锁屏杀死了 VPN。前台齐全、锁屏后三项全无:差异发生在服务生命周期,符合后台限制或被系统停止(断开、忘记、关闭始终开启、另一 VPN 抢占)。前台齐全、锁屏后图标还在但出现始终开启无法连接通知:系统在维持服务,但网关连接失败,这与“锁屏把服务收掉”不是一类。
还要比较流量路径是否仍可能经过 TUN。建立接口时至少要有地址和路由;若路由是开放路由,系统会把匹配流量送进 VPN 接口。锁屏后若服务已 onRevoke(),替代接口已经在转发,再比较应用内“是否像连着”没有意义。
失败时下一步:若无法形成前台基线,回到连接请求与 VPN 列表,确认没有第二个 VPN。若仅锁屏失败,保持始终开启开关不变,改在亮屏但应用退到桌面的条件下复测一次,用来拆开“仅仅不在前台”和“屏幕关闭”两个变量。需要重复启停时,使用 START_CLASH、STOP_CLASH、TOGGLE_CLASH(包名 com.github.metacubex.clash.meta),每次只改一个变量并重填清单。两次清单冲突时,以系统图标、通知、VPN 列表为准,不以应用是否还在近期任务里为准。
https://developer.android.com/develop/connectivity/vpn https://github.com/MetaCubeX/ClashMetaForAndroid