news 2026/9/15 21:18:21

VirtualApp 悬浮窗权限适配:从宿主到沙盒的 4 个关键卡点

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
VirtualApp 悬浮窗权限适配:从宿主到沙盒的 4 个关键卡点

VirtualApp 悬浮窗权限适配:从宿主到沙盒的 4 个关键卡点

【免费下载链接】VirtualAppVirtual Engine for Android(Support 14.0 in business version)项目地址: https://gitcode.com/GitHub_Trending/vi/VirtualApp

悬浮窗是沙盒应用的基础能力,但它的权限机制和普通应用有本质区别:系统只认宿主 UID,悬浮窗却属于沙盒里的应用。VirtualApp 悬浮窗权限适配就围绕这两条主线展开:权限引导,以及跨进程的窗口透传。

为什么沙盒悬浮窗比普通 App 难搞

普通应用的流程很简单:声明SYSTEM_ALERT_WINDOW,用户授权,addView成功。VirtualApp 多两层。

第一层:宿主权限 ≠ 沙盒权限。系统侧的权限检查按"谁发起请求"(UID)执行。沙盒应用的窗口操作实际由宿主进程代为执行,伪装的包名在权限检查里不存在。在 SYSTEM_ALERT_WINDOW 多开场景下,同一个 VAPP 里的所有沙盒应用共享宿主的权限状态——宿主授权一次,全部实例生效。

第二层:跨进程状态同步。沙盒应用跑在独立的 VAPP 进程,宿主进程负责生命周期和 IPC。"能不能弹悬浮窗"这个状态必须在两个进程间保持一致,任何一侧失步,窗口都会被系统撤掉。

沙盒悬浮窗跨进程问题的本质就一句话:窗口活在 VAPP 进程里,权限却挂在宿主 UID 上

VirtualApp 三层架构与 overlay 权限

VA Framework 在应用层 Hook AMS、PMS、Window 等系统服务。沙盒应用调用 WindowManager 时先经过这一层,窗口请求由此被"改道"到宿主的执行链路。

VA Server 负责跨进程通信。overlay 权限是否授予、窗口记录等状态都汇总在 Server,VAPP 进程查询权限时从这里取答案,而不是本地缓存。

VA Native 负责文件系统和 syscall 级 Hook,为沙盒应用提供稳定运行环境。它不直接处理 overlay 权限,却是悬浮窗进程不被回收的底座。

Android 沙盒应用 overlay 权限适配的核心原则是:发起窗口前必须走一次宿主侧的权限判定。架构细节可参考官方 VADev 开发文档。

分场景适配:4 个真实卡点

卡点一:宿主拿不到 SYSTEM_ALERT_WINDOW 时的引导流程

现象:addViewBadTokenException,或悬浮窗直接不显示。原因:API 23 起它被归为特殊权限,运行时授权弹框授不了,必须由用户在设置页手动打开。

正确姿势是"先查、再引导、返回后再复查":

if (Build.VERSION.SDK_INT >= 23 && !Settings.canDrawOverlays(host)) { Intent i = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + host.getPackageName())); // 引导到宿主的权限页 host.startActivity(i); } // 返回回调里再次检查 canDrawOverlays,为 true 才展示悬浮窗

同时确认宿主在 AndroidManifest.xml 中声明了该权限,否则用户打开后查询结果永远是 false。

卡点二:沙盒应用发起悬浮窗时的 Overlay 权限透传

现象:宿主已授权,沙盒应用弹悬浮窗却失败。原因:沙盒的窗口调用全部被宿主 Hook 拦截、以宿主 UID 执行;宿主进程和 VAPP 进程的权限状态一旦不同步(比如用户刚在设置页撤掉授权),系统会直接撤窗。

VirtualApp 的窗口服务 Hook 入口在WindowManagerStub,它替换了系统的 WindowManager Binder 引用:

// WindowManagerStub.inject():把全局代理替换为 Hook 代理 WindowManagerGlobal.sWindowManagerService .set(getInvocationStub().getProxyInterface()); // 之后所有 addView / updateViewLayout 都经过 Hook 层

实现见 窗口服务 Hook 目录。适配要点仍是那句:窗口发起必须走宿主侧的权限判定结果,而不是本地缓存

卡点三:后台悬浮窗被系统回收怎么办

现象:熄屏或切后台后悬浮窗消失。原因:系统会主动清理后台窗口和低重要性进程;悬浮窗挂在已 pause 的 Activity 上时,会随 token 一起失效。

⚠️ 可靠的做法有两个:把悬浮窗生命周期挂到宿主的前台 Service 上(进程重要性高,窗口不被回收);或宿主回前台时主动补申请窗口:

@Override public void onResume() { // 宿主回到前台 if (shouldShowFloat() && floatView == null) { windowManager.addView(floatView, params); // 补申请被回收的窗口 } }

补申请必须在onResume之后做,在onPause/onStop里补会撞上 token 失效。

卡点四:Window Type 的跨版本兼容写法

现象:API 26+ 上用TYPE_PHONE弹窗口抛BadWindowType异常。原因:API 26 起TYPE_PHONE等旧类型保留给系统应用,第三方悬浮窗必须改用TYPE_APPLICATION_OVERLAY

int type = Build.VERSION.SDK_INT >= 26 ? WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY // API 26+:必须用它 : WindowManager.LayoutParams.TYPE_PHONE; // API 26-:用旧类型 WindowManager.LayoutParams lp = new WindowManager.LayoutParams( WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, type, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT);

悬浮窗权限适配 Checklist 📌

#检查项判断方式
1宿主声明SYSTEM_ALERT_WINDOW设置页无权限入口 = 未声明
2跳设置返回后canDrawOverlays为 true日志或断点验证
3沙盒窗口请求走宿主侧权限判定权限状态无本地缓存
4API 26+ 使用TYPE_APPLICATION_OVERLAY日志无BadWindowType
5宿主回后台再回前台后悬浮窗可补上真机在 API 29+ 验证
6撤销授权后窗口被移除且无残留撤销再授予,反复验证
7VAPP 进程退出后无窗口泄漏强杀宿主后检查屏幕

测试矩阵与后续 ✅

测试矩阵至少覆盖API 23(动态权限基线)、API 26(Window Type 变更)、API 30(后台启动限制)、API 34(最新系统行为)四档,并建议在主流通用 ROM 上各跑一遍相同用例。

VirtualApp 版本迭代较快,新系统上的权限行为也在持续变化,最新适配情况以官方仓库 issue 区的讨论为准。

【免费下载链接】VirtualAppVirtual Engine for Android(Support 14.0 in business version)项目地址: https://gitcode.com/GitHub_Trending/vi/VirtualApp

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/15 21:14:42

AI编程规范:构建可审计的人机协作契约

1. 这不是写给AI看的“说明书”,而是给团队留下的技术契约“项目中新增给AI制定的代码规范”——看到这个标题,第一反应不是“又一个AI工具配置文档”,而是:谁在用?用在哪?出了问题谁兜底?我带过…

作者头像 李华
网站建设 2026/9/15 21:13:46

扩散语言模型实战:从one-hot扩散到可控文本生成

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/15 21:06:23

Simulink二自由度车辆模型构建与应用

1. 项目背景与核心价值在车辆动力学研究中,二自由度模型是最基础也是最重要的分析工具之一。它能够有效反映车辆在横向和横摆两个自由度上的运动特性,而质心侧偏角和横摆角速度则是评估车辆操纵稳定性的关键指标。通过Simulink搭建这个模型,我…

作者头像 李华