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

Android Compose LazyGrid重排视频瓦片时EGL_BAD_ACCESS错误排查

问题

使用Android Compose的LazyVerticalGrid展示视频网格,通过继承TextureView的自定义Renderer加载视频流。正常显示无问题,但重排视频瓦片(如交换首尾项)时,部分视频冻结、变绿,日志报错:

E/libEGL: eglMakeCurrentImpl:1038 error 3002 (EGL_BAD_ACCESS)
E/Render: eglMakeCurrent failed
E/Render: EGL error = 0x3002
E/Render: cannot swap buffers!

相关代码:

屏幕布局代码

LazyVerticalGrid(
    ...
) {
    items(items = members, key = { id }) { member ->

       val context = LocalContext.current
       AndroidView(factory = {
       Renderer(context, ...).apply {
          layoutParams = FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT)
       }
    }
 }

自定义View代码

public class Renderer extends TextureView implements TextureView.SurfaceTextureListener {
   private SurfaceTexture mSurface;
   private EGLDisplay mEglDisplay;
   private EGLSurface mEglSurface;
   private EGLContext mEglContext;
   private EGL10 mEgl;
   private EGLConfig eglConfig;
   private GL10 mGl;

   ... //some code for creating the surface
}

对OpenGL了解有限,求问引发EGL_BAD_ACCESS及缓冲区问题的原因。


原因分析
  • EGL资源未正确释放与复用冲突:LazyVerticalGrid的items使用key后,重排时会复用已有View实例而非重建,但自定义Renderer中的EGL资源(EGLDisplay、EGLSurface、EGLContext等)未在View复用前完成清理。当View被复用于新的视频流时,旧的EGL上下文仍绑定在当前线程,新的EGL操作尝试访问已失效或被占用的资源,触发EGL_BAD_ACCESS。
  • SurfaceTexture生命周期未与View绑定:TextureView的SurfaceTexture会在View被detach或复用时发生变化,但自定义Renderer可能未正确处理SurfaceTextureListener的回调(比如onSurfaceTextureDestroyed时未释放EGL资源)。重排时,旧的SurfaceTexture已失效,但EGL仍尝试向其交换缓冲区,导致冻结或绿屏。
  • 线程安全问题:EGL操作(如eglMakeCurrent、eglSwapBuffers)必须在创建EGL上下文的线程执行。如果视频渲染线程未与View的生命周期绑定,重排时View被切换到新的线程环境,或多个线程同时操作同一EGL资源,会引发资源访问冲突。
  • EGL上下文未正确解绑:当View被复用时,若未先调用eglMakeCurrent(null, null, null, null)解绑旧的EGL上下文,新的渲染操作尝试绑定新上下文时,会因旧上下文仍占用当前线程的EGL资源而报错。

内容的提问来源于stack exchange,提问作者Oussèma Hassine

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 12:01:21