Android TexureView、SurfaceView 测试以及堆叠测试

背景

最近App开发中遇到了一个场景,需要两到三个SurfaceView做叠层,并涉及到小窗口播放视频的场景,由于SurfaceView的某些限制,无法有个良好的实现,遂调研了一下解决方案,涉及了TexureView,也发现了一些问题,有些问题并没有给自己找到答案,但是整体思路还是比较完整了。

此文解决已问题

  • 多层SurfaceView 或者SurfaceView与TexureView混合画面的排布;
  • 透明的SurfaceView 模拟AR效果的排布可能遇到问题,只能是多个SurfaceView实现。或多TexureView功能上是无法实现的,TexureView与SurfaceView的混合会遇到问题,并找出原因。

关于重叠的时候出现的问题

使用双Surface 的重叠测试

使用双Surface做重叠操作:
//topsurfaceView.setZOrderOnTop(true);
topsurfaceView.setZOrderMediaOverlay(true); //onAttachedToWindow之前设置
topsurfaceView.getHolder().setFormat(PixelFormat.TRANSLUCENT); //可以在onAttach后设置
两个SurfaceView的重叠区域能正常显示,并实现AR场景.

MacDown Screenshot

如果Bottom是texureView,VideoView在中间,而SurfaceView 在最上层。如下图所示:

MacDown Screenshot



SurfaceView的透明部分一部分能显示VideoView的视频,另外一部分黑色,并没有透明到TexureView,
主要原因从SurfaceView的文档我们知道,surface总是在当前的Window后面绘制出来的,而加入到View Tree里面的只是一占位的View,也就是这么Window的一个洞。由于TexureView在当前的window上,那么SurfaceView的surface在这个Window的后面,所以TextureView会显示黑色,因为后面没有可见的内容了。

注意事项

TextureView如果设置了背景色,将无法绘制

关于这两个类的描述

SurfaceView

android.view.View
    ↳   android.view.SurfaceView
        ↳   android.opengl.GLSurfaceView
        ↳   android.widget.VideoView

Provides a dedicated drawing surface embedded inside of a view hierarchy. You can control the format of this surface and, if you like, its size; the SurfaceView takes care of placing the surface at the correct location on the screen

The surface is Z ordered so that it is behind the window holding its SurfaceView; the SurfaceView punches a hole in its window to allow its surface to be displayed. The view hierarchy will take care of correctly compositing with the Surface any siblings of the SurfaceView that would normally appear on top of it. This can be used to place overlays such as buttons on top of the Surface, though note however that it can have an impact on performance since a full alpha-blended composite will be performed each time the Surface changes.

SurfaceView 提供了一个专门的Surface 嵌入到view Hierarchy中,你能控制这个surface 的格式,大小,位置等.

The Surface是纵深排序(Z-ordered)的,这表明它总在自己所在Window的后面。Surfaceview提供了一个可见区域,只有在这个可见区域内的surface部分内容才可见,可见区域外的部分不可见。surface的排版显示受到视图层级关系的影响,它的兄弟视图结点会在顶端显示。这意味者 surface的内容会被它的兄弟视图遮挡,这一特性可以用来放置遮盖物(overlays)(例如,文本和按钮等控件)。
注意,如果surface上面 有透明控件,那么它的每次变化都会引起框架重新计算它和顶层控件的透明效果,这会影响性能。

TexureView

java.lang.Object
   ↳    android.view.View
       ↳    android.view.TextureView

A TextureView can be used to display a content stream. Such a content stream can for instance be a video or an OpenGL scene. The content stream can come from the application's process as well as a remote process.

TextureView can only be used in a hardware accelerated window. When rendered in software, TextureView will draw nothing.
能显示content stream,比如视频或者OpenGL 画面。这个内容流能来源于别的进程,比如Camera.
TextureView 只能用于支持硬件加速的Window,如果用软解渲染,will draw nothing.

关于这两个Class的异同

1、在显示实现方面,TextureView没有创建单独的Window,跟SurfaceView是通过对当前的Window挖一个洞透过去显示的;<br />
2、TexureView更普通View一样,更方便与移动、变形、做动画等;<br />
3、TexureView只支持硬件加速,不支持软件解码,注意Activity;<br />
4、TexureView在显示camera 预览是,不允许同时画别的东西,即便是lockCanvas了;<br />

1、都能支持堆叠<br />
2、只有在attachedToWindow 后才可用;<br />

相关的一些类的方法

当场景中有多个SurfaceView的时候,上层的SurfaceView可能会被下层的遮挡,这个时候需要使用setZOrderOnTop(true)或者setZOrderMediaOverlay(true)来控制SurfaceView的显示层次。
Android SDK对两个函数的描述:
public void setZOrderOnTop(boolean onTop)

Added in API level 5

Control whether the surface view's surface is placed on top of its window. Normally it is placed behind the window, to allow it to (for the most part) appear to composite with the views in the hierarchy. By setting this, you cause it to be placed above the window. This means that none of the contents of the window this SurfaceView is in will be visible on top of its surface.
Note that this must be set before the surface view's containing window is attached to the window manager.

Calling this overrides any previous call to setZOrderMediaOverlay(boolean).
控制这个surfaceView是否被放在窗口顶层。通常,为了使它与View树整合,它被放在窗口之后。通过这个函数,你可以使SurfaceView被放在窗口顶层。这意味着它所在的窗口的其他内容都不可见。

(注:可以设置surfaceView透明来使其他内容可见)这个函数必须在窗口被添加到窗口管理器之前设置。

调用这个函数会使之前调用的setZOrderMediaOverlay(boolean)无效;

public void setZOrderMediaOverla(boolean isMediaOverlay)

Added in API level 5

Control whether the surface view's surface is placed on top of another regular surface view in the window (but still behind the window itself). This is typically used to place overlays on top of an underlying media surface view.
Note that this must be set before the surface view's containing window is attached to the window manager.
Calling this overrides any previous call to setZOrderOnTop(boolean).
控制这个surfaceView是否被放在另一个普通的surfaceView上面(但是仍然在窗口之后)。这个函数通常被用来将覆盖层至于一个多媒体层上面。
这个函数必须在窗口被添加到窗口管理器之前设置。
调用这个函数会使之前调用的setZOrderOnTop(boolean)无效。

一些知识点

z-ordered

Z-order
is an ordering of overlapping two-dimensional objects, such as windows in a stacking window manager, shapes in a vector graphics editor, or objects in a 3D application.[1] One of the features of a typical GUI is that windows may overlap, so that one window hides part or all of another. When two windows overlap, their Z-order determines which one appears on top of the other.

硬件加速

主要有4个控制级别,下面我举列一下常用的:

//For Application  
<root>
<application android:hardwareAccelerated="true" />
</root>
//For Activity
<root>
<application android:hardwareAccelerated="true">
    <activity ... />
    <activity android:hardwareAccelerated="false" />
</application>
</root>
//For Window
getWindow().setFlags(
    WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
    WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

结语

如果本文中出现了一些问题,希望大家指正,谢谢

[Source Sample Download] (https://github.com/waesteve/CameraAndVideo/tree/master)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容