You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用ArCore时Session.update()触发段错误(SIGSEGV)崩溃

问题原因

崩溃的核心原因是ArCore Session的初始化线程与GL线程不匹配:

  • 你在主线程(onViewCreated)创建了Session,但GLSurfaceView的Renderer方法(onSurfaceCreated、onDrawFrame)运行在独立的GL线程中。
  • ArCore Session需要与使用它的OpenGL上下文绑定,跨线程操作会导致Session无法正确关联GL上下文,最终在session.update()时触发空指针访问(SIGSEGV)。
  • 额外问题:GL_TEXTURE_EXTERNAL_OES类型纹理不支持MIPMAP,你设置的GL_LINEAR_MIPMAP_LINEAR过滤模式会导致OpenGL状态错误,加剧崩溃风险。
解决方案

1. 将Session初始化移至GL线程

把Session的创建、配置逻辑移到onSurfaceCreated方法中(该方法在GL线程执行,确保Session与当前GL上下文绑定)。

2. 修正纹理过滤模式

移除MIPMAP相关的过滤设置,改用GL_LINEAR适配GL_TEXTURE_EXTERNAL_OES纹理。

3. 增加Session空值判断

在生命周期方法中判断Session是否已初始化,避免空指针调用。

修改后的完整代码
class MainFragment : Fragment(R.layout.fragment_main), GLSurfaceView.Renderer {
    private lateinit var surfaceView: GLSurfaceView
    private var session: Session? = null // 改为可空类型

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        surfaceView = view.findViewById(R.id.surface_view)
        surfaceView.setRenderer(this)
        surfaceView.renderMode = GLSurfaceView.RENDERMODE_CONTINUOUSLY
        // 移除主线程中的Session初始化代码
    }

    override fun onResume() {
        super.onResume()
        session?.resume()
    }

    override fun onPause() {
        super.onPause()
        session?.pause()
    }

    override fun onDestroy() {
        super.onDestroy()
        session?.close()
        session = null // 清理资源
    }

    override fun onSurfaceCreated(gl: GL10, cfg: EGLConfig) {
        GLES20.glClearColor(1f, 1f, 1f, 1f)
        
        // 在GL线程初始化Session
        val arSession = Session(requireContext())
        val config = Config(arSession)
        arSession.configure(config)
        this.session = arSession

        val texture = intArrayOf(-1)
        GLES20.glGenTextures(1, texture, 0)
        if (texture[0] < 0) {
            throw Exception("Failed to Create OpenGL texture")
        }
        GLES20.glActiveTexture(GLES20.GL_TEXTURE0)
        GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, texture[0])
        GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE)
        GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE)
        // 修正为GL_LINEAR,适配EXTERNAL_OES纹理
        GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR)
        GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR)
        GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, 0)
        arSession.setCameraTextureName(texture[0])
    }

    override fun onSurfaceChanged(gl: GL10, width: Int, height: Int) {
        GLES20.glViewport(0, 0, width, height)
    }

    override fun onDrawFrame(gl: GL10) {
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT)
        session?.update() // 空值安全调用
    }
}

额外说明

  • 手动EGL线程能正常运行,是因为你在同一个线程中完成了Session初始化、GL上下文创建和ArCore操作,线程上下文匹配。
  • 确保设备已安装ArCore服务,且相机权限已正确授予(可在onViewCreated中添加权限申请逻辑)。

内容的提问来源于stack exchange,提问作者user12653758

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 11:17:54