如何在同一Android应用中兼容VR与2D模式Activity并解决切换崩溃问题?
同一Oculus Quest 2应用中2D/VR模式切换的配置问题
我有一个面向Oculus Quest 2的Android应用,原本仅包含一个VR模式的Activity。现在希望添加第二个使用普通控件的非VR Activity。已知Oculus Quest 2支持运行非VR Android应用:新增带有MAIN和LAUNCHER intent-filter的非VR Activity,同时保留原Activity的com.oculus.intent.category.VR标记后,启动应用可在VR环境中看到悬浮的2D窗口UI,但调用startActivity()启动VR Activity时出现崩溃,崩溃日志如下:
2023-08-24 10:14:49.784 27370-27784 VrRuntimeClient com.x.project I UpdateEvents: HMT was mounted 2023-08-24 10:14:49.784 27370-27784 VrRuntimeClient com.x.project I Client has lost focus. 2023-08-24 10:14:49.796 27370-27784 OsSdk com.x.project E error getting shared memory region, memory type: HeadTracker, failed with Status(-1, EX_SECURITY): 'request throttled' 2023-08-24 10:14:49.800 27370-27784 AudioCapture com.x.project I AudioCapture::PauseAudioCapture 2023-08-24 10:14:49.801 27370-27784 OsSdk com.x.project E error getting shared memory region, memory type: HeadTracker, failed with Status(-1, EX_SECURITY): 'request throttled' 2023-08-24 10:14:49.802 27370-27784 OsSdk com.x.project E error getting shared memory region, memory type: HeadTracker, failed with Status(-1, EX_SECURITY): 'request throttled' 2023-08-24 10:14:49.802 27370-27784 OsSdk com.x.project E error getting shared memory region, memory type: HeadTracker, failed with Status(-1, EX_SECURITY): 'request throttled' 2023-08-24 10:14:49.802 27370-27784 Telemetry com.x.project W [OpenXR] pose validation failure; 2023-08-24 10:14:49.803 27370-27784 libc com.x.project A Fatal signal 6 (SIGABRT), code -1 (SI_QUEUE) in tid 27784 (Thread-2), pid 27370 (arch.project) ---------------------------- PROCESS STARTED (27812) for package com.x.project ---------------------------- 2023-08-24 10:14:50.286 27810-27810 DEBUG pid-27810 A Cmdline: com.x.project 2023-08-24 10:14:50.286 27810-27810 DEBUG pid-27810 A pid: 27370, tid: 27784, name: Thread-2 >>> com.x.project <<< 2023-08-24 10:14:50.286 27810-27810 DEBUG pid-27810 A #01 pc 0000000001562a80 /data/app/~~7Rj4cfcqEuNaKBJTZ8lgfg==/com.x.project-BM56eOP_LGFnK7Uti4Fzdw==/base.apk (std::sys::unix::abort_internal::hd376a7a5dfef13f8+4) 2023-08-24 10:14:50.286 27810-27810 DEBUG pid-27810 A #02 pc 0000000001558ff8 /data/app/~~7Rj4cfcqEuNaKBJTZ8lgfg==/com.x.project-BM56eOP_LGFnK7Uti4Fzdw==/base.apk (rust_panic+120) 2023-08-24 10:14:50.286 27810-27810 DEBUG pid-27810 A #03 pc 0000000001558e0c /data/app/~~7Rj4cfcqEuNaKBJTZ8lgfg==/com.x.project-BM56eOP_LGFnK7Uti4Fzdw==/base.apk (std::panicking::rust_panic_with_hook::hae676ea4cb54d372+664) 2023-08-24 10:14:50.286 27810-27810 DEBUG pid-27810 A #04 pc 0000000001558b54 /data/app/~~7Rj4cfcqEuNaKBJTZ8lgfg==/com.x.project-BM56eOP_LGFnK7Uti4Fzdw==/base.apk (std::panicking::begin_panic_handler::_$u7b$$u7b$closure$u7d$$u7d$::h28e3779ad5029fec+200) 2023-08-24 10:14:50.286 27810-27810 DEBUG pid-27810 A #05 pc 00000000015565a8 /data/app/~~7Rj4cfcqEuNaKBJTZ8lgfg==/com.x.project-BM56eOP_LGFnK7Uti4Fzdw==/base.apk (std::sys_common::backtrace::__rust_end_short_backtrace::hcc3186f99b814c53+4) 2023-08-24 10:14:50.286 27810-27810 DEBUG pid-27810 A #06 pc 00000000015588d8 /data/app/~~7Rj4cfcqEuNaKBJTZ8lgfg==/com.x.project-BM56eOP_LGFnK7Uti4Fzdw==/base.apk (rust_begin_unwind+108) 2023-08-24 10:14:50.286 27810-27810 DEBUG pid-27810 A #07 pc 0000000000ec790c /data/app/~~7Rj4cfcqEuNaKBJTZ8lgfg==/com.x.project-BM56eOP_LGFnK7Uti4Fzdw==/base.apk (core::panicking::panic_fmt::hf634d2dad967350c+44) 2023-08-24 10:14:50.286 27810-27810 DEBUG pid-27810 A #08 pc 0000000000ec7cd8 /data/app/~~7Rj4cfcqEuNaKBJTZ8lgfg==/com.x.project-BM56eOP_LGFnK7Uti4Fzdw==/base.apk (core::result::unwrap_failed::heb325dbe9de0f88a+84) 2023-08-24 10:14:50.286 27810-27810 DEBUG pid-27810 A #09 pc 0000000000f69078 /data/app/~~7Rj4cfcqEuNaKBJTZ8lgfg==/com.x.project-BM56eOP_LGFnK7Uti4Fzdw==/base.apk (core::result::Result$LT$T$C$E$GT$::unwrap::hfaa71aa6fc424486+124) 2023-08-24 10:14:50.286 27810-27810 DEBUG pid-27810 A #10 pc 0000000000f47314 /data/app/~~7Rj4cfcqEuNaKBJTZ8lgfg==/com.x.project-BM56eOP_LGFnK7Uti4Fzdw==/base.apk (project::vr_engine::menu_exp::MenuExp::draw_inner_gl::h4b88970d936f21e9+1088) ...
所需额外配置及修复步骤
正确管理VR Runtime生命周期
从日志中的VrRuntimeClient: Client has lost focus和OsSdk: error getting shared memory region可知,切换到2D Activity时VR Runtime未被正确释放,再次启动VR Activity会引发资源/权限冲突。在启动2D Activity前,必须主动释放VR相关资源:- 调用Oculus SDK的
VrApi.Shutdown()(原生SDK场景)或对应引擎(Unity/Unreal)的VR退出接口 - 确保GL上下文、头部追踪等VR资源被完全释放
- 调用Oculus SDK的
调整Activity启动模式与Intent标记
- 给VR Activity设置
android:launchMode="singleTask"或singleInstance,避免重复创建实例导致资源冲突 - 启动VR Activity时,在Intent中添加
com.oculus.intent.extra.VR_LAUNCH标记,明确告知系统切换到VR模式:Intent vrIntent = new Intent(this, VrActivity.class); vrIntent.putExtra("com.oculus.intent.extra.VR_LAUNCH", true); startActivity(vrIntent);
- 给VR Activity设置
配置Manifest权限与特性
- 确保应用拥有
com.oculus.permission.MANAGE_VR权限(按需添加) - 在
<application>标签中设置android:hardwareAccelerated="true",VR和2D Activity均需开启硬件加速 - 给非VR Activity添加
android:resizeableActivity="true",适配Quest 2的悬浮窗口模式
- 确保应用拥有
处理VR与非VR线程切换
崩溃日志显示Rust线程触发panic,说明VR后台线程未在切换到2D模式时正确终止:- 在2D Activity的
onResume()中终止所有VR相关后台线程 - 在VR Activity的
onCreate()中重新初始化VR线程,避免复用失效资源
- 在2D Activity的
内容的提问来源于stack exchange,提问作者Mutant Bob
相关产品推荐
相关产品推荐

