首先,由于 APPLICATION_MEDIA_SUBLAYER 和 APPLICATION_MEDIA_OVERLAY_SUBLAYER 都小于0,因此,无论如何,字幕始终被渲染在页面的下方。又因为视频理应渲染在字幕的下方,所以 不推荐 开发者在使用 SurfaceView 渲染视频时调用 setZOrderOnTop(true),将视频放在页面视图的顶层。
其次,同时具有 setZOrderOnTop() 和 setZOrderMediaOverlay() 方法,显然是提供给两个不同 SurfaceView 分别使用的,以定义不同的渲染层级,因此同一个页面存在多个 SurfaceView 是正常的,开发者完全可以根据业务场景,合理运用。
- 令人头大的黑屏问题
在使用 SurfaceView 的过程中,笔者最终也遇到了 默认黑屏 的问题:
由于视频本身的加载和编解码的耗时,用户总是会先看到 SurfaceView 的黑色背景一闪而过,然后视频才开始播放的情况,对于产品而言,这种交互体验是 不可容忍 的。
通过上文读者知道,SurfaceView 拥有独立的绘制表面,因此常规对付 View 的一些手段——比如 setVisibility() 、setAlpha() 、setBackgroundColor() 并不能解决上述问题;因此,想真正解决它,就必须先弄清楚 SurfaceView 底层的绘制流程。
SurfaceView 虽然特殊,但其作为视图树的一个结点,其依然参与到了视图树常规绘制流程,这里我们直接看 SurfaceView 的 draw() 方法:
由此可见,当满足 !isAboveParent() 的条件——即 SurfaceView 的子图层类型位于宿主视图的下方时,SurfaceView 默认会将绘图表面的颜色指定为黑色。
显然,该问题最简单的解决方式就是对源码进行hook或者反射,遗憾的是,上文我们也提到了,出于安全性的考量,SurfaceView 的源码是没有公开暴露的。