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

复用SurfaceView播放视频触发SIGSEGV(信号11)崩溃问题求助

崩溃根本原因分析
  • 该崩溃是Android 9(API 28)及以下版本的原生系统bug,触发路径为SurfaceView的异步位置更新逻辑:系统会将SurfaceView的位置变更任务放到hwui后台工作线程(hwuiTask)异步执行,当你复用SurfaceView、或者将SurfaceView从视图树移除后重新添加时,旧的SurfaceControl实例已经被系统回收释放,但异步任务队列中未执行完的位置更新任务仍然持有该SurfaceControl的无效引用,执行时访问空指针偏移0x10的成员,触发SIGSEGV崩溃。
  • 复用SurfaceView的场景下,如果未等待上一次Surface销毁回调完成就直接绑定新的播放数据源,会大幅提升该问题的触发概率。
可行解决方案

方案1:调整SurfaceView复用逻辑(兼容性最好,无性能损耗)

复用SurfaceView前执行以下操作,确保异步任务被清空:

  1. 先调用yourSurfaceView.setVisibility(View.GONE),再调用requestLayout()触发视图重绘
  2. 等待SurfaceHolder.Callback.surfaceDestroyed回调明确触发后,再将SurfaceView设置为View.VISIBLE,绑定新的播放数据源
  3. 禁止在surfaceDestroyed回调执行完成前,给SurfaceView绑定新的渲染上下文

方案2:关闭SurfaceView异步位置更新(仅适用于API 26~28)

通过反射关闭后台异步位置更新逻辑,让位置更新同步在主线程执行,避免异步任务持有无效引用,代码示例如下:

try {
    Method setEnableBgUpdates = SurfaceView.class.getDeclaredMethod("setEnableBackgroundPositionUpdates", boolean.class);
    setEnableBgUpdates.setAccessible(true);
    setEnableBgUpdates.invoke(yourSurfaceView, false);
} catch (Exception e) {
    // 非Android 8.0~9版本无该方法,直接忽略即可
}

方案3:替换为TextureView实现

TextureView没有SurfaceControl异步更新的底层逻辑,复用逻辑更简单,完全不会触发该崩溃。唯一缺陷是比SurfaceView多一次图层合成步骤,性能略低,普通视频播放场景完全可以满足需求。

方案4:放弃SurfaceView复用

如果业务场景允许,每次播放新视频时直接创建新的SurfaceView实例,销毁旧实例,从根源避免旧实例的异步任务访问无效内存的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 15:12:02